atmega 328p timer / stopwatch questions

Last post
15 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm interested in creating a program on an atmega328p that will measure the time difference between two consecutive pushes on a momentary push button. The time between the two pushes can vary between a few seconds to a fraction of a second. I want the timer to always start at zero and time out if goes longer than a few seconds. I want the result to fit into an 8 bit value.

I'm thinking of using Timer/Counter2 in normal mode because I can use an external crystal to slow it down and TOV2 to increment another register every time it overflows. Does this make sense? Is it a good idea?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why limit the result to 8bit? It's going to mean counting in something like 1/10th.. 1/100th seconds.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Why limit the result to 8bit? It's going to mean counting in something like 1/10th.. 1/100th seconds.

I figured it would be easier and I don't really need more resolution than 1/100 sec. Ultimately, I'm looking to keep it as simple as possible without interrupts.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'd suggest using a timer setup in ctc mode to give a time tick of 10ms. The isr can poll the switch status and keep track of one or more software timers. Having a 8 bit var is going to mean trading off the max period vs the time resolution as Cliff suggests. Why the aversion to a larger var? Are you that short of memory?

If you dont want to use interrupts, then poll the timer interrupt flag.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
I'd suggest using a timer setup in ctc mode to give a time tick of 10ms. The isr can poll the switch status and keep track of one or more software timers. Having a 8 bit var is going to mean trading off the max period vs the time resolution as Cliff suggests. Why the aversion to a larger var? Are you that short of memory?

If you dont want to use interrupts, then poll the timer interrupt flag.

Do you think that CTC mode would still be best if I only need a resolution of 1/10 of a sec? I'm not scared of using a larger variable. I've found that I run into the least amount of trouble when I get projects to work first with 8 bits and then modify them accordingly. If I need 24 bits, then I'll do it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There's many ways to skin a cat....... Personally, i'd use ctc mode to give me a timebase to work from. You suggestion of using timer2 would work as well.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I figured it would be easier and I don't really need more resolution than 1/100 sec.
First, if you have a resolution of 1/100 of a second, then the maximum that an 8 bit value can hold will be 2.55 seconds (which would not cover my definition of "a few").

Second, with push buttons you will not likely get a resolution of 1/100 of a second. Switches bounce and that bounce can often take around 50ms which is considerably longer than 1/100 of a second.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why are you using an AVR to do this when every very cheap digital watch ever made in the past 30 years can do this and display the accurate and detailed result?

It would be far cheaper to just get a simple digital watch or stopwatch. Say that you can buy a cheap watch for $10. You have all the displays, all the input buttons, all the mode change buttons, all the battery power needed, and a wrist band for that price. Plus the unit works for your application, which you have told us is the simple measurement of an interval of 0.1 to 5.0 seconds.

If you use an AVR then it will take hours to write the code and much more than 10 dollars to buy the parts. Then you have to write the software, and, even worse, get the software to work correctly. You end up spending ten hours (learning the AVR documentation, programming, and debugging) and $15-$30 in parts and you still don't have something that works as good as a cheap disposable watch.

Is this some kind of school project? If so, then perhaps what the school is trying to teach you is to know when to buy a product off-the-shelf vs. when to design and build one.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'd also go with CTC mode to generate a timebase (either triggering interrupts - easier - or polled). If you have a 10ms timebase, you have a small state machine that detects the first button down and starts counting in software the number of ticks until the next button down. At the same time you'll need to look for button up when you get a button down, and then wait 2 or 3 ticks after button up until you can look for the next button down, for debouncing.

Are you doing anything else time-related? Like driving a 7-segment multiplexed display? In that case you'll need to go to a faster tick e.g. 2.5ms and only do the button checking and tick counting every 4th tick.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Simonetta wrote:
Why are you using an AVR to do this when every very cheap digital watch ever made in the past 30 years can do this and display the accurate and detailed result?

It would be far cheaper to just get a simple digital watch or stopwatch. Say that you can buy a cheap watch for $10. You have all the displays, all the input buttons, all the mode change buttons, all the battery power needed, and a wrist band for that price. Plus the unit works for your application, which you have told us is the simple measurement of an interval of 0.1 to 5.0 seconds.

If you use an AVR then it will take hours to write the code and much more than 10 dollars to buy the parts. Then you have to write the software, and, even worse, get the software to work correctly. You end up spending ten hours (learning the AVR documentation, programming, and debugging) and $15-$30 in parts and you still don't have something that works as good as a cheap disposable watch.

