Mee_n_Mac:
I fixed the 16x2 to be 20x4.
I also did domething with the timer state to perhaps fix that, but the more I look into it the less sure I am that the fix will “take”.
Since you have a button wired to digital pin6, I changed the code to use that as a single scroll button input. So wire that button the same way you’ve wired the start/stop button … except of course it’ll go to pin6.
I’ve done something to perhaps fix the review display(s). I’m not sure why there were stuck displaying the 1’st and 5’th hit times but I changed something I thought was questionalble. I guess we’ll see. There’s still some odd behavior that I wouldn’t have predicted to happen even given the bad coding I’ve seen. There’s probably still some bugs to squash.
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 9, 8);
// set pin numbers
const int StartPin = 7; // the number of the Start 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 = 10; // the number of the buzzer output pin
const int LEDPin = 13; // the number of the LED output pin
const int ScrollPin = 6; // the number of the scroll button input pin
//const int ButtonInPin = A0; // the pin used for the analog buttons
// initialize the constants
const unsigned long MaxTime = 30000; // the max time the timer can run for = 30 secs
const unsigned long WaitTime = 2000; // wait time btw start and timer running = 2 secs plus debounce
const unsigned long DB_delay = 1000; // set a debounce wait time of 1000 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
const byte MaxHits = 20; // Maximum number if hits allowed
// initialize global variables
volatile byte TimerState = 0; // variable for state of timer, running or not running
volatile byte AupDtFlag = 0; // variable indication an A hit has occurred
volatile byte BupDtFlag = 0; // variable indication a B hit has occurred
byte DisplayState = 0; // variable for controlling what’s displayed
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 byte A_count = 0; // variable to hold the number of A hits
volatile byte B_count = 0; // variable to hold the number of B hits
volatile long A_Times[MaxHits];// array to hold up to MaxHits hit times for target A
volatile long B_Times[MaxHits];// array to hold up to MaxHits hit times for target B
long A_splits[MaxHits];
long B_splits[MaxHits];
long AB_splits[MaxHits];
float A_Hit_Factor = 0;
float B_Hit_Factor = 0;
byte S1 = 0; // Switch 1 init to zero
byte S2 = 0; // Switch 2 init to zero
// setup and intialize strings for the display each 20 chars long
String Line1 = " Shot Timer v1 ";
String Line2 = " is alive ";
String Line3 = " ";
String Line4 = " ";
void setup()
{
// set up the LCD’s number of columns and rows:
lcd.begin(20, 4);
lcd.clear();
lcd.print(" Shot Timer 1 “);
lcd.setCursor(0, 1);
lcd.print(” Initializing ");
delay(5000);
// 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);
// for now use pin 6 as button input
pinMode(ScrollPin, INPUT);
digitalWrite(ScrollPin, 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);
lcd.setCursor(0, 1);
lcd.print(" Ready ");
}
void loop()
{
if (TimerState) // is timer running
{
// timer is running
// check to see if this is first pass since start push
// this is goofy and will change when modes are coded
if (DisplayState == 0)
{
DisplayState = 1; // display will show count and time w 1st hit
}
// send data to display if there have been any hits
if (AupDtFlag == 1 || BupDtFlag == 1)
{
CalcTimes();
FormatData();
LCDdisplay();
}
// timer is running so now check for any stop conditions
if ((digitalRead(StartPin) == LOW) || ((millis() - StartTime) > MaxTime) || A_count >= MaxHits || B_count >= MaxHits)
{
StopTimer();
tone(BuzzerPin, FreqLo, BuzzTime10);
// update display just in case last msec hit came in
if (AupDtFlag == 1 || BupDtFlag == 1)
{
CalcTimes();
FormatData();
LCDdisplay();
}
// just for the moment send times to PC for debug
SendTimes();
// delay enough to debounce stop button
delay(DB_delay);
// Change to review display, later this will be mode depandant
DisplayState = 2;
FormatData();
LCDdisplay();
}
}
else
{
// timer is stopped look for start button or review button pushes
if (digitalRead(StartPin) == LOW)
{
// start button pushed
// 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”);
// turn on the LED to show timer is running
digitalWrite(LEDPin, HIGH);
// clear all the prior runs data, reset the display
ClearData();
DisplayState = 0;
FormatData();
LCDdisplay();
// delay the Wait Time from start button push
// this delay is for debounce purposes and should stay
delay(DB_delay);
// this delay will change to random later on
delay(WaitTime);
// enable the interrupts just in case
interrupts();
// save the starting time of this run
StartTime = millis();
// set state of timer to running
TimerState = 1;
// now buzz the speaker for 0.5 secs
tone(BuzzerPin, FreqHi, BuzzTime5);
}
// check for scroll button pushes, change display state as reqd
if (digitalRead(ScrollPin) == LOW)
{
int ds = int(A_count/8) + 1; // find the displaystate max
if (A_count % 8)
{
ds = int(A_count/8) + 2; // find the displaystate max
}
DisplayState++; // increment displaystate upon push
if (DisplayState > ds)
{
DisplayState = 2; // wrap around of scrolling action
}
FormatData();
LCDdisplay();
delay(DB_delay);
}
}
}
void StopTimer()
{
//noInterrupts();
TimerState = 0;
// turn the LED off to show timer is stopped
digitalWrite(LEDPin, LOW);
}
void ClearData()
{
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 : “);
int i = 0;
int k = 0;
for (i=0; i < A_count ; i++)
{
k = i + 1;
//Serial.print(A_count[k]);
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 (i=0; i < B_count ; i++)
{
k = i + 1;
//Serial.print(B_count[k]);
Serial.print(”\t”);
Serial.print(B_Times[i]);
Serial.print(“\t”);
Serial.println(B_splits[i]);
}
}
void ISR_A()
{
if(TimerState)
{
// 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
AupDtFlag = 1;
}
}
void ISR_B()
{
if(TimerState)
{
// 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
BupDtFlag = 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[A_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
}
void FormatData()
{
// routine to format lines of data to be sent to LCD
// presently assume 4 lines of 20 characters
// switch formatting done based on display state
switch (DisplayState)
{
case 1:{
//this is for single A shooter mode
// display number of hits so far
String tmp = "A: # hits = ";
Line1 = tmp + A_count;
// now display the time of last hit in secs out to hundreths of secs
String tmp2 = TimeConvert(A_Times[A_count-1]); // convert hit time to XX.xx format
Line2 = “Hit time= " + tmp2 + " secs”;
Line3 = " ";
Line4 = " ";
break;}
case 2:{
// this is A review mode hits 1-8
tmp = TimeConvert(A_Times[0]); // convert hit time to XX.xx format
tmp2 = TimeConvert(A_Times[4]); // convert hit time to XX.xx format
Line1 = “A 1:” + tmp + “s 5:” + tmp2 + “s”;
tmp = TimeConvert(A_Times[1]); // convert hit time to XX.xx format
tmp2 = TimeConvert(A_Times[5]); // convert hit time to XX.xx format
Line2 = “A 2:” + tmp + “s 6:” + tmp2 + “s”;
tmp = TimeConvert(A_Times[2]); // convert hit time to XX.xx format
tmp2 = TimeConvert(A_Times[6]); // convert hit time to XX.xx format
Line3 = “A 3:” + tmp + “s 7:” + tmp2 + “s”;
tmp = TimeConvert(A_Times[3]); // convert hit time to XX.xx format
tmp2 = TimeConvert(A_Times[7]); // convert hit time to XX.xx format
Line4 = “A 4:” + tmp + “s 8:” + tmp2 + “s”;
break;}
case 3:{
// this is A review mode hits 9-16
tmp = TimeConvert(A_Times[8]); // convert hit time to XX.xx format
tmp2 = TimeConvert(A_Times[12]); // convert hit time to XX.xx format
Line1 = “A 9:” + tmp + “s 13:” + tmp2 + “s”;
tmp = TimeConvert(A_Times[9]); // convert hit time to XX.xx format
tmp2 = TimeConvert(A_Times[13]); // convert hit time to XX.xx format
Line2 = “A 10:” + tmp + “s14:” + tmp2 + “s”;
tmp = TimeConvert(A_Times[10]); // convert hit time to XX.xx format
String tmp2 = TimeConvert(A_Times[14]); // convert hit time to XX.xx format
Line3 = “A 11:” + tmp + “s15:” + tmp2 + “s”;
tmp = TimeConvert(A_Times[11]); // convert hit time to XX.xx format
tmp2 = TimeConvert(A_Times[15]); // convert hit time to XX.xx format
Line4 = “A 12:” + tmp + “s16:” + tmp2 + “s”;
break;}
case 4:{
// this is A review mode hits 17-20
tmp = TimeConvert(A_Times[16]); // convert hit time to XX.xx format
tmp2 = TimeConvert(A_Times[18]); // convert hit time to XX.xx format
Line1 = “A 17:” + tmp + “s19:” + tmp2 + “s”;
tmp = TimeConvert(A_Times[17]); // convert hit time to XX.xx format
tmp2 = TimeConvert(A_Times[19]); // convert hit time to XX.xx format
Line2 = “A 18:” + tmp + “s20:” + tmp2 + “s”;
Line3 = " ";
Line4 = " ";
break;}
default:
// do the default = 0
// 4 string objects
Line1 = " Shot Timer v1 ";
Line2 = " is running ";
Line3 = " Countdown to start ";
Line4 = " in progress ";
}
}
String TimeConvert(long time)
{
// takes the time as argument and returns the time for that hit as a XX.xx string
String tmp3 = String(int((time + 5)/10)); // round msecs into csecs
int k = tmp3.length(); // k will be index to last char in padded string
int km1 = k-1; // km1 will be index to next to last char
int km2 = k-2; // km2 will be position of period
tmp3 = tmp3 + ‘0’; // pad the end of the truncated string with a zero
//now move chars to make space to add a period
tmp3.setCharAt(k, tmp3.charAt(km1)); // move next-2-last to last position in string
tmp3.setCharAt(km1, tmp3.charAt(km2)); // move char to next-2-last position
// now insert period
tmp3.setCharAt(km2, ‘.’);
// tmp3 now holds rounded time in secs XX.xx format
return tmp3;
}
void LCDdisplay()
{
// reset display update flags
AupDtFlag = 0;
BupDtFlag = 0;
// sends 4 lines to LCD using library functions
lcd.clear();
lcd.print(Line1);
lcd.setCursor(0, 1);
lcd.print(Line2);
lcd.setCursor(0, 2);
lcd.print(Line3);
lcd.setCursor(0, 3);
lcd.print(Line4);
}
So see if the start/stop work now and the scroll button too. See if the display transistions from "init" to "ready" and then, *when started*, to "countdown" as it should. See that the LED and buzzer and messages to the PC all work as they used to. When the buzzer buzzes try to put 1 whack/sec into the system so we can roughtly see the times as they are displayed and that they are about right. If you can get more than 10 so hits the display scrollling can be wrung out. Perhaps what's needed are 2 or more test runs: one with 10 hits and a stop button ... and one with 20+ hits -> and autostop ... and one with a 30sec timeout and any number of hits less than 20. Vid of the 1'st run including time from reset to start and then stop and then scroll button action. You can just note the proper, or improper, action(s) of the other 2 test runs.
Just ran this code. The Display works correctly (messages at the beginning and the times for each hit are correct now) and so does the start/stop button. I wired a push button to pin 6 and that doesn’t do anything during review.
This is the corrected code that compiled and ran. I’m still going through the posts you made yesterday and today trying to catch up so this may not be as up to date as you are.
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 9, 8);
// set pin numbers
const int StartPin = 7; // the number of the Start 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 = 10; // the number of the buzzer output pin
const int LEDPin = 13; // the number of the LED output pin
const int ScrollPin = 6; // the number of the scroll button input pin
//const int ButtonInPin = A0; // the pin used for the analog buttons
// initialize the constants
const unsigned long MaxTime = 30000; // the max time the timer can run for = 30 secs
const unsigned long WaitTime = 2000; // wait time btw start and timer running = 2 secs plus debounce
const unsigned long DB_delay = 1000; // set a debounce wait time of 1000 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
const byte MaxHits = 20; // Maximum number if hits allowed
// initialize global variables
volatile byte TimerState = 0; // variable for state of timer, running or not running
volatile byte AupDtFlag = 0; // variable indication an A hit has occurred
volatile byte BupDtFlag = 0; // variable indication a B hit has occurred
byte DisplayState = 0; // variable for controlling what's displayed
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 byte A_count = 0; // variable to hold the number of A hits
volatile byte B_count = 0; // variable to hold the number of B hits
volatile long A_Times[MaxHits];// array to hold up to MaxHits hit times for target A
volatile long B_Times[MaxHits];// array to hold up to MaxHits hit times for target B
long A_splits[MaxHits];
long B_splits[MaxHits];
long AB_splits[MaxHits];
float A_Hit_Factor = 0;
float B_Hit_Factor = 0;
byte S1 = 0; // Switch 1 init to zero
byte S2 = 0; // Switch 2 init to zero
// setup and intialize strings for the display each 20 chars long
String Line1 = " Shot Timer v1 ";
String Line2 = " is alive ";
String Line3 = " ";
String Line4 = " ";
void setup()
{
// set up the LCD's number of columns and rows:
lcd.begin(20, 4);
lcd.clear();
lcd.print(" Shot Timer 1 ");
lcd.setCursor(0, 1);
lcd.print(" Initializing ");
delay(5000);
// 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);
// for now use pin 6 as button input
pinMode(ScrollPin, INPUT);
digitalWrite(ScrollPin, 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);
lcd.setCursor(0, 1);
lcd.print(" Ready ");
}
void loop()
{
if (TimerState) // is timer running
{
// timer is running
// check to see if this is first pass since start push
// this is goofy and will change when modes are coded
if (DisplayState == 0)
{
DisplayState = 1; // display will show count and time w 1st hit
}
// send data to display if there have been any hits
if (AupDtFlag == 1 || BupDtFlag == 1)
{
CalcTimes();
FormatData();
LCDdisplay();
}
// timer is running so now check for any stop conditions
if ((digitalRead(StartPin) == LOW) || ((millis() - StartTime) > MaxTime) || A_count >= MaxHits || B_count >= MaxHits)
{
StopTimer();
tone(BuzzerPin, FreqLo, BuzzTime10);
// update display just in case last msec hit came in
if (AupDtFlag == 1 || BupDtFlag == 1)
{
CalcTimes();
FormatData();
LCDdisplay();
}
// just for the moment send times to PC for debug
SendTimes();
// delay enough to debounce stop button
delay(DB_delay);
// Change to review display, later this will be mode depandant
DisplayState = 2;
FormatData();
LCDdisplay();
}
}
else
{
// timer is stopped look for start button or review button pushes
if (digitalRead(StartPin) == LOW)
{
// start button pushed
// 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");
// turn on the LED to show timer is running
digitalWrite(LEDPin, HIGH);
// clear all the prior runs data, reset the display
ClearData();
DisplayState = 0;
FormatData();
LCDdisplay();
// delay the Wait Time from start button push
// this delay is for debounce purposes and should stay
delay(DB_delay);
// this delay will change to random later on
delay(WaitTime);
// enable the interrupts just in case
interrupts();
// save the starting time of this run
StartTime = millis();
// set state of timer to running
TimerState = 1;
// now buzz the speaker for 0.5 secs
tone(BuzzerPin, FreqHi, BuzzTime5);
}
// check for scroll button pushes, change display state as reqd
if (digitalRead(ScrollPin) == LOW)
{
int ds = int(A_count/8) + 1; // find the displaystate max
if (A_count % 8)
{
ds = int(A_count/8) + 2; // find the displaystate max
}
DisplayState++; // increment displaystate upon push
if (DisplayState > ds)
{
DisplayState = 2; // wrap around of scrolling action
}
FormatData();
LCDdisplay();
delay(DB_delay);
}
}
}
void StopTimer()
{
//noInterrupts();
TimerState = 0;
// turn the LED off to show timer is stopped
digitalWrite(LEDPin, LOW);
}
void ClearData()
{
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 : ");
int i = 0;
int k = 0;
for (i=0; i < A_count ; i++)
{
k = i + 1;
//Serial.print(A_count[k]);
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 (i=0; i < B_count ; i++)
{
k = i + 1;
//Serial.print(B_count[k]);
Serial.print("\t");
Serial.print(B_Times[i]);
Serial.print("\t");
Serial.println(B_splits[i]);
}
}
void ISR_A()
{
if(TimerState)
{
// 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
AupDtFlag = 1;
}
}
void ISR_B()
{
if(TimerState)
{
// 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
BupDtFlag = 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[A_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
}
void FormatData()
{
// routine to format lines of data to be sent to LCD
// presently assume 4 lines of 20 characters
// switch formatting done based on display state
switch (DisplayState)
{
case 1:{
//this is for single A shooter mode
// display number of hits so far
String tmp = "A: # hits = ";
Line1 = tmp + A_count;
// now display the time of last hit in secs out to hundreths of secs
String tmp2 = TimeConvert(A_Times[A_count-1]); // convert hit time to XX.xx format
Line2 = "Hit time= " + tmp2 + " secs";
Line3 = " ";
Line4 = " ";
break;}
case 2:{
// this is A review mode hits 1-8
String tmp = TimeConvert(A_Times[0]); // convert hit time to XX.xx format
String tmp2 = TimeConvert(A_Times[4]); // convert hit time to XX.xx format
Line1 = "A 1:" + tmp + "s 5:" + tmp2 + "s";
tmp = TimeConvert(A_Times[1]); // convert hit time to XX.xx format
tmp2 = TimeConvert(A_Times[5]); // convert hit time to XX.xx format
Line2 = "A 2:" + tmp + "s 6:" + tmp2 + "s";
tmp = TimeConvert(A_Times[2]); // convert hit time to XX.xx format
tmp2 = TimeConvert(A_Times[6]); // convert hit time to XX.xx format
Line3 = "A 3:" + tmp + "s 7:" + tmp2 + "s";
tmp = TimeConvert(A_Times[3]); // convert hit time to XX.xx format
tmp2 = TimeConvert(A_Times[7]); // convert hit time to XX.xx format
Line4 = "A 4:" + tmp + "s 8:" + tmp2 + "s";
break;}
case 3:{
// this is A review mode hits 9-16
String tmp = TimeConvert(A_Times[8]); // convert hit time to XX.xx format
String tmp2 = TimeConvert(A_Times[12]); // convert hit time to XX.xx format
Line1 = "A 9:" + tmp + "s 13:" + tmp2 + "s";
tmp = TimeConvert(A_Times[9]); // convert hit time to XX.xx format
tmp2 = TimeConvert(A_Times[13]); // convert hit time to XX.xx format
Line2 = "A 10:" + tmp + "s14:" + tmp2 + "s";
tmp = TimeConvert(A_Times[10]); // convert hit time to XX.xx format
String tmp3 = TimeConvert(A_Times[14]); // convert hit time to XX.xx format
Line3 = "A 11:" + tmp + "s15:" + tmp2 + "s";
tmp = TimeConvert(A_Times[11]); // convert hit time to XX.xx format
tmp2 = TimeConvert(A_Times[15]); // convert hit time to XX.xx format
Line4 = "A 12:" + tmp + "s16:" + tmp2 + "s";
break;}
case 4:{
// this is A review mode hits 17-20
String tmp = TimeConvert(A_Times[16]); // convert hit time to XX.xx format
String tmp2 = TimeConvert(A_Times[18]); // convert hit time to XX.xx format
Line1 = "A 17:" + tmp + "s19:" + tmp2 + "s";
String tmp3 = TimeConvert(A_Times[17]); // convert hit time to XX.xx format
String tmp4 = TimeConvert(A_Times[19]); // convert hit time to XX.xx format
Line2 = "A 18:" + tmp + "s20:" + tmp2 + "s";
Line3 = " ";
Line4 = " ";
break;}
default:
// do the default = 0
// 4 string objects
Line1 = " Shot Timer v1 ";
Line2 = " is running ";
Line3 = " Countdown to start ";
Line4 = " in progress ";
}
}
String TimeConvert(long time)
{
// takes the time as argument and returns the time for that hit as a XX.xx string
String tmp3 = String(int((time + 5)/10)); // round msecs into csecs
int k = tmp3.length(); // k will be index to last char in padded string
int km1 = k-1; // km1 will be index to next to last char
int km2 = k-2; // km2 will be position of period
tmp3 = tmp3 + '0'; // pad the end of the truncated string with a zero
//now move chars to make space to add a period
tmp3.setCharAt(k, tmp3.charAt(km1)); // move next-2-last to last position in string
tmp3.setCharAt(km1, tmp3.charAt(km2)); // move char to next-2-last position
// now insert period
tmp3.setCharAt(km2, '.');
// tmp3 now holds rounded time in secs XX.xx format
return tmp3;
}
void LCDdisplay()
{
// reset display update flags
AupDtFlag = 0;
BupDtFlag = 0;
// sends 4 lines to LCD using library functions
lcd.clear();
lcd.print(Line1);
lcd.setCursor(0, 1);
lcd.print(Line2);
lcd.setCursor(0, 2);
lcd.print(Line3);
lcd.setCursor(0, 3);
lcd.print(Line4);
}