I learned how to program ESP8266 so I created my first temperature IoT ESP8266 project. I used DHT22 as a temperature and humidity sensor and also I did some testing of power consumption using LIGHT SLEEP (LIGHT_SLEEP_T) mode on ESP8266.
Hardware
As a good example I found Adafruit esp8266 temperature/humidity webserver.
My parts List:
- ESP8266 ESP-01 Wifi Module
- to get 3.3V from 5V use: 3.3V 800mA Voltage Regulator LS1117-3.3 or 3.3V Voltage step-down regulator or L4931-3.3 TO-92
- DHT22 with 10KΩ resistor (Am2302 version in my case)
- USB TTL Serial (to upload the program)
- wires
Once your ESP-01 is programmed the final wiring is quite simple:
So you can connect a 3.7 volt LiPo battery, 5 volt “Cell Phone Recharger” battery, or 9 volt battery. You may also use a 5 volt “wall wart” power supply. I connected standard USB (USB Micro-B Connector Breakout Board) so I could use my old Cell Phone Power Adapter.
If you do not have the ESP8266 programmer you can use a wiring inspiration from Adafruit wiring page or check my post how to easily wire and program ESP-01.
Software program
Check my previous post to configure your arduino IDE for programming ESP8266. I will not post here the server part (maybe later on, I assume you have one or you can just use some cloud IoT server e.g. data.sparkfun.com, dweet.io). My sketch demonstrates a simple sensor read and an HTTP GET call to send data to the server .
There is a special library for DHT22 or DHT11 for ESP8266. I used Adafruit DHT-sensor-library, so you can download it from github.
I included an ESP8266 low power sleep: wifi_set_sleep_type(LIGHT_SLEEP_T);
Normal delay sleep draws 80mA current also with WiFi.disconnect();
but ESP8266 with this LIGHT_SLEEP code draws approximately 10mA current (floating from 3mA-30mA). With the Arduino ESP8266 2.0.0 version library, the sleep mode works only if wifi is NOT disconnected (strange but confirmed by experiments). There is some info also in ESP8266 github discussion.
This code works with Arduino 1.6.5 IDE and with ESP8266 2.0.0 platform lib.
Copy the program below and save as DHTClient.ino:
/* DHTClient - ESP8266 client with a DHT sensor as an input */ #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <DHT.h> #define DHTTYPE DHT22 //or DHT11 #define DHTPIN 2 const char* ssid = "PUT HERE YOUR SSID"; const char* password = "PUT HERE YOUR PASSWD"; WiFiClient client; byte server[] = { 192, 168, 1, 11 }; // http server - PUT HERE YOUR SERVER IP as bytes String serverStr = "192.168.1.11"; // http server - PUT HERE YOUR SERVER IP as string // Initialize DHT sensor - adafruit note // NOTE: For working with a faster than ATmega328p 16 MHz Arduino chip, like an ESP8266, // you need to increase the threshold for cycle counts considered a 1 or 0. // You can do this by passing a 3rd parameter for this threshold. It's a bit // of fiddling to find the right value, but in general the faster the CPU the // higher the value. The default for a 16mhz AVR is a value of 6. For an // Arduino Due that runs at 84mhz a value of 30 works. // This is for the ESP8266 processor on ESP-01 DHT dht(DHTPIN, DHTTYPE, 15); // 11 works fine for ESP8266 float humidity, temperature; // Values read from sensor String webString = ""; // String to display // Generally, you should use "unsigned long" for variables that hold time unsigned long previousMillis = 0; // will store last temp was read const long interval = 2000; // interval at which to read sensor // Required for LIGHT_SLEEP_T delay mode extern "C" { #include "user_interface.h" } void setup(void) { // You can open the Arduino IDE Serial Monitor window to see what the code is doing Serial.begin(115200); // Serial connection from ESP-01 via 3.3v console cable Serial.println("\n\r \n\rWorking to connect"); for (uint8_t t = 4; t > 0; t--) { Serial.print("[SETUP] WAIT "); Serial.println(t); delay(1000); } dht.begin(); // initialize temperature sensor Serial.println("\n\r \n\rDHT done"); gettemperature(); Serial.println(String(temperature)); delay(2); } void loop(void) { delay(2); gettemperature(); // Connect to WiFi network WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.print("\n\r \n\rWorking to connect"); // Wait for connection while (WiFi.status() != WL_CONNECTED) { delay(200); Serial.print("."); } Serial.println(""); Serial.println("DHT Weather Reading Client"); Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); Serial.println(ESP.getChipId()) ; Serial.println("Client started"); if (client.connect(server, 80)) { // http server is running on default port 80 Serial.println("connected"); client.print("GET /SensorWriteToFile.php?temp="); // PUT HERE YOUR SERVER URL e.g. from http://192.168.1.11/SensorWriteToFile.php?temp=10.5&hum=58 client.print(String(temperature)); client.print("&hum="); client.print(String(humidity)); client.println(" HTTP/1.1"); client.print("Host: "); // http server is running on port 80, so no port is specified client.println(serverStr); client.println("User-Agent: Mihi IoT 01"); // PUT HERE YOUR USER-AGENT that can be used in your php program or Apache configuration client.println(); // empty line for apache server //Wait up to 10 seconds for server to respond then read response int i = 0; while ((!client.available()) && (i < 1000)) { delay(10); i++; } while (client.available()) { String Line = client.readStringUntil('\r'); Serial.print(Line); } client.stop(); } else { Serial.println("connection failed"); } Serial.println(); Serial.println(WiFi.status()); //WiFi.disconnect(); // DO NOT DISCONNECT WIFI IF YOU WANT TO LOWER YOUR POWER DURING LIGHT_SLEEP_T DELLAY ! //Serial.println(WiFi.status()); wifi_set_sleep_type(LIGHT_SLEEP_T); delay(60000*3-800); // loop every 3 minutes } void gettemperature() { // Wait at least 2 seconds seconds between measurements. // if the difference between the current time and last time you read // the sensor is bigger than the interval you set, read the sensor // Works better than delay for things happening elsewhere also unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { // save the last time you read the sensor previousMillis = currentMillis; // Reading temperature for humidity takes about 250 milliseconds! // Sensor readings may also be up to 2 seconds 'old' (it's a very slow sensor) humidity = dht.readHumidity(); // Read humidity (percent) //temperature = dht.readTemperature(true); // Read temperature as Fahrenheit temperature = dht.readTemperature(); // Read temperature as *C // Check if any reads failed and exit early (to try again). if (isnan(humidity) || isnan(temperature)) { Serial.println("Failed to read from DHT sensor!"); return; } } }
My Apache2 access log proves that the connection is working… 😎
I used this simple php file (SensorWriteToFile.php) to store the IoT data in my LAMP server file:
<?php // URI: /SensorWriteToFile.php?temp=23.50&hum=48.20 date_default_timezone_set('Europe/Bratislava'); $dateTime = new DateTime(); $dateTimeStamp = $dateTime->format('Y-m-d H:i:s'); $data = $_REQUEST; $data += array("datetime" => $dateTimeStamp ); $data += array("user_agent" => $_SERVER['HTTP_USER_AGENT'] ); $req_dump = json_encode( $data ) . "\n"; $fp = file_put_contents( '/var/www/request.log', $req_dump, FILE_APPEND ); // make /var/www/request.log file writable !! ?>
Sample of the log file (/var/www/request.log) with proper write access:
{"temp":"25.10","hum":"72.10","datetime":"2016-02-07 20:29:58","user_agent":"Mihi IoT 01"} {"temp":"25.20","hum":"69.30","datetime":"2016-02-07 20:31:06","user_agent":"Mihi IoT 01"} {"temp":"25.40","hum":"75.40","datetime":"2016-02-07 20:32:10","user_agent":"Mihi IoT 01"} {"temp":"25.40","hum":"70.30","datetime":"2016-02-07 20:33:15","user_agent":"Mihi IoT 01"} {"temp":"25.10","hum":"65.10","datetime":"2016-02-07 20:34:37","user_agent":"Mihi IoT 01"} {"temp":"25.00","hum":"66.40","datetime":"2016-02-07 20:35:40","user_agent":"Mihi IoT 01"} {"temp":"25.00","hum":"66.00","datetime":"2016-02-07 20:36:49","user_agent":"Mihi IoT 01"} {"temp":"25.00","hum":"64.10","datetime":"2016-02-07 20:37:51","user_agent":"Mihi IoT 01"}
Hi! First I want to thank you for the work .. it is really fantastic and helped me! 🙂
Just I had a little problem running C code, failed because the void gettemperature () must be before the void loop (). I also added libraries #include and #include and worked very well.
Thank you for the excellent work and share the code !!
best regards,
Márcio Marques
Thanks for the reply, might be useful for others. In Arduino IDE arduino-1.6.5-r5 there is no compilation error, but in newer 1.6.7 I have also compilation issues. I’m not sure why.