Although the prescaler on an Arduino's timer can only be set to 1, 8, 32, 64, 128, 256 or 1024, it's actually possible to mess around a bit and derive exactly 1 second intervals out of a timer. Have a look at this sketch, which is derived from the posts on the arduino forum noted at the end of this page. Thanks to the original posters (Gonium, Fuzzillogic and CosineKitty) for the code that was used to derive this sketch.
This sketch flashes the onboard LED (pin 13) at 1 second intervals.
#include <avr/interrupt.h> #include <avr/io.h> int LED = 13; int ledStatus = 0; int newStatus = 1; long int counter = 0; #define COUNTER_START 6 ISR(TIMER2_OVF_vect) { // TCNT2 is being incremented at a rate of 16,000,000 / 64 = 250,000 times a second // (64 is due to the prescaler setting in setup where TCCR2B is set (see page 157 // of ATMega168 datasheet)). This function is called whenever TCNT2 overflows. We // want TCNT2 to overflow after 250 increments to clock our own manual counter // variable which 'overflows' at 1000 to give us millisecond resolution. // To do this, we reset TCNT2 so it starts at 6 after this function finishes. counter++; if (counter == 1000) { // flip the LED 'on' bit newStatus = newStatus ^ 1; counter = 0; } // Start TCNT2 from 6, so TCNT2 = COUNTER_START; }; void setup() { Serial.begin(9600); pinMode(LED, OUTPUT); digitalWrite(LED, HIGH); //Timer2 Settings: Timer Prescaler /64, WGM mode 0 TCCR2A = 0; TCCR2B = 1<<CS22 | 0<<CS21 | 0<<CS20; //Timer2 Overflow Interrupt Enable TIMSK2 = 1<<TOIE2; //reset timer TCNT2 = COUNTER_START; } void loop() { if (ledStatus != newStatus) { // Serial.println("Timer"); digitalWrite(LED, newStatus); ledStatus = newStatus; } } (C) 2011 Dave Hng
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1167000525 |
home > ArduinoSketches >