Make a LED blink while doing some heavy number crunching

I have a problem... I want a LED to blink at a CONSTANT frequency (every 50ms or so) while my Arduino is processing serial GPS data. Since getting the data from the GPS and doing some calculations with it takes some time, I can't get my LED to blink at a constant rate. I tried solving this issue using millis() but that didn't help.

Is there any way of doing this?

Yes. Post your code.

This sketch calculates the factorials of 2 to 200 (quite a lot of number crunching) while blinking an LED at a frequency of roughly 50 mS (50.011 mS):

// BigNumber test: factorials
#include "BigNumber.h"

// function to display a big number and free it afterwards
void printBignum (BigNumber & n)
{
  char * s = n.toString ();
  Serial.println (s);
  free (s);
}  // end of printBignum

const byte LED = 9;

void setup() {
  Serial.begin (115200);
  BigNumber::begin ();  // initialize library
  pinMode (LED, OUTPUT);
  
  // set up Timer 1
  TCCR1A = _BV (COM1A0);  // toggle OC1A on Compare Match
  TCCR1B = _BV(WGM12) | _BV(CS10) | _BV (CS12);   // CTC, scale to clock / 1024
  OCR1A =  390;       // compare A register value (391 * clock speed / 1024)
}  // end of setup

void loop() 
{
  //factorials
  BigNumber fact = 1;

  for (int i = 2; i <= 200; i++)
  {
    Serial.print (i);
    Serial.print ("! = ");
    fact *= i;
    printBignum (fact);
  }  // end of for
}  // end of loop

Big number library here, if you want to test:

http://www.gammon.com.au/forum/?id=11519

Nick, where do you turn the LED on and off?

  TCCR1A = _BV (COM1A0);  // toggle OC1A on Compare Match

That's cheating ;)

Hi Nick

Your code pointed me in the right direction of using the built in timers and setting interrupts

Thanks

It's a good solution. I'm impressed!

Thank you everyone. :)

This solution was also targeted at the people who post in other threads that they "want pre-emptive multitasking" or "multiprocessing" without explaining why. This particular question was succinct as to exactly what "multiprocessing" was required, and thus a solution that the chip is easily capable of could be offered.

The Atmega328 chip is actually quite powerful and capable of doing multiple things at once at the hardware level. In particular, three timers can run at once, plus a watchdog timer, and buffered input/output using the USART chips. In addition it can monitor changes to the pins (external interrupts and pin change interrupts).

If you understand, and work with, the hardware you can get a lot out of it.

I'd add a caveat, if you're programming using the Arduino core, the other thing to understand is how Arduino uses the hardware, e.g. Timer0 for millis() and PWM on pins 5 and 6, Timer1 for PWM on pins 9 and 10, Timer2 for PWM on pins 3 and 11, and also for the Tone function (off the top of my head so don't hold me to the particulars or to completeness).

There are two things to realize here. (1) You can use any of the hardware you want, but there may be a tradeoff with other functionality, and (B) When initializing the hardware, do not assume registers are in their reset states as documented by the datasheet, because Arduino does its own setup. Took me several times to learn that last one :blush:

Elegant solution Nick. For more information on timer interrupts and how they are set up, we have a tutorial here: http://www.engblaze.com/microcontroller-tutorial-avr-and-arduino-timer-interrupts/

It covers configuration and the pros/cons of each timer that Jack mentions.