Low Power Environmental Monitoring System

Author: Costea Ciprian Marian

Master: AAC2

1. Project Objective

The purpose of this project is to develop a low power, portable weather station module, powered by solar energy. This module will be registered in the WeatherUnderground IBM Cloud platform where the queried sensor data can be observed. The module is based on a ESP32 platform, interfaced with a BME280 sensor capable of monitoring the environmental temperature, humidity and atmospheric pressure. Additionally, if needed, this data will also be able to be sent through the Firebase service for better visibility or debugging purposes.

2. Hardware Bill of Materials

  • ESP32-NODEMCU
    • Central processing unit, used to implement the software architecture of the project by switching between power (operational) modes, connecting to WiFi, querying BME280 sensor data, initializing and sending data to the Firebase server (optional) and sending data by HTTP requests to the WeatherUnderground server.

 ESP32 NodeMCU Board

  • BME280 Sensor Module
    • Used to get environmental information with respect to temperature, atmospheric pressure and humidity.

 BME280 Sensor Module

  • TP4056 Lithium Battery Charger
    • Used to charge up the Li-Ion battery from the two parallel connected solar panels.

 TP4056 Lithium Battery Charger Module

  • Lithium Li-Ion battery 18650
  • Battery Case/Holder
  • LDO Voltage Regulator TO92, TEXAS INSTRUMENTS - LP2950CZ-3.3/NOPB
    • Used to drop the voltage supplied form the Li-Ion battery in order to power up the ESP32 board through the 3.3V pin.
  • 2 Solar Panels – 5.5V
  • Breadboard
  • Jumper Wires

3. Hardware Description and Implementation

The hardware schematics and wiring can be observed in the following image developed in Kicad

 Hardware schematic of the project

The ESP32 board is being powered through its 3.3V pin and the communication with the BME280 sensor is realized through the I2C protocol (SCL and SDA pins). With respect to the power input part of the hardware, the two solar panels connected in parallel are charging up the Lithium Li-Ion battery, through the TP4056 Lithium Battery Charger.

The real physical implementation can be observed in the image below:

 Physical implementation of the project

The blue LED light of the ESP32 board indicates that the platform is in the processing state (Active Mode), has a valid WiFi connection and is querying/sending sensor data. Otherwise, the board is in the Hibernate State (Low Power consumption mode). Additionally, the red light from the TP4056 Lithium Battery Charger indicates that the Li-Ion battery is currently charging.

4. Software Architecture

The following flowchart of the software architecture shows the states and transitions which the application will execute. Note that primarily the software will send queried data to “wunderground” server and optionally to Firebase, based on the value set for a specific flag.
With respect to WiFi setup, if the ESP32 board cannot establish the connection in under 20 seconds the software logic will reset the platform in order to avoid any unconditional hangs, resuming its bloc logic execution from the very beginning.

 Software State Machine (Flowchart) of the project

One key aspect in the software architecture is that the 'loop' method, common to an Arduino project, will never be called because we enter a Hibernation state after each processing and transmission of the sensor queried data (performed in the 'setup' routine).

Regarding the transition to a low power consumption mode, the ESP32 platform supports 5 operational power modes:

  • Active mode (Normal Mode) – 160~260mA
    • All the features of the chip are active
  • Modem Sleep mode – 3~20mA
    • All the features of the chip remain active, except WiFi, Bluetooth and radio
  • Light Sleep mode – ~0.8mA
    • Same as “Modem Sleep mode”, except most of the peripherals, RAM and CPU are clock-gated
  • Deep Sleep mode – ~10uA
    • Most of peripherals, CPUs, RAM are powered off
    • Only the ULP Coprocessor, RTC Controller, RTC Peripherals and RTC fast and slow memory remain active
  • Hibernation mode – ~2.5uA
    • Only one RTC Timer and some RTC GPIOs remain active. Everything else is turned off.

