Millis timer code goes bad after about a minute...???

So I’m doing some logging and using the if millis() - timer >= logdelay; type of code to set a logger delay. So, for example if I wanted to log once a second than logdelay = 1000, etc… This works fine for about a minute until it just starts running as fast as the loop allows and logging between 12 and 15 Hz. Here’s the code;

#include <Wire.h>
#include <SD.h>
#include <RTClib.h>
#include <BMP085.h>

#define CHIP_SELECT          8    // SD chip select pin
#define LOG_INTERVAL      1000    // logging interval
#define CHANNELS             8    // define number of channels to log
#define ON_BOARD_ANALOGS     0    // set to 1 if using onboard digital to analog pins
#define PRESSURE_ADDRESS    40    // address of Honeywell pressure sensor
#define LO_CAL              10    // low point calibration for temp sensor at 100 deg. F
#define HI_CAL            1267    // high point calibration for temp sensor at 250 deg. F

RTC_DS1307 RTC;    // define real-time clock instance
BMP085 BMP;        // define barometric pressure/temperature sensor instance

unsigned int logDelay = 0;    // delay for timing logging activities

void setup()
{
  Serial.begin(9600);                   // start serial interface
  Wire.begin();
  BMP.begin();
  RTC.begin();
  pinMode(10, OUTPUT);
  if (!SD.begin(CHIP_SELECT)) {         // see if card is present and can be initialized
    Serial.println("Card failed, or not present");
    return;
  }
  if (! RTC.isrunning()) {                      // if the RTC isn't set,
    RTC.adjust(DateTime(__DATE__, __TIME__));   // set it now.
  }
  delay(1000);
  unsigned int logDelay = millis();     // start the logging timer once initialized
  Serial.println("Unit initializing");
}

/*
*/
int getBaro()
{
  int baro = (BMP.readPressure() * .000296) * 100;  // get barometric pressure in " of Hg
  return baro;
}

/* 
*/
int getAmbTemp()
{  
  int temp = ((BMP.readTemperature() * 1.8) + 32) * 100;  // get temperature and change to F
  return temp;
}

/*
*/
int getLinePressure() 
{
  unsigned int delayTime = 0;
  byte pvalHigh = 0;
  byte pvalLow = 0;
  int pressCounts = 0;
  
  Wire.requestFrom(PRESSURE_ADDRESS, 2);    // setup the request from the pressure sensor
  unsigned int timerHold = millis();        // start a timer to ensure we don't wait for
  while (delayTime < 500 ) {                // data forever.
    if (Wire.available() == 2) {            // if there's two bytes of data, get them
      pvalHigh = Wire.receive();          
      pvalLow = Wire.receive();
      pressCounts = pvalLow + (pvalHigh << 8);
      break;
    }
    delayTime += millis() - timerHold;     // count time until 500 millis is elapsed
  }
  return pressCounts;
}

/*
*/
int getLineTemp()
{
  int lineTemp = analogRead(0);        // get the analog value from the thermistor
  lineTemp = map(lineTemp, LO_CAL, HI_CAL, 100, 250);    // and map it to the linear calibration
  return lineTemp;
}


void loop()
{
  const int ADC_address = 0x48;    // I2C write address for 12-bit ADC  
  DateTime now = RTC.now();
  
  if (millis() - logDelay > LOG_INTERVAL) {     // create data string and writes to a file
    Serial.print("mills = ");
    Serial.println(millis());
    Serial.println("Writing data");
    logDelay = millis();      //reset the log timer
    File dataFile = SD.open("datalog.txt", FILE_WRITE);  // write the data string to a file
    if (dataFile) {
      dataFile.print(now.unixtime());                    // beginning with a timestamp
      dataFile.print(",");
      dataFile.print(getBaro());
      dataFile.print(",");
      dataFile.print(getAmbTemp());
      dataFile.print(",");
      dataFile.print(getLinePressure());
      dataFile.print(",");
      dataFile.println(getLineTemp());
      dataFile.close();
    }
    else {
      Serial.println("error opening datalog.txt");
    }
  }
}

It seems to happen right around the time millis() returns ~65800.

Thanks for any help.

-Ian

unsigned int logDelay

BZZZZT !

Dammit, long int, huh?

Stupid.

Sorry.

-Ian

Dammit, long int, huh?

Close.

Unsigned long int?

The unsigned goes without saying. No flux capacitor's in this project.

-Ian

