Timing problem, elapsedMillis

Hi all,

I’m working on a digital compass project. Based on input from Honeywell’s HMC5883L chip, an LED should flash a certain amount of times per second given it’s orientation to the earth’s magnetic field. I’m using the elapsedMillis library to accomplish the timing.

Problem is, sometimes I’ll get a nice constant flashing output, but then, sporadically it seems, the steady flashing is interrupted for a longer time periods and I lose that nice steady output. I’ve posted what the square wave output on my oscilloscope to help you understand better what the output looks like. Any ideas why this is happening?

Sparkfun_HMC5883L_code.ino (2.86 KB)

Hello,

It might be caused by constantly printing to Serial, every loop(). Try without those Serial.prints.

Also, if you are using the data of the sensor only once per second, why do you read the sensor data every loop()? You could read it once per second too and get the same result.

By the way, this:

if (currentMillis - previousMillis > interval) {

should be this:

if (currentMillis - previousMillis >= interval) {

Thanks for the photo, that explains it very well :stuck_out_tongue:
I think you get what the sketch is doing :confused:

The loop() is running at high speed and the Serial.print is writing to the serial port a lot of data. That will fill the buffer in the Serial library, and that causes to slow things down. The way millis is used, means that it will be delayed.

You could slow the HMC5883 and the Serial.print() down. For example 2 times a second. Or 100 times a second the HMC5883 and 1 time per second the Serial.print(). Anything is possible. The number of times per second something is executed is created with millis().

What about doing everything once a second ? Just bring the HMC5883 and the Serial.print() of the data inside the millis() software timer. That is a quick fix.

It is possible to have a better 1 second software timing, that is accurate at every second. A delay by code will be corrected the next time. It is by doing this: previousMillis += interval;
Then previousMillis is updated, regardless of any delay by the sketch.
The start value of previousMillis should be set at the end of setup(), to get a good start for the first 1 second.

previousMillis must be 'unsigned long' to avoid the rollover problem. The function millis() returns also an 'unsigned long'. I would even call it a bug, if a 'long' is used.

unsigned long previousMillis = 0; //will store last time LED was updated
unsigned long interval = 1000; //interval at which to blink
...
void setup() {
  ...
  previousMillis = millis();
}

void loop() {
  if(currentMillis - previousMillis >= interval) {
    previousMillis += interval;

    // The next part of the code runs every second

    // read data from HMC5883
    ...

    // print out axis
    ...

    // blink led
    ...

    // show leds according direction
    ...
  }
}