For this project we chose the Hibernation Mode, which only keeps alive the RTC timer and some RTC GPIOs used for waking the platform up. In this mode the advertised power consumption is around ~2.5uA. The ESP32 core, WiFi, Bluetooth and other Peripherals will be inactive. In order to transition to Hibernation Mode, the following code snippet is used, in the setup routine. Note that in addition to setting up Deep Sleep for ESP32, we force RTC peripherals and RTC memories to powerdown in order to achieve Hibernation mode status.

#define TIME_TO_SLEEP  7        /* Time ESP32 will be in sleep state -- hibernation (in seconds) */
#define uS_TO_S_FACTOR 1000000  /* Conversion factor for micro seconds to seconds */
 
// configure wakeup source as the RTC Timer
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
 
// force specific powerdown modes for RTC peripherals and RTC memories
esp_sleep_pd_config(ESP_PD_DOMAIN_MAX, ESP_PD_OPTION_OFF);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_OFF);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_OFF);
 
// Enter Hibernation mode
esp_deep_sleep_start();

Sending the queried sensor data to the “wunderground” server is achieved by using HTTP requests as it can be observed in the following code snippet, along with the construction of the HTTP GET request.

String constructHttpGET(float temp, float humidity, float pressure) {
  String url = "https://weatherstation.wunderground.com/weatherstation/updateweatherstation.php?ID=<your_device_id>&PASSWORD=<your_device_passwd>&dateutc=now";
  float tempf;
 
  // Convert temperature to Fahrenheit from Celsius
  tempf = (temp * 1.8) + 32;
  url += "&tempf=" + String(tempf);
  url += "&humidity=" + String(humidity);
 
  pressure *= 0.0296;  // metric to US
  url += "&baromin=" + String(pressure);
  url += "&action=updateraw";
 
  return url;
}
 
void wundergroundSendData(float temp, float humidity, float pressure) {
  HTTPClient httpClient;
  String urlSend;
 
  // Send Data to WunderGround Server
  urlSend = constructHttpGET(temp, humidity, pressure);
  Serial.println("URL to send: " + urlSend);
 
  httpClient.begin(urlSend.c_str());
  Serial.println("Connected to  wunderground server");
  int httpResponseCode = httpClient.GET();
 
  if (httpResponseCode > 0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
  } else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  httpClient.end();
}

5. Results & Challenges

As it can be seen in the following images from the WeatherUnderground, under the page related to the registered device (in this case – IBUCHA284), the periodically queried BME280 sensor data is being received and displayed.

 Wunderground project data table  Wunderground queried data statistics

Among the challenges I've encountered while developing this project, sometimes, when powering the board, the voltage supplied would drop causing the brownout detection system from the ESP32 board to trigger, which leads to a platform reset. In order to bypass this issue, I've applied the following code in the setup routine, which successfully disables the brownout detection system from the ESP32.

#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
 
.....
 
// disable brownout detector
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);

6. Demo and Source Code

7. Further work

More analysis with respect to usage of RTC memory in Deep Sleep as opposed to directly using Hibernation mode would be of interest. While Hibernation mode uses less power by not keeping the RTC recovery memory on, in Deep Sleep we could use this RTC memory to store any relevant data and maybe bypass some of the initialization mechanism. Some effort was invested in this regard, but the RTC_DATA_ATTR data type is not complex enough to support storing information regarding Wifi or Firebase status. Nevertheless, the tradeoff between Hibernation and Deep Sleep could be further explored.

Li-Ion battery level could be monitored by using the ADC module available on the ESP32 platform, taking into consideration that the battery outputs a voltage between 3.7V and 4.2V (when fully charged).

Since this project is finally intended to be installed outdoors, a platform connection through a low throughput, low data rate, low power and long distance communication protocol such as LoRaWAN would be more practical compared to WiFi.

A more suitable case/packaging could be built/developed for the hardware solution of this project.

8. Resources

iothings/proiecte/2022/low_power_environmental_monitoring_system.txt · Last modified: 2023/01/19 21:58 by ciprian.costea
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