Counting and Timing a shock sensor

sspbass:
Is there enough value in that info to justify the need to scroll through all of it?

Perhaps with the rotary encoder it would be easy to navigate through it, I just don’t know.

Maybe after each round of shooting the main data is displayed but details can be accessed at will.

That's all depends on what you want. I think it natural to display the last shot and times and this is what my timer does. Then you review as desired. I guess if you're doing shooter v shooter is might be nice to either scroll or auto blink between the A and B cumulative (last) times.

sspbass:
I do really like the idea of logging the data to an sd card for computer review. You could then chart your progress

over time and have definite measurable results.

That would be nice ! I was thinking you might be able to log them to EEPROM in the Arduino and D/L via USB later.

No, I don’t know how to do either ATM.

sspbass:
ETA: Another thought I just had was that it would be great to compare the two shooter side by side.

If the info could be made to scroll horizontally with the encoder then the top line could be shooter A and the bottomer line shooter B.

That would make comparing data easy. I think that being able to have multiple shooters is where this thing shines, otherwise you might as well just

buy a shot timer.

So something like this, perhaps scrolling from shot to shot if desired ...

BTW : I notice you have a 3.3V LCD display and a 5V Uno. Normally that might be an issue but there is a 1k resistor in the Tx line that you’d initially use to send data to the display. That might be enough to “buffer” the PIC in the display. Still something you might want to e-mail SF tech support about … Can my Uno talk to my 3.3V LCD w/o damaging either.

sspbass:
Is there enough value in that info to justify the need to scroll through all of it?

Just to answer this question explicitly … I found that when I was trying to get better a good drill was to draw and fire 2 shots at 2 targets. Naturally the time to #1 was longer than the time from #1 to #2. Being able to review both times, rather than just the overall time, was valuable. And that drill is different from dividing it up into 2 pieces; just drawing and just moving from one to the next. It’s really all up to what you want to do with your timer.

Just quickly chiming in. I wouldn’t write to EEPROM as moving from the timer to the computer is going to be a bit tougher and the EEPROM does wear out eventually. An SD card can always be replaced (which is good, I lose a microSD in my car once!).

Dan

dkulinski:
Just quickly chiming in. I wouldn’t write to EEPROM as moving from the timer to the computer is going to be a bit tougher and the EEPROM does wear out eventually. An SD card can always be replaced (which is good, I lose a microSD in my car once!).

Dan

How about storing default configurations of the timer in EEPROM (or flash) ? Or is that even needed ? How would I store a par time setting or random vs fixed wait time or a “5 hits = win” so that these wouldn’t have to be entered every time the Arduino is powered down and up ?

EEPROM would be great for that. It has a life time of 100k cycles. Using a ring buffer would probably be best (not that I see someone changing the defaults 100k+ over the lifetime of the device).

http://www.atmel.com/Images/doc2526.pdf - Circular buffers for eeprom app note from Atmel if you really want the gory details.

Dan

dkulinski:
EEPROM would be great for that. It has a life time of 100k cycles. Using a ring buffer would probably be best (not that I see someone changing the defaults 100k+ over the lifetime of the device).

http://www.atmel.com/Images/doc2526.pdf - Circular buffers for eeprom app note from Atmel if you really want the gory details.

Dan

So there needs to be a “StoreConfig” routine the save any user configurable settings from power on to power on (or reset to reset) ? I hadn’t gotten that far in my thinking.

So while you’re thinking about displays, you might want to review the info on this page.

http://www.arduino.cc/playground/Learni … kFunSerLCD

At this point I’m torn between my original thinking to take baby steps and to just do “the right thing” and get the serial display working off an emulated/software UART. Given the arduino is only sending to the LCD and the success you’ve had so far and the worth of having a separate debug link (PC with serial monitor) … I’ll recommend the latter. That’s assuming the tone() didn’t mess up the working code.

Overloaded yet ?? :mrgreen:

Mee_n_Mac:
So while you’re thinking about displays, you might want to review the info on this page.

http://www.arduino.cc/playground/Learni … kFunSerLCD

At this point I’m torn between my original thinking to take baby steps and to just do “the right thing” and get the serial display working off an emulated/software UART. Given the arduino is only sending to the LCD and the success you’ve had so far and the worth of having a separate debug link (PC with serial monitor) … I’ll recommend the latter. That’s assuming the tone() didn’t mess up the working code.

Overloaded yet ?? :mrgreen:

In a good way!

You should see what Mee_n_Mac and I are doing over on the airsoft thread :slight_smile: Poor StaticDet5 never knew what he was getting into!

