Battery Powered Sensors

written by hek

The following tips will reduce the power consumption of your Arduino Sensor allowing it to run on batteries for a longer period of time.

Note: When programming using FTDI adapter on modified 3v3 Pro Minis with removed regulators. Make sure to supply a stable 3v3 power source to the VCC pin yourself.

  1. Use the 3.3V version Arduino Pro Mini with the lower CPU clock speed (8MHz)
  2. Sleep whenever possible by powering down the Arduino and radio. The sensor node can periodically wake up by either triggering a timer interrupt or by an attached sensor registering a reading on one of the Arduino interrupt enabled io-pins. Most of the MySensors example sketches implement sleep mode. When powered down, the CPU, DS18B20 temp sensor and radio consume (very roughly) 120 uA - which is similar to the self discharge rate of a battery.
  3. Disconnect the Arduino's power indicator LED by cutting the track between the LED and the resistor in series or simply desolder one of them. Saves about 1.5 mA
  4. Disconnect or desolder the 3.3 VDC regulator because it is not needed. Cut the Vout pin with a sharp fine wire cutter. See images to the right on how to locate regulator. Saves about 220 uA.
  5. Power the device with two AA batteries connected in series to the PCB. You can power 5 VDC sensors using an ultra low power step up converter (see the Buying Guide below). Power regulators will reduce the battery life due constant power consumption.

There were or are pro mini's, if you desolder the voltage regulator, the mentioned VCC hole is not connected anymore.

--> if you have a pro mini where this is the case, you can't use anymore the usb-to-ttl programmer like that because the pro mini won't be powered on anymore by the VCC of your programmer. You must connect the VCC pin of the programmer with a wire to the other VCC hole.

--> in the other case, like mine pro mini version, no problem, the VCC hole at the right is still connected.

Short video showing how to desolder LED and regulator:

Theoretical Battery Life

The battery life (for a hypothetical temperature sensor) can be calculated by determining the average current for the circuit, using the following general equation:

Iavg = (t0*I0 + t1*I1 ... + tx*Ix) / (t0 + t1 ... + tx)

Note these figures are for illustration purposes - your results will certainly vary. Current is measured at the battery with a battery Voltage of 3.0V.

Idling: I0 = 28 mA, t0 = 0.65 sec (using the delays I set up in the sketch) Transmitting: I1 = 31 mA, t1 = say 50 mSec (time is just a guess) Sleeping: I2 = 120 uA (very roughly), t2 = 15 minutes (the temperature sampling rate)

Using the above figures the effective current = 0.142 mA. The sleep current is difficult to measure accurately, so this figure may vary and will affect the lifetime calculation.

Assume the batteries are good for 2000 mAhr, that gives a lifetime of 14,101 hours, which equals to 19.6 months. The lifetime is dominated by the sleep current and sensor sample rate. Assuming the figures and calculations are correct (let us know if they aren't), it's likely the batteries would die from old age rather than through actual usage.

Boost your batteries

The Arduino 3.3V 8mhz can handle down to roughly 2.8V and the Nrf24l01+ down to 1.9V.

To be able to suck as much juice out of the batteries as possible you can use a DC-DC Step up booster. This booster will convert everything from 0.8V back to 3.3V. Note that a booster can be a bit noisy (and disturb the radio). The booster is also less than 100% efficient, so boosting can be less efficient than just powering the Arduino directly from the batteries and change batteries when they hit 2.8V.

It can help to connect a 0,1uF ceramic capacitor from GND to VOut. To avoid noise to the radio (NRF24l01+) you can power it directly from the batteries since it can operate down to 1.9V and only power the Arduino through the booster.

Measuring and Reporting Battery Level

There are two main strategies for measuring battery voltage. The internal measurement can only be used when the Arduino is powered directly from batteries. The external measurement needs additional components (2 resistors) and uses one of the Arduino's analog pins. The external measurement can be used for boosted nodes as well as nodes powered directly from batteries.

Internal measurement

Example code:

/*
   The MySensors Arduino library handles the wireless radio link and protocol
   between your home built sensors/actuators and HA controller of choice.
   The sensors forms a self healing radio network with optional repeaters. Each
   repeater and gateway builds a routing tables in EEPROM which keeps track of the
   network topology allowing messages to be routed to nodes.

   Created by Henrik Ekblad <[email protected]>
   Copyright (C) 2013-2022 Sensnology AB
   Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors

   Documentation: http://www.mysensors.org
   Support Forum: http://forum.mysensors.org

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   version 2 as published by the Free Software Foundation.

 *******************************

   DESCRIPTION

   This is an example that demonstrates how to report the battery level for a sensor
   using the internal measurement method.
   Instructions for measuring battery capacity are available here:
   http://www.mysensors.org/build/battery

*/

// Enable debug prints to serial monitor
#define MY_DEBUG

// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95

#include <MySensors.h>

uint32_t SLEEP_TIME = 900000;  // sleep time between reads (seconds * 1000 milliseconds)
int oldBatteryPcnt = 0;
#define FULL_BATTERY 3 // 3V for 2xAA alkaline. Adjust if you use a different battery setup.

void setup()
{
}

void presentation()
{
    // Send the sketch version information to the gateway and Controller
    sendSketchInfo("Battery Meter", "1.0");
}

void loop()
{
    // get the battery Voltage
    long batteryMillivolts = hwCPUVoltage();
    int batteryPcnt = batteryMillivolts / FULL_BATTERY / 1000.0 * 100 + 0.5;
#ifdef MY_DEBUG
    Serial.print("Battery voltage: ");
    Serial.print(batteryMillivolts / 1000.0);
    Serial.println("V");
    Serial.print("Battery percent: ");
    Serial.print(batteryPcnt);
    Serial.println(" %");
#endif

    if (oldBatteryPcnt != batteryPcnt) {
        sendBatteryLevel(batteryPcnt);
        oldBatteryPcnt = batteryPcnt;
    }
    sleep(SLEEP_TIME);
}

External measurement

Use a 1MΩ (R1) and 470KΩ (R2) resistor in series, connected to the positive terminal on the battery and ground and then connected the tap point to the A0 input on the CPU.

The tap point could be bypassed with a 0.1 uF capacitor (connected in parallel with R2) to keep the noise level low, at this otherwise high impedance point.

The ADC is set to use the internal reference value of 1.1V - so Vmax at ADCmax = 1.1*(16+4703)/4703 = 3.44V

The battery power value must be converted to a percentage compatible with your Controller.

See the following example on how to measure battery level on A0 and report it to the Controller.

/mysensors/MySensors/examples/BatteryPoweredSensor/BatteryPoweredSensor.ino
Last updated by tekka007, 24 Jul 2022, "Upate CI and HW defs (#1530)"
/*
 * The MySensors Arduino library handles the wireless radio link and protocol
 * between your home built sensors/actuators and HA controller of choice.
 * The sensors forms a self healing radio network with optional repeaters. Each
 * repeater and gateway builds a routing tables in EEPROM which keeps track of the
 * network topology allowing messages to be routed to nodes.
 *
 * Created by Henrik Ekblad <[email protected]>
 * Copyright (C) 2013-2019 Sensnology AB
 * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
 *
 * Documentation: http://www.mysensors.org
 * Support Forum: http://forum.mysensors.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 *******************************
 *
 * DESCRIPTION
 *
 * This is an example that demonstrates how to report the battery level for a sensor
 * Instructions for measuring battery capacity on A0 are available here:
 * http://www.mysensors.org/build/battery
 *
 */



// Enable debug prints to serial monitor
#define MY_DEBUG

// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95

#include <MySensors.h>

int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point

uint32_t SLEEP_TIME = 900000;  // sleep time between reads (seconds * 1000 milliseconds)
int oldBatteryPcnt = 0;

void setup()
{
    // use the 1.1 V internal reference
#if defined(__AVR_ATmega2560__)
    analogReference(INTERNAL1V1);
#else
    analogReference(INTERNAL);
#endif
}

void presentation()
{
    // Send the sketch version information to the gateway and Controller
    sendSketchInfo("Battery Meter", "1.0");
}

void loop()
{
    // get the battery Voltage
    int sensorValue = analogRead(BATTERY_SENSE_PIN);
#ifdef MY_DEBUG
    Serial.println(sensorValue);
#endif

    // 1M, 470K divider across battery and using internal ADC ref of 1.1V
    // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
    // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
    // 3.44/1023 = Volts per bit = 0.003363075

    int batteryPcnt = sensorValue / 10;

#ifdef MY_DEBUG
    float batteryV  = sensorValue * 0.003363075;
    Serial.print("Battery Voltage: ");
    Serial.print(batteryV);
    Serial.println(" V");

    Serial.print("Battery percent: ");
    Serial.print(batteryPcnt);
    Serial.println(" %");
#endif

    if (oldBatteryPcnt != batteryPcnt) {
        // Power up radio after sleep
        sendBatteryLevel(batteryPcnt);
        oldBatteryPcnt = batteryPcnt;
    }
    sleep(SLEEP_TIME);
}

Radio Power consumption

Measured using nRF24 Doctor v1.2 (ref https://forum.mysensors.org/topic/9178/nrf24doctor), nRF24 Doctor and gateway located next to each other.

Radio Module Tx Min/Max [mA] Rx [mA] Sleep [uA] Link
nRF24L01+ EByte E01-ML01D 6.5 / 11.7 11.8 0.75 https://www.aliexpress.com/item/32803704874.html
nRF24L01+ Nordic nRF24L01+-REFMOD (PCB antenna/HC49 crystal) 7.0 / 11.7 12.2 0.98 end-of-life
nRF24L01+ No-name, No-ack ok 6.8 / 11.7 12.0 0.94 unknown
nRF24L01+ No-name, No-ack inverted 11.6 / 21.5 13.7 1.85 unknown
nRF24L01+ No-name, SMD castellated 11.7 / 23.9 13.7 2.02 https://www.aliexpress.com/item/32642004648.html (likely)
nRF24L01+ PA+LNA EByte E01-ML01DP5 32.7 / 135.0 19.3 0.75 https://www.aliexpress.com/item/32638720689.html
nRF24L01+ PA+LNA No-name 37.1 / 177.1 13.7 1.16 unknown

Battery self-discharge

MySensors nodes can run for many years of battery. But some battery types have a high self-discharge; so high that the self-discharge is the dominating factor. Therefore, as a general rule, do not use rechargeable batteries for any node where you want long battery life.

As an example, Ni-MH batteries often have a self-discharge of ~30% per month. Li-ion batteries are better, but still self-discharge at 2-4% per month. Self-discharge rate varies depending on which chemistry the battery is based on. See wikipedia for a list.

More information

https://forum.mysensors.org/topic/2067/my-slim-2aa-battery-node

Images

Shopping Guide

10pcs Arduino Pro Mini Compatible 3.3V
10 is cheaper!
undefined   Buy
undefined   Buy
3V AA Battery holder
For powering 3.3V Arduino.
Unavailable   Buy
undefined   Buy
Arduino Pro Mini Compatible 3.3V
If you are planning to build a battery-powered sensors, the 3.3v pro mini is a good choice. You won't need a regulator for the radio when using this version. Make sure your attached sensors also can run on 3.3V or buy a step-up regulator
Unavailable   Buy
undefined   Buy
DC-DC Step Up Boost Module 3v3
Input 0.8-3.3V, Output 3.3V. Sucks the juice out of your batteries.
Unavailable   Buy
undefined   Buy
DC-DC Step Up Boost Module 5V
Input 1-3V , Output 5V. Use this if you need to power 5V sensors from a 3.3V Arduino Pro Mini
Unavailable   Buy
undefined   Buy

Gateways

Sensors & Actuators

Related Content

Comments