Using interrupts for timing, sensing if 8 o 16MHz Arduino is used.

Hi,

I wrote an Arduino programm using interrupts for timing:

  //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 2kHz
  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 2khz increments
  OCR2A = 249;// = (16*10^6) / (2000*32) - 1 (must be <256)
  // turn on CTC mode
  TCCR2A |= (1 << WGM21);
  // Set CS20 , CS 21 and CS22 bit for 128 prescaler
  TCCR2B |= (1 << CS22) | (0 << CS21) | (1 << CS20);
  // enable timer compare interrupt
  TIMSK2 |= (1 << OCIE2A);

It works well, but if I use a 8MHz Arduino pro mini, the timing is halfed.
I would like to write the interrupts routine to be independent of the hardware used.
How can I get a compiler conditional directive to sense the speed of the used Arduino?
Thank you for your help...

Use the F_CPU macro to determine the clock frequency at compile time, and change the prescalers appropriately.

Pieter

PieterP:
Use the F_CPU macro to determine the clock frequency at compile time, and change the prescalers appropriately.

Pieter

Thank you for the incredibly fast answer.
Could you please ellaborate on how to use the F_CPU macro to sense the CPU speed and buil an appropriate compiler directive?
I tried to google for it, but get a lot of confusing information, nat really related to the Arduino IDE.

Thank you
Laszlo

RIN67630:
Thank you for the incredibly fast answer.
Could you please ellaborate on how to use the F_CPU macro to sense the CPU speed and buil an appropriate compiler directive?
I tried to google for it, but get a lot of confusing information, nat really related to the Arduino IDE.

Thank you
Laszlo

First off, F_CPU isn't read from the fuses into the compiler at compile time. It's set by the board profile in the Arduino IDE and assumes the fuses have been set accordingly. So, it's defined by the code that is compiled. It is possible to burn the fuses at 8MHz and F_CPU to be set for 16MHz and your timing will be off accordingly.

That said, I doubt this can be done for ANY and ALL speeds of F_CPU, but certainly for the common speeds, you can work out the values for OCR1A and CS12 and CS10. Then use #ifndef/#ifdef macros to include the right values for that defined speed.

Perehama:
First off, F_CPU isn't read from the fuses into the compiler at compile time. It's set by the board profile in the Arduino IDE and assumes the fuses have been set accordingly. So, it's defined by the code that is compiled. It is possible to burn the fuses at 8MHz and F_CPU to be set for 16MHz and your timing will be off accordingly.

That said, I doubt this can be done for ANY and ALL speeds of F_CPU, but certainly for the common speeds, you can work out the values for OCR1A and CS12 and CS10. Then use #ifndef/#ifdef macros to include the right values for that defined speed.

I just wanted to write a code that adapts to the some variants provided in the standard IDE: ATmega328p3,3V@8MHZ or any other Arduino ATmega328 models running@16MHz.
How could I sense with an #ifdef if I am compiling for an ATmega328p3,3V@8MHZ?

As stated, the macro 'F_CPU' will be defined for you at compile time based on the board you selected in the IDE under 'Tools --> Board'. You can use that in pre-processor '#if' macros to control what code gets compiled. See: http://www.cplusplus.com/doc/tutorial/preprocessor/

EDIT:
You can also use the 'F_CPU' macro in run-time if() statements.

[color=#5e6d03]#if[/color] [color=#000000]F_CPU[/color] [color=#434f54]==[/color] [color=#000000]16000000[/color]
[color=#5e6d03]#pragma[/color] [color=#000000]message[/color] [color=#005c5f]"16 MHz"[/color]
// set prescaler for 16 MHz here
[color=#5e6d03]#elif[/color] [color=#000000]F_CPU[/color] [color=#434f54]==[/color] [color=#000000]8000000[/color]
[color=#5e6d03]#pragma[/color] [color=#000000]message[/color] [color=#005c5f]"8 MHz"[/color]
// set prescaler for 8 MHz here
[color=#5e6d03]#else[/color]
[color=#5e6d03]#error[/color] [color=#005c5f]"Unsupported clock speed"[/color]  
[color=#5e6d03]#endif[/color]

RIN67630:
I just wanted to write a code that adapts to the some variants provided in the standard IDE: ATmega328p3,3V@8MHZ or any other Arduino ATmega328 models running@16MHz.
How could I sense with an #ifdef if I am compiling for an ATmega328p3,3V@8MHZ?

Who set up the board profile? Assuming you are using MiniCore or something similar, F_CPU is defined in boards.txt so, just as PieterP has illustrated.

PieterP:

[color=#5e6d03]#if[/color] [color=#000000]F_CPU[/color] [color=#434f54]==[/color] [color=#000000]16000000[/color]

#pragma message "16 MHz"
// set prescaler for 16 MHz here
#elif F_CPU == 8000000
#pragma message "8 MHz"
// set prescaler for 8 MHz here
#else
#error "Unsupported clock speed" 
#endif

Super! besten Dank.