unsigned long! int is a 2 byte value. long is a 4 byte value.

The unsigned goes without saying

Sadly, unsigned does not go without saying.
This is C - if you want it, you have to say it.

Learn something everyday. I thought long int and long were two ways of saying the same thing. I was wrong.

@ AWOL, I was joking around a bit with my response. I was intending that I’d left the ‘unsigned’ out of my response, not the actual code.

New code looks like so;

#include <Wire.h>
#include <SD.h>
#include <RTClib.h>
#include <BMP085.h>

#define CHIP_SELECT          8    // SD chip select pin
#define LOG_INTERVAL         1    // logging interval in seconds
#define CHANNELS             8    // define number of channels to log
#define ON_BOARD_ANALOGS     0    // set to 1 if using onboard digital to analog pins
#define PRESSURE_ADDRESS    40    // address of Honeywell pressure sensor
#define LO_CAL              10    // low point calibration for temp sensor at 100 deg. F
#define HI_CAL            1267    // high point calibration for temp sensor at 250 deg. F

RTC_DS1307 RTC;    // define real-time clock instance
BMP085 BMP;        // define barometric pressure/temperature sensor instance

unsigned long logDelay = 0;    // delay for timing logging activities

void setup()
{
  Serial.begin(9600);                   // start serial interface
  Wire.begin();
  BMP.begin();
  RTC.begin();
  pinMode(10, OUTPUT);
  if (!SD.begin(CHIP_SELECT)) {         // see if card is present and can be initialized
    Serial.println("Card failed, or not present");
    return;
  }
  if (! RTC.isrunning()) {                      // if the RTC isn't set,
    RTC.adjust(DateTime(__DATE__, __TIME__));   // set it now.
  }
  delay(1000);
  logDelay = millis();
  Serial.println("Unit initializing");
}

/*
*/
int getBaro()
{
  int baro = (BMP.readPressure() * .000296) * 100;  // get barometric pressure in " of Hg
  return baro;
}

/* 
*/
int getAmbTemp()
{  
  int temp = ((BMP.readTemperature() * 1.8) + 32) * 100;  // get temperature and change to F
  return temp;
}

/*
*/
int getLinePressure() 
{
  unsigned int delayTime = 0;
  byte pvalHigh = 0;
  byte pvalLow = 0;
  int pressCounts = 0;
  
  Wire.requestFrom(PRESSURE_ADDRESS, 2);    // setup the request from the pressure sensor
  unsigned int timerHold = millis();        // start a timer to ensure we don't wait for
  while (delayTime < 500 ) {                // data forever.
    if (Wire.available() == 2) {            // if there's two bytes of data, get them
      pvalHigh = Wire.receive();          
      pvalLow = Wire.receive();
      pressCounts = pvalLow + (pvalHigh << 8);
      break;
    }
    delayTime += millis() - timerHold;     // count time until 500 millis is elapsed
  }
  return pressCounts;
}

/*
*/
int getLineTemp()
{
  int lineTemp = analogRead(0);        // get the analog value from the thermistor
  lineTemp = map(lineTemp, LO_CAL, HI_CAL, 100, 250);    // and map it to the linear calibration
  return lineTemp;
}


void loop()
{
  DateTime now = RTC.now();
  
  if (millis() - logDelay > LOG_INTERVAL) {     // create data string and writes to a file
    logDelay = millis();      //reset the log timer
    File dataFile = SD.open("datalog.txt", FILE_WRITE);  // write the data string to a file
    if (dataFile) {
      dataFile.print(now.unixtime());                    // beginning with a timestamp
      dataFile.print(",");
      dataFile.print(getBaro());
      dataFile.print(",");
      dataFile.print(getAmbTemp());
      dataFile.print(",");
      dataFile.print(getLinePressure());
      dataFile.print(",");
      dataFile.println(getLineTemp());
      dataFile.close();
    }
    else {
      Serial.println("error opening datalog.txt");
    }
  }
}

And works longer than a minute now. Probably should last ~49.7 days or so, huh?

-Ian

Wrong units…

#define LOG_INTERVAL 1 // logging interval in milliseconds

Small correction…

if (millis() - logDelay >= LOG_INTERVAL) { // create data string and writes to a file

The actual wait time is much shorter than 500 milliseconds…

unsigned int timerHold = millis(); // start a timer to ensure we don’t wait for
while (delayTime < 500 ) { // data forever.

delayTime += millis() - timerHold; // count time until 500 millis is elapsed
}