Description:
The IR proximity sensor reads the distance of a specific point of the rotating disk. If it takes less time to get closer to the sensor, the rotational speed is faster. When rotational speed is faster, the LED gets brighter. The photoresistor senses the brightness of the light. The brighter the light, the servo motor moves the magnet further away, which creates a stronger magnetic field.
Progress:
Discussion:
Something that was difficult to figure out was how to use the IR proximity sensor to read rotational speed. We needed it to measure difference in the time when the stick got close to it at first and then close to it again. We wrote software to have the sensor read the time only the first time it gets approached, before spinning away and back again.
Another thing that was difficult was getting the servo motor to stop being really jittery. At first, we noticed that the LED light was flickering, which affected the motor, which in turn made the light flicker. We use an external power to power the servo motor to give it a steady supply of electricity, which stopped the LED from flickering.
We then realized that the noisy data that the photoresistor was picking up was causing the problem. We figured out through testing the range of the LED with analog write that there was a consistent pattern of spiking. We solved this problem by using moving average filter code from the course website. This tweak got rid of the majority of the twitching of the servo motor.
Schematic:
/* Project 1: Double Transducer: Rotation Speed to Magnetic Field Strength Varsha Shankar and Suzanne Nie (varshas)+(suzannen) Description: The double trasnducer takes in rotational speed through the IR proximity sensor and outputs that as a LED brightness. Then a photoresistor reads the LED brightness and outputs that to a servo motor that moves a magnet towards the front as the LED gets brighter and opposite and LED gets dimmer. This changes the magnetic field. Pin mapping: pin | mode | description ------|--------|------------ 5 output LED A2 input photoresistor A3 input potentiometer[testing] A1 input IR sensor 3 output servo Libraries Used: LiquidCrystal Arduino library for I2C LCD displays */ #include <Servo.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> //used to make the data coming in less noisy float filtered_val = 0; const float PREV_WEIGHT = 0.8; const float CUR_WEIGHT = 1 - PREV_WEIGHT; LiquidCrystal_I2C screen(0x27, 16, 2); int LED_brightness; const int LEDPIN = 5; const int PHOTOPIN = A2; int photopinval; Servo servo; const int servopin = 3; int servopos; //Testing purpose //const int potpin = A3; //int oldpotval; //int newpotval; //int potval; int IRval; int IRPin = A1; //used to measure the time difference between each rotation unsigned long timer; unsigned long oldtime; unsigned long newtime; unsigned long timediff; //used to take only one measurement each rotation bool far; void setup() { pinMode(PHOTOPIN, INPUT); pinMode(LEDPIN, OUTPUT); //can use this to test //pinMode(potpin, INPUT); pinMode(IRPin, INPUT); servo.attach(servopin); Serial.begin(115200); screen.init(); screen.backlight(); screen.home(); timer = millis(); oldtime = 0; newtime = 0; timediff = 0; } void loop() { timer = millis(); photopinval = 925 - analogRead(PHOTOPIN); //checks to see if an object is close enough starting and ending a rotation IRval = analogRead(IRPin); if (IRval > 450 and far == false) { far = true; newtime = timer; if ((newtime - oldtime) > timediff) { } timediff = newtime - oldtime; oldtime = newtime; } if (IRval < 450 and far == true) { far = false; } LED_brightness = map(timediff, 0, 750, 0, 255); if (LED_brightness > 255) { LED_brightness = 255; } else if (LED_brightness < 0) { LED_brightness = 0; } analogWrite(LEDPIN, 255 - LED_brightness); filtered_val = filtered_val * PREV_WEIGHT + photopinval * CUR_WEIGHT; servopos = map(filtered_val, 29, 750, 0, 180); servo.write(servopos); screen.home(); screen.print("i:"); screen.setCursor(12, 1); screen.print("o:"); screen.setCursor(6, 0); screen.print("m:"); if (timer % 50 == 0) { screen.setCursor(2, 0); if (timediff <= 0) { timediff = 0; } if (timediff > 750){ timediff = 750; } screen.print(99 - map(timediff, 0, 750, 0, 99)); screen.setCursor(14, 1); screen.print(map(servopos, 0, 180, 0, 99)); screen.setCursor(8, 0); screen.print(99 - map(LED_brightness, 0, 255, 0, 99)); screen.setCursor(8, 1); if (filtered_val < 29) { filtered_val = 29; } if (filtered_val > 750) { filtered_val = 750; } screen.print(map(filtered_val, 29, 750, 0, 99)); } }
Comments are closed.