Thursday, November 11, 2021

Make an ESP8266 WiFi Temperature Sensor & Python Flask Backend - Part 1

Ok, yeah, it's true, I'm a "few" years late to the ESP IoT game. But now that I've finally gotten around to it, I thought it would be fun to start with an Internet of Things (IoT) temperature monitor as I have several use cases in mind:

  • Chest freezer monitor and alarm,
  • Measure temperature differentials between floors in my house,
  • Fish tank temperature monitoring and alerting,
  • Weather monitoring for vegetable garden
  • Template platform for deploying other kinds of sensors

For now, I'm going to prototype a temperature sensor that posts data to an API. I'll showcase several technologies and walk you through the process I use to develop projects like this. 

Here are the requirements I put together for the freezer monitor...

Requirements

  • Periodically measure the temperature
  • Sensor probe must be waterproof
  • Sensor operates wirelessly
  • Store the data centrally
  • Plot the data
  • At least +/- 1 Degree F accuracy
  • Alert the user if temperature is above the threshold

I felt it would be wise to create a simple remote temperature monitoring prototype that meets some of these requirements. I can always add features and make it ready for every at some later date.

I selected the following architecture to support rapid prototyping, provide reasonable accuracy

Architecture

The main components include:
  • WiFi-enabled IoT device with temperature sensor
  • Backend website
  • APIs running on the website to POST and GET temperature data
  • A JavaScript client application that plots data 

Technologies include:

  • Adafruit Huzzah ESP8266 
  • Arduino IDE and toolchain
  • DS18B20 temperature sensor in a water-proof housing
  • Huzzah posts measurements to an HTTP REST/JSON API
  • The API will be implemented with Python Flask on Linux Mint
  • Client-side JavaScript will plot data client-side with Chart.js 
  • The client-side JavaScript will request data via a REST/JSON API call

Here's a diagram showing the components and data flows.

The Huzzah is a breadboard-friendly ESP8266 implementation that's affordable and convenient to use.

For the backend API, I chose Flask, "a lightweight WSGI web application framework." It will be deployed to my Linux Mint system. Since Mint and Raspbian share a common ancestor in Debian this project shouldn't be hard to migrate to a Raspberry Pi.

Chart.js is a simple but flexible charting library.

I'll step you through the "iterative" process I usually followed in developing everything.

Writing Sensor Firmware

We'll start with the code to measure the temperature using the DS18B20. This is a Dallas Semiconductor sensor that uses 1-Wire Protocol. Such a sensor uses a single line for data plus a ground wire and an optional power wire.

DS18B20

The easiest approach is to start with the example sketch for the temperature sensor. You'll need to grab two libraries using Arduino Library Manager: OneWire and DallasTemperature. Next, open File > Examples > DallasTemperature > Simple example sketch. Connector your sensor, compile and upload the sketch, open Serial Monitor, and make sure the sketch is working. 
 
Save it, as we are going to add code to it later to meet our requirements.
 
My source code for this step.

HTTP Client & ESP-Touch

Next we need to know how to get the ESP8266 to connect to a URL. For this I opened a new example sketch: File > Examples > ESP8266HTTPClient > PostHttpClient.

You may notice STASSID and STAPSK are pre-processor macros in the source. They're intended to contain your WiFi SSID and PSK (password). You really, really do NOT want to hard-code this sensitive data into your source code, especially if you check it into a source code repository.

Fortunately, you don't have to. Espressif provides ESP-Touch Protocol with an app for Android and iOS that will conveniently provide your newly-flashed ESP devices with the SSID and PSK for your WiFi AP.

To make use of this capability, install the EspTouch app, open it, and fill in your SSID and Password (PSK) information. 

Then, in your Arduino source, replace the line:

WiFi.begin(STASSID, STAPSK); 

with:

WiFi.beginSmartConfig(); 

and delete the following lines:

#ifndef STASSID
#define STASSID "ssid"
#define STAPSK  "password"
#endif

Finally, change the SERVER_IP macro to your backend web server's IP. (I don't love the idea of hardcoding the IP address, but we can fix that later).
 
For now we just need to make sure the ESP8266 connects to our WiFi Access Point (AP). Upload the sketch and open Serial Monitor. The ESP should be printing out "." repeatedly. Now, open your EspTouch app and fill in the SSID and Password (PSK). Press Confirm to send the WiFi config to the ESP8266. The app will tell you when it succeeds and the ESP will indicate it's connected to your AP.

You should see something like this in Serial Monitor:

.......................................................
Connected! IP address: 192.168.1.76
[HTTP] begin...
[HTTP] POST...
[HTTP] POST... code: 404

So the WiFi connection works, but of course the POST fails because my Linux host, which happens to have a web server running, hasn't implemented /postplain, hence the 404 error. If your host didn't have a web server, you'd get a different error (usually "connection refused" or "timeout") 

My source code for this step

In the next article we'll work on the Python Flask backend.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.