Projects / Low power
Long-Life Barometer Logger
Logs pressure and temperature for months on three AA batteries.
Overview
Deep sleep on an ESP32 still draws tens of microamps, and that's before the regulators and sensors. This logger removes power completely: the ET-P19 TPL5110 timer (35 nA) switches the ET-M01 and its sensors on, the sketch takes one reading, writes it to the ET-A14 FRAM, and signals “done” — and the power is cut again.
The ET-P17 nano-power LDO (25 nA) gives a clean 3.3 V from three AA cells. FRAM keeps data without power and survives a trillion writes, so the log is safe even if the batteries run out. Read it later over USB.
- Average current in the microamp range
- Pressure (hPa) and temperature per sample
- 8,000+ samples in 32 KB of FRAM
- Log survives flat batteries
What you need
ElectroTrical boards
You'll also need
- 3 × AA battery holder (4.5 V)
- 2 Qwiic cables
- A jumper wire for dump mode
- Small enclosure with a vent hole for the barometer
Wiring
The sample interval is set by resistor R1 on the ET-P19 (see its product page; TI's table gives about 57.6 kΩ for 10 minutes). Disconnect the batteries before plugging in USB to read the log.
Power
| From | To | Note |
|---|---|---|
| Battery + | ET-P17 VIN | 3.5–6 V |
| Battery − | ET-P17 GND | |
| ET-P17 3V3 | ET-P19 VIN | Always on |
| ET-P19 VOUT | ET-M01 3V3 | Switched 3.3 V for the MCU and sensors |
| ET-P17 GND | ET-P19 GND / ET-M01 GND |
Control and dump jumper
| From | To | Note |
|---|---|---|
| ET-M01 IO4 | ET-P19 DONE | High = finished, cut power |
| ET-M01 IO5 | GND only when dumping | Leave open for normal logging |
Qwiic chain
| From | To | Note |
|---|---|---|
| ET-M01 Qwiic | ET-S68 Qwiic | LPS22HB at 0x5D |
| ET-S68 Qwiic | ET-A14 Qwiic | FRAM at 0x50 |
Build it
- 01
Set up the Arduino IDE
Install the Espressif ESP32 package, select “ESP32C3 Dev Module” and set USB CDC On Boot to Enabled. No extra libraries are needed.
- 02
Upload over USB
Upload the sketch with only USB connected (no batteries). Open Serial Monitor: each reset logs one sample.
- 03
Clear the log
Connect IO5 to GND, press reset and type x to erase. Remove the jumper.
- 04
Wire the power stage
Unplug USB and wire the batteries, ET-P17 and ET-P19 as in the tables. The ET-M01 now powers up once per interval for less than half a second.
- 05
Read the log
Remove the batteries, connect IO5 to GND, plug in USB and type d. Paste the CSV into a spreadsheet; row number × interval gives the time.
Arduino code
Written for the ET-M01 ESP32-C3 Mini Dev Board. No extra libraries are needed.
#include <Wire.h>
const int DONE_PIN = 4, DUMP_PIN = 5;
const uint8_t LPS = 0x5D, FRAM = 0x50;
const uint16_t REC_SIZE = 4, DATA_START = 4, MAX_RECS = (32768 - DATA_START) / REC_SIZE;
void reg8(uint8_t addr, uint8_t reg, uint8_t val) {
Wire.beginTransmission(addr); Wire.write(reg); Wire.write(val); Wire.endTransmission();
}
void readBytes(uint8_t addr, uint8_t reg, uint8_t* d, int n) {
Wire.beginTransmission(addr); Wire.write(reg); Wire.endTransmission(false);
Wire.requestFrom(addr, (uint8_t)n);
for (int i = 0; i < n; i++) d[i] = Wire.read();
}
void framWrite(uint16_t a, const uint8_t* d, int n) {
Wire.beginTransmission(FRAM); Wire.write(a >> 8); Wire.write(a & 0xFF); Wire.write(d, n); Wire.endTransmission();
}
void framRead(uint16_t a, uint8_t* d, int n) {
Wire.beginTransmission(FRAM); Wire.write(a >> 8); Wire.write(a & 0xFF); Wire.endTransmission(false);
Wire.requestFrom(FRAM, (uint8_t)n);
for (int i = 0; i < n; i++) d[i] = Wire.read();
}
uint32_t getCount() { uint32_t c; framRead(0, (uint8_t*)&c, 4); return c > MAX_RECS ? 0 : c; }
void setCount(uint32_t c) { framWrite(0, (uint8_t*)&c, 4); }
bool measure(float& hPa, float& tC) {
reg8(LPS, 0x10, 0x02); // CTRL_REG1: one-shot mode, block data update
reg8(LPS, 0x11, 0x11); // CTRL_REG2: auto-increment + start one-shot
for (int i = 0; i < 50; i++) { // wait for pressure ready (max ~50 ms)
uint8_t st; readBytes(LPS, 0x27, &st, 1);
if (st & 0x01) {
uint8_t d[5]; readBytes(LPS, 0x28, d, 5);
int32_t p = (int32_t)d[0] | ((int32_t)d[1] << 8) | ((int32_t)d[2] << 16);
hPa = p / 4096.0;
tC = (int16_t)(d[3] | (d[4] << 8)) / 100.0;
return true;
}
delay(1);
}
return false;
}
void setup() {
pinMode(DONE_PIN, OUTPUT);
digitalWrite(DONE_PIN, LOW);
pinMode(DUMP_PIN, INPUT_PULLUP);
Wire.begin(6, 7);
if (digitalRead(DUMP_PIN) == LOW) { // dump mode: stay awake for commands
Serial.begin(115200);
delay(1500);
Serial.println("Dump mode. d = print CSV, x = erase");
return;
}
float hPa, tC;
uint32_t n = getCount();
if (n < MAX_RECS && measure(hPa, tC)) {
uint16_t rec[2] = { (uint16_t)(hPa * 10), (uint16_t)(int16_t)(tC * 100) };
framWrite(DATA_START + n * REC_SIZE, (uint8_t*)rec, REC_SIZE);
setCount(n + 1);
}
digitalWrite(DONE_PIN, HIGH); // TPL5110 cuts the power here
delay(100);
}
void loop() {
if (digitalRead(DUMP_PIN) != LOW || !Serial.available()) return;
char c = Serial.read();
if (c == 'x') { setCount(0); Serial.println("Erased"); }
if (c == 'd') {
uint32_t n = getCount();
Serial.println("sample,pressure_hpa,temperature_c");
for (uint32_t i = 0; i < n; i++) {
uint16_t rec[2];
framRead(DATA_START + i * REC_SIZE, (uint8_t*)rec, REC_SIZE);
Serial.printf("%lu,%.1f,%.2f\n", (unsigned long)i, rec[0] / 10.0, (int16_t)rec[1] / 100.0);
}
}
}
Troubleshooting
Batteries drain fast
Check the ET-M01 is powered only from ET-P19 VOUT (not from ET-P17 directly) and that IO4 reaches DONE. If DONE never goes high, the TPL5110 keeps power on until its next period.
Log is empty
Make sure the dump jumper (IO5 to GND) is removed while logging — in dump mode nothing is recorded.
Pressure reads 0
Check the LPS22HB address: 0x5D by default, 0x5C if its address jumper is changed.
Take it further
- Add the ET-A12 PCF8563 RTC to timestamp each sample
- Add humidity with the ET-S70 SHTC3
- Send a daily summary by LoRa with the ET-C15
Turning this into a product?
We design custom boards that combine these sensors on one PCB, with firmware and production.