How I used DHT22, ESP32 and Raspberry Pi to troubleshoot our refrigerator

Arkajyoti Misra
12 min readFeb 1, 2021

We had a problem with our refrigerator, which is less than five years old. It would stop cooling the main compartment abruptly and would start behaving normally after a period of time and would work just fine until it would stop working again. The freezer was working just fine so I could rule out a compressor issue.

What was frustrating is the erratic nature of the problem and we ended up wasting a lot of food over a few weeks. After reading a bunch of posts on the web and going through some YouTube videos, a potential culprit emerged. It seemed the fan responsible for distributing the cool air within the main compartment could stop working if there was an ice build-up. It appeared to be somewhat of a common problem for this brand. We defrosted the fridge a couple of times but that did not solve the problem.

Before calling for professional help I wanted to gather some data about this anomalous behavior. The last thing I wanted was to have a technician paying us a visit only to find everything is running just fine. Reproducible problems are easier to diagnose than random ones.

With some effort I was able to consistently track the temperature inside the fridge for several days, called a technician and showed him the pattern. He was quite confident that the motor driving the fan was indeed the source of the problem. Unfortunately, he refused to replace the motor as the solution would not be long lasting.

I was not ready to give up yet. I would hate to see the refrigerator end up in a landfill for a relatively minor problem. So I replaced the faulty motor myself following some YouTube videos. Fortunately, it turned out to be a good decision. I continued to track the temperature for several weeks after replacing the motor and plotted the trend in the graph below. You can clearly see how at the beginning the inside of the refrigerator kept warm for days at a stretch before the motor was replaced, indicated by the red line. There has been no temperature fluctuations since and the temperature has been staying steady at around 5 degrees centigrade (41 degrees Fahrenheit). No more wasted food.

It took a lot of technology components to work together for me to get a graph like this. I believe this is a golden age for electronics hobbyists with a lot of easy to program components available with the emergence of the Internet of Things. I learnt a lot from tutorials that other hobbyists have kindly shared and had a blast doing this little experiment. So I thought why not share my experience because it might just help a few folks who love to tinker.

Hardware

There were not many parts required for the project, I just needed a temperature sensor and a microcontroller to drive it. The choice of the microcontroller was dictated by two major criteria. First, it had to be a low power device so that I could run it on battery power over several days at a stretch. Next, it had to have the ability to communicate over the WiFi. Both criteria were met by two very popular microcontrollers on the ESP platform: ESP8266 and its newer cousin ESP32. I picked the latter for my project. For the temperature measurement, a host of very reasonably priced sensors were available, like BME280, DHT11 and DHT22. I went with DHT22 as it was more accurate than DHT11 and there was no need to solder as with BME280.

The remaining piece of hardware I used was a Raspberry Pi to communicate with the microcontroller for gathering the sensor data, run a database server for storing the data and dynamically update a dashboard that I could access from any device connected to my home network to monitor the temperature trend. I could have used a regular computer instead, but I was more comfortable running a Raspberry Pi because of its very low power consumption.

Preparation

There were two primary choices to program an ESP32 board. One could either use the Arduino platform and use the C++ like Arduino programming language or use MicroPython, a lightweight version of python for microcontrollers. I had a reasonable amount of experience with Arduino but I was looking for an opportunity to learn MicroPython, so I took the latter route.

A micro USB port is used to power the ESP32 board and also for data transfers. The first piece of information I needed was the Raspberry Pi serial port to which the ESP32 was connected to, which I could get using dmesg command on the Raspberry Pi.

dmesg | grep tty[79382.661407] usb 1-1.4: cp210x converter now attached to ttyUSB0

The important information to note here was that serial port ttyUSB0 was to be used for all communications. The first task was to prepare the ESP32 board, for which the MicroPython documentation had a very useful getting started guide.

To deploy the firmware on ESP32, I used esptool, a python tool for communicating with ESP32, and erased the board clean.

python3 -m pip install esptoolesptool.py --port /dev/ttyUSB0 erase_flash

Next, I grabbed the latest stable firmware from the MicroPython download page (ESP32-idf3–20200902-v1.13.bin was the latest binary available at that time) and installed it on ESP32.

esptool.py --chip ESP32 --port /dev/ttyUSB0 --baud 460800 write_flash -z 0x1000 ESP32-idf3-20200902-v1.13.bin

There were many different available IDEs for accessing the EP32 filesystem, like uPyCraft or Thonny, but I picked the command line tool rshell for its simplicity. After a pip install on the Raspberry Pi

python3 -m pip install rshell

I could start a new rshell session by typing

rshell --buffer-size=30 -p /dev/ttyUSB0

Typing boards at the rshell prompt showed some useful information.

/home/pi> boards
pyboard @ /dev/ttyUSB0 connected Epoch: 2000 Dirs: /boot.py /pyboard/boot.py

It confirmed the ESP32, identified here as pyboard, was connected to the serial port of the Raspberry Pi and there was just one file named boot.py available on the ESP32 filesystem. The python code in boot.py is the first to get executed when the ESP32 is powered up. Typing repl brought up a REPL prompt where I could interact with the ESP32 using regular python commands:

/home/pi> repl
Entering REPL. Use Control-X to exit.
>
MicroPython v1.13 on 2020-09-02; ESP32 module with ESP32
Type "help()" for more information.
>>>

Wiring

It was now time to connect the DHT22 to the ESP32 board. The DHT22 I had was a newer version of the sensor and came with 3 pins as opposed to 4, which made the connection easier. I connected the negative, positive and the output pins of the DHT22 to the ground, 3.3 volt, and D23 pins of the ESP32 respectively.

To check if the DHT22 was functioning properly I used the rshell.

>>> import machine
>>> import dht
>>> pin23 = machine.Pin(23, machine.Pin.IN, machine.Pin.PULL_UP)
>>> sensor = dht.DHT22(pin23)
>>> sensor.measure()
>>> sensor.temperature()
20.4
>>> sensor.humidity()
44.7
>>>

Both the temperature and humidity readings appeared to be reasonable. Now it’s time to establish wireless communication between the ESP32 and the Raspberry Pi.

Communication

I still had the ESP32 connected to the Raspberry Pi, but eventually I needed to put the ESP32 inside the refrigerator and I had no desire to put the wrong kind of pi, one that’s not edible, there. There were multiple ways the Raspberry Pi could talk to the ESP32 board and grab the sensor data. I used MQTT, a lightweight and simple messaging protocol based on the publish-subscribe (pub-sub) model. Under this model the MQTT server works as a broker where a client, called a publisher, can publish data to a topic and another client, called a subscriber, can subscribe to that topic and access new data as soon as it arrives.

In my case, the MQTT broker would be running on the Raspberry Pi and the ESP32 would be publishing the sensor data to it. The Raspberry Pi also acted as the subscriber in my case because I would store the data on it in a database.

First I needed an MQTT client for the ESP32. A good candidate was the umqtt module from micropython-lib. I needed to save the simple.py file onto the ESP32 under the directory umqtt, which I could conveniently do using rshell.

/home/pi> mkdir /pyboard/umqtt
/home/pi> cp simple.py /pyboard/umqtt/

On the Raspberry Pi I used mosquitto, an open source implementation of MQTT. First I needed to install both mosquitto and mosquitto-client on the Raspberry Pi.

sudo apt install mosquitto mosquitto-clients

The next step was to set the ESP32 to publish the sensor data to an MQTT topic at a regular interval. It was achieved by uploading the following code in the main.py file on the ESP32.

The IP address of the Raspberry Pi, the MQTT broker, was supplied in line 17. Lines 20–21 set up pin 23 of the ESP32 to the out pin of the DHT22. A client id, defined in line 27 and the broker IP address were required to instantiate and connect the MQTT client as defined in lines 39–40. The infinite loop from lines 43–55 took the sensor measurement and extracted both temperature and humidity readings from it and packed them in a string. The string was published to a topic called temp_humid, defined in line 28. This was done at a regular interval of 60 seconds, defined by sleep_time in line 14. The job of the for loop starting in line 30 was to turn the ESP32 on-board blue LED on and off 3 times whenever the board was powered up. This little feature turned out to be very useful to make sure the ESP32 was responding on reconnect.

I was now done setting up the MQTT broker (Raspberry Pi) and the publisher (ESP32). The next step was to set up a client to subscribe to the temp_humid topic where the ESP32 would be publishing the sensor reading. Here all I had to do was to set up the Raspberry Pi as a subscriber to the topic. The mosquitto command line tool was a quick and easy way to test if there was any data published to the topic.

$ mosquitto_sub -d -t "temp_humid"
Client mosqsub|20243-pi0402 sending CONNECT
Client mosqsub|20243-pi0402 received CONNACK (0)
Client mosqsub|20243-pi0402 sending SUBSCRIBE (Mid: 1, Topic: temp_humid, QoS: 0)
Client mosqsub|20243-pi0402 received SUBACK
Subscribed (mid: 1): 0
Client mosqsub|20243-pi0402 received PUBLISH (d0, q0, r0, m0, 'temp_humid', ... (10 bytes))
20.2, 49.6
Client mosqsub|20243-pi0402 received PUBLISH (d0, q0, r0, m0, 'temp_humid', ... (10 bytes))
20.2, 49.6

Hooray! I could access the sensor data. Now I needed to automate the process. I used the paho-mqtt python library for that, which I installed using pip.

python3 -m pip install paho-mqtt

The starter code provided by the creators of the library was good enough for the task at hand, which I incorporated in my solution with some minimal modifications.

Until now I had the ESP32 connected to the Raspberry Pi through the USB cable. Now I needed to make sure the Raspberry Pi could collect data over a wireless network. I needed to make sure the ESP32 would connect to WiFi as soon as it was powered up.

The piece of code necessary to ensure that would go in the boot.py file on the ESP32, where it would import the network module and attempt a fixed number of times to connect to the wireless network with the provided SSID and password. Finally it would print the IP address upon successful connection as a confirmation.

Database

I wanted to gather a sensor reading every 60 seconds. My intention was to monitor the cooling trend of the refrigerator over several weeks or even months and analyze it to see if any particular pattern emerged. Therefore, a time series database turned out to be a natural choice for my use case.

My time series database of choice was InfluxDB, which was quite easy to set up and use on the Raspberry Pi following this excellent guide.

First I added the InfluxDB repository key and installed the package for Raspbian Buster, which was the OS version I was running on my Raspberry Pi.

wget -qO- https://repos.influxdata.com/influxdb.key | sudo apt-key add -
echo "deb https://repos.influxdata.com/debian buster stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
sudo apt update
sudo apt install influxdb

The following commands made sure the database service automatically started following a reboot.

sudo systemctl unmask influxdb
sudo systemctl enable influxdb

Finally, I needed to start the service on the Raspberry Pi.

sudo systemctl start influxdb

I could now start interacting with InfluxDB through the handy shell interface it provides. The first thing I wanted to do was to password protect the database by creating an admin user. This step guaranteed that no unauthorized user could modify the database.

$ influx
> CREATE USER admin WITH PASSWORD '<password>' WITH ALL PRIVILEGES
> exit
$

For the authentication to take effect, I added the following lines to the /etc/influxdb/influxdb.conf file under the section [http]. This file could be modified only as a sudo user.

[http]
auth-enabled = true
pprof-enabled = true
pprof-auth-enabled = true
ping-auth-enabled = true

Finally, the database service had to be restarted for the changes to take effect.

sudo systemctl restart influxdb

Now I could enter the InfluxDB prompt with the authentication I created at the previous step

influx -username admin -password <password> -precision rfc3339

and create a new database ESP32_fridge for storing the sensor reading.

create database ESP32_fridge

I used the influxdb-python library for python to interact with the new database, which could be pip installed.

python3 -m pip install influxdb

Now I could communicate with influxdb through the python REPL and confirm the existence of the database I just created.

$ python3
>>> from influxdb import InfluxDBClient
>>> client = InfluxDBClient(host='localhost', port=8086, username='admin', password='<password>')
>>> client.get_list_database()
[{'name': '_internal'}, {'name': 'ESP32_fridge'}]
>>>

I could see that the newly created ESP32_fridge database was there. The next step was to create a file called log_data.py where I’d put all the python code required for collecting data from the MQTT broker and saving it in the database.

The log_data.py script would be continuously running on the Raspberry Pi. When the script was invoked, the run_loop procedure would run forever. The MQTT client would subscribe to the temp_humid topic as defined in the on_connect procedure. It would capture the sensor reading whenever one was published to the same topic and would put it into a JSON format, called json_body in the procedure on_message. This was a required step because the influxdb client inserts new data in a database in JSON format. The body of the message json_body also contained the current time in the time field, an essential part for a time series database.

"time": datetime.datetime.utcnow()

It was necessary to save the time in UTC format for plotting the temperature time series properly. Finally, the log_to_db procedure was called with this JSON data, where the sensor data was inserted into the database.

The log_data.pywould need to run on the Raspberry Pi continuously. To ensure the script would restart automatically upon a reboot, I created an entry like this in the crontab file:

@reboot sleep 60 && log_data.py

I added a delay of 60 seconds before kicking off the job to make sure the boot process was complete before the script kicked in. Finally I needed to make sure the script was executable.

$ chmod u+x log_data.py

Visualization

For displaying the sensor data, I used Grafana, which is a beautiful piece of software for visualizing time series data with minimal effort from the user. I followed this guide to install Grafana on the Raspberry Pi:

wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
sudo apt update
sudo apt install grafana

Next I needed to start the Grafana server and make sure it too was setup to automatically restart upon reboot.

sudo /bin/systemctl enable grafana-server
sudo /bin/systemctl start grafana-server

Now I could access the database from any computer by pointing to the IP address of the Raspberry Pi and looking at port 3000. The initial setup involved setting up the InfluxDB database esp32_fridge as the data source, and creating a simple query like the following:

SELECT temperature from fridge_temp

Note that fridge_temp was the name of the series (as opposed to table for a regular database) I defined in the JSON data in log_data.py earlier. I ended up using only the temperature, as the humidity measurement did not show any useful trend.

I kept an eye on the dashboard mostly from my mobile phone. The Grafana dashboard displayed the graph very well even on a small screen. There were plenty of useful features available to make the plot pretty but the Grafana feature I was happiest about was the ease with which I could change the time range of the plot.

Final Note

Now that’s it. It was fun creating this solution, where I had to learn a lot of pieces as I went. Before I finish, I wanted to mention one last thing about the temperature plot. If you are curious why there were so many breaks in the plot, it was caused by periods when the battery ran out and the ESP32 stopped working.

--

--