Application: Basic; Stopwatch, More; DAQ

Hi,

As the title suggests, I have an application question...
First of all, I'm nearly positive that this will do the minimum of what I want, but I figured I'd ask anyways.

I need, at the very least, to create a "stopwatch" for a timing system for automobile racing.

The stopwatch needs to be accurate to a thousandth of a second (.001 seconds) and up to 10 minutes (600 seconds).

And that's the only real limitation I have... is the clock speed on this system fast enough for that (I would assume yes).

The reason I need this, and this is the biggest thing I need (besides the accuracy) is to have multiple-trip protection. Frequently with our current system, if the car is traveling slow, the car can trip it two or three times when it's only supposed to do it once. a "multiple trip" protection function is extremely important, so that it will only take one input in the span of say 1 second. It's important that it take the first input, in this case, but that should be simple.

I'll give the minimums:
Output: mm:ss.sss (so 2 places for minutes, 5 places for seconds (3 of which for tenths, hundredths, thousandths)
so I need 7 display outputs total.
I am aware that Arduino can output that many decimal places (up to 8 with the proper hardware?).

It will need to have start/stop/reset functions that can be user controlled.
Start/stop functions also need to be able to take inputs from the sensors.
everything will run off of 12VDC (possible use of batteries can make Arduino run off of other voltage settings... whatever it likes, but run off of batteries none the less.

A lap function will also be extremely appreciated. That is using one sensor input to start the timer, then every time the sensor is tripped it displays the time (for say 10 seconds) and resets the timer. For the next lap.

On that note, lap # and recall of those times would be awesome.

It's worth noting that some application will be lap based (going around a track) and some will be start/stop based (drag racing). I see doing this either with two modes, or just having the start/stop sensor in the same input ports and either using one sensor or two, depending on the application.

Storage of values or uploading values to a computer would be nice. Storing then uploading would also be nice. Ability to put in info for datasets would be nice (for example, put in the name of the driver for each lap set).

Sector times would be very nice. That is, you have a sensor for the start/finish of the run, and other sensors at other spots in the track. It measures the lap time relative to the "main" lap sensor, and also time in between each sensor. I have 5 sensors at the moment.

On software side, some data anlysis would be nice. when uploaded to computer, it could find fastest lap (and with sector times, fastest rolling lap (this analysis uses each sector gate as a start/finish instead of a checkpoint, it then finds the fastest lap, which might have started/ended in the middle of the track, but due to being slow before or after that point, would not show up as being as fast under normal circumstances... I hope that is an adequate description)).

Also plot histograms of data and maybe do some more complicated analysis.

This is the first part of what I want. A piece of harware that only really measures time between sensor trips with some flexibility to filter out multiple trip errors and the like. It would not interface with the car at all.

Depending on how easy/doable/flexible this project and Arduino is in general, I'm sure I could come up with boat loads of other applications, all the way to DAQ and in-car driver instrumentation. Maybe even telemetry stuff?

Last but not least... a recommendation of what hardware to get would be nice.

Cheers!

-Martin

welcome atmh,

you want pretty much at the same time. i think all that's possible in the long run but you should definetely start slowly.

  • how do you want to sense the car? (light barrier, push button)

  • how dow you want to output the data in teh first place? there is no such limit as "8 digits maximum". it just depends on the display, and program size (no long text analysis coming from an arduino).

  • if you send your data to your pc, you theoretically can do pretty much with it, inluding graphical views, "auto email stats to drivers", whatever you want. you just need the programming skills. since this is not an arduino related task, you should keep these ideas in the back of your head for now.

the key to some kind of success is splitting your project in byte or rather bits. get an arduino (if you haven't ) connect a pushbutton instead of your laser light barrier, and start measuring some time. send this data to your computer. if you're familiar with the basics, get an LCD, write some code to output some dummy text to it. if you're familiar with it, merge your two programs... etc.

Thanks for the response.

Basically I was just looking to make sure that Arduino can handle the accuracy and basic stopwatch type inputs. I completely agree that it should, and will be done one step at a time, that's generally how I work anyway.

When I said 8 digits maximum, what I was talking about was the accuracy of the machine (Arduino). Or rather, what is the epsilon of the machine. 64-bit computers are accurate to 15 decimal places, stuff like that. (how many bit is Arduino?)

Since I've never done anything like this before... Where can I get an LCD screen (7 or 8, or more, digits)? I have access to plenty of pushbuttons, that's no problem...

Thanks!

Thanks for the response.
When I said 8 digits maximum, what I was talking about was the accuracy of the machine (Arduino). Or rather, what is the epsilon of the machine. 64-bit computers are accurate to 15 decimal places, stuff like that. (how many bit is Arduino?)

something between 2 and 64bit. i don't know. but i think if that matters at all in terms of accuracy, it's referring to calculations rather than counting.
for an output of mm:ss:sss you only need to keep track of 3 integers all below 1000 as maximum (minutes, seconds, milliseconds) or am i missing something?

you should know that some people noticed accuracy issues with timing, which means an arduino clock would have a slight offset after running for a day. but i believe this offset is persistent, and could be solved by calibrating your arduino (i.e. get the real speed of the crystal once reflect that in the code). i'm not sure. there should be something here in the forum on that topic.
after all an atmega168 on 16MHz should be fast and precise enough to do what you're planning. if it's not, it might be you to find out and hopefully someone comes up with an idea to solve the issue. i'd say just do it :slight_smile:

if you have access to plenty of pushbuttons, there's really no excuse.

for the LCD it would be good to know where you're located. see the tutorial section and try to get something like they used there. you should find something on ebay as well.

//kuk

Hi,

Since I've never done anything like this before... Where can I get an LCD screen (7 or 8, or more, digits)?

Lcd's are nice but they are usually hard to read when your more than 2 meters away from them. If you want to read you results from a distance of 5 meters or more you should look into 7-segment Led displays.

Eberhard

Well I've officially got my Arduino and I just ordered a serial graphical LCD. I don't know if I'll really be able to use the graphical part of the LCD much, but I wanted it for different font sizes. Anyway my project's underway and I've started programming out some basic stopwatch functions. Right now I can only really display them with LED's since I don't have the display here and handy... I hope in short time I'll have some hard code/pictures/etc to post, in the Exhibition section, of course.

Thanks for all your help.

Well I've got the LCD now and I'm having issues with it...

I can't seem to consistently get it to work properly. I've done a couple things and it does some stuff, but it just doesn't seem to work properly.

Either I am communicating with it in a completely wrong manner or the baud rate is not consistent enough for it...

Datasheet for the LCD I got:

My test code, currently set to clear the LCD screen, wait a millisecond, then output the string "text horray" because if I can get it to output some text on the screen correctly, I'll be happy.

there is also a demo program for the computer:
http://www.sparkfun.com/datasheets/LCD/dx160.zip

I used that program and it works good.
I've been trying to use the TTL port.
I don't know what the program on the computer is doing that Arduino is not (also I've check the outputs from Arduino with hyperterminal, baud rate at 57600, works fine).

I was going to change the baud rate to 9600, that seems to be more standard for stuff in general, but I don't know how to software change the baud rate... don't you need to be communicating with it at a particular baud rate, send the signal, then switch to the new baud rate? I don't understand how I would do that with the demo program they give, Arduino (since it's not communicating proerly at the moment) or hyperterminal...

So yeah, for some reason the screen isn't working properly/consistently with Arduino at the moment. Please help!

(this is a simple modification of the debounce tutorial)

/* Debounce
*

  • Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
  • press), the output pin is toggled from LOW to HIGH or HIGH to LOW. There's
  • a minimum delay between toggles to debounce the circuit (i.e. to ignore
  • noise).
  • David A. Mellis
  • 21 November 2006
  • http://www.arduino.cc/en/Tutorial/Debounce
    */

int inPin = 7; // the number of the input pin
int outPin = 13; // the number of the output pin

int state = HIGH; // the current state of the output pin
int reading; // the current reading from the input pin
int previous = LOW; // the previous reading from the input pin

// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0; // the last time the output pin was toggled
long debounce = 200; // the debounce time, increase if the output flickers

void setup()
{
pinMode(inPin, INPUT);
pinMode(outPin, OUTPUT);
Serial.begin(57600);
}

void loop()
{
reading = digitalRead(inPin);

// if we just pressed the button (i.e. the input went from LOW to HIGH),
// and we've waited long enough since the last press to ignore any noise...
if (reading == HIGH && previous == LOW && millis() - time > debounce) {
// ... invert the output
Serial.print(186);
delay(1);
Serial.print("text horray");

if (state == HIGH){
state = LOW;
}
else{
state = HIGH;

}

// ... and remember when the last button press was
time = millis();
}
//if (state == LOW)
// Serial.print("text horray!");

digitalWrite(outPin, state);

previous = reading;
}

From the datasheet:

Text strings are limited to 80 characters and must be terminated with ASCII[255].

From the datasheet:

Text strings are limited to 80 characters and must be terminated with ASCII[255].

Yeah, I apparently missed that.
I love how missing "small" things like that can cause frustration.

working code for this ( DX160 Serial LCD ):

Here's some example code, that works with an Arduino Diecimila:

/*
 * Hello World!
 *
 * This is the Hello World! for Arduino. 
 * outputs to DX160.
 */


void setup()                    // run once, when the sketch starts
{
  Serial.begin(57600);           // set up Serial library at 57600 bps
  Serial.print(186,BYTE);        // Clears the screen (DX160)
  delay(1000);                   // waits a second
  Serial.print("Hello world!");  // prints Hello world! 
  delay(10);                     // waits...
  Serial.print(255,BYTE);        // sends the end-of-string command - gives the "OK" for the DX160 to print.
}

void loop() {
  
}

Hi there atmh! I'm trying to make something similar, like an alfano for my go kart. where you able to finish your project? Some help will be appreciated.
:cry:

Yeah.

The important part is to keep output function limited, since it takes cpu cycles to update the screen, and for the most accurate measurement you want to be "listening" for the signal as much as possible.

As far as an on-board data acquisition system goes... it would be a lot trickier, we never undertook that aspect of the project, but I'm sure it could be done... to an extent. You'd need a place to store all the data though.

Worked great as a lap timer! Took a lot of time/energy/effort though, and first designs always have numerous bugs and issues that pop up.

The important part is to keep output function limited, since it takes cpu cycles to update the screen, and for the most accurate measurement you want to be "listening" for the signal as much as possible.

Your timing capture should be interrupt driven, that way it doesn't matter how long the display and other functions take (within reason) they will have no affect on the timing. That way the listening and counting is done by the CPU hardware, you just have to accumulate the count and display the results at the end of the period.

EDIT: I just noticed this is a 2-year-old thread, are you still working on the project?

heh, no. I was just answering the previous question.

I am aware of interrupt driven detection. There was some reason that wouldn't work for us, I don't remember the details though :-/

It could have been that we are crappy programmers, haha :slight_smile:

Thank for the quick answer. Any change you could post or send me the code you used? I'm just starting with arduino. I know a bit of programming but never did program in C. I would like to use the magnet sensor to activate the stopwatch and show the laps.

Thank you in advance.

newtonn2

Not sure if you were talking to me or atmh, but here's some code from a speedo I did a while back.

#include <avr/io.h>      
#include <avr/interrupt.h>

uint16_t timer_value = 0;
uint8_t new_pulse = 0;

ISR(TIMER1_OVF_vect) {
      // handle timer overflow here if neccessary
}

ISR(TIMER1_CAPT_vect) {
      timer_value = TCNT1;      // get counter value for main loop
      TCNT1 = 0;             // reset counter
      new_pulse = 1;            // set flag for main loop
}

int main(void) {

      TCCR1B = (1<<CS10)|(1<<CS12)|       // Timer clock = system clock / 1024
            (1<<ICES1)|            // rising edge detect
            (1<<ICNC1);            // noise canceller
      TIFR = 1<<ICF1;             // Clear any ICF1 pending interrupts
      TIMSK = (1<<TICIE1)|            // Enable Timer1 Capture 
            (1<<TOIE1);             // and overflow interrupts      
      
      sei();
      while(1) {

            if (new_pulse == 1) {
                  new_pulse = 0;
                  // timer_value = the count from the timer ie. time between pulses
                  do_something_with_value(timer_value);
            }
      }
}

NOTES:

  • Not tested, relevant parts hacked from a much larger program.
  • Also the timer constants (TCCR1V etc) may be different for the processor you are using.- This is AVR GCC code, I'm not sure how that maps to an Arduino but I think it should work.

Thank you so much! I'll give it a try and will let you know how it goes.

I don't have access to the code anymore since this was part of a school project and I'm recently graduated (hooray!). But it's really quite simple, and shouldn't be too difficult to figure out something basic.

Good luck!

@newtonn2
Good luck, I'll be off the air for a week or two so you'll be flying solo, except for the 1000 others on this forum of course :slight_smile: