Have a look at the below. I think I’ve include a skeleton of all the basic stuff needed to start. You’ll have to change the pin numbers/assignments to match your LCD wiring. They are wrong as is below. I’ve fixed a few things and added some others. I would get your Arduino wiring to the LCD checked out using a version of the LCD tutorial code (not the timer code) first and then give this a try … after you’ve reviewed it. It may do more than you want (and while simultaneously doing less than you’ll eventually want) but I figure it’s easier to cut out than to add in.
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// set pin numbers
const int StartPin = 4; // the number of the Start pushbutton pin
const int UpPin = 6; // the number of the ScrollUp pushbutton pin
const int DownPin = 7; // the number of the ScrollDown pushbutton pin
const int TargetAPin = 2; // the number of the A targets input pin
const int TargetBPin = 3; // the number of the B targets input pin
const int BuzzerPin = 9; // the number of the buzzer output pin
const int LEDPin = 13; // the number of the LED output pin
// initialize the constants
const unsigned long MaxTime = 30000; // the max time the timer can run for = 30 secs
const unsigned long WaitTime = 3000; // the wait time btw start button and timer running = 3 secs
const unsigned long DB_delay = 200; // set a debounce wait time of 200 msecs
const unsigned long BuzzTime5 = 500; // set the on time for the buzzer, 500 msecs
const unsigned long BuzzTime2 = 200; // set the on time for the buzzer, 200 msecs
const unsigned long BuzzTime10 = 1000; // set the on time for the buzzer, 1000 msecs
const unsigned int FreqHi = 2000; // High frequency of buzzer tone
const unsigned int FreqLo = 1000; // Low frequency of buzzer tone
int MaxHits = 10; // Maximum number if hits allowed
const int RUN = 1; // make code easy to understand
// initialize global variables
volatile int TimerState = 0; // variable for state of timer, running or not running
int DisplayState = 0; // variable for controlling what's displayed
int HitFlag = 0; // variable indication a hit has occurred
unsigned long StartTime = 0; // variable to hold the start time
unsigned long BuzzTime = 500; // variable to hold the buzzer on time
unsigned int Freq = 2000; // variable for high or low buzzer tone
volatile int A_count = 0; // variable to hold the number of A hits
volatile int B_count = 0; // variable to hold the number of B hits
volatile long A_Times[MaxHits];// array to hold up to 10 hit times for target A
volatile long B_Times[MaxHits];// array to hold up to 10 hit times for target B
long A_splits [MaxHits];
long B_splits [MaxHits];
long AB_splits [MaxHits];
int A_Hit_Factor = 0;
int B_Hit_Factor = 0;
char Line1 [17];
char Line2 [17];
void setup()
{
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// initialize output pins
pinMode(BuzzerPin, OUTPUT);
pinMode(LEDPin, OUTPUT);
digitalWrite(BuzzerPin, LOW);
digitalWrite(LEDPin, LOW);
// initialize the input pins with internal pullups
pinMode(StartPin, INPUT);
pinMode(UpPin, INPUT);
pinMode(DownPin, INPUT);
pinMode(TargetAPin, INPUT);
pinMode(TargetBPin, INPUT);
digitalWrite(StartPin, HIGH);
digitalWrite(UpPin, HIGH);
digitalWrite(DownPin, HIGH);
digitalWrite(TargetAPin, HIGH);
digitalWrite(TargetBPin, HIGH);
// opens serial port, sets data rate to 9600 bps
Serial.begin(9600);
// setup ext pins as interrupts
attachInterrupt(0, ISR_A, FALLING);
attachInterrupt(1, ISR_B, FALLING);
}
void loop()
{
if (digitalRead(StartPin) == LOW)
{
// start stop button has been pushed, is timer running
if (TimerState == !RUN)
{
// timer is not running so start it
// Do the following debug code only to get system running
// This will send message to PC to show button was pushed
Serial.println("Timer is running");
// clear all the prior runs data
ClearData();
// delay the Wait Time from start button push
// this delay is for debounce purpose and should stay
delay(DB_delay);
// this delay will change to random later on
delay(WaitTime);
// turn on the LED to show timer is running
digitalWrite(LEDPin, HIGH);
// enable the interrupts just in case
interrupts();
// save the starting time of this run
StartTime = millis();
// set state of timer to running
TimerState = RUN;
// now buzz the speaker for 0.5 secs
tone(BuzzerPin, FreqHi, BuzzTime5)
// no need to debounce as mucho time has elapsed
}
else
{
// start stop button has been pushed again to stop timer
StopTimer();
tone(BuzzerPin, FreqLo, BuzzTime10);
// delay enough to debounce stop button
delay(DB_delay);
// just for the moment send times to PC only not to display
SendTimes();
}
}
// send data to display if they have been any hits
if (HitFlag == 1)
{
CalcTimes()
// this is goofy but for now change display state here
DisplayState = 1;
}
FormatData()
LCDdisplay()
//Check for max time out if timer is running
if (TimerState == RUN)
{
if ((millis() - StartTime) > MaxTime)
{
// call the function that does all the things needed to stop
StopTimer();
tone(BuzzerPin, FreqLo, BuzzTime10);
// just for the moment send times to PC only not to display
SendTimes();
}
}
}
void StopTimer()
{
//noInterrupts();
TimerState = !RUN;
// turn the LED off to show timer is stopped
digitalWrite(LEDPin, LOW);
}
void ClearData()
{
// This will need to change is more hits are allowed
A_count = 0;
B_count = 0;
for (int i=0; i < MaxHits ; i++)
{
A_Times[i] = 0;
B_Times[i] = 0;
A_splits[i] = 0;
B_splits[i] = 0;
AB_splits[i] = 0;
}
A_Hit_Factor = 0;
B_Hit_Factor = 0;
}
void SendTimes()
// temp routine to send data to serial monitor
{
Serial.println("Timer is stopped");
Serial.println("Here are the times for Shooter A");
Serial.print("Number of hits : ");
Serial.print("\t");
Serial.println(A_count);
Serial.println("A Hit and split times are : ");
for (int i=0; i < A_count ; i++)
{
Serial.print\(A_count[i+1];
Serial.print("\t");
Serial.print(A_Times[i]);
Serial.print("\t");
Serial.println(A_splits[i]);
}
Serial.println("Here are the times for Shooter B");
Serial.print("Number of hits : ");
Serial.print("\t");
Serial.println(B_count);
Serial.println("B Hit and split times are : ");
for (int i=0; i < B_count ; i++)
{
Serial.print\(B_count[i+1];
Serial.print("\t");
Serial.print(B_Times[i]);
Serial.print("\t");
Serial.println(B_splits[i]);
}
}
void ISR_A()
{
if(TimerState == RUN)
{
// store the hit time
A_Times[A_count] = millis() - StartTime;
// increment the hit count and array index
++A_count;
// set the Hit flag so other stuff will update
HitFlag = 1;
}
}
void ISR_B()
{
if(TimerState == RUN)
{
// store the hit time
B_Times[B_count] = millis() - StartTime;
// increment the hit count and array index
++B_count;
// set the Hit flag so other stuff will update
HitFlag = 1;
}
}
void CalcTimes()
{
// routine to calculate all data and declare winner
// not all calcs having meaning for uses of timer
// calculate A splits and cumlative hit factor
if (A_count > 1)
{
for (int i=1; i < A_count ; i++)
{
A_splits[i] = A_Times[i] - A_Times[i-1];
}
}
else
{
A_splits[0] = A_Times[0];
}
A_Hit_Factor = A_Times[B_count - 1]/A_count;
// calculate B splits and cumlative hit factor
if (B_count > 1)
{
for (int i=1; i < B_count ; i++)
{
B_splits[i] = B_Times[i] - B_Times[i-1];
}
}
else
{
B_splits[0] = B_Times[0];
}
B_Hit_Factor = B_Times[B_count - 1]/B_count;
// Calculate A - B times just in case
int Min_count = min(A_count, B_count);
for (int i=0; i < Min_count ; i++)
{
AB_splits[i] = A_Times[i] - B_Times[i];
}
// add more here for A vs B modes
HitFlag = 0;
}
void FormatData()
{
// routine to format lines of data to be sent to LCD
// presently assume 2 lines of 16 characters
// switch formatting done based on display state
switch (DisplayState)
{
case 1:
// this is for single A shooter mode
// number of hits so far
Line1 = char(A_count);
// print the time of last hit in secs
Line2 = char(A_Times(A_count-1)/1000);
break;
case 2:
//this is for A vs B mode
break;
default:
// do the default =0 for now
// 2 char arrays for lines 1 and 2
Line1 = "Arduino timer v1";
Line1 = "says Hello World";
}
}
void LCDdisplay()
{
// sends 2 lines to LCD using library functions
lcd.clear();
lcd.print(Line1);
lcd.setCursor(0, 1);
lcd.print(Line2);
}
{DK : feel free to review and comment the hell out of the above}