Counting and Timing a shock sensor

sspbass:
5. I let it time out at 30 seconds and it automatically restarted again. I guess that indicates that it’s not a debounce issue?

Well that’s odd ! Should be a good clue though. I’m now thinking perhaps the buzzer is causing some electrical noise or power supply voltage dip and making the switch appear to be pushed. Perhaps disconnect the wire to the buzzer and see if the problem goes away.

Negative ghost rider, removed the buzzer and it still re-started.

sspbass:

  1. Yes the bottom line fades out like you see in the video.
That's because the updating of the display is a bit goofy right now. I figured it would change later so I didn't put a lot of thought into it. Every pass throught the main loop() causes the display to the cleared and then refreshed with whatever data is in the Line1 and Line2 strings. I'll opine that sending the data to the LCD takes a little bit of time so the first parts displayed get displayed longer before the clear ... and so appear brighter and less flickery. The proper thing to do is only update the display when there's a need to and not every pass though the loop().

sspbass:
3. Not sure what you mean about the led on pin 13. The LED lights up when the 1st buzzer starts and goes out when the second buzzer goes. I don’t see anything odd about it.

That’s good and I could just see it working between the wires in the vid. If the buzzer is disconnected, it can be the way to know the timer is running or not.

sspbass:
Negative ghost rider, removed the buzzer and it still re-started.

Hmmmm … :doh:

BTW which function got reassigned to pin 1 ?

The start button.

Here is what I’m running right now.

#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 = 1;       // 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 = 10;      // 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 = 3000;      // 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
const unsigned 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;

// setup and intialize two strings for the display each 16 chars long
String Line1 = "Arduino timer v1";
String Line2 = "says Hello World";










void setup()
{
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  lcd.clear();

  // 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 there 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 : ");
  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 == 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[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
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
      String tmp = "A: # hits = ";
      // for loop to create the proper number of padding spaces
      // tmp holds 12 characters
      // need 3 or less spaces to pad so hit count is right justified
      // 3 spaces for hits 0-9, 2 spaces for 10-99, 1 space else
      for (int i=3; i >= sizeof(char(A_count)); i--)
      {
        tmp = tmp + ' '; // add space to end of existing string
      }
      // display number of hits so far
      String Line1 = tmp + A_count ;
      // print the time of last hit in secs
      String tmp2 = "Time is ";
      String Line2 = tmp2 + (A_Times[A_count-1]);
      break;}
    case 2:{
      // this is for A vs B mode
      // put that display code here
      break;
    default: 
      // do the default =0 for now
      // 2 string objects for lines 1 and 2
      Line1 = "Arduino Timer v1";
      Line2 = "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);
}

sspbass:
The start button.

Hang on … isn’t pin 1 also used for the serial communications ? I’ll check but … IIRC

EDIT : Yup pin 1 is the serial Tx out from the Arduino. So everytime the code writes to the PC/monitor it’ll be toggling the start/stop pin. Find another free/unused pin for the start/stop. Pin 0 is not available, it’s the serial Rx in to the Arduino.

Now on to debugging the LCD !

Yipee! That took care of it. Unfortunately I’m out of pins and had to comment out references to the down pin on pin 7 and used 7 for the star/stop button.

By my quick count you’re out of pins ! So for now use one of the pins assigned (but not yet used) for the up or down button inputs. Why not pin …

ooops I’ve typed too slowly. :shifty:

So we know that initialzing Line1/2 to stuff and declaring them as Strings works. That data gets sent to the LCD. So why isn’t the hit data showing up there. I had expected that even if the hit data formatted for the LCD was AFU the LCD display would change and be AFU. I wonder if "HitFlag is getting set properly ? Or if the formatting is so AFU the LCD rejects it ?

Try this to see if the display will change at all when a hit is detected.

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
      String tmp = "A: # hits = ";
      // for loop to create the proper number of padding spaces
      // tmp holds 12 characters
      // need 3 or less spaces to pad so hit count is right justified
      // 3 spaces for hits 0-9, 2 spaces for 10-99, 1 space else
      //for (int i=3; i >= sizeof(char(A_count)); i--)
      //{
        //tmp = tmp + ' '; // add space to end of existing string
      //}
      // display number of hits so far
      Line1 = tmp ;
      // print the time of last hit in secs
      String tmp2 = "Time is ";
      Line2 = tmp2 ;
      break;}
    case 2:{
      // this is for A vs B mode
      // put that display code here
      break;
    default: 
      // do the default =0 for now
      // 2 string objects for lines 1 and 2
      Line1 = "Arduino timer v1";
      Line2 = "says Hello World";}
  }
}

