Battery Powered ESP8266 Temperature/Humidity Monitor with DHT11

About This Project

This Project will check Temperature, Humidity, and Heat Index using an ESP-12f and a DHT11 sensor and will run on 2 AAA batteries (or whatever your 3/3.3v battery preference may be). During transmission the ESP draws around 72mA on average and during sleep it draws 0.05mA. I’m not sure how to calculate how long that will last, but updating only every 10 minutes it should last for quite some time! The Arduino sketch is below and requires the DHT sensor library by Adafruit version 1.2.3 as well as the Cayenne library.

Note:
Pin 16 has to be connected to the reset pin for the ESP to wake up from sleep.

// This example shows how to connect to Cayenne using an ESP8266 and send/receive sample data.
// Make sure you install the ESP8266 Board Package via the Arduino IDE Board Manager and select the correct ESP8266 board before compiling. 

//#define CAYENNE_DEBUG
#define CAYENNE_PRINT Serial
#define DHTTYPE DHT11
#define DHTPIN  14

#include <CayenneMQTTESP8266.h>
#include <DHT.h>

// WiFi network info.
char ssid[] = "";
char wifiPassword[] = "";

// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = "";
char password[] = "";
char clientID[] = "";

//Variables for DHT11 values
float h, t, hif;
//Time to sleep - 10 minutes - delete a zero to set to 1 minute
int SleepTime = 600000000;
//Values sent/error booleans
bool CayenneSent = false;
bool ReadError = false;

DHT dht(DHTPIN, DHTTYPE);

void setup() {
	Serial.begin(9600);
  Serial.println("Setup");
	Cayenne.begin(username, password, clientID, ssid, wifiPassword);

  CayenneSent = false;
  ReadError = true;
}

void loop() {
  //Run Cayenne Functions
	Cayenne.loop();

  //Only check values if there is a ReadError 
  if (ReadError){
    ReadError = false;
    //Check if read failed and try until success
    int WhileLoops = 0;
    do {
      WhileLoops++;
      //We can't go too long without calling Cayenne.loop() so exit this loop after 2 seconds and set an error flag
      if (WhileLoops >= 4){
        Serial.println("Sensor Read Error");
        ReadError = true;
        break;
      }
      //Read temperature as Fahrenheit
      t = dht.readTemperature(true);
      //Read humidity (percent)
      h = dht.readHumidity();
      //Read temperature as Fahrenheit
      t = dht.readTemperature(true);
      //Calculate Heat Index as Fahrenheit
      hif = dht.computeHeatIndex(t, h);
  
      delay(500);
    } while  (isnan(t) || isnan(h));

    Serial.print("Humidity: ");
    Serial.println(h);
    Serial.print("Temperature (f): ");
    Serial.println(t);
    Serial.print("Heat Index (f): ");
    Serial.println(hif);
  }
  else {
    //Check if we sent all values and sleep for 10 minutes if we did
    if (CayenneSent){
      Serial.println("Sent all values - sleeping");
      delay(100);
      ESP.deepSleep(SleepTime, WAKE_RF_DEFAULT);
      delay(100);
    }
  }
}

// Default function for sending sensor data at intervals to Cayenne.
// You can also use functions for specific channels, e.g CAYENNE_OUT(1) for sending channel 1 data.
CAYENNE_OUT_DEFAULT()
{
  //Check if there was a read error and skip sending values if there is
  if (!ReadError){
    //Send Values
    Cayenne.virtualWrite(0, h, "rel_hum", "p");
    Cayenne.virtualWrite(1, t, "temp", "f");
    Cayenne.virtualWrite(2, hif, "temp", "f");
    
    //Set CayenneSent to true so we know when to sleep
    CayenneSent = true;
  }
}

