One of my previous Arduino projects was an Engineering 1 final project where we had to receive a small foam ball into a box 24″x12″x12″, then launch it into the next box that is immediately next to ours. Our plan began with a spring loaded catapult system that quickly proved to be unwieldy. Due to other finals going on at the time, it was only days before the competition (the result of which, by the way, determined 50% of our class grade) that we scrapped our old plan, and came up with a new one.
Our plan used a series of ramps to receive the ball and guide it to a launch bay and triggering a servo flipper arm to slap the ball out of the box. This actually proved quite difficult, as the flipper arm was out of position more often than it was ready to receive a ball. We wrestled with having the ball hit a button, as well as futzing with a pressure sensor. Ultimately, neither worked and both components broke. Out of hope, I found a photoresistor in my parts bin. We installed it to trigger the servo, which worked great! The only tricky bit was writing a calibration routine that could adjust to the changing light in the room. We also had to tell people to keep a distance – a dark shadow could accidentally trigger our arm.
The day of the event, it went flawlessly! We had our ball tossed in rather than launched from the previous box due to an utter failure of their launch mechanism, which avoided our one (known) design flaw of the box being unable to accept a ball at too high a speed, lest it bounce over our barricades and fail to trigger the sensor. We won additional honors from the teachers in the Professors’ Choice and Creative Design categories! Check out our code, poster, and video below. (Pardon the potato video quality. Also, pardon the potato code quality. I wasn’t running on much sleep when I wrote it, and it just needed to work.)
If only passing calculus was as fun as this class was…
Check out our project poster here
#include <Servo.h> #define MINDELTA 40 #define TRIGGERDELAY 300 #define SWEEPANGLE 180 #define SWEEPDELAY 2 Servo myservo; // create servo object to control a servo // a maximum of eight servo objects can be created int pos = 0, baseval, basevalset = 0, sensorValue, i, consecutiveruns, first=1; // variable to store the servo position int basevalpercent, mindeltapercent; void setup() { myservo.attach(9); // attaches the servo on pin 9 to the servo object Serial.begin(9600); } void loop() { if(!basevalset){ Serial.println("Setting base value..."); for(i=0; i<10; i++){ baseval += .1*analogRead(A0); delay(15); } basevalset=1; sweepServo(); Serial.println("Dumping config..."); Serial.println("./././././././././././././././././."); Serial.print("Base value set to "); Serial.print(baseval); Serial.print(" ("); Serial.print(baseval*4.9); Serial.print("mV, "); Serial.print(baseval/10.24); Serial.println("%)"); Serial.print("Minimum delta is "); Serial.print(MINDELTA); Serial.print(" ("); Serial.print(MINDELTA*4.9); Serial.print("mV, "); Serial.print(MINDELTA/10.24); Serial.println("%)"); Serial.print("Trigger delay is "); Serial.print(TRIGGERDELAY); Serial.println("ms"); Serial.print("Sweep angle is "); Serial.print(SWEEPANGLE); Serial.print(" degrees; "); Serial.print(SWEEPDELAY); Serial.println(" ms signal delay"); Serial.println("./././././././././././././././././."); }else{ // Read the input on analog pin 0: sensorValue = analogRead(A0); if((baseval-sensorValue) > MINDELTA){ Serial.print("Triggered; delta is "); Serial.print(baseval - sensorValue); Serial.print(" ("); Serial.print((baseval - sensorValue)/MINDELTA); Serial.println("% of threshhold)"); delay(TRIGGERDELAY); sweepServo(); }else{ if(baseval - sensorValue > (.25 * MINDELTA)){ Serial.print("Not triggered; delta is "); Serial.print(baseval - sensorValue); Serial.print(" ("); Serial.print((baseval - sensorValue)/MINDELTA); Serial.println("% of threshold)"); } } delay(50); } } void sweepServo(){ for(pos = 0; pos < SWEEPANGLE; pos ++){ myservo.write(pos); delay(SWEEPDELAY); } for(pos = 180; pos>=1; pos--){ myservo.write(pos); delay(10); } }