I’m back, and we’re making progress.

When it stars timeing and I set off the shock sensor it displays

"A: # hits =

Time is"

No data but at least it’s switching to something different.

When I hit the start/stop button again though the lcd stays the same, it doesn’t clear.

sspbass:
I’m back, and we’re making progress.

When it stars timeing and I set off the shock sensor it displays

"A: # hits =

Time is"

No data but at least it’s switching to something different.

When I hit the start/stop button again though the lcd stays the same, it doesn’t clear.

OK so it’s the whole converting data to strings and appending that to the constant part that’s AFU. Funny according to this …

http://arduino.cc/en/Reference/StringObject

http://arduino.cc/en/Tutorial/StringAdditionOperator

… I thought that stuff would work. Still it’ll probably be some small change to get it working. Let me think about making a small change to start with and ignore getting the right justify correct.

As for the reset of the LCD it should stay the same until a re-start. It won’t change back to the “Hello World” start message unless you’ve changed the ClearData() function and added the “DisplayState = 0;” line. See below.

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;
  DisplayState = 0;
}

If you read the links above you see that adding a long integer, like the output from a millis() function, to a constant string is allowed. So the Line2 formatting below should work. Similarly adding a integer to get Line1 should work. So try this …

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
      String tmp = "A: # hits = ";
      // for loop to create the proper number of padding spaces
      // tmp holds 12 characters
      // need 3 or less spaces to pad so hit count is right justified
      // 3 spaces for hits 0-9, 2 spaces for 10-99, 1 space else
      //for (int i=3; i >= sizeof(char(A_count)); i--)
      //{
        //tmp = tmp + ' '; // add space to end of existing string
      //}
      // display number of hits so far
      Line1 = tmp + A_count ;
      // print the time of last hit in secs
      String tmp2 = "Time is ";
      Line2 = tmp2 + (A_Times[A_count-1]);
      break;}
    case 2:{
      // this is for A vs B mode
      // put that display code here
      break;
    default: 
      // do the default =0 for now
      // 2 string objects for lines 1 and 2
      Line1 = "Arduino timer v1";
      Line2 = "says Hello World";}
  }
}

I’m not sure what happens with leading zeros in a long integer, like a time, but I guess we’ll see.

Bingo!

http://www.youtube.com/watch?v=OOJ4nD6K … e=youtu.be

OK then, that’s some progress ! So what’s left to be demonstrated ? Convert the msecs time display to seconds in the XXX.xx format. After that I think you need to decide what you want displayed and when. And add the extra features and “game” modes.

FWIW you can add switches on a analog pin. One, 2, 3 and more switches can be arranged as a switched voltage divider that provides a varied voltage, to be read via the A/D converter.

I decided that a beer wasn’t enough. Alas I don’t have the makings for a proper MaiTai at hand so I’m settling for a Black Russian ! :dance:

I’ve changed a few things (LED changes state with start/stop button push, display shouldn’t flicker, max targets = 20) and want to “document” what I think should be a new working baseline for the code. So here it is, give it a try and see if it still works … but better !

#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

// 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 unsigned int MaxHits = 20;         // 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 UpDtFlag = 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;

// setup and intialize two strings for the display each 16 chars long
String Line1 = "Arduino timer v1";
String Line2 = "says Hello World";


void setup()
{
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  lcd.clear();
  lcd.print("Hello World");
  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);

  // 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");

      // turn on the LED to show timer is running
      digitalWrite(LEDPin, HIGH);

      // clear all the prior runs data, reset the display
      ClearData();
      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 = RUN;

      // now buzz the speaker for 0.5 secs
      tone(BuzzerPin, FreqHi, BuzzTime5);
    }
    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
      SendTimes();
    }
  }
  // send data to display if there have been any hits
  if (UpDtFlag == 1)
  {
    CalcTimes();
    FormatData();
    LCDdisplay();
    // this is goofy but for now change display state here
    DisplayState = 1;
  }

  //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
    SendTimes();
    }
  }
}


