Wifi Temp & Humidity Sensor with ESP8266

Wifi Temperature and Humidity Sensor

Ive always liked sensors, and being able to create a cluster of them working together in my home, im able to make the home smarter than ever. this is one of those IoT (Internet Of Things ) projects that you can make aswell!

As far as cabling and how to program the ESP8266, i'll refer you to Adafruit, as they have already made a nice guide with the setup and as the components are mostly the same: https://learn.adafruit.com/esp8266-temperature-slash-humidity-webserver/overview

The unit looks like this once ready, I made it quite a bit bigger than it needs to be because of future addons I might add to it or remove, so every component is more or less swappable.

Parts used:

  • ESP8266 ~ $2
  • DHT22 ~ $3
  • Battery Case $1
  • 1000 uF Capacitor
  • 1 x 10k resistor
  • Case ~ $2 ( From any Hardware Store, Utility Box )
  • A 3.3v Voltage Regulator (XC6203E332PR)
  • Wires
  • Batteries ~ Alkaline 2700 mAh rating

 

The ESP8266 is a super cheap wifi board which is programmable with the Arduino IDE and looks like this

Voltage Regulator 

The voltage regualtor im using is the XC6203E332PR Low-dropout regulator which you can get from ebay around $2 for 10 pcs, Initially I used the LM1117 3.3v regulator used in the Adafruit guide but since it has a constant current draw of about 5-8mA, that is not acceptable for something that should operate for a long time. I did try differnet types of buck converters aswell but those had the same result, a current draw around 5-8mA, thus the XC6203E332PR was perfect as it has a constant current draw of around 4uA.

Battery Life

The unit should run for at least a year running on 3 AA 2700 mAh batteries until you have to change them, or go with rechargable batteries.

Calculating the battery life for this setup with AA batteries is done this way.

A typical Alkaline AA battery has around 2700 mAh charge. The ESP8266 will be sleeping for the most part and the current draw at that time will be around 0.04 uA with the regulators operational current included.

It will wake up every half an hour to send the temperature which takes at most arount 4 seconds and at that time the current draw will be an average of 100 mA (more like a burst up to 130 mA and then settle arount 70 mA).

So doing a little math here we can get the estimate!

By taking the battery mAh rating and multiplying it with 0.85 we get 2295 mAh, this is a more correct rating as the batteries have internal resistance and all sorts of factors which limit us from getting the batteries theoretical rating of 2700 mAh

We multiply our "on" time per hour in milliseconds, as we only start the unit twice in an hour it is 4000 * 2 = 8000 milliseconds and subtract that from an hour in milliseconds 3600000 - 8000 which is 3592000 ms, the amount of milliseconds the device is sleeping per hour. Yey, ok lets move on.

So as we know our device draws around 100 mA when on, and that it is on for 8000 ms, we can make the following calculation 100 times 8000 and get a millisecond value of 800000 ms.

We do the same for when it is sleeping, the current draw when sleeping was 0.04 mA which is 0.04 * 3592000 = 143680 ms.

adding everything up and we will get the amount of estimated runtime.

so taking the 800000 "On" ms + 143680 "Off" ms and dividing that with 3600000 (full hour) will give us the real mA of around 0.26333~ per hour.

we divide the battery rating of 2295 with 0.26333~ and get 8755.08, then divide that by hours per day, and we get the estimated rating!

i.e. 8755.08 / 24 = 364 days.

Now this is just an estimate if it actually takes 4 seconds every time, my usual is around 2 seconds within my wifi setup and with that we get 593 days! (it all depends on what kind of environment you are in.)

It can also make a big difference to configure static ips to further increase the wifi module and router handshake which happens every wake up.

So Yey! :D

 

One of my units run on two 18650 rechargable batteries in parallel to increase the amount of mAh, battery type does not matter as long as the voltage is not more than 8v which is the maximum voltage for the Low Dropout Voltage Regulator im using altough the mAh ratings change a lot between them.

 

The Code

/* DHTServer - ESP8266 Webserver with a DHT sensor as an input */

#include ESP8266WiFi.h
#include WiFiClient.h
#include WiFiUDP.h

#include DHT.h
#define DHTTYPE DHT22
#define DHTPIN 2
#define DHT_VPIN 4 // DHTVPIN Controlls the Transistor
ADC_MODE(ADC_VCC);

// Time to sleep (in seconds):
const int sleep_in_minutes = 30; // Minutes
const int sleep_in_seconds = 60*sleep_in_minutes; // Seconds
const char* firmware = "1.3";
const char* ssid = "YourWifiSid";
const char* password = "YourWifiPWD";
float humidity, temp_c; // Values read from sensor
unsigned long start, finished, elapsed;
unsigned long sleeptime;

