Counting and Timing a shock sensor

I got the LCD to print hello world so that works.

http://www.sparkfun.com/tutorial/AIK/LC … -guide.pdf

I moved the buzzer pin to pin 10 and I took what was supposed to be pin 2 & 3 from the above link and moved them to pin 8 & 9.

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("\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]);
  }
}

I noticed that this code was different.

For the b count you have a line that is

Serial.print(B_count[i+1]);

but you don’t have a similar line for the A section.

Oh and… that parenthesis didn’t fix it.

sspbass:
I noticed that this code was different.

For the b count you have a line that is

Serial.print(B_count[i+1]);

but you don’t have a similar line for the A section.

Oh and… that parenthesis didn’t fix it.

Musta copied and pasted worse that I thought ! I’ll guess it’s not liking the addition of 1 to the for loop index. So try to get around that by using another variable.

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]);
  }
}

If that doesn’t work eliminate the 2 lines mentioned, the ones with the Serial.print(X_count[k]); No need to get hung up on the debugging code. IF the LCD works in this code then there will be little need for the prints to the PC serial monitor!

I’m a wreck!

I commented out the trouble lines above and then it had a problem with this line.

Line1 = char(A_count);

saying…incompatible types in assignment of ‘char’ to ‘char[17]’

While I was trying to figure that out I hit undo a couple too many times and then it gave the error

"two or more data types in declaration of ‘setup’.

I reloaded a previous save but it still says it, it won’t highlight a line so I dont know what the heck its problem is.

I was trying to have 2 character arrays, Line1 and Line2, that would be populated as desired by numbers and characters needed for the display. Since the hit count is a number and not a character, I was trying to convert it into a character and “load” that result into Line1. I guess the above is not the right way to do that. I believe the library function for the LCD will handle numeric input and display it properly, so stricly speaking you could just send the count(s) to the display using …

lcd.print(A_count);

I’m just not sure how to easily make a line display someting like

A: # hits = 13

… and have it be properly right/left justified. My thinking was to concatenate various length character arrays to get “Line1”. For that matter I think I forgot to put the end-of-array indicator, ‘\0’, in Line1[16] as well. Naturally the same process would be used for “Line2”.

According to this …

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

I think the following should work for at least line 1 of the display. Then again I’m not sure the last char in the string is still a null character. I’m less sure about line 2 as I don’t know that dividing a long integer (miliis()) by 1000 returns an integer. If it does then line 2 might display but without the fractional part. In any case it’ll prove instructive as to what works and what doesn’t. The changed parts are as follows :

// setup two strings for the display 16 chars long
// make last character in string the null ID
char Line1 [17];
char Line2 [17];
Line1[16] = {'\0'};
Line2[16] = {'\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
      Line2 = String(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";
      Line2[] = "says Hello World";
  }
}

does the

Line1[16] = {'\0'};
Line2[16] = {'\0'};

need to go in the setup section as opposed to the global variables section perhaps?

I’m getting a compiling error stating “expected constructor, destructor, or type conversion before ‘=’ token”

sspbass:
does the

Line1[16] = {'\0'};

Line2[16] = {‘\0’};



need to go in the setup section as opposed to the global variables section perhaps?



I'm getting a compiling error stating "expected constructor, destructor, or type conversion before '=' token"

Since all it’s doing is setting 2 variables, the last ones in 2 character arrays, equal to some value (a NULL character), I’d think they’d be OK there. No different from setting any other variable to some initial value. Latter on this …

String Line1 = tmp + A_count ;

Line2 = String(A_Times(A_count-1)/1000);

… gets done, so perhaps those “initializing” statements aren’t even needed. Line1 and Line2 may get their NULL characters added via the String function(s).

I’d comment the offending lines out and see what happens, It’s only software.

If the result doesn’t choke on that anymore, but chokes on the above “Line2 = …”, then comment that out as well. I think it good if you can get any display on the LCD from this code working, Then it can be made to work properly. I’m hopeful it’ll display the “hello world” portion right after the timer starts and before the 1’st hit is sensed. Getting line 1 to display the hit by hit count would be next and then getting the time of each hit, formatted nicely on line 2, would be next. Break the problem up into managable pieces and attack each piece. Once these can be done, I think you can figure out how to display anything.

