Pages: [1]   Go Down
Author Topic: All about timers - how to handle sw interrupts?  (Read 1867 times)
0 Members and 1 Guest are viewing this topic.
Czech Republic
Offline Offline
Sr. Member
****
Karma: 4
Posts: 312
Absolute Beginner, yet.
Newbie in Arduino
since May 2013
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
Logged

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...

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 610
Posts: 49080
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

0
Offline Offline
Shannon Member
****
Karma: 206
Posts: 12076
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

[ I won't respond to messages, use the forum please ]

USA
Offline Offline
Jr. Member
**
Karma: 4
Posts: 91
If you can't fix it with a hammer, it must be an electrical problem.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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."
Logged


India
Offline Offline
Full Member
***
Karma: 0
Posts: 176
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

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.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 480
Posts: 18732
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged


Czech Republic
Offline Offline
Sr. Member
****
Karma: 4
Posts: 312
Absolute Beginner, yet.
Newbie in Arduino
since May 2013
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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.
« Last Edit: July 22, 2013, 05:01:51 am by K5CZ » Logged

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...

Pages: [1]   Go Up
Jump to: