I will think before I code…
December 27, 2006 – 10:54 amAs CosineKitty pointed out: My Arduino timer interrupt code did not work because the Prescaler bits were not set correctly.
Applying basic boolean logic helps ;-) This is the working code:
I will think before I code, I will think before I code, I will think before I code, …
The timer now works perfectly. I think the CTC mode will be more efficient, but my measurement shows that the clock has a slight skew (3 ms) when the Arduino starts up (lets say, during the first five minutes). Later, the skew is about zero. So the overflow mechanism is quite exact ;-)
Note that the TIMER2 is used for PWM in the Arduino libraries, so this sketch might interfere with PWM applications - I did not test this.
14 Responses to “I will think before I code…”
Hey,
Nice work on the project. I’ve never had anything to do with interupts, so I wanted to start with you code to see how it all works. I can’t get it to compile however. Are you using the standard Arduino 007 environment? I couldn’t get it to link interrupt.h or io.h in their default locations, but after i moved them around I get errors in pretty much every line with
By Alex on Jan 24, 2007
Alex,
I developed with Arduino0006, but since the code doesn’t use any external interrupt routines it should run without any changes in Arduino0007. Did you remove the blanks in the include lines? The line
#include < avr / interrupt.h >should not have any blanks between the brackets. Sorry, I didn’t figure out how to tell Wordpress not to insert any tags. Does this solve your issue? You can also find a working example in my Arduino DCF77 clock lib.
-Mathias
By md on Jan 25, 2007
This is great thanks. I can finally set definate sampling rates. To get this to run on arduinos with atmega 168 note
//Timer2 Settings: Timer Prescaler /64,
TCCR2A |= (1
By Nicky on Mar 1, 2007
Again, nice one. Your code is the holy grail that I’m basing my project on (credited of course).
I’m not a programmer - I’ve only ever really used wrapper languages like the Arduino IDE, so I don’t fully understand every line yet, but having a working example is invaluable.
Next step is to get simmilar code working on an AtTint12/13/15 - I know they have a simmilar internal timer, but I’m not yet good enough to port over the required registers etc.
By Alex on Apr 3, 2007
Hi Alex,
thanks. Porting the code should not be that difficult - AFAIK the structure of the Atmel AT* is pretty much the same for all models. You might want to check which bits are set in the control registers for the ATMega8 code above, and translate it to your chip. Use the datasheets from Atmel - have fun!
-Mathias
By md on Apr 4, 2007
Mathias,
Thanks to your code (and your mistakes!) I think I understand the whole bitwise operations thing, and also the timer interrupts. I THINK i’ve translated it to the AtTiny15, but sorting a few other things out.
Next question - I’m using your code to update a variable infrequently - every 6 minutes. It seems wasteful to have the controller sitting around during this time. I’m looking at the arduino sleep code, but the wakeup function seems to only be looking at an external interrupt. Have you got any ideas, or seen others using sleep this way?
Essentially I want to start optimising this for lower power consumption to eventually have it running off battery power. Obviosuly the longer the battery life the better!
By trialex on Apr 13, 2007
Hi trialex,
The AT-* chips support various sleepmodes, for an overview, consult e.g. the AVRlib sleep.h documentation. I assume you have to figure out which one of the sleepmodes is suitable for your application and use sleep.h directly (or set the bits as described in the datasheet).
On the ATMega8, you can use the “power-save” mode to safe power while waking on a timer comparison interrupt - this way, you could use the timer to wake the chip every six minutes.
I will need to use the power management features for my clock, so I am looking forward to see your code ;-)
-Mathias
By md on Apr 14, 2007
Thanks a lot!
By Z on Apr 19, 2007
Huh! Looks like we are doing similar projects.
Looking at the data sheets for the Attiny15, Attiny2313 and Atmega8 shows you that by far the biggest saving is made by using a smaller device. Even in normal operation the tiny’s use much lower current than the mega’s.
The tiny’s have only “normal” and “idle” modes. The “idle” current for the 15 in like 10 times lower than the mega’s “power-save”
Damn the tiny15 only having 6 ports! I need 6 output, 1 input. I’m trying to do some tricking switching between modes, but not reliable yet. Need to work out how internal pull-ups work…
By trialex on Apr 20, 2007
;-) Trialex, this is interesting, thanks for pointing out. Maybe it makes no sense to try to safe power on the ATMegas - battery lifetime will be short anyway. Since I think my way of displaying the time will not be very power-efficient, I will probably not investigate power saving any more…
As for the output port problem: I don’t know your design, but maybe a shift register as the 74HC595 chip can help. You need 3-5 pins on the microcontroller side to controll 8 output pins on the shift register - which might do in your case. And for additional outputs, you can simply chain the shift registers…
By md on Apr 20, 2007
this is a great code to get me started on timers. my goal is more on the audio side. i’ll get to it at some point. in the meantime, any idea why output only works on pin13? i tried changing to 7, 8, 12, … and none work. if i plug my ext led to 13 and set ledpin to 13 (original code), no problem but if i change ledpin and put my led on corresponding pin >> nothing. does the interupt affect all pins (even the non-pwm ones)?
thanks.
By mat on May 26, 2007
Hi mat,
I see no reason why the LED output should not work on other pins. I can think of two problems: (1) Do you use a resistor (220 Ohms) when using another pin? Pin 13 has a build-in resistor, for other pins, you need to use an external one. (2) I don’t remember which PWM pin corresponds to the second timer interrupt, but it should be safe to try pin 4 or 5 for the LED.
Hope this helps,
-Mathias
By md on May 28, 2007
I can’t get this code to work… I am using Arduino 0012.
The error:
In function ‘void __vector_9()’:
error: ‘TCNT’ was not declared in this scope In function ‘void setup()’:
In the code, the line RESET_TIMER2; is marked yellow.
Does anyone know how to fix this?
Thanks!
By Stijn on Oct 1, 2008
Hi Stijn,
I haven’t tested the code with recent Arduino versions - but your problem has something to do with the naming of control registers. Do you use an ATMega168-based Arduino? There are some differences in register naming.
For example, for my DCF77 library I had to define things differently, see
http://gonium.net/md/2007/04/18/tweaking-the-code/
Try to adjust the code accordingly.
HTH,
-Mathias
By md on Oct 6, 2008