// Initialize DHT sensor
DHT dht(DHTPIN, DHTTYPE, 11); // 11 works fine for ESP8266

unsigned int localPort = 2390; // local port to listen for UDP packets

IPAddress ipMulti (192,168,0,10); // The IPAddress where you want to receive the packets

byte packetBuffer[512]; //buffer to hold incoming and outgoing packets

WiFiUDP Udp; // A UDP instance to let us send and receive packets over UDP

void setup()
{
pinMode(DHT_VPIN, OUTPUT);
digitalWrite(DHT_VPIN, HIGH);
start=millis();
Serial.begin(115200);
Serial.println("DHT Temp and Humidity Sensor");
dht.begin();

// Connect to WiFi network
WiFi.begin(ssid, password);
// WiFi.config(ip);

// Wait for connection
Serial.print("\n\r \n\rTrying to Connect to: ");
Serial.print(ssid);
int tries=0;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
tries++;
if (tries > 30){
break;
}
}
Serial.println();

printWifiStatus();

Serial.print("Sending to port:");
Serial.println(localPort);
Serial.print("Firmware: ");
Serial.println(firmware);
Serial.print("ESP_ID=");
Serial.println(ESP.getChipId());
Serial.print("Voltage is ");
Serial.print(ESP.getVcc());
Serial.println("v");
// Udp.begin(localPort);
multicas_at_start_esp8266();
}

void loop()
{
delay(1000);
Serial.println("Should not be in this loop...");
}

void multicas_at_start_esp8266() //When ESP8266 starts, Broadcast presence of ESP8255
{
delayMicroseconds(100);
humidity = dht.readHumidity(); // Read humidity (percent)
temp_c = dht.readTemperature(false); // Read temperature as

if( -999 <= temp_c && -999 <= humidity)
{
Udp.beginPacket(ipMulti, 2390);
Udp.write("ESP_ID=");
Udp.print(ESP.getChipId());
Udp.write("|IPAddress=");
Udp.print(WiFi.localIP());
Udp.write("|Humidity=");
Udp.print((float)humidity);
Udp.write("|Temp=");
Udp.print((float)temp_c);
Udp.write("|Voltage=");
ESP.getVcc();
Udp.print((float)ESP.getVcc()*0.001);
Udp.write("|Firmware=");
Udp.print(firmware);
finished=millis();
Udp.write("|ElapsedTime=");
Udp.print((finished-start)/1000);
Udp.write("s");
if(ESP.getVcc() < 3000) {
Udp.write("|Status=");
Udp.write("low battery");
}
Udp.endPacket();
Serial.print("StartupTime=");
Serial.print((finished-start)/1000);
Serial.println("sec");
Serial.print("Sensors got temp: ");
Serial.print(temp_c);
Serial.print("*C and humidity: ");
Serial.print(humidity);
Serial.println("%");
}
else {
Udp.beginPacket(ipMulti, 2390);
Udp.write("ESP_ID=");
Udp.print(ESP.getChipId());
Udp.write("|IPAddress=");
Udp.print(WiFi.localIP());
Udp.write("|ERROR Sensor failed to measure, got temp: ");
Udp.print(temp_c);
Udp.write(" and humidity: ");
Udp.print(humidity);
Udp.endPacket();
Serial.print("Sensor failed to measure, got temp: ");
Serial.print(temp_c);
Serial.print(" and humidity: ");
Serial.print(humidity);
Serial.println("%");
}
delay(500);
hibernate();
}

void printWifiStatus() {
Serial.println("");
Serial.print("Connected to wifi: ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}


void hibernate(){
digitalWrite(DHT_VPIN, LOW);
pinMode(DHT_VPIN, INPUT);
if(ESP.getVcc() < 2900) {
// Battery Empty ( < 2.9 Volts)
sleeptime = 0;
// Normal battery ( > 3.0 Volts)
} else if(ESP.getVcc() > 3000){
sleeptime = sleep_in_seconds * 1000000; // Your Time
} else {
// Low battery ( < 3.0 Volts)
sleeptime = 120 * 60 * 1000000; // 2 Hours
}
Serial.print("Going into deep sleep for: ");
Serial.print(sleeptime);
Serial.println(" microseconds.");
ESP.deepSleep(sleeptime);
}

 

End Result

You could make as many units as you need and place them in areas out of sight, or mount them to a wall/ceiling and just sit back and relax.

The actual setup is the same for differnet kinds of sensors and readings, so once you have done a project like this, you can easily implement the same technique for other sensors.

 

 

Im sending my results to a splunk instance but you could easily create your own fetching script or send the packet to a site on the web.

 

 Thanks!

 

Posted on: Wednesday 07 January 2015