Introduction: Meteorino: Extend Battery Life on NodeMCU? Just Switch It Off.

Meteorino is just a simple stand-alone, unmanned, temperature/humidity reporting system. But I would like to share with you all my designing/developing/constructing experience as I am sure I have faced with problems everyone has when trying to set up a generic WiFi sensor meter that should work uninterruptedly 24/7.

The results can easily be inherited by any similar project (with NodeMCU or equivalent) when a microcontroller is needed to send data over WiFi during discrete and short intervals per hour.

Step 1: Parts and Components

  • Microcontroller NodeMCU
  • DHT22 sensor
  • TPL-5110 timer
  • Switch
  • Capacitors and resistors as reported in the schematics
  • 3xAA alkaline batteries
  • Enclosure case

Step 2: The Problem

I was in the need to continuously monitor external or indoor temperature/humidity and other related physical quantities (heat index, dew point, battery level) in any place, not counting on an AC electric socket. In this scenario, battery life was an high priority issue and of course the first approach I have dealt with was DeepSleep capability of ESP8266 (which is embedded in NodeMCU).

I was largely disappointed when I first measured NodeMCU's power consumption in DeepSleep: several tenths of milliAmperes! Main part of that power was used to keep alive the UART, the voltage regulator and the RTC. I couldn't get rid of the voltage regultaor, as I was thinking to power the microcontroller through the VIN pin; on the other hand, removing the UART from the circuit could have been a dangerous issue (due to the small size of the components) and I would have preferred to leave the UART functionality on the circuit, in order to eventually update the sketch without problems.

Ultimately, I considered that I needed the NodeMCU working only for few seconds (the time to send data to WiFi, 8 seconds) each 30 minutes: why keeping everything powered forever if I only need it alive for 0.4% of the time (see my Power Cycle drawing)? Here it came the solution.

Step 3: The Solution

With that kind of power cycle (few seconds per hour) I decided not to pursue the DeepSleep way anymore, but to SWITCH OFF the circuit. So, I was in the need to build a timer circuit, extremely low-power, able to switch on the NodeMCU, wait for a DONE signal and then switch it off for 30 minutes. While I was trying to reinvent the wheel, I jumped upon the Texas Instruments TPL5110: a low power timer with an integrated MOSFET driver ideal for power gating in duty cycled or battery powered applications, consuming only 35nA (yes, those are nanoAmperes!).

The TPL5110 provides selectable timing intervals from 100ms to 7200s and is designed for power gating applications. The Adafruit's breakout board for this components has a led and a trimmer on it, which I have disabled by cutting the two PCB lines on the back. The time interval is set by a resistor (see tables in the specifications datasheet): I chose a parallel of 2 resistors (100kΩand 1MΩ), which gave me around 29.5 minutes of delay. Once the NodeMCU has finished its cycle, it sends a HIGH signal on the DONE pin of TPL-5110, so to inform it to switch off the power and start counting for 30 minutes.

One issue made me crazy for a week before finding a solution: it seems that TPL-5110 doesn't like the high current spikes that ESP8266 injects on the power line upon switching on, and it falls into an undetermined state. The first tests don't work and I was about to abandon this solution as the timer was not supplying the right voltage to the circuit. Then, one day, I connected 2 capacitors: a 2,220µf directly on the battery and a 47µF on TPL-5110 DRV pin. Gotcha! Things started working as they should have, and Meteorino is proudly doing its job since several months.

Step 4: Batteries and Voltage Reading

With the TPL-5110 solution, the system is consuming 80mA for 8 seconds each 30 minutes, and 35nA during the remaining time. The calculations bring to an average current of 350µA, and with these numbers I decided to use 3xAA alkaline batteries (4.5 v or more at full charge) connected to VIN pin of NodeMCU. Considering that at those current rates the microcontroller can operate down to 3.3-3.4 volts, batteries life could reach more than 2 months of continuous operations. I tested several alkaline batteries, and the best choice for me was Duracell Plus Power or Energizer Max. I recommend not to use cheap alkaline batteries, otherwise the life duration can drastically change.

I have also built another Meteorino with a LiFePo4 3.2 cell, connected to the 3V3 pin: that battery is still working at 3.1 volts after 4 months!

Then I came to the battery reading issue. As NodeMCU has an internal ADC available through the A0 pin, I followed the suggestions found on this article; I calculated the calibration LSB number and hard coded it in the sketch. This solution is giving me an acceptable precision on reading (+/- 3mV), so I can check batteries from the cloud, together with the environmental data.

float LSB = 0.0066666667;

Step 5: The Sensor

The sensor is a DHT22 (more reliable than its brother DHT11). Using NodeMCU, do NOT include the standard DHT sensor library, but use DHTesp by Mark Ruys. None of the DHT libraries I found were written to work without errors on the ESP32. For ESP32 (a multi core/ multi processing SOC) task switching must be disabled while reading data from the sensor.

Step 6: Data Report: ThingSpeak

In order to have a constant and historical data report, I used ThingSpeak. It is a free web service that lets you collect and store sensor data in the cloud and develop IoT applications. The ThingSpeak web service provides apps that let you analyze and visualize your data on the browser or on any smartphone.

I will not give instructions on how to enroll and start a channel on ThingSpeak, as it is really trivial. Just point your browser here:

Step 7: Notifications: IFTTT

As Meteorino is working 24/7 from its place (that could be indoor or outdoor), I thought it was nice to have a notification if something went wrong. For this purpose, I used 3 IFTTT webhook services to send me an email when:

  • data read from DHT22 is not valid;
  • sending data to ThingSpeak fails;
  • low battery level

Write your IFTTT API key into the user_config.h file and customize this applet to your needs.

Step 8: Schematics

Step 9: Code

We need to run the device, connect to the WiFi AP, read the sensor, transmit data to ThingSpeak and switch off NodeMCU. So, the sketch run each time the setup and never reaches the loop function.

To reduce WiFi connection time, I assigned a static IP to Meteorino (I suggest not to use DHCP,as it will use more battery power). The flowchart is quite self-explanatory: the WiFi connection has a MAX_RETRY constant and if it fails, the device is switched off for a cycle. At the end of the operations, NodeMCU sets D1 to HIGH in order to trigger the off-cycle of TPL-5110.

There are variables you need to set in user_config.h, to fit to your needs:

  • IP address and LAN settings;
  • WiFi SSID and password
  • ThingSpeak write API key and channel number
  • IFTTT API key

To ensure triggering of TPL-5110, I put it into a while(1) loop: it doesn't hurt, as if two or more DONE signals are received within the time interval, only the first DONE signal is processed.

// toggle DONE so TPL knows to cut power!
while (1) { digitalWrite(DONEPIN, HIGH); delay(1); digitalWrite(DONEPIN, LOW); delay(1); }

Step 10: Enclosure Case

For the case I used a round electrical junction box. It is easy to open and everything fits right in. Meteorino can also be placed in the outside, but do not expose it to direct rain: the box is waterproof but the DHT22 sensor is not.

Step 11: Image Gallery