Battery powered ESP8266 sensor

The ESP8266 is a powerful and inexpensive device. There is almost no need anymore to use proprietary RF protocols like the nRF24 chip that was popular some years ago. However, there is one major problem when using WLAN: power consumption.

When connected to a WLAN, the ESP8266 consumes at least 80mA – sometimes even more. If you use 3 2400mAh that means, they will be empty in a bit more than a day. This doesn’t sound like a good deal.

Luckily, for sensor applications, you don’t have to be connected to the LAN the whole time. You don’t even have to have the ESP itself running. To save as much power as possible, you have to do the following:

  1. Collect your data. If this takes time, do it before connecting to WLAN. If it takes just a few millesconds, it doesn’t matter much.
  2. Connect to WLAN.
  3. Send data.
  4. Go to deep sleep mode. You use the ESP.deepSleep() method for this.

You have to look at a few things when using the ESP.deepSleep() method:

  1. To wake up after sleeping, GPIO16 of the ESP8266 has to be connected to RESET. Otherwise the device won’t wake up again.
  2. The delay parameter is defined in microseconds (not seconds or milliseconds). If it looks like your device isn’t sleeping at all, you might have used a value that is too small (you won’t even notice if the device sleeps for 3600 microseconds)
  3. There is a second parameter that can have the values WAKE_RF_DEFAULT, WAKE_RFCAL,WAKE_NO_RFCAL, WAKE_RF_DISABLED. The WAKE_RF_DISABLED looks good, but beware to use it. Using this does not mean that the RF subsystem is disabled during sleep (it always is), but that it is disabled when waking up again. Your ESP8266 won’t be able to do any network communication anymore.

A few other tips to save energy:

  1. Do not turn on LEDs for a longer time. Flashing them a few milliseconds is usually a good visual feedback and will consume only a tiny bit of energy.
  2. If you need to have LEDs on for a longer time, dimm them. analogWrite is your friend for this.

Check out this sample code. It uses WiFiManager which helps to connect to configure your WLAN SSID/password and even the name/IP address of the MQTT broker.

#include         // Generic ESP8266 WiFi routines
#include        // MQTT client
#include           // Local DNS Server used for redirecting all requests to the configuration portal
#include    // Local WebServer used to serve the configuration portal
#include         // WiFi Configuration Magic


const char* mqtt_server = "192.168.1.88";
const char* mqtt_channel_up = "active";
const char* mqtt_channel_data = "sensor/%d/adc";

const int pin_red = 15;
const int pin_green = 12;
const int pin_blue = 13;
const int pin_button = 4;
const int analog_ldr = 0;

const int sleepSeconds = 60 * 15;

WiFiManager wifiManager;
WiFiClient espClient;
PubSubClient client(espClient);


void send_sensor_data(void) {
  Serial.println("Sending sensor data\n");
  int data = analogRead(A0);
  char s_channel[50];
  char s_id[10];
  char s_data[10];
  sprintf(s_channel, mqtt_channel_data, ESP.getChipId());
  sprintf(s_id, "%d", ESP.getChipId());
  sprintf(s_data, "%d", data);

  digitalWrite(pin_blue, HIGH);
  client.connect("ESP8266Client");
  digitalWrite(pin_blue, LOW);
  if (! client.connected()) {
    Serial.println("Could not connect to MQTT broker, doing nothing");
  } else {
    digitalWrite(pin_green, HIGH);
    client.publish(mqtt_channel_up, s_id); // show that this device is up
    client.publish(s_channel, s_data); // send sensor data
    digitalWrite(pin_green, LOW);
  }
}

void setup() {
  delay(500); // This makes it easier to upload new firmware and/or press the "clean" button

  pinMode(pin_red, OUTPUT);
  pinMode(pin_green, OUTPUT);
  pinMode(pin_blue, OUTPUT);

  digitalWrite(pin_red, HIGH);

  // Setup Serial interface for debugging
  Serial.begin(115200);

  //  Bring up WLAN
  WiFiManager wifiManager;

  //sets timeout until configuration portal gets turned off
  //useful to make it all retry or go to sleep
  //in seconds
  wifiManager.setTimeout(60);

  WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);
  wifiManager.addParameter(&custom_mqtt_server);

  if (digitalRead(pin_button) == 0) {
    // reset settings
    wifiManager.resetSettings();
  }

  //fetches ssid and pass and tries to connect
  //if it does not connect it starts an access point with the specified name
  //here  "AutoConnectAP"
  //and goes into a blocking loop awaiting configuration
  if (!wifiManager.autoConnect()) {
    Serial.println("failed to connect and hit timeout");
    delay(100);
    // do nothing: deep sleep, but longer than usual. Something might be wrong and
    // we should save power
    ESP.deepSleep(sleepSeconds * 10 * 1000000, WAKE_RF_DISABLED);
  }

  mqtt_server = custom_mqtt_server.getValue();

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // Setup MQTT client
  client.setServer(mqtt_server, 1883);

  digitalWrite(pin_red, LOW);
}

void loop(void) {
  send_sensor_data();
  Serial.printf("Sleeping deep for %i seconds...", sleepSeconds);
  ESP.deepSleep(sleepSeconds * 1000000);
  delay(100);
}

Is wireless the future?

Looking at new companies in the home automation industry it looks like many of them prefer some kind of radio frequency data transmission. This makes sense as customers don’t want to have additional cables in their home. But is this really the future of home automation? I’m not sure. Here are some arguments against wireless control:

  1. Reliability: with more and more devices communicating wireless, interoperability problems can become more and more problematic.
  2. Power supply: with some exceptions (e.g. EnOcean), even wireless devices need a power supply. This mean either cabling or batteries that need to be changed regularly
  3. Security: Wireless devices are easier to attack than wired devices (at least if these are not connected to a public network).

Especially the security aspect is important in my point of view. Many home automation devices will be used for 10-50 years. While it might be reasonable to buy a new music player every 5 years, you don’t want to change your wall switches every 10 years. The development of encryption algorithms has shown that no algorithm is secure forever. This means the software has to be updated from time to time. Newer encryption algorithms might even need more powerful hardware. Do you believe your supplier will provide software updates for the devices during the next 20 years?