Just an FYI, an uninitialized array will have junk in its location. So I see you are stuffing a couple strings in there but you haven’t initialized the rest to be zeros.

Dan

I was just doing some reading and apparently a string object is a bit more than just a character array. Perhaps the right thing to do is declare Line1 and Line2 to be strings right up front and use them as such all the way though. I think string object automagically include the NULL terminator. So …

// setup two strings for the display 16 chars long
// make last character in string the null ID
char Line1 [17];
char Line2 [17];
Line1[16] = {'\0'};
Line2[16] = {'\0'};

… becomes …

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

And to avoid the other issues mentioned above …

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
      tmp = "Time is "
      Line2 = tmp + (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 think I can just set the string objects; Line1, Line2 and tmp = “stuff” since they’ve been declared as strings up front.

dkulinski:
Just an FYI, an uninitialized array will have junk in its location. So I see you are stuffing a couple strings in there but you haven’t initialized the rest to be zeros.

Dan

Yeah, see if my revision above is more consistent. Instead of using char arrays, I’m sticking to using string objects now and letting the compiler handle the details. I think it’ll make things easier though I don’t know if I have all the string syntax down correctly.

To be honest I have never used the string object in any of my code. But it looks good to me. I suspect the assignment operator is overridden to copy the array over and ensure proper termination. I still have yet to fully review your code.

Dan

I finally got some time and I got the code to at least compile.

I uploaded everything and now the led to signal the start flashes and the buzzer goes every three seconds without me pushing anything.

I tried putting in a line of code that would display Hello World to the lcd in the setup but that doesn’t even come up.

I then added a 5 second delay after I display the text. It gets to the delay so there must be something wrong with how the lcd is wired.

Could it be the pins 2 & 3 I changed to pin 8 &9 to accommodate the interrupt pins?

I’m not sure why it continuously buzzes though.

#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 = 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 = 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 = 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
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();
  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");

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

Correction: I got the LCD display to work. it comes up, displays my Hello World, then it displays the “Arduino timer v1” & “says Hello World”.

It still continues to flash and buzz every three seconds though.

sspbass:
Correction: I got the LCD display to work. it comes up, displays my Hello World, then it displays the “Arduino timer v1” & “says Hello World”.

It still continues to flash and buzz every three seconds though.

One step forward, one back ! :mrgreen: Luckily this one is easy to diagnose and spot. Your intuition that it’s a pin assignment problem is correct but it’s not pins 2 & 3, it’s pin 4. It appeared to me that the timer is starting all by itself and stopping all by itself, as soon as it could. Like the start/stop button is being held pressed. Look at the pin assignments in the code above and you’ll see pin 4 is being used as the start button pin and for the LCD. Change one or the other to a free digital pin and that should fix this problem. You may want to make a list of what pin does what and which pins are left unused. You’ll want to add other input buttons to control the display (presently assigned to pins 6 & 7 but unused).

I think it’s a big step that the LCD display … displays !! :dance: Maybe with the above fix it’ll display the shot count and times on a shot by shot basis as they occur. :pray:

Good catch.

I moved it to pin 1 and that took care of it starting by itself.

New problem:

Push the start/stop button

Start buzzer beeps when it should

As soon as the start buzzer goes the lcd displays “Arduino timer v1” & “says Hello World”.

Push the start/stop button again and the lcd clears and starts over with void loop immediately.

*Correction – The lcd doesn’t clear but keeps the Arduino timer v1… message the entire time.

More Info

the Arduino timer v1… message comes up immediately when the sketch is uploaded which shouldn’t happen.

I even have a lcd.clear() in the setup so something isn’t happening correctly.

I also add some more time to the debounce for a total of 500 ms and it still starts back up on its own after the initial start/stop cycle.

It appears to be making it all the way to the point where it sends the data to the computer via the serial monitor and then starts over.

I don’t know how that would work.

When you do a reset it should clear the LCD and display a simple “Hello World” for about 5 secs. Then when the main loop runs it should switch to the more complex “Arduino timer v1”, “says Hello World” 2 line display. Then it should just sit there until the start button is pushed. Then either :

  • 30 secs have elapsed and then the long buzzer sounds (no display change) or

  • you whack the sensor(s) and the display should show the hit count and time. Stopping the timer should keep the last display. ATM I don’t think I did a display reset upon a re-start. A “DisplayState = 0;” should probably be added to the ClearData function so when the timer is re-started the display shows the complex “Hello World”.

Does the PC display still act as it should ? Does the LCD display show hit by hit times and count ?

What pin assignment did you change, the LCD or the start/stop button (just to keep my end correct) ?

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;
}

I don’t know what to say about the timer running immediately after the upload. I guess for now I’m going to ignore that as a stop button should work and stop the timer. It sounds like the timer is still stopping and then restarting upon the “stop” push ? I’m thinking there might be a problem reading the button at the stop end of things. Here’s my thinking …

When the start is pushed the Arduino detects the initial contact of the switch and starts the timer. It then waits the debounce delay and the 3 sec wait time before doing anything else. Obviously your finger is off the button and any bouncing is done by these 3+ secs. When you press the button for the stop function the Arduino only waits the (relatively short) debounce delay before it goes back to reading the switch for a re-start. This may not be long enough to get your finger off the button and let any bouncing settle. Even your increase to 500 msec might have been too short (depends on your button push obviously). Good thing is there’s no real need to “hurry” a re-start after a stop push. And that delay is adjustable, separate from the start delay. If the timer times out after 30 secs and doesn’t restart (look at the LED) then the above is most likely the problem. If so try the following …

const unsigned long WaitTime = 2000;     // the wait time btw start button and timer running = 2 secs plus debounce
const unsigned long DB_delay = 1000;     // set a debounce wait time of 1000 msecs

I took a video of what it’s doing.

I agree that the restarting is just a debounce issue as it doesn’t do it every time as you can see in the vid.

Now its on to the lcd display issue.

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

ETA: I took the DB_delay all the way up to 3 seconds and it is still starting by itself every time.

It’s official, I’m confused.

is it in the right place?

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

sspbass:
I took a video of what it’s doing.

I agree that the restarting is just a debounce issue as it doesn’t do it every time as you can see in the vid.

Now its on to the lcd display issue.

Nice vid. Does the last part of the display look different in real life when the timer is running or stopped, like it does in the vid ? I think that's another easy fix. As for the LCD not displaying the hit by hit ... well that's something to look into. I guess I'm not that surprised. Things were going too easy. That part of the code does stuff I'm not really sure about.

Does the PC still get a good report of all the hits and their times ? I assume the LED in the vid was tied to the output of the 1-shot detector.

sspbass:
ETA: I took the DB_delay all the way up to 3 seconds and it is still starting by itself every time.

It’s official, I’m confused. is it in the right place?

That's the right place. Increasing DB_delay there (manually) or by changing the value of DB_delay in the constants section should work. I'll have to have a beer and ponder this. Does the LED tied to pin 13 show a constant run condition (or a veeerrry quick stop and looooong run) ? I'll have to check the vid again to be sure but the short and long, start and stop, buzz times didn't seem all that different, nor sound very different.

If you let the timer time out (30 secs) does it restart automagically after that ?

  1. Yes the bottom line fades out like you see in the video.

  2. The PC does get a good report, I should have included that in the vid.

  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.

  4. The start and stop buzzers do sound different in person. It’s probably just hard to pick up on with the crappy mic on a camera.

  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?

Let me know if you would like a video of anything in particular. That was the first video I ever uploaded to youtube and it was pretty painless.

In ths vid I can see and hear the buzz time being different so that’s good. I can see the run/stop LED is off after the reset and comes on after the start button plus delay. Some whacks occur then it goes off with the stop push … but comes back on shortly thereafter. A repush seem to stop it for good. It does, in the vid, look like push time plus switch bounce. Maybe we should change the run/stop LED to come on before the wait delay to help in debugging this ?

From …

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();

to this …

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();

      // move this part up to here
      // turn on the LED to show timer is running
      digitalWrite(LEDPin, HIGH);

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

      // enable the interrupts just in case
      interrupts();