Components and supplies
Through Hole Resistor, 2k ohm
Photo transistor light sensor
HC-05 Bluetooth Module
Tiny Breadboard
Android device
1/2" PVC pipe and connectors
Alphanumeric LCD, 16 x 2
Through Hole Resistor, 200 kohm
Jumper wires (generic)
Neodymium Disc Magnets
Male/Female Jumper Wires
High Brightness LED, White
Arduino UNO
5V 650nm 5mW Red Dot Diode Laser Head Red Laser Diode 6mm Red Laser Diode Laser Head
Tools and machines
Soldering iron (generic)
Quick setting epoxy resin
3D Printer (generic)
Solder Wire, Lead Free
Hot glue gun (generic)
Gorilla Glue
Apps and platforms
MIT App Inventor 2
Project description
Code
Solar Car Challenge (optional phone app for Bluetooth connection)
scheme
MIT App Inventor Code (.aia) for Android Phone to see photogate results via Bluetooth and to reset photogate
1inary file (no preview
Laser_Photogate-2_lanes
arduino
Code to calibrate lasers, time, display results and send them via optional Bluetooth module
1/* PhototransistorVoltage Solar Car Timer by Nelson Farrier 2 * Power each phototransistor with 5v and GND 3 * Connect the 2 phototransistors yellow wires 4 * into A0 & A1 to detect start and stop of car. 5 * Use 4 pins (below) to indicate laser alignment 6 * Use 4 analog pins (A0-A3) for detecting photo transistor voltage 7 */ 8#include <LiquidCrystal_I2C.h> // Must be downloaded separtely & put in your Arduino's libraries folder 9 10/*----- LCD Pin configuration-----*/ 11//GND - GND 12//VCC - 5V 13//SDA - ANALOG Pin 4 14//SCL - ANALOG pin 5 15 16LiquidCrystal_I2C lcd(0x27, 16, 2); 17 18const boolean testing = false; 19 20const int align1Pin = 8; // pin to show laser is on 1st mark 21const int align2Pin = 9; // pin to show laser is on 2nd mark 22const int align3Pin = 10; // pin to show laser is on 1st mark 23const int align4Pin = 11; // pin to show laser is on 2nd mark 24 25const int interval = 10; // accuracy of timer in milliseconds 26float threshold = 0.75; // voltage where phototransistor shows car is in the way 27float v1, v2, v3, v4, timer1Count, timer2Count; 28boolean A, B, C, D, doneLtiming, doneRtiming, triggeredL, triggeredR, overLmtL, overLmtR, statusLCDshown, statusRshown, statusLshown, finishLshown, finishRshown; // A & C on one lane, B & D on other 29int count=0, msg = 0; 30char inSerial[15]; 31const int StartL = 1; 32const int StartR = 2; 33const int FinishL = 3; 34const int FinishR = 4; 35const int leftLane = 0; 36const int rightLane = 1; 37const float overtime = 60000; // 1 minute 38 39// bluetooth codes 40const int Reset = 9; 41const int Other = 10; 42 43void setup() // Built-in initialization block 44{ 45 Serial.begin(9600); // Set data rate to 9600 bps 46 pinMode(align1Pin,OUTPUT); 47 pinMode(align2Pin,OUTPUT); 48 pinMode(align3Pin,OUTPUT); 49 pinMode(align4Pin,OUTPUT); 50 Serial.println("!Waiting to connect to Bluetooth..."); 51 lcd.begin(); 52 lcd.clear(); 53 lcd.setCursor(16,2); 54 lcd.backlight(); 55 lcd.setCursor(0 ,0); 56} 57 58void loop() { 59 lcd.setCursor(16,2); // initialize the lcd for 16 chars 2 lines, turn on backlight 60 lcd.backlight(); 61 62 A = B = C = D = doneLtiming = doneRtiming= triggeredL = triggeredR = overLmtL = overLmtR = statusLCDshown = false; // A & C on one lane, B & D on other 63 finishLshown = finishRshown = statusLshown = statusRshown = false; 64 boolean wait = true; 65 waitForAlignment(); 66 timer1Count = 0; 67 timer2Count = 0; 68 count = 0; 69 70 delay(1000); 71 Serial.print("!Ready..."); 72 lcd.clear(); 73 lcd.setCursor(0 ,0); //Start at character 4 on line 0 74 lcd.print("Ready..."); 75 delay(1000); 76 77 Serial.println("Set..."); 78 lcd.print("Set..."); 79 80 while ((!doneLtiming) || (!doneRtiming)) { 81 if (triggeredL || triggeredR) { 82 if (!statusLCDshown) { 83 lcd.setCursor(0 ,1); 84 lcd.print("Race Started!"); 85 if (testing) { 86 Serial.println(A); 87 Serial.println(B); 88 Serial.println(C); 89 Serial.println(D); 90 } 91 statusLCDshown = true; 92 } 93 if ((triggeredL) && (!statusLshown)) { 94 Serial.println("Race started in left lane"); 95 statusLshown = true; 96 } 97 if ((triggeredR) && (!statusRshown)) { 98 Serial.println("Race started in right lane"); 99 statusRshown = true; 100 } 101 102 } 103 104 if (triggeredL && !doneLtiming) { // add interval to timer because L lane has started 105 timer1Count = timer1Count+interval; 106 } 107 if (triggeredR && !doneRtiming) { // add interval to timer because R lane has started 108 timer2Count = timer2Count+interval; 109 } 110 if (timer1Count > overtime) { 111 doneLtiming = overLmtL = true; 112 } 113 if (timer2Count > overtime) { 114 doneRtiming = overLmtR = true; 115 } 116 v1 = volts(A0); 117 v2 = volts(A1); 118 v3 = volts(A2); 119 v4 = volts(A3); 120 if (v1 < threshold) { digitalWrite(align1Pin, LOW); } // turn off (and leave off) LED's as they are triggered 121 if (v2 < threshold) { digitalWrite(align2Pin, LOW); } 122 if (v3 < threshold) { digitalWrite(align3Pin, LOW); } 123 if (v4 < threshold) { digitalWrite(align4Pin, LOW); } 124 125 if (!triggeredL) { 126 triggeredL = (v1 < threshold) || (v3 < threshold); // initial trigger L (front or back) 127 A = (v1 < threshold); 128 C = (v3 < threshold); 129 } 130 else { 131 if (A) { // final trigger L (front or back) 132 if (v3 < threshold) { 133 doneLtiming = true; 134 if (!finishLshown) { 135 Serial.println("Left lane finished"); 136 showLaneTime(leftLane,timer1Count,overLmtL); 137 finishLshown = true; 138 } 139 } 140 } 141 if (C) { 142 if (v1 < threshold) { 143 doneLtiming = true; 144 if (!finishLshown) { 145 Serial.println("Left lane finished"); 146 showLaneTime(leftLane,timer1Count,overLmtL); 147 finishLshown = true; 148 } 149 } 150 } 151 } 152 153 if (!triggeredR) { 154 triggeredR = (v2 < threshold) || (v4 < threshold); // initial trigger R (front or back) 155 B = (v2 < threshold); 156 D = (v4 < threshold); 157 } 158 else { 159 if (B) { // final trigger R (front or back) 160 if (v4 < threshold) { 161 doneRtiming = true; 162 if (!finishRshown) { 163 Serial.println("Right lane finished"); 164 showLaneTime(rightLane,timer2Count,overLmtR); 165 finishRshown = true; 166 } 167 } 168 } 169 if (D) { 170 if (v2 < threshold) { 171 doneRtiming = true; 172 if (!finishRshown) { 173 Serial.println("Right lane finished"); 174 showLaneTime(rightLane,timer2Count,overLmtR); 175 finishRshown = true; 176 } 177 } 178 } 179 } 180 181 delay(interval); // Delay for defined time 182 } 183 184 // end timer count and display results 185 flashScreen(); 186 delay(80); 187 if (testing) { 188 Serial.print(triggeredL); 189 Serial.print(triggeredR); 190 Serial.print(doneLtiming); 191 Serial.println(doneRtiming); 192 } 193 Serial.println("!Race Complete"); 194 showLaneTime(leftLane,timer1Count,overLmtL); 195 showLaneTime(rightLane,timer2Count,overLmtR); 196 Serial.println(""); // print blank line 197 198//loop until bluetooth "Reset" sent or rebooted 199 200 201while (wait) { 202 int i=0; 203 int m=0; 204 delay(500); 205 if (Serial.available() > 0) { 206 while (Serial.available() > 0) { 207 inSerial[i]=Serial.read(); 208 i++; 209 } 210 inSerial[i]='\\0'; 211 msg = Check_Protocol(inSerial); 212 wait = (! msg == Reset); 213 if (msg == Reset) { 214 flashLED(8); 215 } 216 } 217} 218} 219 220//----------------------------------------- 221 222void showLaneTime(int lane, float timerCount, boolean overLmt) { 223if (lane == leftLane) { 224 Serial.print("Left Lane Time: "); 225 lcd.setCursor(0,0); 226 lcd.print("L Time="); 227} else { 228 Serial.print("Right Lane Time: "); 229 lcd.setCursor(0,1); 230 lcd.print("R Time="); 231 232} 233 if (!overLmt) { 234 Serial.print(timerCount/1000); // Display timerCount in #.## format 235 Serial.println(" sec"); 236 lcd.print(timerCount/1000); 237 lcd.println(" sec "); 238 } 239 else { 240 Serial.print("past limit"); 241 lcd.println(" past lmt "); 242 } 243} 244 245 246float volts(int adPin) // Measures volts at adPin 247{ // Returns floating point voltage 248 return float(analogRead(adPin)) * 5.0 / 1024.0; 249} 250 251void flashScreen() { 252 for(int i = 0; i< 3; i++) 253 { 254 lcd.backlight(); 255 delay(150); 256 lcd.noBacklight(); 257 delay(150); 258 } 259 lcd.backlight(); // finish with backlight on 260} 261 262int Check_Protocol(char inStr[]){ 263 int i=0; 264 int m=0; 265 uint32_t c=0; // color of bounce 266 267 Serial.println(inStr); 268 if (!strcmp(inStr,"Reset")){ //Reset system 269 //Serial.println("Reset"); 270 return Reset; 271 for(m=0;m<11;m++){ 272 inStr[m]=0;} 273 i=0; 274 } 275 276 if (!strcmp(inStr,"other")){ 277 Serial.println("Other"); 278 return Other; 279 for(m=0;m<11;m++){ 280 inStr[m]=0;} 281 i=0; 282 } 283 else{ 284 for(m=0;m<11;m++){ 285 inStr[m]=0;} 286 i=0; 287 } 288} 289 290void flashLED(int pinNum) { 291 digitalWrite(pinNum, LOW); 292 delay(200); 293 digitalWrite(pinNum, HIGH); 294 delay(200); 295 digitalWrite(pinNum, LOW); 296 delay(200); 297 digitalWrite(pinNum, HIGH); 298 delay(200); 299 digitalWrite(pinNum, LOW); 300 delay(200); 301 digitalWrite(pinNum, HIGH); 302 delay(200); 303 digitalWrite(pinNum, LOW); 304} 305 306void waitForAlignment() { 307 boolean Start1 = false; 308 boolean Start2 = false; 309 boolean Finish1 = true; 310 boolean Finish2 = true; 311 Serial.println("!Checking Laser Alignment..."); // wait for either phototransistor to be dimmed 312 lcd.clear(); 313 lcd.setCursor(0 ,0); //Start at character 1 on line 0 314 lcd.print("Checking Laser"); 315 lcd.setCursor(0 ,1); //Start at character 1 on line 1 316 lcd.print("Alignment..."); 317 delay(2000); 318 boolean done = false; 319 lcd.clear(); 320 while (!done) { 321 v1 = volts(A0); 322 digitalWrite(align1Pin, !(v1 < threshold)); 323 Start1 = !(v1 < threshold); 324 alignmentCheck(Start1,StartL,v1); 325 if (testing) { 326 Serial.print( " "); 327 Serial.print(v1); // Display measured A0 volts 328 Serial.println(" volts "); 329 } 330 331 v2 = volts(A1); 332 digitalWrite(align2Pin, !(v2 < threshold)); 333 Start2 = !(v2 < threshold); 334 alignmentCheck(Start2,StartR,v2); 335 if (testing) { 336 Serial.print( " "); 337 Serial.print(v2); // Display measured A1 volts 338 Serial.println(" volts "); 339 } 340 341 v3 = volts(A2); 342 digitalWrite(align3Pin, !(v3 < threshold)); 343 Finish1 = !(v3 < threshold); 344 alignmentCheck(Finish1,FinishL,v3); 345 if (testing) { 346 Serial.print( " "); 347 Serial.print(v3); // Display measured A2 volts 348 Serial.println(" volts "); 349 } 350 351 v4 = volts(A3); 352 digitalWrite(align4Pin, !(v4 < threshold)); 353 Finish2 = !(v4 < threshold); 354 alignmentCheck(Finish2,FinishR,v4); 355 if (testing) { 356 Serial.print( " "); 357 Serial.print(v4); // Display measured A3 volts 358 Serial.println(" volts "); 359 } 360 361 Serial.println(" "); 362 delay(500); // Delay for 0.5 seconds 363 done = (Start1 && Start2 && Finish1 && Finish2); 364 } 365 Serial.println("!Lasers Aligned"); // wait for either phototransistor to be dimmed 366 lcd.clear(); 367 lcd.setCursor(0 ,0); //Start at character 4 on line 0 368 lcd.print("Lasers Aligned"); 369 delay(2000); 370} 371 372void alignmentCheck(boolean aligned, int section, float v) { 373 String fullTextOut, smTextOut; 374 if (section == StartL) { 375 fullTextOut = "Left Start"; 376 smTextOut = "A"; 377 lcd.setCursor(0, 0); 378 } 379 if (section == StartR) { 380 fullTextOut = "Right Start"; 381 smTextOut = "B"; 382 lcd.setCursor(8, 0); 383 } 384 if (section == FinishL) { 385 fullTextOut = "Left Finish"; 386 smTextOut = "C"; 387 lcd.setCursor(0, 1); 388 } 389 if (section == FinishR) { 390 fullTextOut = "Right Finish"; 391 smTextOut = "D"; 392 lcd.setCursor(8, 1); 393 } 394 if (aligned) { 395 Serial.println(fullTextOut+" Aligned"); 396 lcd.print(smTextOut+"=OK "); 397 } 398 else { 399 Serial.print(fullTextOut+"="); // Display "Ax = " 400 lcd.print(smTextOut+"="); 401 Serial.print(v); // Display measured Ax volts 402 Serial.println(" volts "); // Display " volts" & newline 403 lcd.print(v); // Display measured Ax volts 404 lcd.print("v "); // Display " volts" & newline 405 } 406}
Laser_Photogate-2_lanes
arduino
Code to calibrate lasers, time, display results and send them via optional Bluetooth module
1/* PhototransistorVoltage Solar Car Timer by Nelson Farrier 2 * Power 3 each phototransistor with 5v and GND 4 * Connect the 2 phototransistors yellow 5 wires 6 * into A0 & A1 to detect start and stop of car. 7 * Use 4 pins 8 (below) to indicate laser alignment 9 * Use 4 analog pins (A0-A3) for detecting 10 photo transistor voltage 11 */ 12#include <LiquidCrystal_I2C.h> // Must be downloaded 13 separtely & put in your Arduino's libraries folder 14 15/*----- LCD Pin configuration-----*/ 16//GND 17 - GND 18//VCC - 5V 19//SDA - ANALOG Pin 4 20//SCL - ANALOG pin 5 21 22LiquidCrystal_I2C 23 lcd(0x27, 16, 2); 24 25const boolean testing = false; 26 27const int align1Pin 28 = 8; // pin to show laser is on 1st mark 29const int align2Pin = 9; // pin to 30 show laser is on 2nd mark 31const int align3Pin = 10; // pin to show laser is 32 on 1st mark 33const int align4Pin = 11; // pin to show laser is on 2nd mark 34 35const 36 int interval = 10; // accuracy of timer in milliseconds 37float threshold = 0.75; 38 // voltage where phototransistor shows car is in the way 39float v1, v2, v3, 40 v4, timer1Count, timer2Count; 41boolean A, B, C, D, doneLtiming, doneRtiming, triggeredL, 42 triggeredR, overLmtL, overLmtR, statusLCDshown, statusRshown, statusLshown, finishLshown, 43 finishRshown; // A & C on one lane, B & D on other 44int count=0, msg = 0; 45char 46 inSerial[15]; 47const int StartL = 1; 48const int StartR = 2; 49const int FinishL 50 = 3; 51const int FinishR = 4; 52const int leftLane = 0; 53const int rightLane 54 = 1; 55const float overtime = 60000; // 1 minute 56 57// bluetooth codes 58const 59 int Reset = 9; 60const int Other = 10; 61 62void setup() // 63 Built-in initialization block 64{ 65 Serial.begin(9600); // 66 Set data rate to 9600 bps 67 pinMode(align1Pin,OUTPUT); 68 pinMode(align2Pin,OUTPUT); 69 70 pinMode(align3Pin,OUTPUT); 71 pinMode(align4Pin,OUTPUT); 72 Serial.println("!Waiting 73 to connect to Bluetooth..."); 74 lcd.begin(); 75 lcd.clear(); 76 lcd.setCursor(16,2); 77 78 lcd.backlight(); 79 lcd.setCursor(0 ,0); 80} 81 82void loop() { 83 84 lcd.setCursor(16,2); // initialize the lcd for 16 chars 2 lines, turn on backlight 85 86 lcd.backlight(); 87 88 A = B = C = D = doneLtiming = doneRtiming= triggeredL 89 = triggeredR = overLmtL = overLmtR = statusLCDshown = false; // A & C on one lane, 90 B & D on other 91 finishLshown = finishRshown = statusLshown = statusRshown = 92 false; 93 boolean wait = true; 94 waitForAlignment(); 95 timer1Count = 0; 96 97 timer2Count = 0; 98 count = 0; 99 100 delay(1000); 101 Serial.print("!Ready..."); 102 103 lcd.clear(); 104 lcd.setCursor(0 ,0); //Start at character 4 on line 105 0 106 lcd.print("Ready..."); 107 delay(1000); 108 109 Serial.println("Set..."); 110 111 lcd.print("Set..."); 112 113 while ((!doneLtiming) || (!doneRtiming)) { 114 115 if (triggeredL || triggeredR) { 116 if (!statusLCDshown) { 117 lcd.setCursor(0 118 ,1); 119 lcd.print("Race Started!"); 120 if (testing) { 121 Serial.println(A); 122 123 Serial.println(B); 124 Serial.println(C); 125 Serial.println(D); 126 127 } 128 statusLCDshown = true; 129 } 130 if ((triggeredL) 131 && (!statusLshown)) { 132 Serial.println("Race started in left lane"); 133 134 statusLshown = true; 135 } 136 if ((triggeredR) && (!statusRshown)) 137 { 138 Serial.println("Race started in right lane"); 139 statusRshown 140 = true; 141 } 142 143 } 144 145 if (triggeredL && !doneLtiming) 146 { // add interval to timer because L lane has started 147 timer1Count 148 = timer1Count+interval; 149 } 150 if (triggeredR && !doneRtiming) { // 151 add interval to timer because R lane has started 152 timer2Count = timer2Count+interval; 153 154 } 155 if (timer1Count > overtime) { 156 doneLtiming = overLmtL = 157 true; 158 } 159 if (timer2Count > overtime) { 160 doneRtiming = overLmtR 161 = true; 162 } 163 v1 = volts(A0); 164 v2 = volts(A1); 165 166 v3 = volts(A2); 167 v4 = volts(A3); 168 169 if (v1 < threshold) { digitalWrite(align1Pin, LOW); 170 } // turn off (and leave off) LED's as they are triggered 171 if (v2 < threshold) 172 { digitalWrite(align2Pin, LOW); } 173 if (v3 < threshold) { digitalWrite(align3Pin, 174 LOW); } 175 if (v4 < threshold) { digitalWrite(align4Pin, LOW); } 176 177 if 178 (!triggeredL) { 179 triggeredL = (v1 < threshold) || (v3 < threshold); // 180 initial trigger L (front or back) 181 A = (v1 < threshold); 182 C = (v3 183 < threshold); 184 } 185 else { 186 if (A) { // 187 final trigger L (front or back) 188 if (v3 < threshold) { 189 doneLtiming 190 = true; 191 if (!finishLshown) { 192 Serial.println("Left 193 lane finished"); 194 showLaneTime(leftLane,timer1Count,overLmtL); 195 196 finishLshown = true; 197 } 198 } 199 } 200 201 if (C) { 202 if (v1 < threshold) { 203 doneLtiming = true; 204 205 if (!finishLshown) { 206 Serial.println("Left lane finished"); 207 208 showLaneTime(leftLane,timer1Count,overLmtL); 209 finishLshown 210 = true; 211 } 212 } 213 } 214 } 215 216 if (!triggeredR) 217 { 218 triggeredR = (v2 < threshold) || (v4 < threshold); // initial 219 trigger R (front or back) 220 B = (v2 < threshold); 221 D = (v4 < threshold); 222 223 } 224 else { 225 if (B) { // 226 final trigger R (front or back) 227 if (v4 < threshold) { 228 doneRtiming 229 = true; 230 if (!finishRshown) { 231 Serial.println("Right 232 lane finished"); 233 showLaneTime(rightLane,timer2Count,overLmtR); 234 235 finishRshown = true; 236 } 237 } 238 } 239 240 if (D) { 241 if (v2 < threshold) { 242 doneRtiming = true; 243 244 if (!finishRshown) { 245 Serial.println("Right lane finished"); 246 247 showLaneTime(rightLane,timer2Count,overLmtR); 248 finishRshown 249 = true; 250 } 251 } 252 } 253 } 254 255 delay(interval); 256 // Delay for defined time 257 } 258 259 // end timer count and 260 display results 261 flashScreen(); 262 delay(80); 263 if (testing) { 264 Serial.print(triggeredL); 265 266 Serial.print(triggeredR); 267 Serial.print(doneLtiming); 268 Serial.println(doneRtiming); 269 270 } 271 Serial.println("!Race Complete"); 272 showLaneTime(leftLane,timer1Count,overLmtL); 273 274 showLaneTime(rightLane,timer2Count,overLmtR); 275 Serial.println(""); // 276 print blank line 277 278//loop until bluetooth "Reset" sent or rebooted 279 280 281while 282 (wait) { 283 int i=0; 284 int m=0; 285 delay(500); 286 if (Serial.available() 287 > 0) { 288 while (Serial.available() > 0) { 289 inSerial[i]=Serial.read(); 290 291 i++; 292 } 293 inSerial[i]='\\0'; 294 msg = Check_Protocol(inSerial); 295 wait 296 = (! msg == Reset); 297 if (msg == Reset) { 298 flashLED(8); 299 } 300 } 301} 302} 303 304//----------------------------------------- 305 306void 307 showLaneTime(int lane, float timerCount, boolean overLmt) { 308if (lane == leftLane) 309 { 310 Serial.print("Left Lane Time: "); 311 lcd.setCursor(0,0); 312 313 lcd.print("L Time="); 314} else { 315 Serial.print("Right Lane Time: 316 "); 317 lcd.setCursor(0,1); 318 lcd.print("R Time="); 319 320} 321 322 if (!overLmt) { 323 Serial.print(timerCount/1000); // Display timerCount 324 in #.## format 325 Serial.println(" sec"); 326 lcd.print(timerCount/1000); 327 328 lcd.println(" sec "); 329 } 330 else { 331 Serial.print("past 332 limit"); 333 lcd.println(" past lmt "); 334 } 335} 336 337 338 339float volts(int adPin) // 340 Measures volts at adPin 341{ // Returns 342 floating point voltage 343 return float(analogRead(adPin)) * 5.0 / 1024.0; 344} 345 346 347void flashScreen() { 348 for(int i = 0; i< 3; i++) 349 { 350 lcd.backlight(); 351 352 delay(150); 353 lcd.noBacklight(); 354 delay(150); 355 } 356 lcd.backlight(); 357 // finish with backlight on 358} 359 360int Check_Protocol(char inStr[]){ 361 362 int i=0; 363 int m=0; 364 uint32_t c=0; // color of bounce 365 366 Serial.println(inStr); 367 368 if (!strcmp(inStr,"Reset")){ //Reset system 369 //Serial.println("Reset"); 370 371 return Reset; 372 for(m=0;m<11;m++){ 373 inStr[m]=0;} 374 i=0; 375 376 } 377 378 if (!strcmp(inStr,"other")){ 379 Serial.println("Other"); 380 381 return Other; 382 for(m=0;m<11;m++){ 383 inStr[m]=0;} 384 i=0; 385 386 } 387 else{ 388 for(m=0;m<11;m++){ 389 inStr[m]=0;} 390 i=0; 391 } 392} 393 394void 395 flashLED(int pinNum) { 396 digitalWrite(pinNum, LOW); 397 delay(200); 398 399 digitalWrite(pinNum, HIGH); 400 delay(200); 401 digitalWrite(pinNum, LOW); 402 403 delay(200); 404 digitalWrite(pinNum, HIGH); 405 delay(200); 406 digitalWrite(pinNum, 407 LOW); 408 delay(200); 409 digitalWrite(pinNum, HIGH); 410 delay(200); 411 412 digitalWrite(pinNum, LOW); 413} 414 415void waitForAlignment() { 416 boolean 417 Start1 = false; 418 boolean Start2 = false; 419 boolean Finish1 = true; 420 boolean 421 Finish2 = true; 422 Serial.println("!Checking Laser Alignment..."); // 423 wait for either phototransistor to be dimmed 424 lcd.clear(); 425 lcd.setCursor(0 426 ,0); //Start at character 1 on line 0 427 lcd.print("Checking Laser"); 428 429 lcd.setCursor(0 ,1); //Start at character 1 on line 1 430 lcd.print("Alignment..."); 431 432 delay(2000); 433 boolean done = false; 434 lcd.clear(); 435 while (!done) { 436 437 v1 = volts(A0); 438 digitalWrite(align1Pin, !(v1 < threshold)); 439 Start1 440 = !(v1 < threshold); 441 alignmentCheck(Start1,StartL,v1); 442 if (testing) 443 { 444 Serial.print( " "); 445 Serial.print(v1); 446 // Display measured A0 volts 447 Serial.println(" volts 448 "); 449 } 450 451 v2 = volts(A1); 452 digitalWrite(align2Pin, !(v2 453 < threshold)); 454 Start2 = !(v2 < threshold); 455 alignmentCheck(Start2,StartR,v2); 456 457 if (testing) { 458 Serial.print( " "); 459 Serial.print(v2); 460 // Display measured A1 volts 461 Serial.println(" volts 462 "); 463 } 464 465 v3 = volts(A2); 466 digitalWrite(align3Pin, !(v3 467 < threshold)); 468 Finish1 = !(v3 < threshold); 469 alignmentCheck(Finish1,FinishL,v3); 470 471 if (testing) { 472 Serial.print( " "); 473 Serial.print(v3); 474 // Display measured A2 volts 475 Serial.println(" volts "); 476 477 } 478 479 v4 = volts(A3); 480 digitalWrite(align4Pin, !(v4 481 < threshold)); 482 Finish2 = !(v4 < threshold); 483 alignmentCheck(Finish2,FinishR,v4); 484 485 if (testing) { 486 Serial.print( " "); 487 Serial.print(v4); 488 // Display measured A3 volts 489 Serial.println(" volts "); 490 491 } 492 493 Serial.println(" "); 494 delay(500); 495 // Delay for 0.5 seconds 496 done = (Start1 && 497 Start2 && Finish1 && Finish2); 498 } 499 Serial.println("!Lasers Aligned"); 500 // wait for either phototransistor to be dimmed 501 lcd.clear(); 502 lcd.setCursor(0 503 ,0); //Start at character 4 on line 0 504 lcd.print("Lasers Aligned"); 505 delay(2000); 506} 507 508void 509 alignmentCheck(boolean aligned, int section, float v) { 510 String fullTextOut, 511 smTextOut; 512 if (section == StartL) { 513 fullTextOut = "Left Start"; 514 515 smTextOut = "A"; 516 lcd.setCursor(0, 0); 517 } 518 if 519 (section == StartR) { 520 fullTextOut = "Right Start"; 521 smTextOut 522 = "B"; 523 lcd.setCursor(8, 0); 524 } 525 if (section == FinishL) 526 { 527 fullTextOut = "Left Finish"; 528 smTextOut = "C"; 529 lcd.setCursor(0, 530 1); 531 } 532 if (section == FinishR) { 533 fullTextOut = "Right Finish"; 534 535 smTextOut = "D"; 536 lcd.setCursor(8, 1); 537 } 538 if 539 (aligned) { 540 Serial.println(fullTextOut+" Aligned"); 541 542 lcd.print(smTextOut+"=OK "); 543 } 544 545 else { 546 Serial.print(fullTextOut+"="); // Display 547 "Ax = " 548 lcd.print(smTextOut+"="); 549 Serial.print(v); // 550 Display measured Ax volts 551 Serial.println(" volts "); // Display 552 " volts" & newline 553 lcd.print(v); // Display measured 554 Ax volts 555 lcd.print("v "); // Display " volts" & newline 556 557 } 558}
Solar Car Challenge (optional phone app for Bluetooth connection)
scheme
MIT App Inventor Code (.aia) for Android Phone to see photogate results via Bluetooth and to reset photogate
1inary file (no preview
Downloadable files
Laser Photogate 2 Lane Schematic
Laser Photogate Schematic for 2 Lanes
Laser Photogate 2 Lane Schematic
Laser Photogate 2 Lane Schematic
Laser Photogate Schematic for 2 Lanes
Laser Photogate 2 Lane Schematic
Documentation
PVC protective wedge
An optional triangular wedge can be made to prevent any car from sideswiping the center laser base of the final photogate--either from wood or with this 3D printed version.
PVC protective wedge
PVC protective wedge
An optional triangular wedge can be made to prevent any car from sideswiping the center laser base of the final photogate--either from wood or with this 3D printed version.
PVC protective wedge
LCD screen cover
An optional cover for the enclosure with mounting posts for a 16x2 Arduino LCD screen.
LCD screen cover
Comments
Only logged in users can leave comments
Anonymous user
5 years ago
Nice project. One quibble. The specification for a 3D printer is kind of a barrier to adoption for many people. I now understand it's optional, but I would stress that in the subtitle "Necessary tools and machines." I almost skipped over the project.