1

I want to work with interrupts and heard that the watchdog timer is effective way to deal with them. I haven't been able to find a good tutorial on them though and was wondering if someone could head me in the right direction or give me a couple tips and an example.

asked Apr 21, 2015 at 22:15
3
  • 2
    Which part of the datasheet are you having trouble with? Commented Apr 21, 2015 at 22:23
  • 6
    Watchdogtimer is NOT a recommended way of dealing with interrupts. It is dedicated to restarting the system on timeout. Most or all other timers are able to do this much more flexibly. Commented Apr 21, 2015 at 22:54
  • Look at the TimerOne library. Commented Apr 22, 2015 at 14:28

2 Answers 2

0

For the Uno, you can set an interrupt on digital pins 2 and 3. Check out http://www.arduino.cc/en/Reference/attachInterrupt for more details.

Here is the example code from that page:

int pin = 13;
volatile int state = LOW;
void setup()
{
 pinMode(pin, OUTPUT);
 attachInterrupt(0, blink, CHANGE);
}
void loop()
{
 digitalWrite(pin, state);
}
void blink()
{
 state = !state;
}

In this case, blink() will be called anytime pin 0 changes state. If you only want the rising or falling edge, change the call to attachInterrupt to say RISING or FALLING instead of CHANGE.

answered Apr 22, 2015 at 15:49
2
  • I know that but I don't understand how to integrate the code and the offical site is not helping me. Commented Apr 22, 2015 at 16:00
  • There is an example on that page -- if you take the blink function and replace it with your code, it will be called anytime pin 0 changes state. You can also change the interrupt to only be called on the rising or falling edge as well in the attachInterrupt call. I'll add the example to my answer as well. Commented Apr 22, 2015 at 16:03
1

Since you talk about the watchdog I presume you want timer interrupts. (There are also I/O interrupts, for instance when the level of a pin changes state.) Like Russell McMahon says the watchdog is not a good source. The ATmega has several timers (8-bit and 16-bit) which serve your exact purpose. Let's view some example code:

// timer interrupts
// adapted from code by Amanda Ghassaei
// June 2012
// http://www.instructables.com/id/Arduino-Timer-Interrupts/
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
*/
// timer setup for timer0, timer1, and timer2.
// For arduino uno or any board with ATMEL 328/168.. diecimila,
// duemilanove, lilypad, nano, mini...
// this code will enable all three arduino timer interrupts.
// timer0 will interrupt at 2kHz
// timer1 will interrupt at 1Hz
// timer2 will interrupt at 10kHz
// storage variables
boolean toggle0 = 0;
boolean toggle1 = 0;
boolean toggle2 = 0;
void setup() {
 // set pins as outputs
 pinMode(8, OUTPUT);
 pinMode(9, OUTPUT);
 pinMode(13, OUTPUT);
 cli(); // stop interrupts
 // set timer0 interrupt at 2kHz
 TCCR0A = 0; // set entire TCCR2A register to 0
 TCCR0B = 0; // same for TCCR2B
 TCNT0 = 0; // initialize counter value to 0
 // set compare match register for 2khz increments
 OCR0A = 124; // = (16*10^6) / (2000*64) - 1 (must be <256)
 // turn on CTC mode
 TCCR0A |= (1 << WGM01);
 // Set CS01 and CS00 bits for 64 prescaler
 TCCR0B |= (1 << CS01) | (1 << CS00); 
 // enable timer compare interrupt
 TIMSK0 |= (1 << OCIE0A);
 // set timer1 interrupt at 1Hz
 TCCR1A = 0; // set entire TCCR1A register to 0
 TCCR1B = 0; // same for TCCR1B
 TCNT1 = 0; // initialize counter value to 0
 // set compare match register for 1hz increments
 OCR1A = 15624; // = (16*10^6) / (1*1024) - 1 (must be <65536)
 // turn on CTC mode
 TCCR1B |= (1 << WGM12);
 // Set CS12 and CS10 bits for 1024 prescaler
 TCCR1B |= (1 << CS12) | (1 << CS10); 
 // enable timer compare interrupt
 TIMSK1 |= (1 << OCIE1A);
 // set timer2 interrupt at 10kHz
 TCCR2A = 0; // set entire TCCR2A register to 0
 TCCR2B = 0; // same for TCCR2B
 TCNT2 = 0; // initialize counter value to 0
 // set compare match register for 8khz increments
 OCR2A = 199;// = (16*10^6) / (10000*8) - 1 (must be <256)
 // turn on CTC mode
 TCCR2A |= (1 << WGM21);
 // Set CS21 bit for 8 prescaler
 TCCR2B |= (1 << CS21); 
 // enable timer compare interrupt
 TIMSK2 |= (1 << OCIE2A);
 sei(); // enable interrupts
} // end setup
ISR(TIMER0_COMPA_vect){ // timer0 interrupt 2kHz toggles pin 8
 // generates pulse wave of frequency 2kHz/2 = 1kHz (takes two cycles 
 // for full wave- toggle high then toggle low)
 toggle0 = HIGH - toggle0;
 digitalWrite(8, toggle0);
}
ISR(TIMER1_COMPA_vect) { // timer1 interrupt 1Hz toggles pin 13 (LED)
 // generates pulse wave of frequency 1Hz/2 = 0.5kHz (takes two cycles
 // for full wave- toggle high then toggle low)
 toggle1 = HIGH - toggle1;
 digitalWrite(13, toggle1);
}
ISR(TIMER2_COMPA_vect) { // timer1 interrupt 10kHz toggles pin 9
 // generates pulse wave of frequency 10kHz/2 = 5kHz (takes two cycles 
 // for full wave- toggle high then toggle low)
 toggle2 = HIGH - toggle2;
 digitalWrite(9, toggle2);
}
void loop() {
 // do other things here 
}

This sets up 3 different timers: one at 500 µs, one at 1 s, one at 100 µs. For the details about each timer, look up the registers in the datasheet.
With each timer goes a timer interrupt service routine (ISR). These perform the action required when an interrupt occurs. It's a good practice to exit an ISR as quickly as possible. Only do the things which are really time-critical, but for the rest set a flag to indicate that the interrupt occurred. Then in the main loop you continuously check that flag, and when it is set, perform the necessary actions. Don't forget to clear the flag when you're done.

answered Apr 22, 2015 at 9:28
2
  • I appreciate the code here but I want to do hardware interrupts. I wasn't able to make it clear because I didn't know but I want to make the robot stop when it senses the edge of a table. Therefore I believe that would be a hardware intterupt with a rising edge or something. Commented Apr 22, 2015 at 15:33
  • 1
    @EinsteinJr.: then could you please remove reference to the watchdog timer in your question? It's misleading to say the least. Commented Apr 22, 2015 at 16:51

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.