Low power temp logger

Hi everyone

First time poster, long time lurker!

I'm looking to design a simple device which achieves the following:

  1. Low power usage - must be able to run off batteries for a minimum of 7 days (max 10-14)

  2. Take readings from up to 8 temperature proves (DS18B20)

2b. A second version would also make use of a GPS module to plot the journey - aware this increases power consumption, would need to run for max 4 days.

  1. Record said readings in a csv file for easy graphing

  2. Record date/time stamp

  3. Allow dump of data via a direct USB connection

  4. Device can then be 'reset' and recirculated. (Ideally this should be achieved without needing to fire up the IDE)

  5. The only connectivity it really needs is USB for local dumping of data/reset of the device.

The use case is monitoring temperature of a parcel throughout a test journey to ensure it remains within spec whilst we develop innovative packaging.

I've seen many Arduino based projects but they don't seem clear on the data extraction/reset methods, nor do they really discuss power consumption.

Any advice on this is appreciated, I'm relatively new to Arduino and have been learning over the last few months.

How often should temperature readings be taken?

Are there any restrictions about sending batteries through the postal system in your country?

Would it be acceptable to use a micro-SD card for downloading the data, instead of via USB?

My initial thoughts are

  • Arduino Pro Mini, 3.3V version. Power led can be removed for additional power savings.
  • Micro-SD card writer (also 3.3V version, most sold are 5V)
  • 3.7V Li-Po battery, capacity to be determined, but I suspect 2000mAh might be enough.
  • You will need a USB-serial adapter (also 3.3V) for programming and debugging. This won't be part of the final circuit.
  • You will need an RTC (Real Time clock) module.
  • Build a prototype on breadboard first. This can be soldered onto stripboard later.
  • Before purchasing components, post a link here so the forum can check suitability.

Sorry, should have clarified!

Sample time to be once every 5 minutes

Perfectly acceptable to use an SD card rather than usb

No restrictions on sending batteries in the post providing the parcel is appropriately marked with relevant coshh symbols

Take a look at FRAM memory, it is inexpensive and is not power hungry. Yes it remembers without any power. I typically replace the EEPROM memory on the RTC with one of the FRAM chips. Works great but some care must be taken as it is not an exact fit.

A DS3231 RTC running on its own coin cell (for years) has an open-drain active-low alarm output that could be used to control power to the entire rest of the circuit via a P-channel mosfet, shutting it down completely between readings. On boot the processor would take the readings, save them, set the next alarm time, and then clear the RTC's alarm flag, which would turn off the mosfet.

The key determinant of battery life would be the "5 minute" parameter, particularly if you use GPS. So you might want to think about how far the package could go in five minutes, or how much the temperature could change.

Do you assume the GPS will be useable inside a package, inside a truck? Have you tested that?

Hi Everyone

I've managed to get the logger working as follows

  1. Initially built a breadboard module using the DS3231 I had on hand, uSD card module and the ds18b20 sensors coupled with an arduino nano - after some trial and error, tweaking etc, now working beautifully

  2. This was then built onto veroboard and sent 'out' into the field for testing, worked great with a 5min sampling interval but only lasted about a day using a single 18650 cell connected to a DC-DC buck converter

  3. revisited the code, did some more research and incorporated the LowPower library, this brought the time in action to about 2 days - still 4 days shy of my targeted 6days in use

  4. I've since purchased some of the 'Deek-Robot' logger modules and built 2 units with this in conjunction with a nano.

I'm satisfied with the logger itself but the only place i'm stuck is with regard to powering the thing whilst its out and about!

I've trialled the 18650 shields but these look very sketchily made and I don't trust them.

For this first iteration, I still feel I need to solve the power issue; how to get a reliable, safe 5v power supply into the package which has enough capacity for 6 days in transit.

I think once i've nailed this, then I can look into the 3.3v version as this will require some modifications to the modules and I'd like to use what I have on hand for now.

The SD card modules I have are:

The RTC modules I have on hand are:

The Deek-Robot module I'm using is:

I have the same module from a uk ebay seller.

One version of my code is below and this does include an LED which is set to blink so I can see something is happening, this is just during testing. I have separate code which works with the deek-robot module which i'll post tomorrow as it is on my computer in the office.

#include <Wire.h>
#include <DS3231.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SPI.h>
#include <SD.h>

#define ONE_WIRE_BUS 7
#define CHIP_SELECT 10
#define BUTTON_PIN 9
#define LED_PIN 8

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DS3231 rtc(SDA, SCL);
File logFile;