Is this some kind of school project? If so, then perhaps what the school is trying to teach you is to know when to buy a product off-the-shelf vs. when to design and build one.


Wow, give the guy a break. It's nobody's business if he wants to re-invent something he can buy cheaper. Presumably he values the experience of doing it himself. We're not his guardian.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think the reasoning for "reinventing the wheel" is important. Sometimes it is just the knowledge gained -- sometimes it forms part of a larger project. I find the time limit of a few seconds interesting -- why that requirement. If it is just for the purpose of learning, it makes sense to explore the advantages and disadvantages of different solutions.

I also prefer the option of creating a time base using a timer and implementing a soft timer based upon that. The only issue with multi-word variables then becomes the need to read ISR/main shared variables atomically - easy with the avr/atomic.h header.

Martin Jay McKee

As with most things in engineering, the answer is an unabashed, "It depends."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mckeemj wrote:
I think the reasoning for "reinventing the wheel" is important. Sometimes it is just the knowledge gained -- sometimes it forms part of a larger project. I find the time limit of a few seconds interesting -- why that requirement. If it is just for the purpose of learning, it makes sense to explore the advantages and disadvantages of different solutions.

I also prefer the option of creating a time base using a timer and implementing a soft timer based upon that. The only issue with multi-word variables then becomes the need to read ISR/main shared variables atomically - easy with the avr/atomic.h header.

Martin Jay McKee

It's for a musical project. Most music has two beats to it that fall within 2.55 seconds. I'm trying to design an application that triggers events based on the tempo entered by the user.

I don't want to break the loop with IRQ's if I don't have to because it will mess up the tempo and the other stuff that is going on. However, I could trigger an IRQ on the second button push.

Thanks for the insight guys. I'm going to put together something tomorrow based on the feedback that I have received.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As I said, knowing about the application can be helpful... If everything were based on a software counter generated by an ISR, there would be no need to worry about losing sync.

Just thinking out loud... in the last year, the group I'm with has done pieces with tempos from ( roughly ) 44bpm to 168bpm ( that was interesting! ). I'm assuming that your "two beats" would be the major beats in a duple meter so it would really be 22bpm - 84pbm ( assuming a 4/4 time signature, which is pretty typical for duple ). That would give a range of .7 sec. - 2.72 sec. between beats. Now, the difference between 92bpm and 96bpm is quite noticeable so the resolution should, probably, be finer. That means a resolution of, at least 48 ( 96/2 ) steps regardless of the time between beats. The limiting side is going to be short beat times, so let's just call the resolution ~.7/50 sec. or 14ms. To be on the safe side, that could just be made 10ms. Then, as it happens, we are back to the 1/100 sec. resolution. But an 8-bit word won't hold the full time range for some of the lower tempos ( and they can get even more ponderous than I considered ) so for future-proofing it would make sense to count in a 16-bit word at a rate of 100Hz. This count would then drive not just the button press reading, but also any event generation. Everything stays in sync, there's sufficient resolution for the music and events to appear simultaneous, and in the future, when requirements change, there's room to grow.

Martin Jay McKee

As with most things in engineering, the answer is an unabashed, "It depends."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've decided to start this thread back up again because I have free time now and I want to solve this problem.

I've taken into account everything that has been posted in this thread and have come to the conclusion that 16 bits would probably work better because I will have more resolution/total time as mckeemj has suggested.

My next question is what is the first step? Unfortunately I don't even know where to start with the psuedo code.

What if I used a separate AVR or a timing IC? How would you guys do it from scratch if I didn't have to maintain an infinite loop?

Quote:

I'd suggest using a timer setup in ctc mode to give a time tick of 10ms. The isr can poll the switch status and keep track of one or more software timers. Having a 8 bit var is going to mean trading off the max period vs the time resolution as Cliff suggests. Why the aversion to a larger var? Are you that short of memory?

If you dont want to use interrupts, then poll the timer interrupt flag.

This sounds like the best idea but I don't have a clue how to do it. So basically I set up Timer 1 or 2, poll the interrupt flag, increment a register, determine the number of flags that were set by subtracting start from finish and then use the difference to look up a table?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For some added clarity, here is a page that explains what I want to do:

http://www.electricdruid.net/index.php?page=projects.taplfo