I made a small project to have a battery operated ESP8266 (using Adafruit's Huzzah board) which reads temperature and humidity from a DHT22 sensor, it also reads the battery voltage using a simple voltage divider circuit wired to the analog IO pin of the ESP. The ESP will then connect to Adafruit's IO service and send it latest readings.
I am using a 3.7v Li-Ion battery wired to the VBAT+ pin of the huzzah board. To minimize battery load, I put a ESP.deepsleep() call at the end of my main loop.
This seemed to work fine at first, but I found that after x hours, the ESP would crash, in such a way that even pushing the reset button on the huzzah board would not help, I really had to remove/replug the battery before the ESP would start again correctly.
I had my laptop connector all the time so I had the logfile of what the ESP sent over its serial line, and I could see before it died, the readings from the DHT22 started being off.
See below a 'correct' loop followed by a 'faulty' loop:
Connecting to MQTT... MQTT Connected!
V: 3.32 | T: 18.40 | H: 50
Connecting to AP: -removed-......Failed
Connecting to AP: -removed-....
WiFi connected
Connecting to MQTT... MQTT Connected!
V: 3.31 | T: nan | H: 2147483647
Connecting to AP: -removed-......Failed
Connecting to AP: -removed-......Failed
Connecting to AP: -removed-......Failed
Connecting to AP: -removed-......Failed
Connecting to AP: -removed-......Failed
Connecting to AP: -removed-....
WiFi connected
As you can see the temperature becomes NaN, and the humidity is way off (should be between 0-100).
Anyone got any idea what this could be?
This is the code i'm using:
#include <Adafruit_MQTT_Client.h>
#include <Adafruit_MQTT.h>
#include <DHT.h>
#include <ThingSpeak.h>
#include <ESP8266WiFi.h>
//AP definitions
int status = WL_IDLE_STATUS; // the Wifi radio's status
struct WifiConn
{
char *Ssid;
char *Password;
};
WifiConn APList[] = {
{"-removed-", ""}
,{"-removed-", "-removed-"}
,{ "-removed-", "-removed-" }
,{ "-removed-", "-removed-" }
};
WiFiClient client;
/************************* Adafruit.io Setup *********************************/
#define AIO_SERVER "io.adafruit.com"
#define AIO_SERVERPORT 1883 // use 8883 for SSL
#define AIO_USERNAME "-removed-"
#define AIO_KEY "-removed-"
// Store the MQTT server, username, and password in flash memory.
// This is required for using the Adafruit MQTT library.
const char MQTT_SERVER[] PROGMEM = AIO_SERVER;
const char MQTT_USERNAME[] PROGMEM = AIO_USERNAME;
const char MQTT_PASSWORD[] PROGMEM = AIO_KEY;
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, MQTT_SERVER, AIO_SERVERPORT, MQTT_USERNAME, MQTT_PASSWORD);
/****************************** Feeds ***************************************/
// Setup a feed called 'photocell' for publishing.
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
const char TEMP_FEED[] PROGMEM = AIO_USERNAME "/feeds/esp8266-1-temp1";
Adafruit_MQTT_Publish TempFeed = Adafruit_MQTT_Publish(&mqtt, TEMP_FEED);
const char HUM_FEED[] PROGMEM = AIO_USERNAME "/feeds/esp8266-1-hum1";
Adafruit_MQTT_Publish HumFeed = Adafruit_MQTT_Publish(&mqtt, HUM_FEED);
const char VIN_FEED[] PROGMEM = AIO_USERNAME "/feeds/esp8266-1-vin1";
Adafruit_MQTT_Publish VinFeed = Adafruit_MQTT_Publish(&mqtt, VIN_FEED);
#define REPORT_INTERVAL 60 // in sec
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
float fOldTemp;
int iOldHum;
#define VOLTAGE_PIN A0
float fOldVoltage;
// Bug workaround for Arduino 1.6.6, it seems to need a function declaration
// for some reason (only affects ESP8266, likely an arduino-builder bug).
void MQTT_connect();
void setup() {
Serial.begin(115200);
Serial.println();
while (WiFi.status() != WL_CONNECTED)
{
wifiConnect();
}
ThingSpeak.begin(client);
fOldTemp = -1;
fOldVoltage = -1;
dht.begin();
pinMode(VOLTAGE_PIN, INPUT);
Serial.println("");
}
void loop() {
MQTT_connect();
float vout = analogRead(VOLTAGE_PIN) / 1024.0;
float fVoltage = vout / 0.090909;
float fTemp = dht.readTemperature();
int iHum = dht.readHumidity();
if ((fTemp != fOldTemp)
|| (iHum != iOldHum)
|| (fVoltage != fOldVoltage))
{
SendData(fTemp, fVoltage, iHum);
fOldTemp = fTemp;
Serial.print("V: ");
Serial.print(fVoltage);
Serial.print(" | T: ");
Serial.print(fTemp);
Serial.print(" | H: ");
Serial.println(iHum);
}
int cnt = REPORT_INTERVAL;
ESP.deepSleep(REPORT_INTERVAL * 1000000, WAKE_RF_DEFAULT);
}
void wifiConnect()
{
for (auto& AP : APList)
{
int iConnTries = 0;
Serial.print("Connecting to AP: ");
Serial.print(AP.Ssid);
WiFi.begin(AP.Ssid, AP.Password);
while (WiFi.status() != WL_CONNECTED && iConnTries <= 5) {
delay(1000);
Serial.print(".");
iConnTries++;
}
if (WiFi.status() != WL_CONNECTED)
{
Serial.println("Failed");
}
else
{
Serial.println("");
Serial.println("WiFi connected");
return;
}
}
}
void SendData(float temp, float voltage, int iHum)
{
TempFeed.publish(temp);
VinFeed.publish(voltage);
HumFeed.publish(iHum);
}
// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
int8_t ret;
// Stop if already connected.
if (mqtt.connected()) {
return;
}
Serial.print("Connecting to MQTT... ");
uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000); // wait 5 seconds
retries--;
if (retries == 0) {
// basically die and wait for WDT to reset me
while (1);
}
}
Serial.println("MQTT Connected!");
}