The goal of this project is to learn more about wireless communication protocols in embedded systems by programming an ESP32 to serve temperature and humidity data to both a mobile phone (through bluetooth) and a computer (through wifi). It involves building a custom PCB with a sensor, display, and ESP32 module, and then programming that module to communicate with the wired components on the board and other devices wirelessly as mentioned.
- Built on a custom PCB.
- Serves weather data to a mobile phone via an app.
- Serves weather data to a computer via the browser.
- Serves a downloadable file of data history.
The hardware of the project consists of the ESP32 module, a DHT11 temperature and humidity sensor, a 1602 LCD display module, and an AMS1117-3.3 voltage regulator, along with the required peripheral components. The voltage regulator supplies the ESP32 module with the required 3.3V power, whereas the sensor and display run off the main 5V power. GPIOs are connected so that the ESP32 can communicate with the sensor and display.
This project is built on FreeRTOS, which allows us to schedule tasks that run concurrently without blocking. There are 5 main tasks:
- Read Temperature and Humidity
- Update LCD Display
- Bluetooth Low Energy GATT Server
- Connect Wi-Fi
- HTTP Server
The data communication protocol used by the DHT11 is a unique protocol based on timing. First, the open drain data bus is pulled low for 20 ms by the MCU to indicate a read request. Then, the bus is pulled low for 80 us by the sensor to acknowledge the request, followed by 40 data bits. The data consists of 8 bit humidity integral value, 8 bit humidity tenths place value (always 0), 8 bit temperature integral value, 8 bit temperature tenths place value (both in celsius), and 8 bit checksum. A 0 is transmitted as a 50 us low pulse followed by a 30 us high pulse. A 1 is transmitted by a 50 us low pulse followed by a 70 us high pulse. The code simply waits for the rising and falling edges and times the pulses to read the data.
Commands are sent to the LCD by setting the data lines into specific positions and then pulsing the E input. This task will initialize the LCD by putting it into two-line mode and removing the cursor. Then, when it receives a signal from the Read Temperature and Humidity task that a new message is available, it sends all the characters to the display one-by-one.
The BLE GATT Server is configured with a single service that contains 3 characteristics: temperature and humidity, SSID, and password. The temperature and humidity characteristic has a client configuration descriptor which allows the client to subscribe to notifications. This allows the ESP32 to send new data points immediately upon reading them from the sensor. The other two characteristics allow the client (mobile app) to upload wifi credentials so that the ESP32 can connect to wifi and host the website.
The connect_wifi task simply allows us to attempt to connect to the local wifi network using the stored credentials in nvs flash. When the user updates the credentials via the app, the new credentials are stored in the nvs flash memory.
The http_server task hosts the http web server which provides an alternative way to read the live temperature and humidity data from the ESP32. The IP address given to the ESP32 can be entered into the url bar of a web browser, which will perform an HTTP GET request to the ESP32. The code will take a template html file from the nvs flash and fill in the appropriate temperature and humidity data into the template, and then send the result as an HTTP response.
The mobile app is written using the Flutter framework, making it easy to deploy on both Android and iOS. It uses the FlutterBluePlus package to interact with the BLE GATT server on the ESP32. It features routines for connecting, reading temperature and humidity, subscribing to notifications, and uploading wifi credentials.