Dan

me_n_mac… The Arduino isn’t liking your code for using tone() to adjust the buzzer.

it says variable or field “Buzz” declared void.

sspbass:
me_n_mac… The Arduino isn’t liking your code for using tone() to adjust the buzzer.

it says variable or field “Buzz” declared void.

Hmmm try this, I got rid of “Buzz”. It’s simpler actually.

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

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 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
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 int A_Times[10];    // array to hold up to 10 hit times for target A
volatile int B_Times[10];    // array to hold up to 10 hit times for target B

void setup()
{
  // 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 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);
      // no need to debounce switch, delay inherit with tone
      // just for the moment send times to PC only not to display
      SendTimes();
    }
  }
  //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()
{
  A_count = 0; 
  B_count = 0;
  A_Times  [0,0,0,0,0,0,0,0,0,0];
  B_Times  [0,0,0,0,0,0,0,0,0,0];
}

void SendTimes()
{
  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 times are : ");
  for (int i=0; i < A_count ; i++)
  {
    Serial.println(A_Times[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 times are : ");
  for (int i=0; i < B_count ; i++)
  {
    Serial.println(B_Times[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;
  }
}

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

BTW you should probably AC couple your Arduino output pin to the piezo speaker. Put something like a 1 uF capacitor between the pin and the speaker. It may work connected directly but the speaker will be happier when AC coupled.

Haha, thats odd. I got it to compile but now when it starts timing the piezo Im using as a shock sensor starts to buzz and won’t shut off.

ETA… Just as I thought, bad ground.

I hooked it up to another computer and now I can’t get any communication with the serial monitor. Is there some trick that I forgot about?

sspbass:
I hooked it up to another computer and now I can’t get any communication with the serial monitor. Is there some trick that I forgot about?

Communication ??? As in it won’t download to the Arduino or as in the Arduino runs but you don’t see the messages/timing data you used to ? If it’s the later you probably have to set up the serial monitor window to be 8N1 at 9600 baud.

The latter. It is set to 9600 baud but I still don’t know where the 8n1 is. I didn’t change anything to do with that on my laptop.

sspbass:
The latter. It is set to 9600 baud but I still don’t know where the 8n1 is. I didn’t change anything to do with that on my laptop.

Is this outside of the Arduino environment, just using something like Hyperterminal ? If so you have to pick the comm port and assign it to the proper USB port and then set it up ala 8N1. If you’ve got the Arduino IDE running on another PC and this is the Arduino monitor, I don’t know what to do.

I’m sitting here looking at wiring up my lcd but it uses several pins that this sketch is already using.

Is there anything I need to take into consideration when changing the pins used in the sketch?

The lcd uses pins: 12, 11, 5, 4, 3, & 2 .

sspbass:
I’m sitting here looking at wiring up my lcd but it uses several pins that this sketch is already using.

Is there anything I need to take into consideration when changing the pins used in the sketch?

The lcd uses pins: 12, 11, 5, 4, 3, & 2 .

The link you gave before is to a serial LCD …

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

The only connection to the Arduino should be to it’s Tx (out) line. I’ll recommend that you use a software emulation of a UART, which will allow simultaneous communication to the serial monitor and LCD. I believe the serial LCD library already uses this as part of it’s library function. The Tx line from the Arduino (which can be any digital pin with a “soft” UART) goes to the Rx line of the LCD, which is (according to the schematic) on pin 1 of the JP3 connector on the SF “backpack”. I think it’s even labelled RX.

My apologies, the LCD that I got was this one.

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

On a side not the piezo no longer makes any noise since we starting using the tone function instead of just setting the pin high.

Is this due to the timer issue that was discussed earlier?

sspbass:
On a side not the piezo no longer makes any noise since we starting using the tone function instead of just setting the pin high.

Is this due to the timer issue that was discussed earlier?

Do you move the wiring to pin 9 ? And does the timing still time ? If so does it time accurately, not off by perhaps 0.5 secs ?

sspbass:
My apologies, the LCD that I got was this one.

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

Ugh. You’ll have to search the Arduino forums on how to code for that one. Changing pins numbers shouldn’t be too much of an issue but you do need to retain the 2 input pins for the external interrupts (target inputs on 2, 3) as is. It sounds that the tone() function will map to just about any digital pin. The pushbuttons can be changed to any digital pins as well. Betweeen moving these pins assignments and the 2 for the LCD (pins 2 and 3), it may be made to work (assuming there are enough pins for all the I/O).

ps : 'pologies. Twas another poster who suggested the serial LCD.