Hi everyone,
I've been working on a timing gate for a CO2 racer unit with some students at my school. Please excuse the massive amounts of commented out code, I need to clean it up a bit, but for the most part it works as intended. Basically I have an arduino in a box which has some led lights and an LCD screen. The launcher has an LED and a LDR which send a signal to capture the start time when the launcher fires and the cars begin, then the gate itself has 2 LDRs which each look for a drop of at least 50 units signalling the car passing the gate. The Arduino sets the finish time as a variable and displays it to the LCD screen and the LED lights flash based on which track (1 or 2) finished first.
Last but not least, there is a 2 pin button which I have connected to ground and to pin 11 to be used as a reset button. I have declared a variable for the reset state an am trying to run a reset function when the button is pressed. It kind of worked originally, except that the button was very sensitive to touch (and even putting your hand near it, not actually touching it) and when the button was pressed the arduino would rest 3 or 4 times before running the code again.
I surmised that this was due to the ambient electricity in the circuit and that a pull up resistor might solve the problem. After following the InputPullupSerial tutorial I implemented the inbuilt pull up resistor and switch the button states to check for in order to reset (ie checking for resetButton == LOW instead of HIGH) but alas, now the button does nothing at all.
This is a fairly minor thing I know, but it bugs me that the code doesn't work exactly as I want it to. Is there something I'm missing in my code?
I've tried to be pedantic with my code, as I teach software design and I want to be able use the code as an example with my students to explain what is happening with each line of code. The check for resetButton is right at the end of the code and the declaration of the rest function is just before the main loop.
Edit - Removed commented code as it was too long to attach
// Include the LCD library code:
#include <LiquidCrystal.h>
// Initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
LiquidCrystal lcd(1, 2, 3, 4, 5, 6);
// Declare unsigned long variables to track possibly large numbers
unsigned long time1 = 0; // Time for Track 1
unsigned long time2 = 0; // Time for Track 2
unsigned long startTime = 0; // Start Time
// Set variables for analog pins to read data from LDRs
int LDR_PinS = A0; // Launcher LDR
int LDR_Pin1 = A1; // Track 1 LDR
int LDR_Pin2 = A2; // Track 2 LDR
// Variables to hold ambient light
int ambient1 = 0;
int ambient2 = 0;
// Set variables for the start and finish states as well as Start Time
int start = 0; // Value used to tell whether the launcehr has fired or not
int finish = 0; // Boolean value that tells whether or not a car has crossed the line
// Variable to store LDR readings from the Launcher, Track 1 and Track 2
// as well as to store the finish times for both tracks
int LDRReadingS = 0; // Variable to store the LDR reading from the Launcher
int LDRReading1 = 0; // Variable to store the LDR reading from Track 1
int LDRReading2 = 0; // Variable to store the LDR reading from Track 2
int finishTime1 = 0; // Variable to store final finish time for Track 1
int finishTime2 = 0; // Variable to store final finish time for Track 2
// Reset button state
int rButton = 1;
// Variables to store who wins the race for LEDs
int t1Win = 0;
int t2Win = 0;
// Variables to store whether the track has ended
int t1Finish = 0;
int t2Finish = 0;
// LDR Testing
int LDRT = 0; // 0 = Skip testing LDR values
void setup() {
// Set up the LCD's number of columns and rows
lcd.begin(16, 2);
lcd.clear();
// Setup IO for digital inputs and outputs
pinMode(12, OUTPUT); // Gate LEDs
pinMode(11, INPUT_PULLUP); // Reset button
pinMode(7, OUTPUT); // Track1 LED1
pinMode(8, OUTPUT); // Track1 LED2
pinMode(9, OUTPUT); // Track2 LED1
pinMode(10, OUTPUT); // Track2 LED2
// Turn on Gate LEDs
digitalWrite(12, HIGH);
// LED Startup sequence...
digitalWrite(7, HIGH);
delay(250);
digitalWrite(8, HIGH);
delay(250);
digitalWrite(9, HIGH);
delay(250);
digitalWrite(10, HIGH);
delay(250);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
delay(250);
digitalWrite(7, HIGH);
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
delay(250);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
// Print "Track 1: ..." to TOP line of LCD
lcd.setCursor(0, 0);
lcd.print("Track 1:");
// Print "Track 2: ..." to BOTTOM line of LCD
lcd.setCursor(0, 1);
lcd.print("Track 2:");
// Take ambient light levels
ambient1 = analogRead(LDR_Pin1);
ambient2 = analogRead(LDR_Pin2);
}
void(* resetFunc) (void) = 0; //Declare reset function
void loop() {
// Capture the LDR reading from the launcher and both tracks
LDRReadingS = analogRead(LDR_PinS);
LDRReading1 = analogRead(LDR_Pin1);
LDRReading2 = analogRead(LDR_Pin2);
// Launcher Logic - If the value for LDR rises above 150
// AND the races hasn't started yet, then capture
// the start time and set the Start boolean to 1
// The race has begun!
if (LDRReadingS >= 150 && start == 0) {
startTime = (millis()/1000.000);
start = 1;
lcd.setCursor(9, 0);
lcd.print("...");
lcd.setCursor(9, 1);
lcd.print("...");
}
// LDR Testing - If LDRT is set to 1, test LDR values
if (LDRT == 1) {
// Print LDR values to LCD
lcd.setCursor(0, 0);
lcd.print("LDR1:");
lcd.setCursor(6, 0);
lcd.print(LDRReading1);
lcd.setCursor(10, 0);
lcd.print("Start:");
lcd.setCursor(0, 1);
lcd.print("LDR2:");
lcd.setCursor(6, 1);
lcd.print(LDRReading2);
lcd.setCursor(11, 1);
lcd.print(LDRReadingS);
}
// Track 1 finish code - IF ambient1 drops 50 points below the initial value AND the race has started
// AND Track 1 has not crossed the line, record the finish time in finishTime1 and display it to the LCD
if (LDRReading1 <= (ambient1-50) && start == 1 && t1Finish == 0) {
float finishTime1 = ((millis()/1000.000) - startTime);
t1Finish = 1;
lcd.setCursor(9, 0);
lcd.print(finishTime1, 3);
// If Track 2 hasn't finished yet then Track 1 has won the race
if (t2Finish == 0){
t1Win = 1;
}
}
// Track 2 finish code - IF ambient2 drops 50 points below the initial value AND the race has started
// AND Track 2 has not crossed the line, record the finish time in finishTime2 and display it to the LCD
if (LDRReading2 <= (ambient2-50) && start == 1 && t2Finish == 0) {
float finishTime2 = ((millis()/1000.000) - startTime);
t2Finish = 1;
lcd.setCursor(9, 1);
lcd.print(finishTime2, 3);
// If Track 1 hasn't finished yet then Track 2 has won the race
if (t1Finish == 0){
t2Win = 1;
}
}
if (t1Win == 1){
// Turn OFF Track 2 LEDs
digitalWrite(9, LOW);
digitalWrite(10, LOW);
// Track 2 LED Win Sequence
digitalWrite(7, HIGH);
digitalWrite(8, LOW);
delay(50);
digitalWrite(7, LOW);
digitalWrite(8, HIGH);
delay(50);
}
if (t2Win == 1){
// Turn OFF Track 1 LEDs
digitalWrite(7, LOW);
digitalWrite(8, LOW);
// Track 2 LED Win Sequence
digitalWrite(9, HIGH);
digitalWrite(10, LOW);
delay(50);
digitalWrite(9, LOW);
digitalWrite(10, HIGH);
delay(50);
}
// Reset button
rButton = digitalRead(11); // Read INPUT from pin11 to the button state
if (rButton == LOW) {
resetFunc(); //call reset
}
}