I'm looking to design a simple device which achieves the following:
Low power usage - must be able to run off batteries for a minimum of 7 days (max 10-14)
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.
Record said readings in a csv file for easy graphing
Record date/time stamp
Allow dump of data via a direct USB connection
Device can then be 'reset' and recirculated. (Ideally this should be achieved without needing to fire up the IDE)
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.
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?
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
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
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
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
Need to work out best and safest way to power this thing reliably for 6 days
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?
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
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: