Introduction and Motivation
I want to adjust and monitor the performance of my home HVAC system to improve energy efficiency. I have a single HVAC unit in a two story house with a split plenum to divide the airflow between the two levels. I'd like to optimize the air baffle adjustment between the upper and lower floors for the different seasons (heating vs cooling). I'd also like to have a method of monitoring system performance to know when I need filter replacement or other equipment maintenance.
Project Overview
To optimize the airflow I would use a system of remote temperature sensors (initially 3 -> 1 each at an air outlet register on each floor and 1 at the air return inlet on the first floor). I would adjust the baffle position to best equalize the temperature differential between floors. The system would continuously monitor the temperature between floors and also between the outlets and the return inlet and send an alert if the differentials were outside set limits (separate limits for heating and cooling). To monitor system health I would use a main control unit attached to the HVAC unit to monitor system sound and vibration patterns.
I would use ESP32 units with temperature sensors added as the remote sensors. I would use the QuickFeather board as the main controller and take advantage of the MEMS microphone and the accelerometer to do the sound and vibration sensing. I would add an ESP32 unit to connect with the QuickFeather via UART to allow communication with the remote sensors and the SensiML cloud. I would use the SensiML Toolkit to train a model to detect abnormal operating conditions.
To facilitate communications with the remote sensors and the main controller, I am going to use MQTT over WiFi. I will set up a Mosquitto MQTT broker (server) running on a Raspberry Pi 4.
Building the Project
Step 1: Build the remote sensors
For the remote sensors, I am going to use an M5StickC Plus with a BME280 temperature/humidity sensor. The M5StickC Plus is an ESP32 module with a small display and internal battery. I am using the I2C interface on the top module connector with the BME280 sensor. I am going to mount these sensors on the inlet and outlet vent registers, so I 3D printed a mounting plate and mounting clip for each unit.
Below is the sensor for the first floor inlet. The sensor publishes temperature, humidity, and battery level data using MQTT and also displays the data locally.
Step 2: Install MQTT and create HVAC Dashboard
I am using a Raspberry Pi 4 as the host for the MQTT broker, so installation is reasonably straightforward.
Install Mosquitto Broker
pi@RPi4Two:~ $ sudo apt update
pi@RPi4Two:~ $ sudo apt install -y mosquitto mosquitto-clients
pi@RPi4Two:~ $ sudo systemctl enable
pi@RPi4Two:~ $ mosquitto -v
1617484295: mosquitto version 1.5.7 starting
1617484295: Using default config.
1617484295: Opening ipv4 listen socket on port 1883.
Install Node-RED
pi@RPi4Two:~ $ bash <(curl -sL https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/update-nodejs-and-nodered)
To automatically run Node-RED when the Pi boots up, you need to enter the following command:
pi@RPi4Two:~ $ sudo systemctl enable nodered.service
pi@RPi4Two:~ $ reboot
Node-RED will default to port 1880, so to start the visual programming environment in a browser just use URL http://YOUR_RPi_IP_ADDRESS:1880
Node-RED is a visual programming tool that allows you to easily create functional flows using functional node elements. In this case I am building MQTT publish and subscribe flows and implementing a dashboard. The node-red-dashboard module is a set of nodes that are used to create a live data dashboard. To install into Node-RED:
pi@RPi4Two:~ $ node-red-stop
pi@RPi4Two:~ $ cd ~/.node-red
pi@RPi4Two:~/.node-red $ npm install node-red-dashboard
pi@RPi4Two:~/.node-red $ sudo reboot
The dashboard shows up at http://Your_RPi_IP_address:1880/ui
Here is the flow that I set up for the Floor1 Remote Sensor:
And the display on the dashboard for the Inlet Remote Sensor (same basic flow for all remote sensors):
Step 3: Build Main Controller
I purchased a plastic case to house the controller's two boards and the LiPo battery. I printed a mounting plate to hold the proto PCB that is used to interconnect the boards and to separate it from the battery which is mounted under it.
The completed assembly mounted in the case. When the unit is deployed it will be powered by a USB power adapter because the battery will only last several hours if I am doing continuous monitoring. The battery is mainly used for testing and development. The switch on the right is to shut off battery power.
Step 4: Program the Controller Boards
The primary board in the controller unit is the QuickLogic QuickFeather. The QuickFeather uses an ARM Cortex M4F MCU which is augmented with an EOS S3 FPGA. For my project I am initially only using the MCU capability. The QuickFeather also has 2 onboard sensors that I'll use with my project, an mCube MC3635 accelerometer and a Infineon IM69D130 PDM digital microphone. I'll use the accelerometers to measure the HVAC unit vibration during operation and the microphone to detect audio. For my initial proof of concept, I'm only going to implement the accelerometer because I haven't figured out how to use both sensors simultaneously with TinyML. The QuickFeather is programmed using the TinyFPGA Programmer Application. Initially, for capturing data the QuickFeather is programmed with a precompiled binary for the Simple Stream data collection.
I am using a Win 10 PC for the development computer, so all instructions are relative to that. I should also mention that I had issues connecting to the USB serial device on the QuickFeather. I could only get it to work on 1 of 3 computers and I was never able to resolve this issue even after posting on the QuickLogic forum. Obviously, all development is done on that one computer that would connect.
Flashing the QuickFeather firmware requires that Git and Python 3.6 or greater are installed on on the development computer. The TinyFPGA Programmer used for flashing is a Python program. There is good documentation for flashing here: https://sensiml.com/documentation/firmware/quicklogic-quickfeather/quicklogic-quickfeather.html#flashing-quickfeather-firmware.
To flash the Simple Stream firmware to the QuickFeather MCU it is simplest to put the quickfeather-data-collection.bin file in the same directory with the tinyfpga-programmer-gui.py and execute the command in that directory: (replace COMX with the appropriate com port)
python tinyfpga-programmer-gui.py --port COMX --m4app quickfeather-data-collection.bin --mode m4
Reset the QuickFeather and once the LED stops flashing blue, the board is now streaming accelerometer data to the UART port.
I am going to be using the QuickFeather remotely, so I need to add a WiFi interface. I used the Adafruit HUZZAH32 Feather board. I set it up and programmed it per the instructions here: sensiml/esp32_simple_http_uart.
The HUZZAH32 is programmed using the ESP-IDF framework to be a UART to HTTP bridge. Using the instructions it is straightforward to configure the WiFi SSID/Password, but not having used ESP-IDF before - I could not figure out how to configure a Static IP. My XFinity router is having problems reserving an IP for the MAC address of the HUZZAH32, so unfortunately I have a problem that it gets periodically assigned a different DHCP IP address. To work around this I use an Android application - Fing to find the IP address corresponding to the HUZZAH32 Mac address.
Step 5: Install SensiML Analytics Toolkit
SensiML offers a free Community Edition of the Analytics Toolkit Community-Edition. You just need to register for an account. The two components of the Analytics Toolkit that I'll be using for this project are the Data Capture Lab (DCL) and the Analytics Studio.
Data Capture Lab has a Windows Installer that you can download from here: SensiML Data Capture Lab.
SensiML Analytics Studio is a Web application that doesn't require a download. It is located here: SensiML Analytics Studio
Step 6: Capture HVAC operating data for training TinyML model
I tried different locations on the HVAC unit's frame for sensitivity and I settled on the side adjacent to the water heater.
Within Data Capture Lab the Sensor is selected and the Device connected.
The IP address is already different from what it was previously.
Then Capture Properties need to be set. I'm using 4 different data labels for the different HVAC modes.
And I am capturing Train and Test data sets
Because the HVAC Unit has reasonably long cycle times between modes. I can capture a lot of data in each mode. I set Capture (Max Record) time to 5 minutes (300 seconds).
This is a capture of the HVAC transitioning from Off to Furnace.
A close up of the transition. The Z axis is orthogonal to the panel and shows the largest amplitude. I may be able to use only the Z axis data for the model, but I'll initially use all axes in case there are nuances between the modes.
Project Explorer showing the collected data sets.
Next I need to segment the data which will be easy to do manually because the data is fairly distinct. Using the previous example we can just select the sample segment that represents the Furnace and deselect the rest.
Step 7: Build TinyML model
Data Capture Lab automatically uploads all of the project data to the cloud, so it is immediately available when you log into SensiML Analytics Studio. Here is the top level view of my project:
The first step is to select the data that will be used to train and test the model. To do this you construct a query that will extract the data from the collected data. The AC unit of my HVAC system is still winterized, so I'll collect data and create a new model including that data later. Here is the query that I built for the Off, Fan, and Furnace classes. There are 6 data sets per class (5 training, 1 test).
Then you build a pipeline to process the data using AutoML. AutoML will basically figure out the best elements to use for the model based on the type of segmenter used and the accuracy and size constraints. Since this is time series data, I'm using a windowing segmenter with a 1 second window (100 samples at 100 Hz). AutoML will then build 5 classifier models for you to evaluate.
In my case the modes are quite distinct so AutoML is able to get accuracy with fairly simple models. Distinguishing AC (which uses a remote compressor) and maintenance conditions like a dirty filter may require a much more complex model if only using accelerometer data. But a simple model will allow me to validate the process of building and deploying a model.
Here are some details of the first pipeline (model). It has good feature separation which allows it to achieve high accuracy (99%).
Then the model is tested against the test data sets.
And achieves good accuracy.
Step 8: Deploy and Test TinyML model
There are two deployment options from Analytics Studio. It can build a binary file that can be flashed to the QuickFeather that provides a simple recognition streaming interface that can demonstrate classifier operation or it can create a library that can be integrated with custom code.
To test the model, I'm going to download a binary of the Knowledge Pack that is configured for the QuickFeather board and use the Simple-Streaming Gateway Application to monitor the Classification (Recognition) results.
I downloaded and flashed the Knowledge Pack binary to the QuickFeather using the tinyfpga-programmer.
The Simple-Streaming-Gateway is a Python program that is run on the host PC.
It runs in a browser window on the host - http://localhost:5555. The gateway can be used for both Data Capture and Recognition.
This video shows a test of the model with normal thermostatic control of the HVAC furnace. The thermostat was initially at the control point, the temperature dropped 1 degree below the set point and the furnace turned on. At about 1 minute into the video, you can see the unit transition from Off to Fan to Furnace (3-1-2). And at about 2 minutes the temperature reaches the set point and the unit transitions back to Off (2-1-3). (The video has been edited for brevity)
So, the model is working as expected. One thing that I did encounter is that with the Community Edition of Analytics Studio, there is a limit to the number of classifications you can perform on the device per power cycle. Initially, this limit only allowed me to run for 15 minutes. SensiML has since increased the limit 100X, so I can now run continuously for 25 hours.
I would like to use an enhanced model for PM (preventative maintenance) of the HVAC, so in that case I'll need to get a paid subscription or possibly use a method to automatically reset the QuickFeather once a day.
Step 9: Integrate Recognition with HVAC MQTT Dashboard
In order to utilize the HVAC mode classification with the MQTT Dashboard requires being able to publish the recognition data from the QuickFeather. Since I am doing this over WiFi, I'm going to use an MQTT client on the HUZZAH32 board. I initially intended to program the HUZZAH32 using ESP-IDF, but I ran into problems getting the MQTT/tcp library example to compile. I was getting 'MQTT_ERROR_TYPE_TCP_TRANSPORT' undeclared errors. I tried syncing submodules and even reverting to the previous version to no avail. At that point I switched to using the Arduino IDE to program the HUZZAH32. I used the PubSubClient library (like I did with the remote temp sensors) to set up MQTT and I used the ArduinoJson library to parse the recognition JSON object that the Knowledge pack was sending over the UART. Then I publish the recognition classification as the topic "hvac/mode". I also publish the numeric classification as "hvac/classification" for plotting.
I updated the HVAC Dashboard as shown below to show the HVAC mode and classification. The HVAC status is not currently active. Eventually it will be a function of different sensor inputs in different HVAC modes (TBD). Example Status categories would be Good, Fault, or Maintenance (req'd).
I also added a Reset button to reset the QuickFeather when the Classification limit has been reached. I'll probably automate this to reset everyday at midnight. Haven't decided whether to do that via Node-RED or in the HUZZAH32 firmware.
And I decided that it would be nice to have the temperature, humidity, and battery status at the controller, so I added a BME280 to the HUZZAH32.
Here is a video showing the Mode and Classification Number changing as the Furnace cycles On and Off. The unit does transition through a short period of Fan only, but I am publishing at 30 second intervals so the Fan cycles aren't always captured. I've sped the video up 20X as the Furnace was on for about 8 minutes.
And here is the complete data capture cycle in the afternoon showing the system converging to a steady state control point (because this is in a "Heat" mode the system achieved the set point and didn't cycle for the rest of the day - the outside temperature was around 58 F, so the house is sufficiently insulated to maintain the 66 F set point without additional heat).
Step 10: Capture Remote Sensor data to verify air baffle adjustment
I have my register temperature sensors in west facing rooms. The register positions are approximately aligned vertically. I realized that I am going to get different control dynamics between the morning and afternoon (and between heating and cooling). I decided that the for heating that I wanted to have the baffle setting for the initial furnace cycle in the early morning when the system is coming out of the overnight temperature setback. Since the baffle is set to decrease the airflow to the warmer second floor bedroom, it has the effect of damping the thermal response. Here is the initial two cycles in the morning that get the system settled to the control point.
Here is the zoomed in view:
The initial temperature differential is about 8 degrees F and after 2 cycles it is about 1 degree F, so I think that validates the current adjustment. I'll need to redo this for cooling. Ideally, at some point I could install a motorized baffle for continuous adjustment.
Project Summary and Next Steps:
I think that I've established a good baseline for my project. I still need to add the AC mode to the model and I'd also like to add audio input (both at the controller using the QuickFeather microphone and also with a remote audio and vibration sensor at the outside compressor unit). I'll need to get a fair amount of data to see if I can detect maintenance or fault conditions with vibration and sound.
I've learned a lot about Machine Learning using the SensiML Analytics ToolKit. It is a full featured and robust framework. I hope to use it in future projects where I can use its customizable model capability.
I did not fully utilize the capabilities of the QuickFeather. I think for me the learning curve was too steep, especially when trying to integrate other hardware. I am starting to encounter more opportunities to use Zephyr with other IoT hardware, so I may try to use more of the QuickFeather features in the future. For this project the FPGA wasn't necessary, but it was nice to try some of the examples provided.
Comments