void setup() {
  pinMode(BUTTON_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
  Serial.begin(9600);
  sensors.begin();
  rtc.begin();

  if (!SD.begin(CHIP_SELECT)) {
    Serial.println("Card failed, or not present");
    // Flash the LED three times at a frequency of 500 milliseconds
    flashLED();
    return;
  }
  Serial.println("SD card initialized.");
  openLogFile();
}

void loop() {
  if (digitalRead(BUTTON_PIN) == HIGH) {
    closeFile();
    while (digitalRead(BUTTON_PIN) == HIGH) delay(10);
    openLogFile();
  }
  logData();
  delay(10000);
}

void openLogFile() {
  logFile = SD.open("tempLog.txt", FILE_WRITE);
  if (logFile) {
    Serial.println("Log file opened successfully.");
    digitalWrite(LED_PIN, LOW);
    if (logFile.size() == 0) {
      logFile.println("Day, Date, Time, Sensor ID, Temperature(C)");
    }
  } else {
    Serial.println("Error opening log file.");
    // Flash the LED three times at a frequency of 500 milliseconds
    flashLED();
  }
}

void logData() {
  Time t = rtc.getTime();
  char timeBuffer[20];
  char dateBuffer[20];
  sprintf(timeBuffer, "%02d:%02d:%02d", t.hour, t.min, t.sec);
  sprintf(dateBuffer, "%04d-%02d-%02d", t.year, t.mon, t.date);
  String dayOfWeek = dayAsString(t.dow);
  sensors.requestTemperatures();

  for (uint8_t i = 0; i < sensors.getDeviceCount(); i++) {
    float temperature = sensors.getTempCByIndex(i);
    if (logFile) {
      logFile.print(dayOfWeek);
      logFile.print(", ");
      logFile.print(dateBuffer);
      logFile.print(", ");
      logFile.print(timeBuffer);
      logFile.print(", Sensor ");
      logFile.print(i);
      logFile.print(", ");
      logFile.println(temperature);
      logFile.flush();
      digitalWrite(LED_PIN, HIGH); // Turn LED on
      delay(50); // Adjust this delay as needed
      digitalWrite(LED_PIN, LOW); // Turn LED off
    }
    Serial.print("Date: ");
    Serial.print(dateBuffer);
    Serial.print(" Time: ");
    Serial.print(timeBuffer);
    Serial.print(" Sensor ");
    Serial.print(i);
    Serial.print(" Temperature: ");
    Serial.println(temperature);
  }
}

void closeFile() {
  if (logFile) {
    logFile.close();
    Serial.println("Log file closed successfully.");
    // Rapid blink for 10 seconds
    for (int i = 0; i < 20; i++) { // 20 iterations for rapid blinking
      digitalWrite(LED_PIN, HIGH); // Turn LED on
      delay(50); // Blink interval
      digitalWrite(LED_PIN, LOW); // Turn LED off
      delay(50); // Blink interval
    }
  }
}

String dayAsString(int dayOfWeek) {
  switch (dayOfWeek) {
    case 1: return "Monday";
    case 2: return "Tuesday";
    case 3: return "Wednesday";
    case 4: return "Thursday";
    case 5: return "Friday";
    case 6: return "Saturday";
    case 7: return "Sunday";
    default: return "Invalid";
  }
}

void flashLED() {
  for (int i = 0; i < 3; i++) {
    digitalWrite(LED_PIN, HIGH);
    delay(500);
    digitalWrite(LED_PIN, LOW);
    delay(500);
  }
}

In short

  1. Need to work out best and safest way to power this thing reliably for 6 days
  2. Redesign using 3.3v modules.

Are there any arduino/esp devices which have a small amount of storage on board which can be accessed via a web interface or similar?

I.e. if I send the device out, it comes back and is connected to wirelessly for downloading the log file?

Many thanks

Have a look at commercial devices available for doing this.

I would prefer to DIY this for now as once we have it logging on battery power there is some further functionality we intend to implement for a very specific use case

Nothing wrong with DIY , but Worth looking at what’s available to see how others do it.

Also worth looking at power saving techniques ( sleeping ) and if used to “ prove” conditions things like calibration etc

I've seen some commercial devices out there but quite expensive for what they are and i quite like the challenge and satisfaction of having built something with my own hands!

power saving; i'm conscious i need to look at removing LED's etc but currently it is all around power supply where i'm having trouble.

a mains powered one? not an issue. batteries is a whole new thing for me

I don't think there's any magic here. You have a circuit that is On all the time, and it draws battery power at whatever rate, and the battery lasts so many days. One solution would be to completely power down the circuit between logging events so that no current is used up when everything is idle. The DS3231 could be used to power on the circuit every five minutes using its alarm feature. This would require a P-channel mosfet and a resistor. Is that something you would consider doing?

Short of that, there may be ways to reduce current draw, such as eliminating blinking LEDs, which use a lot of current, and which won't be seen anyway, and perhaps other changes. I don't think you've posted a schematic yet. With that, someone might see other ways to reduce current draw.

And you did mean "boost converter", not "buck converter".

Here's what the RTC-controlled power switch would look like:

Sounds like an iButton Thermochron.