Images:
Narrative:
A vibrator is attached to a sensor which senses the rate of vibration. Based on this vibration, a light is turned on underneath a box. How much the vibrator vibrates determines how bright the light gets. So if the vibrator vibrates a lot, the light gets really bright, and if the vibrator does not vibrate a lot, the light does not get as bright. The brightness of the light is captured by another sensor which senses how bright the light is. The sensor then tells the computer how much to turn a motor to move a stick. So if the light is really bright, the motor is told to move the stick very far, and if the light is not as bright, the motor is told to move the stick not as far. The states of all of these inputs and outputs (i.e. the level of change) is fed to a display that shows how much each step has changed.
Progress images:
Discussion:
Throughout the development process, the easiest part was definitely the planning stage. The stage where we brainstormed three different ideas and paid little attention towards the actual build. It was a time where we let our imaginations run wild and had little to debug since the projects weren’t fully implemented, only idealized. Once we finally got to the building and coding stage however, we found implementing past the planning phase is much harder. It involved having to build the circuit while making sure none of the wires had loose connections, building a connection between the vibration motor and Arduino which meant stripping two male- to-female wires as well as the vibration motor and securing them together with athletic tape (neither of us had electrical tape on standby), measuring the value of the accelerometer with a broken accelerometer (which we only later realized), soldering an LED and photoresistor, building a linkage system out of popsicle sticks, and figuring out the code to tie these pieces together. All of these steps came with their own frustrating challenges that allowed us to grown our knowledge of sensors and Arduino development
The most frustrating thing that we learned was that analog input pins on the Arduino can pick up a lot of noise from other parts of the board. In particular, adjacent analog input pins can read signals from each other almost as if they were connected. In our case, we thought the accelerometer was wired to the Arduino and we were reading a signal from it, but it turned out to not be connected to the Arduino at all. Despite this fact, we still read an analog input from that pin and when compared to the signal produced by the potentiometer, the signals matched exactly in how they changed with input into the potentiometer. Instead of reading the accelerometer data, we were actually reading ghost signals from the adjacent potentiometer input pin which was only solved by moving the accelerometer input pin to the opposite side of the analog input pin array.
We also learned the importance of data structures in signal processing, especially when performing arithmetic operations. While trying to write values to our stepper motor, we came into a problem where we couldn’t get our code to run for more than 1 loop. This was caused by the way in which we were storing the variables used to calculated step count. We chose to store the all our variables as type “int” by default which meant that it would round down to the nearest integer when it stored the step value. The some of the values we were setting as the used to calculate the number of steps, however, were on a scale of 0 to π which meant that they were frequently in between 0 and 1. Because these values were rounded down even if they were 0.9, this meant that we ended up with division by zero causing our program to break and only run once. Storing the variables used to calculate step number solved this problem.
Looking back now, there are several factors that would’ve changed the direction of the project completely. For instance, the first time we met to work on the project was the Sunday before the project was due because we thought it was plenty of time before the deadline. This was a mistake on our part and we should’ve been more proactive about meeting before Sunday (i.e. on Friday and Saturday). This would’ve given us more time to realize where we were going wrong and what we could’ve done to fix the problem. Another factor would’ve been a better sensor to detect the frequency of the vibration coming from the vibration motor. We noticed that the accelerometer was pretty noisy and we had trouble reading the sensor. Maybe these changes would have improved our project, or possibly caused new problems, but these are just a few we’ve chosen to reflect on.
Functional Block Diagram and Schematic
Code Submission
/* 60-223, Project 1 Amelia Lopez (aelopez) James Kyle (jkyle1) Time spent: 8 hours Description: Takes in a vibration input, transforms that analog input value into an LED brightness, which is then transformed into a distance controlled by the stepper motor. Vibration input is read through an accelerometer and LED intensity value is read through a photoresistor. Challenges: The stepper motor isn't responding to the photoresistor's value as we intended, so that half of the code is buggy. Since the vibration motor works on a pulse, this causes the light to blink fairly fast but it still dims/brightens as a result of the vibration motor speed. Next time: Definitely take more time to understand what went wrong between the photoresistor value and the stepper motor desired output. I think looking at the Arduino libraries is a good place to start with this because maybe someone else had the same problem and published their solution for open source use that we can cite and tweak to the specs of our project Collaboration and Sources: 1) For the accelerometer readings (line 163-167), used code from https://tinyurl.com/Accelerometerlink 2) For LCD display, used code from http://www.arduino.cc/en/Tutorial/LiquidCrystalHelloWorld 3) For stepper motor, used code from https://tinyurl.com/StepperMotorLink Inputs: Potentiometer (which varies vibration motor rate) In-between: LED Output: Stepper motor, LCD display Pin mapping: Arduino pin | type | description ------------|--------|------------- A0 input potentiometer A1 input X-pin Accelerometer A2 input Y-pin Accelerometer A3 input Z-pin Accelerometer A4 input photoresistor 13 output Stepper Motor Driver IN1 12 output Stepper Motor Driver IN2 ~11 output Vibration motor ~10 output Stepper Motor Driver IN3 ~9 output Stepper Motor Driver IN4 8 output LCD RS 7 output LCD E ~6 output LED ~5 output LCD D4 4 output LCD D5 ~3 output LCD D6 2 output LCD D7 (digital PWM~) LCD circuit: LCD RS pin to digital pin 8 LCD Enable pin to digital pin 7 LCD D4 pin to digital pin 5 LCD D5 pin to digital pin 4 LCD D6 pin to digital pin 3 LCD D7 pin to digital pin 2 LCD R/W pin to ground LCD VSS pin to ground LCD VCC pin to 5V 10K resistor: ends to +5V and ground wiper to LCD VO pin (pin 3) */ #include <Stepper.h> #include <LiquidCrystal.h> //DECLARING ARDUINO PINS const int POTENT = A0; const int ACCE_X = A1; const int ACCE_Y = A2; const int ACCE_Z = A3; const int PHOTORES = A4; const int STEP_IN1 = 13; const int STEP_IN2 = 12; const int VIBRATION_MOTOR = 11; const int STEP_IN3 = 10; const int STEP_IN4 = 9; const int LCD_RS = 8; const int LCD_E = 7; const int LED_PIN = 6; const int LCD_D4 = 5; const int LCD_D5 = 4; const int LCD_D6 = 3; const int LCD_D7 = 2; //DECLARING INTS FOR ACCELOREMETER AND LED int accel_xVal = 0; int lightVal = 0; //DECLARING MISC. CONSTANTS USEFUL TO STEPPER MOTOR const int maxAnalogValue = 1023; const int stepsPerRevolution = 64; //fits the specification of our motor const int motorSpeed = 20; float currentDistance = distOfString / 2; //PRECONDITION: OBJECT HAS TO BE HALFWAY int targetDistance; float steps; bool stepMotor = false; //DECLARING INTS FOR LCD WAITING TIMES const int WAIT_TIME = 300; unsigned long timeVariable = 0; // initialize the library by associating any needed LCD interface pin // with the Arduino pin number it is connected to LiquidCrystal lcd(LCD_RS, LCD_E, LCD_D4, LCD_D5, LCD_D6, LCD_D7); Stepper myStepper(stepsPerRevolution, STEP_IN1, STEP_IN2, STEP_IN3, STEP_IN4); void setup() { //INPUT PINS pinMode(POTENT, INPUT); pinMode(VIBRATION_MOTOR, OUTPUT); pinMode(ACCE_X, INPUT); pinMode(ACCE_Y, INPUT); pinMode(ACCE_Z, INPUT); pinMode(PHOTORES, INPUT); //OUTPUT PINS pinMode(LED_PIN, OUTPUT); pinMode(VIBRATION_MOTOR, OUTPUT); //MOTOR functions myStepper.setSpeed(motorSpeed); // set up the LCD's number of columns and rows: lcd.begin(16, 2); //print constant letters on screen lcd.print("i:"); lcd.setCursor(6, 0); lcd.print("m:"); lcd.setCursor(8, 1); lcd.print("0"); lcd.setCursor(12, 1); lcd.print("o:"); } void loop() { //READING POTENTIOMETER VALUE //POTENTIOMETER VALUE DETERMINES VIBRATION MOTOR RATE int potentValue = analogRead(POTENT); // 0 <= potentValue <= 1023 int vibrationStrength = map(potentValue, 0, 1023, 0, 153); // 0 <= vibrationStrength <= 155 analogWrite(VIBRATION_MOTOR, vibrationStrength); //using PWM int xVal = analogRead(ACCE_X); //ACCELEROMETER MEASURES VIBRATION MOTOR RATE (x-axis) //RATE MEASURED IS USED TO LIGHT UP AN LED A CERTAIN INTENSITY int oldX = accel_xVal; accel_xVal = analogRead(ACCE_X); int dif = abs(oldX - accel_xVal); int lightVal = map(dif, 0, 520, 0, 255); analogWrite(LED_PIN, lightVal); //PHOTORESISTOR TAKES IN LED INTENSITY VALUE //PHOTORESISTOR VALUE USED TO CHANGE STEPPER MOTOR int photoValue = analogRead(PHOTORES); // 0 <= potentValue <= 1023 int lowbound = 700; //bright light int highbound = 990; //no light //int stepVal = map(photoValue, lowbound, highbound, targetDistance = map(photoValue, 850, 1000, 0, 60); //Convert photoresistor value into desired distance into rotations for stepper motor if (targetDistance != currentDistance) { steps = (targetDistance - currentDistance) * stepsPerRevolution / 360; currentDistance = targetDistance; stepMotor = true; } //Setting step stepper motor to desired distance if (stepMotor == true) { myStepper.step(steps); delay(500); //Wait 0.5s for motor to finish moving stepMotor = false; } //UPDATING VALUES ON LCD if (millis() - timeVariable > WAIT_TIME) { //updating input sensor value lcd.setCursor(2, 0); lcd.print(map(xVal, 0, 525, 0, 99)); //updating middle step actuator lcd.setCursor(8, 0); lcd.print(map(lightVal, 0, 255, 0, 99)); //updating middle step sensor value lcd.setCursor(8, 1); lcd.print(map(photoValue, lowbound, highbound, 0, 99)); //updating output actuator value lcd.setCursor(14, 1); lcd.print(map(steps, 0, currentDistance, 0, 99)); delay(200); timeVariable = millis(); } }