void StopTimer()
{
  //noInterrupts();
  TimerState = !RUN;
  // 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;
  DisplayState = 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 == 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
    UpDtFlag = 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
    UpDtFlag = 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 2 lines of 16 characters
// switch formatting done based on display state
  switch (DisplayState)
  {
    case 1:{
      //this is for single A shooter
      String tmp = "A: # hits = ";
      // for loop to create the proper number of padding spaces
      // tmp holds 12 characters
      // need 3 or less spaces to pad so hit count is right justified
      // 3 spaces for hits 0-9, 2 spaces for 10-99, 1 space else
      //for (int i=3; i >= sizeof(char(A_count)); i--)
      //{
        //tmp = tmp + ' '; // add space to end of existing string
      //}
      // display number of hits so far
      Line1 = tmp + A_count ;
      // print the time of last hit in secs
      String tmp2 = "Time is ";
      Line2 = tmp2 + (A_Times[A_count-1]);
      break;}
    case 2:{
      // this is for A vs B mode
      // put that display code here
      break;
    default: 
      // do the default =0 for now
      // 2 string objects for lines 1 and 2
      Line1 = "Arduino timer v1";
      Line2 = "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);
  // reset the display update flag
  UpDtFlag = 0;
}

So how do you get the time into seconds and with a decimal? Do you need to use floating point variables?

How about something like this display http://www.jameco.com/webapp/wcs/stores … 2137844_-1

ETA: I’ll try the new code once my movie is finished.

sspbass:
So how do you get the time into seconds and with a decimal? Do you need to use floating point variables?

Good questions. I dunno. Right now if you wanted a XX.xxx (note the thousands of a second) I’d be tempted to convert the time into plain characters and just divide the whole seconds and decimal part into … 2 parts and then insert a decimal point inbetween and send the result to the display. No FP calcs needed. If you want to round off the times to the nearest 1/100 of a sec (technically the proper thing to do), then I’m not sure what to do. I really hate to do FP calcs as they take soooo much time but in this case that may not be a real concern. It’s the rounding that I have to look into and I think I’ve seen such functions for an Ardiuno someplace.

sspbass:
How about something like this display http://www.jameco.com/webapp/wcs/stores … 2137844_-1

That looks to be the same (perhaps w/o the serial interface) as the SF one I (half) kiddingly suggested a while ago. The 4 lines obviously allows a lot more info to be displayed. Might be nice in a A vs B competition. I wonder if it takes the same interface and library as the one you’ve got now ? I suspect that’s the case but I don’t know that it’s true.

Again that’s all up to you as to what you want displayed and how much $$s you want to spend to do it.

It’s like the old racing adage … “Speed costs money. How fast do you want to go ?” :mrgreen:

I hear ya there. The way I look at it though is that going from 2 lines to 4 lines is exponentially better when trying to compare two shooters. Otherwise your trying to scroll through screen after screen of info. And the one I linked was only $10 more than the one i’m using now. I tried to find one on sparkfun but they didn’t have any 4 line ones that were serial.

Oh and… The code you modified worked great. Took care of the flashing. What did you change to do that?

sspbass:
I hear ya there. The way I look at it though is that going from 2 lines to 4 lines is exponentially better when trying to compare two shooters. Otherwise your trying to scroll through screen after screen of info. And the one I linked was only $10 more than the one i’m using now. I tried to find one on sparkfun but they didn’t have any 4 line ones that were serial.

The one SF sells is not serial and takes (ugh) 11 lines to inteface to. Unless you want to spring more $$s for a “backpack” to add to it, it’s a loser.

http://www.sparkfun.com/products/256

http://www.sparkfun.com/products/258

The thing is … I don’t know that the Jameco one is any different. Hmmmm ???

EDIT : I take that back. it does say “•Parallel (6800 MPU) or Serial MPU interface”. Not a lot of detail but …

sspbass:
Oh and… The code you modified worked great. Took care of the flashing. What did you change to do that?

Kewl ! :dance: I put the updating of the display into the conditional that the UpDtFlag has been set. Since that would mean a delay in restoring the startup display, I also added the functions needed to update the display to the start button pushed thread of code.

As for the XX.xx display of time, I think I need to split the data into those 2 parts and stick a decimal point inbetween as the String objects nor display handle FP numbers. Converting to an int would truncate the decimal part so that’s out. I may need another BR to figure this out ! :think: