Environment monitoring using Sparrow and ESP8266

Cocioaba Cristian Gabriel - SRIC


To make use of the low power of the IEEE 802.15.4 and the integration of the Wi-Fi, a hybrid network can be used, a heterogeneous WSN composed by both of this types of wireless networks but in which each node can transmit messages to any other node, regardless of its position and network type. In this way, all IEEE 802.15.4 nodes have access to the Internet.

For 802.15.4 network, we used Sparrow v4 board and for Wi-Fi, the ESP8266 module.


Hardware connection

To connect the two types of networks, there must be a direct link between the Coordinator from the Wi-Fi network and the Coordinator from the IEEE 802.15.4. This link can be implemented by a serial interface through UART.

Sparrow ESP8266
RX Pin 20 - MOSI GPIO14 TX
TX Pin 12 - MISO GPIO12 RX


For the purpose of monitoring environment parameters, it is only needed that each node to send data from its own sensors to the Internet or a Sink node (data aggregation node). In this way, sensor data travels in only one direction. For future need of configuring, or sending a specific message to the whole network or only one node, there should be very little to modify in implementation, the process just reversing the transmission direction and implement the handle action to that message.

WSN Protocol for ESP8266 is a lightweight protocol for creating a WSN over Wi-Fi with ESP8266 chips. It is a similar model to the CoAP protocol, but is based on IPv4 and UDP stack. The Coordinator is called a “Head node”, which can also act as a Router and the Device is called simply “Node”. It supports network discovery and auto-arranging nodes into star, tree and mesh networks. It extends the limitations of the Wi-Fi range by creating new access points for other nodes to connect and auto-redirect the messages from and into the subnets.

Serial data

Sensor data

struct sensor_data_t {
  uint32_t node_id;
  sensor_type_t sensor_type;
  sensor_value_t sensor_value;

Sensor value struct

union {
  sensor_temperature_t temperature;
  sensor_light_t light;
  sensor_battery_t battery;
} sensor_value_t;

Sensor types

enum sensor_type_t {

Gathering data

Temperature and humidity

struct sensor_temperature_t {
  float temperature;
  float humidity;


struct sensor_light_t {
  uint16_t UV;
  uint16_t visible;
  uint16_t IR;
  uint16_t proximity;


typedef float sensor_battery_t;


Software serial example on Sparrow

#include <SoftwareSerial.h>
#include <SHT2x.h>
#include "sensor_interface.h"
SoftwareSerial espSerial(MOSI, MISO); // RX, TX
void serial_write_packet(const sensor_packet_t* packet)
    espSerial.write((uint8_t*)packet, sizeof(sensor_packet_t));
sensor_temperature_t sensor_temperature_read()
	sensor_temperature_t sensorValue;
	sensorValue.humidity = SHT2x.GetHumidity();
	sensorValue.temperature = SHT2x.GetTemperature();
	return sensorValue;
void setup(){
    espSerial.begin(ESP_SERIAL_BAUND); // default 115200
void loop(){
    sensor_temperature_t temperature = sensor_temperature_read();
    packet.sensor_type = SENSOR_TEMPERATURE;
    packet.sensor_value.temperature = temperature;

ESP8266 solar energy harvesting

For creating a Wireless Sensor Network, all the nodes need to run for a long period of time. And, because they are usually deployed in a remote or hard to access area, they are required to be powered by batteries. Therefore, rises the need to efficiently use that limited battery power and to also recharge it over time, so that the network to be “always-on”.

Nodes power consumption

In a Wireless Sensor Network, nodes are typically equipped with power-constrained batteries, which are often difficult and expensive to be replaced once the nodes are deployed. Therefore, it is a critical consideration on reducing the power consumption in the network design. Energy in WSN nodes is consumed by the CPU, by sensors or actuators, and by radio, with the last consuming the most

Although both protocols operate at 2.4 GHz frequency, 802.15.4 is low-speed and low-rate and ATmega128RFA1 has Ultra Low Power consumption as we can see below.

ATmega128RFA1 power consumption

ESP8266 power consumption when radio is on

In contrast, ESP8266 has more processing power and together with the power required by the bandwidth and data rate of Wi-Fi, it utilizes almost 10 times more energy, as we can see below.

The ESP8266 microcontroller provides 3 configurable sleep modes, which can be configured as required by each application: • Modem-sleep • Light-sleep • Deep-sleep

ESP8266 measured power consumption

The first step for making a sustainable solution for a WSN was to measure the power consumption of the ESP8266 chip and see if the measurements align with the technical specifications.

For initial measurements, we load the ESP microcontroller with a program that starts in modem-sleep for 10 seconds, in which it turns on and off the build in LED, then connects to the Wi-Fi network and sends a HTTP POST request to a server with the value of its VCC voltage and at the end it enters deep-sleep for another 20 seconds.

As we can see in the figure below, the Wi-Fi radio switches on as soon as the ESP wakes up. The boot loader runs for about 0.35 seconds, after which it is deactivated when the “setup” function is run in the program and we force it to be off, thus entering modem-sleep. The next 3 to 10 seconds (in some of our cases) are spent connecting to the Wi-Fi access point and getting an IP. This may vary, depending on the router and DHCP traffic, taking about 3 seconds sometimes.

Next comes about 1.2 seconds of idle time, which, after some research, it is associated with the fact that Espressif SDK persists the connection information to flash memory.

The final power peak is the HTTP request, which varies between 90mA to 200mA.

The average current consumption for the ESP when running this test program in different states can be seen in the table below:

There were also peeks of power randomly occurring during data transmission, which varies from 100mA to even 300 mA. Either there was an error at the measurements, or the ESP needed to send a stronger signal. The maximum length of these peaks was around 0.05 seconds.

Estimating battery life for an ESP node

If the ESP runs in the default mode, it draws a current of approximately 75mA. And when running continuously, the total power consumptions is about 75mAh. We will further use the same battery capacity as a reference for comparing the power consumption of different modes, i.e. popular LiPo battery of 3800mAh. The above current consumption will drain the reference battery in around 50.6 hours, i.e. 2 days and 2 hours, considering an ideal battery.

In our test, the total power consumption for this test, considering the maximum wait time for the Wi-Fi connection of 10 seconds is:

0.35s * 80mA + 10s * 17mA + 10s * 75mA + 0.05s * 250mA ~= 0,285mAh per cycle

This is a total of 20.4 active seconds per cycle. In a real-life scenario, we will want to extend the deep-sleep period to minimum 5 minute for measuring an environment parameter, like temperature. This will add another 0.25mA * 300s = 75mAs = 0.02mAh to the total calculated above and will extend the cycle total period to 320 seconds, to a total of around 11 cycles per hour.

And so, the total amount of capacity needed is around 0.305mAh per cycle and a total of 3.355mAh. This consumption will last with the reference 3800 mAh battery for about 47 days.

This a good improvement over the previous consumption when running continuously, but it can still be improved.

Optimizing power consumption

The first thing a node should do is to read sensors data and then decide either to send the data or go back to sleep. In this case, we do not want the Wi-Fi radio to be on, without the need to use it.

The code to disable the Wi-Fi is the following:

WiFi.mode( WIFI_OFF );
delay( 1 );

Then, just before the call to establish the Wi-Fi connection, we turn the radio back on:

delay( 1 );
// Bring up the Wi-Fi connection
WiFi.mode( WIFI_STA );

At boot time, before we can disable the Wi-Fi radio, the ESP chip still turns it on, resulting in a sharp power peak. This default behavior can be changed by setting the WAKE_RF_DISABLED flag in ESP.deepSleep() call.

WiFi.disconnect( true );
delay( 1 );

This saves another 0.007mAh for each cycle, to a total of 0.077mAh.

Furthermore, disabling network persistence will save around 1.2 seconds on Wi-Fi connection initialization at 71mA, which in turn saves 0.023mAh.

Also, by setting a -static IP, the DHCP time will be reduced, but this will depend on each network. It most cases, the time was reduced to an average of 6 seconds. This will reduce another 4 seconds from the initial estimation. Which means another 0.083mAh.

As we can see in the figure below, the first peak was eliminated, and the connection time was reduced.

The total power consumption for a cycle is now down to:

10s * 17mA + 6s * 75mA + 0.05s * 250mA + 300s * 0.25mA ~= 0.197 mAh per cycle2.167 mAh

With this, the ESP chip will last with the reference 3800 mAh battery for about 73 days.

We must notice, that although the power peaks are not present in the figure above, during our tests, we observed multiple times that they happen to appear randomly, as seen in Figure 6. and that is the reason that we included them in the above calculation.

Also, the 10 seconds of modem-sleep we set in this test which operates at around 17 mA, can be reduced greatly in real-life scenario, when acquiring data from sensor, either digital ones through I2C interface or analog ones. The wait time for calibration depends on each sensor, but, for example, the DHT22 temperature sensor needs an average of 2 seconds to calibrate and be available for data read. This adds, of course, another consumer on the battery, but it is a low-power sensor, operating at 1mA or maximum 1.5 mA.

Keeping data after Deep-Sleep

When the ESP chip shuts down the CPU and after it wakes up, it runs the program from the userinit. This means that all the values stored in memory in a processing cycle are not available anymore, which is not very good for sensor value comparation and for message queues. For resolving this problem, we used the chip flash memory for storing important information before going to sleep. It can store files as text or binary data using the Arduino FS library implementation of ESP SDK.

void seput() {
  while (!Serial) continue;
  if (!SPIFFS.begin())
    Serial.println("Failed to mount file system");
bool loadDataRaw(const char* filename, Data& data){
  File dataFile = SPIFFS.open(filename, "r");
  if (!dataFile){
    Serial.println("Failed to open data file");
    return false;
  size_t size = dataFile.size();
  if (size != sizeof(Data)) {
    Serial.print("Data file size is too large. Found "); Serial.print(size); Serial.print(" expected "); Serial.println(sizeof(Data));
    Serial.println("Bad file was removed.");
    return false;
  char* buffer = new char[size];
  dataFile.readBytes(buffer, size);
  memcpy(&data, buffer, size);
  return true;
bool saveDataRaw(const char* filename, Data& data) {
  File dataFile = SPIFFS.open(filename, "w+");
  if (!dataFile) {
    Serial.println("Failed to open data file for writing");
    return false;
  size_t size = sizeof(Data);
  uint8_t* buffer = new uint8_t[size];
  memcpy(buffer, &data, size);
  const uint8_t* bufferToWrite = buffer;
  size_t sizeWritten = dataFile.write(bufferToWrite, size);
  if(sizeWritten != size) {
    Serial.println("Failed to save data file. Not enough bytes were written.");
    if(SPIFFS.exists(filename)) {
    return false;
  // Close the file (File's destructor doesn't close the file)
  return true;

Solar energy harvesting

We used a solar panel with the dimensions of 160x116x2.5(±0.2) mm. This, in theory, should provide a 2.5W power at 5V voltage when the Solar radiation is the most powerful.

When testing it, we observed that the solar panel was not giving a steady current and voltage, but instead both varied based on how much Solar radiation strikes the panel and the orientation of the panel. This means that it cannot safely charge the LiPo battery. To overcome this problem, we used the TP4056 regulator, which can charge a LiPo battery, in theory, at a steady voltage of 4.2 V and a 1A current

We then measured the battery charger output with both the battery and ESP chip connected and got a maximum of 420 mA at 4.12 V, meaning 1.73 W, and an average of around 300 mA at 4.12 V, meaning 1.236 W between 1pm and 6 pm (see below).

This will total to 950mAh, representing 3.9Wh for 14 hours per day. This represents an approximation of the power gained and stored in the battery, and at the same time running the ESP.

Considering the previous results of ESP power consumption of 2.167mAh at 3.3 V, representing around 0.0072Wh. This means that it will consume around 0.1Wh in the 14 hours of sunlight and 0.072Wh in the remaining 10 hours of night.

Regarding this, the solar panel can store in the battery approximately 3.8Wh in the time of the sunlight. The remaining 3.8Wh should allow the ESP chip to run for about 22 days without recharging.


For testing the theoretical results, we measured the voltage of the VCC voltage from the ESP. It was connected to a 3800mAh LiPo battery, which was charged from the solar panel.

We present in the figure below tree days of measurement, starting with a relatively low charged battery, at around 3.7 V.

The voltage increases at the first day sunrise, followed by a discharge at night. After that, we encountered a cloudy weather, followed by another sunny day, which kept the battery fully charged. Our test suggests that the theoretical results are correct and that the ESP can run on battery and harvest solar energy.


iothings/proiecte/2017/environment-monitoring.txt · Last modified: 2021/12/06 22:23 by dan.tudose
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0