I'm interested to learn more about deep sleep, I would welcome any information on how to increase battery life (or general tips).
I currently have a test rig running:
Wemos D1 mini (ESP8266)
Wemos battery shield
BME280 connected as I2C
18650 2200mAh battery connected to battery shield
This is publishing sensor readings every 10 seconds and going to deep sleep. At present I am only getting 5 days battery life.
I will of course increase the sleep time to more like 120 seconds (as it's controlling a heater I don't want too long an interval). But from my research so far, it seems the deep sleep time battery usage is not the factor, actually getting the 'awake time' battery usage down in more important.
Code general description:
Define Wifi, MQTT credentials.
Define topics to publish to.
Call wifi setup function
Check for BME280 sensor
Call MQTT connect function
Call heartbeat function (sends RSSI value to node red)
Call sendSensor function (read temp/humidity)
Call battery level function (send battery level to node red)
delay 500ms to allow MQTT messages to be published
Deep sleep for x seconds
Full code is at the bottom of the post.
Ideas:
Increase deep sleep time (not too long as the sensor is indirectly controlling a heater, via node red)
Remove serial prints might reduce time 'awake'?
Reducing time wifi is connected - read sensor first then connect?
Further reading on my list:
Three part blog on redcing power usage
Full code:
//v004 MQTT conservatory weather station
////Code originally based on https://www.home-assistant.io/blog/2015/10/11/measure-temperature-with-esp8266-and-report-to-mqtt/
//
//Hardware:
//Wemos D1 mini, BME280 sensor wired as I2C, Raspberry Pi 3 node red and moquitto MQTT server.
//
//Description:
//BME temp, humidity and pressure readings are published to the MQTT server (also printed to serial).
//Heartbeat RSSI value of device gets sent to MQTT broker, node red can light a Blynk LED/colour text (if online/offline)
//BME280 wiring - 3V to Vcc / Gnd to Gnd / D1 to SCL / D2 to SDA
//
//Changelog:
//v002 added deep sleep (first attempt)
//v003 added battery voltage monitoring
//v004 testing battery life improvements (removed serial prints)
//
#include <ESP8266WiFi.h>
#include <Wire.h>
#include <PubSubClient.h>
#include <BME280I2C.h>
#include <SimpleTimer.h>
#define wifi_ssid ""
#define wifi_password ""
#define mqtt_server ""
#define mqtt_user ""
#define mqtt_password ""
#define temperature_topic "house/consv/sensor/temperature"
#define humidity_topic "house/consv/sensor/humidity"
#define pressure_topic "house/consv/sensor/pressure"
#define heartbeat_topic "house/consv/sensor/heartbeat" //for heartbeat
#define freeram_topic "house/consv/sensor/freeram" // send device free ram
#define battery_topic "house/consv/sensor/battery" // send battery voltage
WiFiClient espClient;
PubSubClient client(espClient);
BME280I2C bme; // Default : forced mode, standby time = 1000 ms
// Oversampling = pressure ×1, temperature ×1, humidity ×1, filter off,
long rssi; // setup variable for RSSI heartbeat value
char *client_id = "Wemos_no_1_MQTT"; // MQTT Client ID
//Setup variables for later
float temp;
int hum;
int pres;
void setup() {
// Connect D0 to RST to wake up
pinMode(D0, WAKEUP_PULLUP);
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
while (!Serial) {} // Wait
Wire.begin();
while (!bme.begin())
{
Serial.println("Could not find BME280 sensor!");
delay(500);
}
// bme.chipID(); // Deprecated. See chipModel().
switch (bme.chipModel())
{
case BME280::ChipModel_BME280:
Serial.println("Found BME280 sensor! Success.");
break;
case BME280::ChipModel_BMP280:
Serial.println("Found BMP280 sensor! No Humidity available.");
break;
default:
Serial.println("Found UNKNOWN sensor! Error!");
}
reconnect(); //connect to MQTT server
heartbeat(); // publish RSSI value as heartbeat
sendSensor(); //publish sensor readings
battery(); // read battery level
delay(500); //delay to allow for MQTT messages to be published
ESP.deepSleep(10 * 1000000); // 10 seconds
}
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(wifi_ssid);
WiFi.begin(wifi_ssid, wifi_password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
// If you do not want to use a username and password, change next line to
// if (client.connect("ESP8266Client")) {
if (client.connect(client_id, mqtt_user, mqtt_password)) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 1 seconds");
// Wait 1 seconds before retrying
delay(1000);
}
}
}
void heartbeat() // function for heartbeat check
{
Serial.print("RSSI:");
Serial.println(WiFi.RSSI());
client.publish(heartbeat_topic, String(WiFi.RSSI()).c_str(), true);
client.publish(freeram_topic, String(ESP.getFreeHeap()).c_str(), true);
}
void sendSensor() // function to send sensor readings to MQTT
{
//read latest values
temp = bme.temp();
hum = bme.hum();
pres = bme.pres();
if (isnan(temp)) {
Serial.println("Error reading temperature!");
}
else
{
Serial.print("Temperature: ");
Serial.println(String(temp).c_str());
client.publish(temperature_topic, String(temp , 1).c_str(), true);
}
if (isnan(temp)) {
Serial.println("Error reading humidity!");
}
else
{
Serial.print("Humidity: ");
Serial.println(String(hum).c_str());
client.publish(humidity_topic, String(hum).c_str(), true);
}
if (isnan(pres)) {
Serial.println("Error reading pressure!");
}
else
{
Serial.print("Pressure: ");
Serial.println(String(pres / 100).c_str());
client.publish(pressure_topic, String(pres / 100).c_str(), true);
}
}
void battery()
{
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 4.5V):
float voltage = 4.5 * (sensorValue/1023.0);
// send out the value you read:
Serial.print("Voltage: ");
Serial.println(voltage);
client.publish(battery_topic, String(voltage).c_str(), true);
}
void loop(){}