Datalogging trigger issues - random sleep intervals

Hi there,

I have created a data logger project where I am comparing 3 different temperature sensors. The Arduino wakes up once every 4 seconds following the trigger from a DS3231 RTC and measures the three temperature sensors once before going to sleep. The code for the project is:

#include "subseaDatalogger.h"

ssDataLogger ssDL;

void setup()
{

  ssDL.begin(4);  //Initialise and set wake up period to 4 seconds

  ssDL.newHeader("Time (s), LM35 (C), DS3231 (C), 328P (C)");  //Header for the .csv file
  ssDL.newExtender("_temp");                                   //adds "_temp" to the end of every file
  
}

void loop()
{

      ssDL.quickWrite(ssDL.indicatorLED, HIGH);

        ssDL.readTime();
        ssDL.readTemperature();
        ssDL.readDS3231Temperature();
        ssDL.readAVRTemperature();
        
        ssDL.newline();

        ssDL.saveToSD();

      ssDL.quickWrite(ssDL.indicatorLED, LOW);
      
    ssDL.goToSleep(); //Goes into power-down sleep mode and waits for RTC to trigger a wake-up

}

and everything works great, I end up with a file that looks like this:

However, I keep running into the issue that my datalogger will randomly sleep for much longer periods of time. Sometimes a minute, sometimes longer...
As an example, the difference in time for every datapoint should be 4 seconds, i.e., when I measure a datapoint, if the current time is 00:00:40, then the previous measurement time is 00:00:36, but, there are points in all of my files where the time is a minute or sometimes a few minutes:


and here is what the time difference looks like in the actual .csv file:
image

the code that I use to send the Arduino to sleep is:

void ssDataLogger::goToSleep()
{
//Set power down mode and set sleep enable
  SMCR |= bit(SM1) | bit(SE);

// Set alarm to wake up from RTC
  setAlarmTime(); 


// -------------- BOD disable - Assumes 5V supply won't fail! then sleep -----------
  MCUCR |= (3 << 5);
  MCUCR  = (MCUCR & ~(1 << 5)) | (1 << 6);
  __asm__ __volatile__("sleep");
}

where the setAlarmTime(); function is declared as:

void ssDataLogger::setAlarmTime()
{
    alarm += timeStep;

    if(alarm>59)
        alarm -= 60;

    writeDS3231(0x07, ((alarm/10) << 4)|(alarm%10)); //Write next alarm time to DS3231 alarm seconds register
    writeDS3231(0x0F, 0b10001000); //Set A1F high in control register, needed to reset alarm and to  write output trigger pin low

    return;
}

where alarm and timeStep are private uint8_t variables declared in the ssDataLogger class.

Essentially, I have no idea as to what my datalogger will randomly sometimes sleep for a minute or longer when most of the time it sleeps for exactly 4 seconds as intended.

The only thing I think it could be is in how I am organising my memory, as when I compile my code I get this message:

Sketch uses 19618 bytes (60%) of program storage space. Maximum is 32256 bytes.
Global variables use 1646 bytes (80%) of dynamic memory, leaving 402 bytes for local variables. Maximum is 2048 bytes.
Low memory available, stability problems may occur.

As my ssDataLogger object also uses an SD card, an ADS1115 ADC...
Do people think that this is simply an issue that is arising due to low memory?

As the DS3231 registers doesn't seem to be initialized (don't tell us that's in the part of the code you're hiding from us!) I guess that the other registers don't have the content you expect the to have.

Post the content of a complete file (no screenshots of text data anymore!).

That's possible but not probable given the data you already opened. Though I might change my mind if I see more output and more code.

1 Like

May or may not have anything to do with your problem, but:

writeDS3231(0x0F, 0b10001000); //Set A1F high in control register, needed to reset alarm and to  write output trigger pin low

I don't think that the comment matches the code here. My DS3231 datasheet (19-5170; Rev 10; 3/15) shows in Figure 1 (page 11) that the A1F bit is bit 0 (LSB) of the control/status register at address 0x0F.

EDIT: A further read of the datasheet indicates that the A1F bit is cleared by writing a 0 to it. It looks like you are therefore clearing the Alarm 1 flag (writing a 0 to it), but I'm not sure about the 2 bits you do set. The MSB is the OSF (Oscillator Stop Flag) bit which it looks like you can only reset to 0. The other bit you set (EN32kHz) controls the 32kHz output signal.

1 Like

if you have a second Arduino, can you monitor the signal to verify spacing?
saving only millis() and the top 10 highest spans might show that the problem is in the timing signals and not the wake.

Hi everyone,

thankyou for your responses, @pylon, here is the complete code I was using including the header files:
temperatureDatalogger.cpp (11.1 KB)
temperatureDatalogger.h (1.7 KB)
temperatureDatalogger.ino (901 Bytes)

I have also included a pin connection description at the beginning of the .ino file.

@markd833, yes I wasn't too sure about that on reflection either. This code is actually part of a bigger university project and I am producing the code as well as the PCBs and the sensors that we will be using and so I, unfortunately, lost track as to why I was writing those specific bits!
After going through the RTClib.h examples, I found a DS3231 example and I have re-written my setAlarmTime() function to be more in tune with the method that is suggested by the people who have developed the library

@dave-in-nj that sounds like a good idea, I'm bogged down with some other university work at the moment but I will try this later and see if this helps to find the problem

note: it's also worth mentioning that this isn't likely to be a problem with the DS3231 as it has happened with multiple RTCs and arduinos...

setAlarmTime() is complete different than the version in post #0. Which one was actually used?

Where did you post the complete output?

Hi @pylon, sorry for the late response, I have been away but I left the datalogger running on my bedroom window whilst I was away. Thank you @markd833 for pointing this out, It appears that changing the setAlarmTime() was the only correction I required!

here is an example output file I have now:

exampleOutputs.zip (191.6 KB)
(ignore the temperature readings for the LM35, it appears that the sensor fell out of the breadboard before I left for my break lol)

thankyou everyone for your help!

It seems that your problems are fixed, at least in the provided output files the regular gaps you described cannot be found.