ESP8266 IoT room thermometer – part 2

Having cobbled together an ESP8266 microcontroller, temperature sensor and TFT LCD screen, the next step was to have the device talk to a server.

There are two reasons for wanting to connect to a server: first, to get time and date updates; and second, to report the temperature and humidity so that the server can display them on an intranet web page and, maybe, log the data for later perusal.

And if you think that the initials MQTT are marching their way towards this post – well, they are, but only to be told to bugger off.

The web way

I have tinkered with MQTT. It is, after all, the protocol du jour for all things related to the Internet of Things (IoT). Indeed,  I’m half-way through a project in which I’m using an ESP8266 to control a bunch of neopixels in a wall light. The idea is to have a central server – actually, my Dawnclock – fade up the light in the morning.

That’s still a work in progress (I’m half-way through a lot of projects), but it taught me three things. First, MQTT is very easy to understand. Second, it’s reasonably easy to implement, although you do need specific server software running somewhere. And third, I found it difficult to get it to work with 100% reliability. More than a few messages would go missing.

For this temperature sensor project, MQTT seemed like overkill, to be honest. I already have an intranet server running (on a Raspberry Pi). It seemed much easier to use that.

Here’s a code fragment, so you can see what I mean.

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#define HTTP_SERVER "http://10.0.0.159/iotServer.php"
typedef enum {TIME_INFO, DATE_INFO} DatetimeInfo;
HTTPClient http;

void getDateTime(DatetimeInfo option) {
    String getRequest = String(HTTP_SERVER) + "?func=";
    if (option == TIME_INFO) {
        getRequest += "timereq";
    } else {
        getRequest += "datereq";
    }
    http.begin(getRequest);
    int httpResponseCode = http.GET(); // See here for list of possible responses: https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h#L45
    String httpData = http.getString();
    http.end();
    if (httpResponseCode == 200) {
        server_errors = 0;
        if (option == TIME_INFO) {
            timeStr = httpData;
            printTime();
        } else {
            dateStr = httpData;
            printDate();
        }
    } else {
        printError("Error contacting server");
        timeStr = "--:--";
        dateStr = "-";
        server_errors++;
    }
}

void sendDataReport() {
    String getRequest = String(HTTP_SERVER) + "?func=report&sensor=" + String(SENSOR_NAME);
    getRequest += "&data=" + dataString(DATA_FMT_REPORT);
    http.begin(getRequest);
    int httpResponseCode = http.GET();
    String httpData = http.getString();
    http.end();
    if (httpResponseCode == 200) {
        server_errors = 0;
        printMsg(httpData);
    } else {
        printError(String(httpResponseCode) + ": " + httpData);
        server_errors++;
    }
}

The various functions that start ‘print…’ (such as printMsg()) are defined elsewhere and simply put messages or data on the TFT screen.

At regular intervals I simply call getDateTime(TIME_INFO) or getDateTime(DATE_INFO) to get the current time or date. And, at somewhat longer intervals, I call sendDataReport() to transmit the current temperature and humidity to the server.

The HTTPClient class is very easy to use. Send a request and get back a payload, which in this case is the time or date suitably formatted and ready to throw up on the screen.

You can see how the code is simply interacting with a PHP script (iotServer.php) running on the server. I guess if you wanted to blow the whole thing out of proportion you could call this a REST API, but it’s hardly worth the name.

On the intranet server, the iotServer.php script saves the values to a text file. This is read by the web server when you visit the ‘IoT’ page and is displayed like this.

You can see I’m doing the same with the temperature sensor in the Dawnclock. I’m planning to add several sensors around the house.

It’s all very simple and works reliably.

Asking the time

After the last post, Richard P mentioned the idea of querying an NTP server to get the time, rather than the intranet web server.

I admit it had never occurred to me to use NTP. It’s an interesting idea and I started looking into it. A Beginner’s Guide to the ESP8266, available on GitHub, has a helpful chapter on how to access an NTP server for this very purpose.

In the end, though, I decided not to go this route (although I’ll bear it in mind for future projects). The reason is that’s it’s simply not necessary here.

I want the device to access the intranet server anyway – to report the temperature. That’s really the core functionality. And the intranet server has one advantage over an NTP server as a time source – it’s on the local network. Should our ADSL go down, the intranet server will still be able to provide the time to local devices such as this thermometer. There’s no reason for the thermometer to reach out to the Internet, nor for it to be reachable via the Internet.

Using the intranet server via HTTP allows me to adhere to an important principle – keep it simple.

Boxing day

Finally, I was going to talk about boxing up the device in this post. But as the PCBs haven’t arrived yet, that’s possibly a bit previous. So I’ll make one final post when the PCBs get here and I finish up the project.

 

Never miss a post

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.