One second interval too long?

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

I'm trying to build an alarm clock with a Teensy 2.0 (ATMega32U4) and I've programmed it to generate an interrupt every second using this code:

  //
  // setup timer1 to generate an interrupt every second
  //
  TCCR1A = 0x00;
  TCCR1B = 0x0C;  // CTC1, mode 4, CK / 256 ==> prescaler 256x
  OCR1AH = 0xF4;   // 16000000 / 256 = 62500 = 0xF424
  OCR1AL = 0x24;
  TCNT1H = 0;
  TCNT1L = 0; 

I also print a string in the interrupt handler (with the HID_Listen program) but it looks to me like the interval between the printouts is slightly larger then 1 second, more like 1.5 seconds.

Is there an error in my timer code?

Building my dreams!

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

avrcalc.exe agrees F424 with /256 on 16MHz (obviously F423 if CTC)

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

I found the culprit.

I needed to set the CPU clock prescalar as well. Don't know what it defaults to but I needed the following code:

#define CPU_PRESCALE(n)	(CLKPR = 0x80, CLKPR = (n))

 CPU_PRESCALE(0);

  //
  // setup timer1 to generate an interrupt every second
  //
  TCCR1A = 0x00;
  TCCR1B = 0x0C;  // CTC1, mode 4, CK / 256 ==> prescaler 256x
  OCR1AH = 0xF4;   // 16000000 / 256 = 62500 = 0xF424
  OCR1AL = 0x24;
  TCNT1H = 0;
  TCNT1L = 0; 
  set_bit( TIMSK1, OCIE1A );

I now see printouts every second.

Building my dreams!

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

From the datasheet I gather that when you program the device the CPU prescaler gets set to 8. So you need to reset it manually.

Building my dreams!

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

And, of course, for a clock, you'll need a crystal as the internal oscillator would drift terribly.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

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

Quote:

you'll need a crystal as the internal oscillator would drift terribly.

Lucky for him PJRC thought of this and put a 16MHz crystal into the Teensy 2.0 design then. (of course they kind of had to as a USB controller doesn't get very far without an 8MHz/16MHz crystal after all!)

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

Quote:
I also print a string in the interrupt handler
This, also, is generally frowned upon (if you mean within the ISR() itself).

--greg
Still learning, don't shout at me, educate me.
Starting the fire is easy; the hardest part is learning how to keep the flame!

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

gregsmithcts wrote:
Quote:
I also print a string in the interrupt handler
This, also, is generally frowned upon (if you mean within the ISR() itself).

Frowned upon by WHOM? I'm a hobbyist and I do whatever I want. :D

It's just for debug purposes anyway. As soon as I've got it working I'll remove it.

Building my dreams!

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

The reason (even for hobbyist debug) to not put a printf() in an ISR() is it may take longer to execute than it takes for the next interrupt of that type to come along. Even if one doesn't come along you are starving the mainline of execution which may/may not be important. You can often get away with:

printf(".");

or something equally short but shorter still will be to avoid printf() all together and go straight for:

uart_putchar('.');

just to show the ISR() is being activated.

(then again lighting an LED probably "costs" even less)

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

Quote:
I'm a hobbyist and I do whatever I want
Me too. However, if one does not take friendly advice and goes against best practice, then one is likely to find that problems begin to occur. If one also deliberately ignores said advice, then when these problems occur, one is likely to find ones self out in the cold. ;)

--greg
Still learning, don't shout at me, educate me.
Starting the fire is easy; the hardest part is learning how to keep the flame!

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

For a real time clock that is more than a test or student project, use a DS1307 IC. I believe SparkFun.com has small PCB boards for $6-7 that have a DS1307 IC, a 32KHz crystal, a CR2032 holder and battery, and a header. This is an excellent deal.

Then connect this board to the Teeny 2.0 (which should have TWI (aka: I2C) connections. Then it is a question of writing the software to set the clock to the right time, get the time from the clock, and display it usefully.

The big advantage of a stand-alone RTC chip is that it keeps the time while the AVR is powered off or in deep sleep mode.

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

bigpilot wrote:

Frowned upon by WHOM? I'm a hobbyist and I do whatever I want. :D

Well what happens if the main code is executing the print function and the interrupt kicks in and wants to execute the print function as well? If that is not taken into account, chaos will ensue, if the function is not re-entrant. Of course if the interrupt is the only place you write then by all means.

But simply put it is generally best to have interrupts do whatever minimum it takes to do something and set a flag variable that it has happened so the main code can react to this flag when it has time.

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

Quote:

As soon as I've got it working I'll remove it.

Using a debugging technique that might very well contribute critical problems of it's own can be very frustrating..

One example would be to investigate why one is loosing interrupts by executing lengthy code in the ISR (causing even more interrupts to be overrun and thus lost). Perhaps not exactly your situation, but you'll hopefully get the picture.

Take good advice when they are given.

OTOH, the advice could have been better formulated. Substituting "is not recommended" for "is frowned upon", perhaps?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

Quote:
the advice could have been better formulated.
In this particular case, it was a simple statement of fact. As evidenced by the reply, the OP didn't apparently care 'why' this is frowned upon. In answer to his question... ME! I frown upon it generally.
To have phrased my statement as you suggest, could well have prompted the response, 'WHY', which would have progressed the discussion towards the reasons now given. However, I wonder if it really matters as...
Quote:
and I do whatever I want

We shall no doubt see in the future if the OP has recurring ISR timeout's and dropped events due to not heeding the advice given after my post :)

--greg
Still learning, don't shout at me, educate me.
Starting the fire is easy; the hardest part is learning how to keep the flame!

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

Simonetta wrote:
For a real time clock that is more than a test or student project, use a DS1307 IC. I believe SparkFun.com has small PCB boards for $6-7 that have a DS1307 IC, a 32KHz crystal, a CR2032 holder and battery, and a header. This is an excellent deal.

Then connect this board to the Teeny 2.0 (which should have TWI (aka: I2C) connections. Then it is a question of writing the software to set the clock to the right time, get the time from the clock, and display it usefully.

The big advantage of a stand-alone RTC chip is that it keeps the time while the AVR is powered off or in deep sleep mode.

I don't care too much about power consumption. I could get it down by using interrupts on the keys and only waking up on those and timer interrupts but this is just for fun and still being useful. I am using a RTC IC (PCF8583) for another project (a home thermostat) where power consumption is important since it will be battery powered.

BTW I posted the code for this clock in another thread. I initially tried to cram it into a 2K ATTiny device but I needed help to get the size down. With the kind help of some of the people on this forum I succeeded, although I never built the ATTiny based clock.

Building my dreams!