So I am working on a DIY electronic timer for a pinewood derby track. I found a general 2 lane schematic and program from the Derby Talk forums: Will GP Software communicate with an Arduino? - Derby Talk
I believe I have made most of the necessary changes to use it for a 4 lane track. However, I am not a programmer, with a very rudimentary knowledge of programming. The timer will be utilizing the Arduino UNO. It will connect to a laptop via USB port and interface with the Grand Prix Race Manager v9 software: GrandPrix Race Manager . My inputs for the four lanes (1-4)will be landing on 11D, 10D, 03D, & 04D respectively. Here is the code I have modified:
/* Pinewood Derby Timer
* By Jason Scholten
Pinewood Derby timer that works with the GrandPrix Race Manager Software.
See the "Read Me" file in the sketch folder for setup instructions.
*/
int ready = 13; //Timer ready LED
int start = 12; //Start gate switch
int fin1 = 11; //Lane 1 finish line detector
int fin2 = 10; //Lane 2 finish line detector
int fin1 = 3; //Lane 3 finish line detector
int fin2 = 4; //Lane 4 finish line detector
int reset = 9; //Reset switch
int lane1win = 8; //Lane 1 win LED
int lane2win = 7; //Lane 2 win LED
int timing = 6; //"timing" LED
int finished = 5; //Red finished LED
int time1 = 0; //lane 1 raw timing data
int time2 = 0; //lane 2 raw timing data
int time3 = 0; //lane 3 raw timing data
int time4 = 0; //lane 4 raw timing data
int winner = 0; //winner light bit
int startpush = LOW; //start button status
int starttime = 0; //start time in millis
int rss = HIGH; //reset button status
int fnl1; //lane 1 lane detector status
int fnl2; //lane 2 lane detector status
int fnl3; //lane 3 lane detector status
int fnl4; //lane 4 lane detector status
int running = 0; //track timing status bit
int fractional1; //lane 1 timing display interger
int fractional2; //lane 2 timing display interger
int fractional3; //lane 3 timing display interger
int fractional4; //lane 4 timing display interger
int lane1 = 0; //lane 1 finish
int lane2 = 0; //lane 2 finish
int lane3 = 0; //lane 3 finish
int lane4 = 0; //lane 4 finish
int crss = 0; //computer reset
int force = 0; //force data send
void setup()
{
pinMode(timing, OUTPUT);
pinMode(start, INPUT);
pinMode(fin1, INPUT);
pinMode(fin2, INPUT);
pinMode(fin3, INPUT);
pinMode(fin4, INPUT);
pinMode(reset, INPUT);
pinMode(lane1win, OUTPUT);
pinMode(lane2win, OUTPUT);
pinMode(lane3win, OUTPUT);
pinMode(lane4win, OUTPUT);
pinMode(ready, OUTPUT);
pinMode(finished, OUTPUT);
digitalWrite(reset, HIGH);
Serial.begin(9600);
}
void loop()
{
if (Serial.available() > 0 && running == 0) { //looks for initial reset from software
crss = Serial.read();
}
rss = digitalRead(reset); //manual initial reset
if (crss == 65 && running == 0 || rss == LOW && running == 0) {
Serial.println("C");
digitalWrite(ready, HIGH);
running = 1;
crss = 0;
delay(100);
}
startpush = digitalRead(start);
rss = digitalRead(reset);
if (startpush == HIGH && rss == HIGH && running == 1 && crss == 0) { //timer start
starttime = millis();
digitalWrite(timing, HIGH);
digitalWrite(ready, LOW);
Serial.println("B");
running = 2;
delay(100);
}
fnl1 = digitalRead(fin1); //timing on lane 1
if (fnl1 == LOW && running == 2 && lane1 == 0) {
time1 = millis() - starttime;
lane1 = 1;
}
fnl2 = digitalRead(fin2); //timing on lane 2
if (fnl2 == LOW && running == 2 && lane2 == 0) {
time2 = millis() - starttime;
lane2 = 1;
}
fnl1 = digitalRead(fin1); //timing on lane 3
if (fnl3 == LOW && running == 2 && lane3 == 0) {
time3 = millis() - starttime;
lane3 = 1;
}
fnl2 = digitalRead(fin2); //timing on lane 4
if (fnl4 == LOW && running == 2 && lane4 == 0) {
time4 = millis() - starttime;
lane4 = 1;
}
if (lane1 == 1 && lane2 != 1 lane3 != 1 && lane4 != 1 && winner == 0) { //winner lights lane 1
digitalWrite(lane1win, HIGH);
winner = 1;}
if (lane1 != 1 && lane2 == 1 lane3 != 1 && lane4 != 1 && winner == 0) { //winner lights lane 2
digitalWrite(lane2win, HIGH);
winner = 2;
if (lane1 != 1 && lane2 != 1 lane3 == 1 && lane4 != 1 && winner == 0) { //winner lights lane 3
digitalWrite(lane3win, HIGH);
winner = 3;}
if (lane1 != 1 && lane2 != 1 lane3 != 1 && lane4 == 1 && winner == 0) { //winner lights lane 4
digitalWrite(lane4win, HIGH);
winner = 4;
}
if (Serial.available() > 0 && running == 2) { //Force Data Send detect
force = Serial.read();
}
if (force == 70 && lane1 == 1 && lane2 == 0 && lane3 == 0 && lane4 == 0 && running == 2) { //forces lane 1 to quit timing
lane2 = 1;lane3 = 1;lane4 = 1;
}
if (force == 70 && lane1 == 0 && lane2 == 1 && lane3 == 0 && lane4 == 0 && running == 2) { //forces lane 2 to quit timing
lane1 = 1;lane3 = 1;lane4 = 1;
}
if (force == 70 && lane1 == 0 && lane2 == 0 && lane3 == 1 && lane4 == 0 && running == 2) { //forces lane 3 to quit timing
lane1 = 1;lane2 = 1;lane4 = 1;
}
if (force == 70 && lane1 == 0 && lane2 == 0 && lane3 == 0 && lane4 == 1 && running == 2) { //forces lane 4 to quit timing
lane1 = 1;lane2 = 1;lane3 = 1;
}
if (lane1 == 1 && lane2 == 1 && running == 2) {
digitalWrite(finished, HIGH);
Serial.print("1 - "); //serial print for lane 1
Serial.print( (int) (time1 / 1000L));
Serial.print(".");
fractional1 = (int)(time1 % 1000L);
if (fractional1 == 0)
Serial.print("000");
else if (fractional1 < 10)
Serial.print("00");
else if (fractional1 < 100)
Serial.print("0");
Serial.println(fractional1);
Serial.print("2 - "); //serial print for lane 2
Serial.print( (int) (time2 / 1000L));
Serial.print(".");
fractional2 = (int)(time2 % 1000L);
if (fractional2 == 0)
Serial.print("000");
else if (fractional2 < 10)
Serial.print("00");
else if (fractional2 < 100)
Serial.print("0");
Serial.println(fractional2);
Serial.print("3 - "); //serial print for lane 3
Serial.print( (int) (time3 / 1000L));
Serial.print(".");
fractional3 = (int)(time3 % 1000L);
if (fractional3 == 0)
Serial.print("000");
else if (fractional3 < 10)
Serial.print("00");
else if (fractional3 < 100)
Serial.print("0");
Serial.println(fractional3);
Serial.print("4 - "); //serial print for lane 4
Serial.print( (int) (time4 / 1000L));
Serial.print(".");
fractional4 = (int)(time4 % 1000L);
if (fractional4 == 0)
Serial.print("000");
else if (fractional4 < 10)
Serial.print("00");
else if (fractional4 < 100)
Serial.print("0");
Serial.println(fractional4);
digitalWrite(timing, LOW);
running = 3;
}
if (Serial.available() > 0 && running == 3) { //computer timer reset
crss = Serial.read();
}
rss = digitalRead(reset); //manual timer reset
if (crss == 65 && running == 3 || rss == LOW && running == 3) {
starttime = 0;
time1 = 0;
time2 = 0;
time3 = 0;
time4 = 0;
running = 4;
lane1 = 0;
lane2 = 0;
lane3 = 0;
lane4 = 0;
winner = 0;
digitalWrite(lane1win, LOW);
digitalWrite(lane2win, LOW);
digitalWrite(lane3win, LOW);
digitalWrite(lane4win, LOW);
digitalWrite(finished, LOW);
digitalWrite(ready, HIGH);
crss = 0;
y = 0;
Serial.flush();
}
if (crss == 0 && running == 4) { //serial ready status
Serial.print("C");
running = 1;
}
}
The section I am most unsure about is in the middle where it talks about forcing Lane 1-4 to quit timing. I am not sure if I made the additions of Lanes 3 and 4 correctly. The original code and schematic can be found here : grandprix-race-central.com/modules.php?name=Downloads&d_op=getit&lid=23
Any feedback and advice would be most appreciated, thanks.