To deal with wireless connectivity issues you can modify CayenneMQTTWiFiClient.h in the Arduino\libraries\Cayenne-MQTT-ESP-master\src folder. Below is my solution to the ESP staying awake and draining the batteries when it cannot connect to the configured wifi network. If the ESP fails to connect 30 times it’s safe to say it probably won’t. In that case I have the ESP go in to sleep mode for 5 minutes before it tries again. Keep in mind every time you update the library you will have to make this change as it will be overwritten by the update.

/*
The MIT License(MIT)

Cayenne Arduino Client Library
Copyright (c) 2016 myDevices

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files(the "Software"), to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef _CAYENNEMQTTWIFICLIENT_h
#define _CAYENNEMQTTWIFICLIENT_h

#include "CayenneArduinoMQTTClient.h"

#ifndef WRITE_CHUNK_SIZE
#define WRITE_CHUNK_SIZE 0 // The chunk size to use when sending data, 0 means data will not be sent in chunks.
#endif // !WRITE_CHUNK_SIZE


class CayenneMQTTWiFiClient : public CayenneArduinoMQTTClient
{
public:
	/**
	* Begins Cayenne session and in the process establishes a WIFI connection with the supplied ssid and WIFI password
	* @param username Cayenne username
	* @param password Cayenne password
	* @param clientID Cayennne client ID
	* @param ssid WiFi network id
	* @param wifiPassword WiFi network password
	*/
	void begin(const char* username, const char* password, const char* clientID, const char* ssid, const char* wifiPassword)
	{
		int status = WL_IDLE_STATUS;
		WiFi.mode(WIFI_STA);
		delay(500);
		if (WiFi.status() == WL_NO_SHIELD) {
			CAYENNE_LOG("WiFi not present");
			while (true);
		}

		CAYENNE_LOG("Connecting to %s", ssid);
		if (wifiPassword && strlen(wifiPassword)) {
			WiFi.begin(ssid, wifiPassword);
		}
		else {
			WiFi.begin(ssid);
		}
		int timeoutcounter=0;
		while (WiFi.status() != WL_CONNECTED) {
			timeoutcounter++;
            if (timeoutcounter >= 30){
                CAYENNE_LOG("Failed to connect to wireless - sleeping for 5 minutes");
                delay(100);
                ESP.deepSleep(300000000, WAKE_RF_DEFAULT);
                delay(100);
            }
			delay(500);
		}
		CAYENNE_LOG("Connected to WiFi");

		IPAddress local_ip = WiFi.localIP();
		CAYENNE_LOG("IP: %d.%d.%d.%d", local_ip[0], local_ip[1], local_ip[2], local_ip[3]);
		CayenneArduinoMQTTClient::begin(_wifiClient, username, password, clientID, WRITE_CHUNK_SIZE);
	}
	/**
	* Begins Cayenne session, assumes that the WIFI is already up and running. 
	* @param username Cayenne username
	* @param password Cayenne password
	* @param clientID Cayennne client ID
	*/
	void begin(const char* username, const char* password, const char* clientID)
	{
		if (WiFi.status() != WL_CONNECTED) {
			CAYENNE_LOG("CayenneMQTTWiFiClient.begin called without WIFI being connected. Either use begin (..., ssid, wifipassword) to establish the connection here. Or setup the WIFI connection manually before calling this variant of the begin function");
		}
		IPAddress local_ip = WiFi.localIP();
		CAYENNE_LOG("IP: %d.%d.%d.%d", local_ip[0], local_ip[1], local_ip[2], local_ip[3]);
		CayenneArduinoMQTTClient::begin(_wifiClient, username, password, clientID, WRITE_CHUNK_SIZE);
	}


private:
	WiFiClient _wifiClient;
};

CayenneMQTTWiFiClient Cayenne;

#endif

What’s Connected

ESP-12f
1000uf Capacitor
PCB Headers
Jumper Wires
Single Sided Perf Board
DHT11
2 AAA battery holder

Triggers & Alerts

I set up a trigger to email me when the temperature drops below 65 (cold) and another trigger to email me when the temperature is above 90 (hot)

Scheduling

Can’t think of any way scheduling would fit in here.

Dashboard Screenshots

Photos of the Project

19 Likes

So coool !!!
Let us know how much time it lasts :slight_smile:

I started running yesterday morning, I’ll update the post when the last update comes in to Cayenne!

So today I discovered I need to modify some Cayenne files for this to work efficiently. First I had some wifi problems then the Cayenne servers were down for a bit which caused the ESP to be awake the entire time trying to connect and killed my batteries. I’m going to see if I can find the wifi and Cayenne connection functions and add in a counter to deep sleep for 5 minutes after 15 unsuccessful connections.

1 Like

Keep us updated with this! The Cayenne team is really interested, this is where we want Cayenne to be able to go and support :slight_smile:

-B

2 Likes

Added instructions on creating BlynkSimpleEsp8266_mod.h to handle wireless connectivity issues draining batteries. I will also be adding a modified file to sleep on Cayenne connectivity issues soon.

Hi Adam

This looks really good - something I want to try. :slight_smile:
This also looks very re-usable - e.g. connect a switch and you have a battery powered door alarm.

I am new to Cayenne - got my first sensor working last night on an Arduino UNO.

Also new to the ESP-12f.

Can you add a few words on connecting / downloading to the ESP-12f as it would help those coming at it for the first time?

Thanks for a useful little project.

The Esp stuff is certainly fun-
I haven’t played with the Esp12f yet, but I’ve been enjoying the ESP12-e.

It’s pretty cut and dried stuff.
Upload a script/sketch using Arduino IDE,
then add functions in the App, just like a Pi.

Thanks for the quick reply.

I have used the Arduino IDE with a UNO to learn and try out stuff including canva and Pro Minis for a card reader application that is in daily use.

I was looking for the specifics.
What board type do you use in the IDE?
Your picture shows a USB interface (which I have) - what pins are used to connect to the ESP12?

I was thinking of making several of your battery powered monitors, to monitor several rooms at the same time - can multiple devices appear on the same dashboard?

Thanks

In the IDE you can use the ESP-12e board. The 12f has less memory so to may run in to problems with very large sketches without the IDE warning you, but so far I have not had a problem. The 12f supposedly has a better antenna and I saw them when I was making an order so I got 5 of them from banggood.com.
I am using a FTD1232 I got an amazon to program it. It’s nice because it has a 3.3v/5v jumper to give you the voltage you need. For programming and testing it should run an ESP but I wouldn’t try to run relays or anything else unless you get a separate power supply to avoid overloading your USB controller. The GND goes to GND, VCC to VCC (set to 3.3v or use a regulator if using 5v), RX on the FTD goes to TX on the ESP, and TX on the FTD goes to RX on the ESP. ESP pins are listed below.

Also, GPIO 15 has to be grounded at boot to boot normally. GPIO 15 and GPIO 0 have to be grounded to boot in to programming mode. Because of this I tend to just jumper GND and GPIO 15 on my circuits so I don’t have to worry about it and then I just lose that pin.

Great!
Can you post the scheme of ESP8266 shield.
It’s real interesting. You use a capacitor and switch? What’s the procedure for flashing the ESP8266.

Here’s you go…

you only need 3 pins-

TX (transmit) goes to REC (receive)
REC goes to TX
…and GROUND.

Don’t bother with the onboard +3.3 regulator,
the ESP draws too much current.
Be SURE to set your interface voltage to 3.3!

Here’s the one I got-

Thanks again - Did a bit more searching and I think I should be good to go when they arrive.

After tou install Arduino IDE FROM Arduino,
and after you physically attach the FTDI232 pins
Tx, Rx, Gnd (be sure 3.3V is selected)

and import the ESP8266 library
http://esp8266.github.io/Arduino/versions/2.0.0/doc/installing.html
(after downloading it- don’t forget to INSTALL it! :wink:
and then import the Cayenne .zip library
into the Arduino Library

After you start the Arduino IDE,

Choose tools/port -select wherever your FTDI USB/Serial converter is-
choose Tools/Board “ESP8266 Generic”

compile/upload the “Hook” file onto the ESP12e
by shorting GPIO 0 to GND for 5 seconds on power-up.
It’s now in programming mode.
upload this file AFTER starting Device/ADD
on your remote HTML or App.
Substitute YOUR Token, SSID and Password :slight_smile:

#include "CayenneDefines.h"
#include "BlynkSimpleEsp8266.h"
#include "CayenneWiFiClient.h"
#define CAYENNE_DEBUG
#define CAYENNE_PRINT Serial

char token[] = "MyToken";
char ssid[] = "MySSID";
char password[] = "MyPass";

void setup()
{
  Serial.begin(115200);
  Cayenne.begin(token, ssid, password);
}
void loop()
{

  Cayenne.run();
}

The FTDI model I put in my post above will run an ESP12-e for programming/testing just fine, just make sure you have a good capacitor like 1000uf or more. Like I said, just don’t power the ESP + any other device and you’ll be fine. Average mA draw is about 75-80mA which USB can handle just fine. It’s the surges that are not good for the USB port, and the big cap smooths that out. Here is the link https://www.amazon.com/gp/product/B00IJXZQ7C/ref=ox_sc_act_title_2?ie=UTF8&psc=1&smid=A30QSGOJR8LMXA

Some more info about USB port power consumption:

The USB 1.x and 2.0 specifications provide a 5 V supply on a single wire to power connected USB devices.

A unit load is defined as 100 mA in USB 2.0, and 150 mA in USB 3.0.
A device may draw a maximum of 5 unit loads (500 mA) from a port in USB2.0; 6 (900 mA) in USB 3.0.

Works very well, I am pleased with the ease of putting this project together. The only think id like to change is the temp format to Celsius, I will try to figure it out but maybe someone has a quick answer how to change that
Great work on this project !

The power issue has nothing to do with the amount of power delivered to the USB port.

The problem is the FTDI232 on-board TINY SMT-mounted 3.3 volt LINEAR voltage regulator.
It’s WEAK, -as all SMT linear regulators are
(I THINK this SMT 3.3v regulator is rated to 100mA).

…and adding a 1000mF electrolytic is just- WRONG.
That giant electrolytic cap isn’t gonna charge itself…
crowbar current limiting is the only thing saving your USB ports.
Lucky you.
I use 45mF/35V electrolytics on my regulator inputs and outputs
and I use .2mF/50v ceramics as my de-glitching filters.

I’d stick with my advice of not using the FTDI regulator, and strongly suggest using a switching regulator (like the 78SR3.3 ,1.5Amps), with a voltage input range anywhere from +7.5 to +36Vdc.

The Esp12-e and 3 LED diodes may well push that weak FTDI voltage regulator over the edge. Another unexplained reboot…

Pushing power components this close to the edge is…unadvisable.

-but, to each his own…

Here is one I use that is rated for 1A, though you are correct that the one on the FTDI is nowhere near 1A. I saw 50mA in a comment on the amazon page but there are no datasheets for this, so it could be anything.

I’m using a 1000uF (1mF) capacitor, not a 1000mF. 45mF is way overkill. 2200uF is the sweet spot but I do not currently have any right now. Searching google for “crowbar current limiting USB” brought back nothing, what exactly is that?

If you are using the first ever USB 2.0 controller, yes, you will not want to consider this. If all you want to do is upload a sketch with out peripherals attached, USB 3.0 will handle this just fine. I regularly create sketches that simulate sensor input to test that everything will work before I put it on an ESP that is ready to go. I’ve never once had an ESP reboot unless there is a coding error. You do bring up a good point about the regulator on the FTDI, but worst case there is you end up burning out the regulator.

So, long story short, if you’re worried about your FTDI or your USB port don’t use it to power the ESP.