Go Down

Topic: All about timers - how to handle sw interrupts? (Read 2 times) previous topic - next topic

K5CZ

Hi, my idea is to use a timer for operate with input events (buttons, end switches - including debounce) and in the main program works only with the last stable detected states of inputs.

I read many websites about this but I do not understand all of them. So questions are:

- which timer(s) is free for use in Arduino UNO R3?
- what is bare minimum to use 10 Hz timer (program example)?

Thanks!
Arduino Uno R3, Arduino Mega 2560 R3, Ethermega (R3), and some Ethernet Shields (R3), Chronodots, TMP36 sensors, DS18B20 sensors, LCDs/TFTs, RS232C to learn and play...

PaulS

Quote
- which timer(s) is free for use in Arduino UNO R3?

What else are you doing? All timers serve dual purpose. The question is what do you want to give up? PWM? Servo control? millis()?

Quote
- what is bare minimum to use 10 Hz timer (program example)?

Which timer? For something to happen ten times a second, I wouldn't use interrupts or timers at all. A simple check of the current time, using millis() and a comparison to the last time an event occurred, is often good enough. It depends, to a large extent, on exactly how accurate the time between events needs to be, which depends on what the actual events are.

MarkT

Timers generate hardware interrupts - a software interrupt is something different.
[ I won't respond to messages, use the forum please ]

JimEli


Timers generate hardware interrupts - a software interrupt is something different.


Per Datasheet:

"The External Interrupts are triggered by the INT0 and INT1 pins or any of the PCINT23..0 pins. Observe that, if enabled, the interrupts will trigger even if the INT0 and INT1 or PCINT23..0 pins are configured as outputs. This feature provides a way of generating a software interrupt."

sreedevk

Hello, this is fairly simply. There are various kinds of software interrupts. Rising, falling, Low, Change. Rising interrupt gets triggered gets activated when a transition from 0 to5V happen at the interrupt pin. Falling is quite the opposite. Change is any transition. High to low or low to high. Low, when the input to the interrupt pin is 0V. I don't understnad why you asked for 10Hz timer. That comes under hardware interrupts. To understand sw interrupts better check this out:
http://www.youtube.com/watch?v=CRJUdf5TTQQ
I'll also tell a bit about hw interrupts. There are 3 timers on the Arduino. Timer1 is 16 bit timer. Meaning it can count from 0-65535 (2^16). The timer counts with each clock pulse i.e suppose your microcontroller is running at 1Hz, the count advances by one every second. Keep in mind that fact that you microcontroller runs at a high freq like 16MHz. To get a code to run with high accuracy, you can choose a value to count up to. When the count gets there the interrupt gets triggered and the count is reset to 0 and the code is executed. You can use prescalers to scale the freq i.e you can have the timer count up from 0 to the value you want at a freq which is microcontroller freq divided by any of these values 1, 8, 64, 256 or 1024. So you can have a code executed at a particular time precisely. Actually you do not need to go into all that deep Arduino Timer library helps you with hw interrupts. All you have to do is write a function,specify the time at which it has to be executed.
http://playground.arduino.cc/code/timer
http://playground.arduino.cc/code/timer1
http://www.instructables.com/id/Arduino-Timer-Interrupts/
Note that Timer1 is 16 bit, however I don't think that's the case with Timer2&3.

Nick Gammon

Normally Timer 0 is already in use for millis(), micros() and delay() function calls. Other ones are free but are pressed into service by other libraries as PaulS says.

Timers info: http://www.gammon.com.au/forum/?id=11504

To detect key presses you hardly need timers, or even interrupts.

A pin-change interrupt could be used to detect a press on any key if you are busy doing something else.

Stuff about detecting key presses: http://www.gammon.com.au/switches
http://www.gammon.com.au/electronics

K5CZ

#6
Jul 22, 2013, 11:05 am Last Edit: Jul 22, 2013, 12:01 pm by K5CZ Reason: 1
My English is not so good, and maybe I was wrong to comment on what I want. Anyway Timer 0 and Timer 1 are used by different useful functions, while Timer 2 is used only for a function tone(), I might not need,  so I wrote timer interrupt handler that works exactly what I need.

Code: [Select]

#define ledPin 13 //blinking indicator

//because slowest timer2 interrupt frequency is 60 Hz and I want 10 Hz, I must divide
#define COMPARE_MATCH_REGISTER 155 //1024 prescaler & 100 Hz = 155,25
#define INT_RATIO 10 // 100 Hz ÷ 10 = 10 Hz

//volatile because interrupt
volatile bool timer2_interrupt_in_progress=false; //bypass if the program execution takes longer than the interrupter frequency
volatile int interrupt_numerator=1;               //ratio

void setup()
{
 pinMode(ledPin, OUTPUT);
//**************************************************************************
//*********************** initialize timer interrupt ***********************
//**************************************************************************
 noInterrupts();                 // disable all interrupts
 //Timer2 Settings
 TCCR2A = 0;
 TCCR2B = 0;
 TCNT2  = 0;
 TIMSK2 = 0;
 TCCR2A |= (1 << WGM21);         // turn on CTC mode
 //Prescaler
 // none: TCCR2B |= ((0<<CS22) | (0<<CS21) | (1<<CS20));
 //    8: TCCR2B |= ((0<<CS22) | (1<<CS21) | (0<<CS20));
 //   64: TCCR2B |= ((0<<CS22) | (1<<CS21) | (1<<CS20));
 //  256: TCCR2B |= ((1<<CS22) | (0<<CS21) | (0<<CS20));
 // 1024: TCCR2B |= ((1<<CS22) | (0<<CS21) | (1<<CS20));
 TCCR2B |= ((1<<CS22) | (0<<CS21) | (1<<CS20));
 TIMSK2 |= (1 << OCIE2A);        // enable timer compare interrupt
 OCR2A = COMPARE_MATCH_REGISTER; // compare match register
 interrupts();                   // reenable all interrupts
//**************************************************************************  
};

//**************************************************************************
//******************************** execute *********************************
//**************************************************************************
ISR(TIMER2_COMPA_vect)            // timer compare interrupt service routine
{
 if ( !timer2_interrupt_in_progress ){          //previous run must be done
   timer2_interrupt_in_progress = true;         //processing flag
   if ( interrupt_numerator++ == INT_RATIO ){
     interrupt_numerator = 1;
     //some code here
     //example: fast blinking LED
     digitalWrite(ledPin, !digitalRead(ledPin));//toggle LED pin
   };
    timer2_interrupt_in_progress = false;
 };
};

//**************************************************************************

void loop()
{
 //some code here
};


And so, thanks for link about interrupts.
Arduino Uno R3, Arduino Mega 2560 R3, Ethermega (R3), and some Ethernet Shields (R3), Chronodots, TMP36 sensors, DS18B20 sensors, LCDs/TFTs, RS232C to learn and play...

Go Up