A fun IoT starter project is temperature sensors: Everyone cares about the weather. I am using the esp8266 and a DS18b20 sensor to post the temperature on my balcony to twitter.
For the current version of this project i`m using a Wemos D1 Mini that i had laying around: rev1 used an ESP8266-01, but that version of the esp has some disadvantages when it comes to IoT Sensor applications: Power management
This topic really deserves a separate post, but when developing IoT solutions power consumption is a very important factor. A lot of micro-controllers can be quite power-hungry when running on full throttle, and WiFi communication is something that draws a fair bit of current as well. But here is the thing; They don’t need to be on all the time. At least not for most applications.
On Rev1, battery life was ~ 5 days on 2 AA batteries. On Rev 2, its a few months (and counting) on 3 AA`s. Both units use the same chip (esp8266), So whats the secret?
DeepSleep
DeepSleep
In short, deep sleep is a concept employed by a lot of micro-controller designers to shut down as much of the internal parts of the micro-controller as possible when it is not in use and thereby minimizing power consumption. For the esp, true deepSleep is achieved by shutting down everything except the RTC (RealTimeClock): The RTC keeps count of the defined sleep period and wakes the controller back up again by Setting GPIO16 low; This pin needs to be connected to the RST pin of the ESP for it to work.
According to specs, the esp uses only 20 µA while in deep sleep. That’s pretty efficient!
Note: Max deepsleep on the esp8266 is about 71 minutes, any more than this and it wont wake back up as this is the limit of the clock.
The first version of the esp to hit the market (Commonly referred to as the 01) only had 8 pins broken out: GPIO1, GPIO2, TX, RX, VCC, GND, RST and CH_PD. As mentioned, you need access to GPIO16 of the micro-controller to wake it up from deep sleep again. I’ve seen people do various hacks to accomplish this, but would not recommend it as you’ll risk shorting some pins.
Long story short: Rev1 of the balcony TwitterTemp did not go into deepsleep between operations but instead used a WAIT. That’s the reason behind the incredible difference in Power-consumption.
Wemos D1 Mini
Now a few words about the Wemos D1 mini.
It has 16 pins and a push-button reset, and in short its a breakout board for thevESP8266 with an onBoard USB UART and a power converter (USB supplies 5 volts, the esp runs on 3.3 v), with functionality a lot like the NodeMCU, if you are familiar with those.
These modules are a lot easier to flash code onto and prototype with, but cost a bit more than the bare chip. As the USB UART and power conversion will cost you a bit of power as well, this will not be as efficient as using just a bare chip would be, So i might do that for rev3. When powering the Wemos via the 5-volt rails you are bypassing the UART, so this helps a bit.
Circuit
Code
For this project i used the ThingSpeak API And the ThingTweet. The first version of this was actually one of my first ever projects, so in the spirit of giving credit where credit is due i got a lot of the inspiration for it from this project.
You’ll need an API key for the ThingSpeak API, you can get this from their site for free. As this code uses the DeepSleep function, all the action is happening in the setup-block
#include <ESP8266WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 4 // DS18B20 pin
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
const char* ssid = "YourSSIDName";
const char* password = "YourSSIDPassword";
const char* host = "api.thingspeak.com";
const char* APIkey = "YourAPIKey";
const int SleepSeconds = 3600;
void setup() {
Serial.begin(115200);
delay(10);
// Connect to the Wifi Network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
float temp;
DS18B20.requestTemperatures();
temp = DS18B20.getTempCByIndex(0);
Serial.print("Temperature: ");
Serial.println(temp);
char charVal[12];
dtostrf(temp, 8, 2, charVal);
Serial.print("connecting to ");
Serial.println(host);
// Create TCP connection
WiFiClient client;
const int httpPort = 80;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
return;
}
// Create the URI for the request
String url = "/update?key=";
url += APIkey;
url += "&field1=";
url += charVal;//String(temp);
Serial.print("Requesting URL: ");
Serial.println(url);
// Send the request to the server
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
delay(10);
//DeepSleep for the set amount of time
ESP.deepSleep(SleepSeconds * 1000000);
delay(100);
}
void loop()
{
}
There you go! You can check out the current temperature over at @TerrasseTemp