Introduction: Raspberry Pi Zero W Based Personal Temperature Controller
Space heaters usually come with a thermostat for temperature control. The temperature control is done at the heating device and are might not be where you are located. Also, a lot of the space heaters just have a numbered dial for temperature control and not actual temperature settings. I wanted to be able to detect the surrounding temperature where I am sitting at and use that to control a space heater to warm my surrounding to the desired temperature level. My goal was to have to do a minimum amount of work and at a reasonable cost. Also, I want to be able to see and control things from my mobile phone. The approach I took was to use a Raspberry Pi Zero programmed with Python as the temperature controller and and an off-the-shelf AC power relay to switch the space heater on and off.
Supplies
Here is the list of components that I used (prices are at time of writing and for reference only):
- Raspberry Pi Zero W ($10) - There is an updated Raspberry Pi Zero 2 W ($15) that can be used as well.
- Raspberry Pi Zero case ($5.95) - This comes with three different type of cover and a Mini Camera Cable. We will just be using the fully enclosed cover for this.
- DHT22 temperature sensor ($9.95) - This comes with a 10K ohm resistor that we will need to use.
- Controllable Four Outlet Power Relay Module ($32.95) - This has an always-on outlet to power the Raspberry Pi Zero W.
- 16GB Micro SD Card ($7.73) - Can use a 8 GB Micro SD card for this if you have one lying around.
- 5V power adaptor and micro USB cable - I used one left over from an old Android phone I had. You probably have these 5V power adaptors and micro USB cables lying around. The standard Raspberry Pi Zero W power adaptor is 1.5A but I found that a 5V 1A adaptor worked OK for me.
- Breadboard Jumper wires ($6.98) - Pack comes with 120 pieces of different jumpers. I used 2 male-to-female and 3 female-to-female Breadboard Jumper Wires.
- Break-away Male Header ($4.95) - There are 10 pieces of the 36-pin 0.1" Short Break-away Male Header in the package. We plan to break off 6 pins for this. So, if you have these header pins lying around, go ahead and use them.
- Right angle metal bracket (optional)
- Space Heater - I used an oil-filled radiator type space heater. Your can choose your own of space heater (the power relay module can switch a heater up to 1440W).
Here are the tools I used:
- Computer with a SD card reader/writer to prepare and program the Raspberry Pi 2 W
- HDMI monitor with standard-to-mini HDMI cable (or regular HDMI cable and mini HDMI adaptor)
- Keyboard and mouse with Micro USB Male to USB Female OTG Adapter and USB Hub
- Soldering iron and appropriate solder for the soldering iron
- Hot glue gun and appropriate hot glue
- Scotch tape
- Small slotted screw driver
Step 1: Prepare the MicroSD Card
The Raspberry Pi Zero W depends on an operation system (OS) software that will be loaded onto the microSD card to run. Raspberry Pi Imager is the quick and easy way to install Raspberry Pi OS to a microSD card, ready to use with the Raspberry Pi Zero W.
Please go to the official Raspberry Software page to download and install the appropriate Raspberry Pi Imager onto your computer. Make sure you have a microSD card reader on your computer. Once the Raspberry Pi Imager has been installed on your computer, run it. Insert the microSD card into the reader on your computer.
From the Raspberry Pi Imager interface window, click "CHOOSE OS" and from the drop-down menu, select "Raspberry Pi OS (32-bit)". Click "CHOOSE STORAGE" to open up a selection window showing the devices that the Imager can write to. If you have inserted the microSD card, an item with "SD Card - 16GB" (or 8GB, if that is what you inserted) should show up. Select that item. Now, click "WRITE". The Imager will install the Raspberry Pi OS onto the SD card.
After the OS has been installed onto the microSD card, remove it from the reader and and save it for the step when we assemble the Raspberry Pi Zero W board in Step 3.
Step 2: Prepare the Raspberry Pi Zero W Board
This step will require some small amount of soldering. The Raspberry Pi Zero W board has two rows of 20 hole pads next to each other on one edge of the board. Each hole pad has a pin number assigned to it. All the hole pads are round except for one. The square hole pad signifies Pin1. Pin2 is next to it towards the 2-hole row direction and Pin3 is next to Pin1 back to the long row direction. So the old numbered pins are on one side of the long row of hole pads while the even ones are on the other long row (see photo above to verify your understanding).
Connecting to these hole pads will allow the Raspberry Pi Zero to interface with external devices. We will primarily use the Power, Ground and a couple of GPIO (general purpose input/output) pins. We will not cover the details of what all the pins are here. Spark Fun has a pretty detailed getting stared tutorial for the Raspberry Pi Zero W if you are interested to find out more.
For this, we are going to break off 6 of the header pins from the 36-pin male header and insert that into the holes for Pins 6, 8, 10, 12,14 and 16. Make sure your are inserting the pin headers from the bottom of the board (see above photo for illustration). Solder pins 6, 14 and 16 on the top of the board. You can solder all 6 Pins but we will just be using 3 of the pins. Best way is to hold the header in place and solder one of the pins on the end and let it cool down. This will keep the header in place for you to complete soldering the rest of the pins.
Next, we will solder the 10K ohm resistor that came with the DT22 onto Pin1 and Pin11 of the board. Best way is to bend the leads of the resistor so that it would fit snuggly into the holes. Make sure you insert the resistor from the top of the board (see photo above). You can solder the resistor from the top to tack it down. However, be sure to add solder on the bottom of the board to fully secure the resistor onto the board.
The final step is to trim back the resistor leads to about the same length as the header pins and also straighten the two leads so they point out like the header pins.
Step 3: Assembling the Control Module
Insert the prepared microSD card from Step 1 into the microSD card slot of the Raspberry Pi Zero W (see photo above). Install the Raspberry Pi Zero W board into the case (red part). Make sure the openings are aligned with the connectors. The header pins and resistor leads should stick out of the long open slot in the bottom of the case. The board should snap into place with a slight push on the board onto the case. At this point, you can also cover the case up with the lid that came with it.
This next step is optional. The idea is to keep everything together as neatly as possible. I had a metal angle bracket that I used hot glue to attach to the power adaptor and the bottom of the Raspberry Pi Zero W case. That way, I when I plug the AC power adaptor into the outlet, the Raspberry Pi Zero W and case will be held up with the pins in the back will be available for connection.
You can mimic what I've done or use an alternative approach for the AC power adaptor and mounting hardware that you have.
Step 4: Wiring Up the Control Module and Plug Into AC Relay Module
Tear off three female-to-female and two female-to-male jumper wires from the jumper wire package.
Insert Pin 1, 2 and 4 of the DHT-22 onto one end of the 3 female-to-female jumper wires (see picture above). Notice that looking at the DHT-22 sensor from the front, Pin 1 is the left-most pin. For this illustration, I've connected the purple jumper to Pin 1, the red jumper to Pin 2 and the orange jumper to Pin 4. Also, I've used a little bit of Scotch tape to keep the jumpers in place. I put a small piece of tape in the back to keep the jumpers from coming off and wrapped a small loop of tape around the pins to keep the tape in the back from coming off.
Remove the green connector from the side of the AC Power Relay Module. This is the control input for the Power Relay Module. Loosen the two screws on top with a small screwdriver. Insert the two male pins of the female-to-male jumpers into the side of the connector (see photo above) and tighten the two screws. Check to make sure that the two jumpers are securely fasten to the green connector. For illustration here, insert the yellow jumper to the left and the green jumper to the right.
Next connect up the jumpers to the back of the Raspberry Pi Zero W board (see photo above)
- Purple jumper (from Pin 1 of the DHT-22) to Pin 1 of the Raspberry Pi Zero W (one leg of the 10K ohm resistor)
- Red jumper (from Pin 4 of the DHT-22) to Pin 11 of the Raspberry Pi Zero W (the other leg of the 10K ohm resistor)
- Orange jumper (from Pin 2 of the DHT-22) to Pin 6 of the Raspberry Pi Zero W (one of the header pins)
- Green jumper (from the right side of the green connector) to Pin 14 of the Raspberry Pi Zero W (one of the header pins)
- Yellow jumper (from the left side of the green connector) to Pin 16 of the Raspberry Pi Zero W (one of the header pins)
- Note that you can add more jumpers if you need to increase the distance where you need to place the DHT-22 sensor
Finally, connect up the Control Module to the AC Power Relay Module (see photo above)
- Plug the 5V Power Adaptor into the "always ON" AC outlet of the AC Power Relay Module
- Connect the micro USB cable from the 5V Power Adaptor to the Raspberry Pi Zero W. Note that there are two micro USB connectors on the Raspberry Pi Zero W board. Connect to the one closer to the outside. There is label on the Raspberry Pi Zero W case showing which is the micro USB connector for power.
- Insert the green connector back into the side of the AC Power Relay Module
Step 5: Setting Up the Raspberry Pi Zero W
Next, we will set up the Raspberry Pi Zero W for programming.
First, we will have to connect the Raspberry Pi Zero W to a HDMI monitor, keyboard and mouse. Unfortunately, you will need a standard-to-mini HDMI cable (or regular HDMI cable and mini HDMI adaptor), a micro USB Male to USB Female OTG Adapter and USB Hub to complete all the connections.
After you've made all the connections, power up the AC Power Relay Module. After a minute or so, a "Welcome to Raspberry Pi Desktop" splash screen should come up. It will stay up momentarily. Then the screen blanks and comes back with various text showing status before an arrow for mouse showing up. This all can take a few minutes while the board gets itself ready for setup.
Eventually, a desktop will show up and a window is launched showing "Welcome to Raspberry Pi". Follow the instructions to set up the board
- press next to get started
- Set Country - select Setting location - please wait... (few minutes wait)
- Change Password - can click Hide characters off to see password. We will use this same password to connect to the Raspberry Pi Zero W remotely in the next Step.
- Set up screen - to fit everything on screen
- Select WiFi Network - hit next to enter password. Connecting to network, please wait... will be displayed. If successful, will show the next window.
- Update Software - will see checking for updates - please wait... and then Installing updates - please wait... This could take quite a few minutes to complete. So be patient.
- Finally, System is up to date will show up. Hit OK.
- Setup is now completed and board will restart. This again could take a few minutes to complete.
When the desktop comes back up, click the Raspberry logo on top left corner of the screen. From dropdown menu, select Preference > Raspberry Pi Configuration. When the Raspberry Pi Configuration window opens up, click on the Interfaces tab. Enable SSH and VNC (see picture above). Click OK.
Hover mouse over the WiFi icon on the upper right hand corner of the desktop (see lower photo on the right). Make a note of the number on the second line that is of the form xxx.xxx.xxx.xxx (info between "wlan0: Configured" and "/24"). In this example the number is 192.168.1.238. Yours could be different. This is the IP address that we will need to use in Step 11.
Step 6: Connecting to the Raspberry Pi Zero W Remotely
In this step, we will download the VNC Viewer and use that to connect and control the Raspberry Pi Zero W remotely.
If you do not have the VNC Viewer installed on your computer, please go to RealVNC download page to download the VNC Viewer. The site should automatically detect what OS you are running on your computer to provide you with the proper VNC Viewer to download. If not, please select the appropriate OS and hit "Download VNC Viewer" button.
Go to the download folder of your computer and double click on the VNC-Viewer-(version and your OS) file. Follow the instructions and install the VNC Viewer on your computer.
Open the VNC Viewer and type in "raspberrypi.lan" in the search bar and hit return. An "Authenticate to VNC Server" window will pop up (see picture above). Enter "pi" as the username and the password that you entered in Step 5. Check the "Remember Password" box. Hit OK.
The VNC Viewer will attempt to connect to the VNC Server on the Raspberry Pi Zero W. If connection is successful, a new VNC Viewer window will appear and the same desktop that you saw in Step 5 on the HDMI monitor will be presented within the VNC Viewer window.
There should be a thick white line in the center of the top edge of this new VNC Viewer window. When you hover over it, a drop down selection bar will appear:
- Click on the 4-way arrow icon on the left to expand the VNC Viewer window to fill the whole screen, or conversely, click the icon to shrink the window to smaller size.
- Click on the X icon on the right to disconnect.
- There are other icons. Feel free to explore what they do. We will not be using any of the other VNC Viewer functions here.
Please note that after you have connected to the Raspberry Pi Zero W the first time, a convenient short cut icon will show up on the original VNC Viewer window (see picture above). You can just double click on this short cut icon to connect to the Raspberry Pi Zero W and access it's desktop the next time.
Step 7: Installing the Necessary Libraries
In this step, we will install two libraries to support the Python program that we will be creating. The first library is to support the DHT-22 sensor and the second is a GUI library to create a user interface to display temperatures and control settings. From this point on, we will use the VNC Viewer to access the Raspberry Pi Zero W remotely from the computer.
On the Raspberry Pi desktop, click the black "Terminal" icon. A terminal window will appear (see picture above). We will type in some commands in the terminal window to install the two libraries,
To use the DHT-22, will have to install the DHT library first. In the terminal window, type in the following and hit return. Please note that the code blocks in the black areas are for your information only to show what the expected output from the terminal could be. No action is needed after you hit return, except in one case where you will have to type in "y" to continue the process:
- git clone https://github.com/adafruit/Adafruit_Python_DHT.git
pi@raspberrypi:~ $ git clone https://github.com/adafruit/Adafruit_Python_DHT.git Cloning into 'Adafruit_Python_DHT'... remote: Enumerating objects: 325, done. remote: Total 325 (delta 0), reused 0 (delta 0), pack-reused 325 Receiving objects: 100% (325/325), 98.35 KiB | 239.00 KiB/s, done. Resolving deltas: 100% (176/176), done.
- cd Adafruit_Python_DHT/
pi@raspberrypi:~ $ cd Adafruit_Python_DHT/ pi@raspberrypi:~/Adafruit_Python_DHT $
- sudo apt-get update (please note that your output from this step might be different)
pi@raspberrypi:~/Adafruit_Python_DHT $ sudo apt-get update Hit:1 http://archive.raspberrypi.org/debian bullseye InRelease Get:2 http://raspbian.raspberrypi.org/raspbian bullseye InRelease [15.0 kB] Fetched 15.0 kB in 4s (3,973 B/s) Reading package lists... Done
- sudo apt-get install build-essential python-dev (after the process has started, you will have to answer "y" to for installation to continue - this step could take some time to complete)
pi@raspberrypi:~/Adafruit_Python_DHT $ sudo apt-get install build-essential python-dev Reading package lists... Done Building dependency tree... Done Reading state information... Done Note, selecting 'python-dev-is-python2' instead of 'python-dev' build-essential is already the newest version (12.9). The following package was automatically installed and is no longer required: libfuse2 Use 'sudo apt autoremove' to remove it. The following additional packages will be installed: libpython2-dev libpython2-stdlib libpython2.7 libpython2.7-dev libpython2.7-minimal libpython2.7-stdlib python-is-python2 python2 python2-dev python2-minimal python2.7 python2.7-dev python2.7-minimal Suggested packages: python2-doc python-tk python2.7-doc binfmt-support The following packages will be REMOVED: python-is-python3 The following NEW packages will be installed: libpython2-dev libpython2-stdlib libpython2.7 libpython2.7-dev libpython2.7-minimal libpython2.7-stdlib python-dev-is-python2 python-is-python2 python2 python2-dev python2-minimal python2.7 python2.7-dev python2.7-minimal 0 upgraded, 14 newly installed, 1 to remove and 18 not upgraded. Need to get 6,816 kB of archives. After this operation, 27.3 MB of additional disk space will be used. Do you want to continue? [Y/n] y Get:1 http://mirror.pit.teraswitch.com/raspbian/raspbian bullseye/main armhf libpython2.7-minimal armhf 2.7.18-8 [396 kB] Get:2 http://mirror.pit.teraswitch.com/raspbian/raspbian bullseye/main armhf python2.7-minimal armhf 2.7.18-8 [1,076 kB] Get:3 http://mirror.pit.teraswitch.com/raspbian/raspbian bullseye/main armhf python2-minimal armhf 2.7.18-3 [34.2 kB] Get:5 http://mirror.pit.teraswitch.com/raspbian/raspbian bullseye/main armhf python2.7 armhf 2.7.18-8 [311 kB] Get:4 http://mirror.us.leaseweb.net/raspbian/raspbian bullseye/main armhf libpython2.7-stdlib armhf 2.7.18-8 [1,802 kB] Get:6 http://mirror.pit.teraswitch.com/raspbian/raspbian bullseye/main armhf libpython2-stdlib armhf 2.7.18-3 [21.2 kB] Get:7 http://mirror.pit.teraswitch.com/raspbian/raspbian bullseye/main armhf python2 armhf 2.7.18-3 [24.5 kB] Get:8 http://mirror.pit.teraswitch.com/raspbian/raspbian bullseye/main armhf libpython2.7 armhf 2.7.18-8 [865 kB] Get:9 http://mirror.pit.teraswitch.com/raspbian/raspbian bullseye/main armhf libpython2.7-dev armhf 2.7.18-8 [1,967 kB] Get:10 http://mirror.pit.teraswitch.com/raspbian/raspbian bullseye/main armhf libpython2-dev armhf 2.7.18-3 [21.3 kB] Get:12 http://mirror.pit.teraswitch.com/raspbian/raspbian bullseye/main armhf python2.7-dev armhf 2.7.18-8 [292 kB] Get:13 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf python2-dev armhf 2.7.18-3 [1,216 B] Get:14 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf python-dev-is-python2 all 2.7.18-9 [1,528 B] Get:11 http://mirrors.syringanetworks.net/raspbian/raspbian bullseye/main armhf python-is-python2 all 2.7.18-9 [2,940 B] Fetched 6,816 kB in 9s (737 kB/s) (Reading database ... 99566 files and directories currently installed.) Removing python-is-python3 (3.9.2-1) ... Selecting previously unselected package libpython2.7-minimal:armhf. (Reading database ... 99561 files and directories currently installed.) Preparing to unpack .../0-libpython2.7-minimal_2.7.18-8_armhf.deb ... Unpacking libpython2.7-minimal:armhf (2.7.18-8) ... Selecting previously unselected package python2.7-minimal. Preparing to unpack .../1-python2.7-minimal_2.7.18-8_armhf.deb ... Unpacking python2.7-minimal (2.7.18-8) ... Selecting previously unselected package python2-minimal. Preparing to unpack .../2-python2-minimal_2.7.18-3_armhf.deb ... Unpacking python2-minimal (2.7.18-3) ... Selecting previously unselected package libpython2.7-stdlib:armhf. Preparing to unpack .../3-libpython2.7-stdlib_2.7.18-8_armhf.deb ... Unpacking libpython2.7-stdlib:armhf (2.7.18-8) ... Selecting previously unselected package python2.7. Preparing to unpack .../4-python2.7_2.7.18-8_armhf.deb ... Unpacking python2.7 (2.7.18-8) ... Selecting previously unselected package libpython2-stdlib:armhf. Preparing to unpack .../5-libpython2-stdlib_2.7.18-3_armhf.deb ... Unpacking libpython2-stdlib:armhf (2.7.18-3) ... Setting up libpython2.7-minimal:armhf (2.7.18-8) ... Setting up python2.7-minimal (2.7.18-8) ... Linking and byte-compiling packages for runtime python2.7... Setting up python2-minimal (2.7.18-3) ... Selecting previously unselected package python2. (Reading database ... 100307 files and directories currently installed.) Preparing to unpack .../0-python2_2.7.18-3_armhf.deb ... Unpacking python2 (2.7.18-3) ... Selecting previously unselected package libpython2.7:armhf. Preparing to unpack .../1-libpython2.7_2.7.18-8_armhf.deb ... Unpacking libpython2.7:armhf (2.7.18-8) ... Selecting previously unselected package libpython2.7-dev:armhf. Preparing to unpack .../2-libpython2.7-dev_2.7.18-8_armhf.deb ... Unpacking libpython2.7-dev:armhf (2.7.18-8) ... Selecting previously unselected package libpython2-dev:armhf. Preparing to unpack .../3-libpython2-dev_2.7.18-3_armhf.deb ... Unpacking libpython2-dev:armhf (2.7.18-3) ... Selecting previously unselected package python-is-python2. Preparing to unpack .../4-python-is-python2_2.7.18-9_all.deb ... Unpacking python-is-python2 (2.7.18-9) ... Selecting previously unselected package python2.7-dev. Preparing to unpack .../5-python2.7-dev_2.7.18-8_armhf.deb ... Unpacking python2.7-dev (2.7.18-8) ... Selecting previously unselected package python2-dev. Preparing to unpack .../6-python2-dev_2.7.18-3_armhf.deb ... Unpacking python2-dev (2.7.18-3) ... Selecting previously unselected package python-dev-is-python2. Preparing to unpack .../7-python-dev-is-python2_2.7.18-9_all.deb ... Unpacking python-dev-is-python2 (2.7.18-9) ... Setting up libpython2.7-stdlib:armhf (2.7.18-8) ... Setting up libpython2.7:armhf (2.7.18-8) ... Setting up libpython2.7-dev:armhf (2.7.18-8) ... Setting up python2.7 (2.7.18-8) ... Setting up libpython2-stdlib:armhf (2.7.18-3) ... Setting up python2 (2.7.18-3) ... Setting up libpython2-dev:armhf (2.7.18-3) ... Setting up python-is-python2 (2.7.18-9) ... Setting up python2.7-dev (2.7.18-8) ... Setting up python2-dev (2.7.18-3) ... Setting up python-dev-is-python2 (2.7.18-9) ... Processing triggers for desktop-file-utils (0.26-1) ... Processing triggers for gnome-menus (3.36.0-1) ... Processing triggers for libc-bin (2.31-13+rpt2+rpi1+deb11u2) ... Processing triggers for man-db (2.9.4-2) ... Processing triggers for mailcap (3.69) ...
- sudo python3 setup.py install
pi@raspberrypi:~/Adafruit_Python_DHT $ sudo python3 setup.py install running install running bdist_egg running egg_info creating Adafruit_DHT.egg-info writing Adafruit_DHT.egg-info/PKG-INFO writing dependency_links to Adafruit_DHT.egg-info/dependency_links.txt writing top-level names to Adafruit_DHT.egg-info/top_level.txt writing manifest file 'Adafruit_DHT.egg-info/SOURCES.txt' reading manifest file 'Adafruit_DHT.egg-info/SOURCES.txt' reading manifest template 'MANIFEST.in' writing manifest file 'Adafruit_DHT.egg-info/SOURCES.txt' installing library code to build/bdist.linux-armv6l/egg running install_lib running build_py creating build creating build/lib.linux-armv6l-3.9 creating build/lib.linux-armv6l-3.9/Adafruit_DHT copying Adafruit_DHT/Raspberry_Pi.py -> build/lib.linux-armv6l-3.9/Adafruit_DHT copying Adafruit_DHT/Raspberry_Pi_2.py -> build/lib.linux-armv6l-3.9/Adafruit_DHT copying Adafruit_DHT/Beaglebone_Black.py -> build/lib.linux-armv6l-3.9/Adafruit_DHT copying Adafruit_DHT/platform_detect.py -> build/lib.linux-armv6l-3.9/Adafruit_DHT copying Adafruit_DHT/Test.py -> build/lib.linux-armv6l-3.9/Adafruit_DHT copying Adafruit_DHT/common.py -> build/lib.linux-armv6l-3.9/Adafruit_DHT copying Adafruit_DHT/__init__.py -> build/lib.linux-armv6l-3.9/Adafruit_DHT running build_ext building 'Adafruit_DHT.Raspberry_Pi_2_Driver' extension creating build/temp.linux-armv6l-3.9 creating build/temp.linux-armv6l-3.9/source creating build/temp.linux-armv6l-3.9/source/Raspberry_Pi_2 arm-linux-gnueabihf-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -ffile-prefix-map=/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -ffile-prefix-map=/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.9 -c source/Raspberry_Pi_2/pi_2_dht_read.c -o build/temp.linux-armv6l-3.9/source/Raspberry_Pi_2/pi_2_dht_read.o -std=gnu99 source/Raspberry_Pi_2/pi_2_dht_read.c: In function ‘pi_2_dht_read’: source/Raspberry_Pi_2/pi_2_dht_read.c:128:24: warning: comparison of integer expressions of different signedness: ‘int’ and ‘uint32_t’ {aka ‘unsigned int’} [-Wsign-compare] 128 | if (pulseCounts[i] >= threshold) { | ^~ arm-linux-gnueabihf-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -ffile-prefix-map=/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -ffile-prefix-map=/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.9 -c source/Raspberry_Pi_2/pi_2_mmio.c -o build/temp.linux-armv6l-3.9/source/Raspberry_Pi_2/pi_2_mmio.o -std=gnu99 arm-linux-gnueabihf-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -ffile-prefix-map=/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -ffile-prefix-map=/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.9 -c source/_Raspberry_Pi_2_Driver.c -o build/temp.linux-armv6l-3.9/source/_Raspberry_Pi_2_Driver.o -std=gnu99 arm-linux-gnueabihf-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -ffile-prefix-map=/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -ffile-prefix-map=/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.9 -c source/common_dht_read.c -o build/temp.linux-armv6l-3.9/source/common_dht_read.o -std=gnu99 arm-linux-gnueabihf-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-z,relro -g -fwrapv -O2 -Wl,-z,relro -g -fwrapv -O2 -g -ffile-prefix-map=/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 build/temp.linux-armv6l-3.9/source/Raspberry_Pi_2/pi_2_dht_read.o build/temp.linux-armv6l-3.9/source/Raspberry_Pi_2/pi_2_mmio.o build/temp.linux-armv6l-3.9/source/_Raspberry_Pi_2_Driver.o build/temp.linux-armv6l-3.9/source/common_dht_read.o -lrt -o build/lib.linux-armv6l-3.9/Adafruit_DHT/Raspberry_Pi_2_Driver.cpython-39-arm-linux-gnueabihf.so creating build/bdist.linux-armv6l creating build/bdist.linux-armv6l/egg creating build/bdist.linux-armv6l/egg/Adafruit_DHT copying build/lib.linux-armv6l-3.9/Adafruit_DHT/Raspberry_Pi.py -> build/bdist.linux-armv6l/egg/Adafruit_DHT copying build/lib.linux-armv6l-3.9/Adafruit_DHT/Raspberry_Pi_2.py -> build/bdist.linux-armv6l/egg/Adafruit_DHT copying build/lib.linux-armv6l-3.9/Adafruit_DHT/Beaglebone_Black.py -> build/bdist.linux-armv6l/egg/Adafruit_DHT copying build/lib.linux-armv6l-3.9/Adafruit_DHT/platform_detect.py -> build/bdist.linux-armv6l/egg/Adafruit_DHT copying build/lib.linux-armv6l-3.9/Adafruit_DHT/Test.py -> build/bdist.linux-armv6l/egg/Adafruit_DHT copying build/lib.linux-armv6l-3.9/Adafruit_DHT/Raspberry_Pi_2_Driver.cpython-39-arm-linux-gnueabihf.so -> build/bdist.linux-armv6l/egg/Adafruit_DHT copying build/lib.linux-armv6l-3.9/Adafruit_DHT/common.py -> build/bdist.linux-armv6l/egg/Adafruit_DHT copying build/lib.linux-armv6l-3.9/Adafruit_DHT/__init__.py -> build/bdist.linux-armv6l/egg/Adafruit_DHT byte-compiling build/bdist.linux-armv6l/egg/Adafruit_DHT/Raspberry_Pi.py to Raspberry_Pi.cpython-39.pyc byte-compiling build/bdist.linux-armv6l/egg/Adafruit_DHT/Raspberry_Pi_2.py to Raspberry_Pi_2.cpython-39.pyc byte-compiling build/bdist.linux-armv6l/egg/Adafruit_DHT/Beaglebone_Black.py to Beaglebone_Black.cpython-39.pyc byte-compiling build/bdist.linux-armv6l/egg/Adafruit_DHT/platform_detect.py to platform_detect.cpython-39.pyc byte-compiling build/bdist.linux-armv6l/egg/Adafruit_DHT/Test.py to Test.cpython-39.pyc byte-compiling build/bdist.linux-armv6l/egg/Adafruit_DHT/common.py to common.cpython-39.pyc byte-compiling build/bdist.linux-armv6l/egg/Adafruit_DHT/__init__.py to __init__.cpython-39.pyc creating stub loader for Adafruit_DHT/Raspberry_Pi_2_Driver.cpython-39-arm-linux-gnueabihf.so byte-compiling build/bdist.linux-armv6l/egg/Adafruit_DHT/Raspberry_Pi_2_Driver.py to Raspberry_Pi_2_Driver.cpython-39.pyc creating build/bdist.linux-armv6l/egg/EGG-INFO copying Adafruit_DHT.egg-info/PKG-INFO -> build/bdist.linux-armv6l/egg/EGG-INFO copying Adafruit_DHT.egg-info/SOURCES.txt -> build/bdist.linux-armv6l/egg/EGG-INFO copying Adafruit_DHT.egg-info/dependency_links.txt -> build/bdist.linux-armv6l/egg/EGG-INFO copying Adafruit_DHT.egg-info/top_level.txt -> build/bdist.linux-armv6l/egg/EGG-INFO writing build/bdist.linux-armv6l/egg/EGG-INFO/native_libs.txt zip_safe flag not set; analyzing archive contents... Adafruit_DHT.__pycache__.Raspberry_Pi_2_Driver.cpython-39: module references __file__ creating dist creating 'dist/Adafruit_DHT-1.4.0-py3.9-linux-armv6l.egg' and adding 'build/bdist.linux-armv6l/egg' to it removing 'build/bdist.linux-armv6l/egg' (and everything under it) Processing Adafruit_DHT-1.4.0-py3.9-linux-armv6l.egg creating /usr/local/lib/python3.9/dist-packages/Adafruit_DHT-1.4.0-py3.9-linux-armv6l.egg Extracting Adafruit_DHT-1.4.0-py3.9-linux-armv6l.egg to /usr/local/lib/python3.9/dist-packages Adding Adafruit-DHT 1.4.0 to easy-install.pth file Installed /usr/local/lib/python3.9/dist-packages/Adafruit_DHT-1.4.0-py3.9-linux-armv6l.egg Processing dependencies for Adafruit-DHT==1.4.0 Finished processing dependencies for Adafruit-DHT==1.4.0
The second library is to support the creation of a Graphic User Interface (GUI) from the Python program. On the terminal window, type in the following:
- sudo pip3 install guizero (this could take some time to install)
pi@raspberrypi:~/Adafruit_Python_DHT $ sudo pip3 install guizero Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple Collecting guizero Downloading https://www.piwheels.org/simple/guizero/guizero-1.2.0-py3-none-any.whl (42 kB) |████████████████████████████████| 42 kB 100 kB/s Installing collected packages: guizero Successfully installed guizero-1.2.0
After the libraries are installed, close the terminal window.
Step 8: Programming the Raspberry Pi Zero W
In this step, we will create a Python program to sense the temperature and send out a control signal to turn the AC Power Relay Module on and off. From this point on, we will use the VNC Viewer to access the Raspberry Pi Zero W remotely from the computer.
Click on the raspberry icon on the upper left hand corner of the Raspberry Pi desktop. On the drop down menu, click the "Programming > " selection and another menu will appear. Click on the "Thonny Python IDE" selection (see left photo above) and a Thonny window will open up.
Download the attached dTempControl.py file from this step to your computer. Open the file with a text editor and copy the content of the file to the top part of the Thonny window (see photos on the right).
Hit the "Save" icon on the Thonny window and save the content in a file name "dTempControl.py" in a folder that you will create named "dTempControl". You could save the content to any file name. However, the following steps will assume that you are following the instructions here.
Feel free to scroll around to take a close look at the dTempControl.py program. Python is relatively easy to read and I have added a lot of comments in the program to explain what the individual lines do. I will not go over the program here, but feel free to ask if you have any questions in the comments below.
On a high level, the program has three basic features
- Provide temperature control - by reading the temperature detected by the DHT-22 module and compare with a Desired Temperature to determine if the heater should be ON or not
- Provide a GUI for temperature display and Control - both the Current/Desired Temperatures are displayed and a pair of buttons are provided to increase or decrease the Desired Temperature setting
- Provide a daily log of the sensed data - store the current time, temperature, humidity and ON/OFF status of the heater to a daily files stored on the Raspberry Pi Zero W microSD card in the dTempControl folder.
The following parameters are hardcoded in the program but can be changed to fit one's preference
- The desiredTemperature variable (initial Desired Temperature) is set at 70 degree F in line 24 of the code.
- The desiredVariance variable (heater control range) is set to 1 degree F in line 25 of the code,
- The frequency of data logging is determined by the value of count variable in a comparison done in line 55 of the code. It is currently set to allow count to increment of 30 times. Assuming that the whole readTemp() function cycle takes 2 seconds, a log entry will be added every minute. However, with all the processing that the Raspberry Pi Zero W has to do, the readTemp() function has taken more than 2 seconds most of the time.
Attachments
Step 9: Testing the Program
To test the program, click on the "Run" button on the Thonny window. A new "dTemp - a Debby Solution" window should appear displaying the Desired and Current Temperatures. In the middle of this window are the up and down control buttons. The Desired Temperature should say "70" (unless you have changed the initial setting) and the Current Temperature should show the temperature that reflects the temperature that the DHT-22 sensor is detecting. If you blow some warm air onto the DHT-22 sensor, the Current Temperature should go up. Please note that the temperature change would not be instantaneous. It might take a little bit of time (at least a few seconds) for the temperature of the sensor to change.
To change the Desired Temperature setting, click on the ^ or v icon. Please note that the Desired Temperature update will not occur immediately. The display is updated every time a new temperature update was obtained from the DHT-22. This is a minimum of 2 seconds, and could be more, based on the all the tasks that the Raspberry Pi Zero W processor has to do. So, please be patient. Click and wait.
As the program starts up, a .csv file will be created with the file name based on the current date. New data is appended to the file with the following four entries per line:
- Time
- Temperature (degrees in F)
- Humidity (in %)
- Status of the heater control (ON or OFF)
If the program is left running, a new file is created everyday with the current date as the new file name. Each file created would be less than 30 KB in size. So, a whole year of files will only take up about 10 MB of space on the microSD card.
To find out what has been saved, open up a Terminal window as you did in Step 6. This time type in the following commands:
- cd dTempControl/ (change into the dTempControl folder directory)
- ls -l (list all the files in the folder in long form)
- cat FileName.csv (display content of file - change FileName to the one that you are interested in seeing)
The following is a sample output from the Terminal window:
pi@raspberrypi:~ $ cd dTempControl/ pi@raspberrypi:~/dTempControl $ ls -l total 12 -rw-r--r-- 1 pi pi 507 Jan 3 18:25 2022-01-03.csv -rw-r--r-- 1 pi pi 6407 Jan 3 17:32 dTempControl.py pi@raspberrypi:~/dTempControl $ cat 2022-01-03.csv Timestamp, Temperature, Humidity, Heater State 17:34,72.5,25.5,OFF 17:37,72.0,25.7,OFF 17:39,71.8,26.1,OFF 17:42,71.4,26.0,OFF 17:44,71.2,26.0,OFF 17:46,71.2,26.2,OFF 17:49,71.1,26.0,OFF 17:51,70.9,24.5,OFF 17:53,70.9,25.7,OFF 17:56,71.8,24.9,OFF 17:59,73.2,24.5,OFF 18:01,73.2,25.4,OFF 18:04,72.7,25.5,OFF 18:05,72.3,25.4,OFF 18:07,72.0,25.3,OFF 18:09,71.8,25.4,OFF 18:11,71.6,24.5,OFF 18:13,71.6,24.8,OFF 18:15,71.4,25.9,OFF 18:18,71.4,25.9,OFF 18:21,71.2,25.4,OFF 18:23,71.1,25.7,OFF 18:25,70.9,25.6,OFF
Step 10: Have Program Automatically Start Up
At this point the dTempControl.py program is ready for execution. You can run the program by opening the Thonny Python IDE in Step 8 (the dTempControl.py program should be opened by default, if that was the last file opened) and click the Run button. Or, you run the program by opening a Terminal window, as we did in Step 7 and type in "python3 /home/pi/dTempControl/dTempControl.py". However, to simplify the process, it would be best to have the program autostart each time the Raspberry Pi Zero W is powered on.
To do this, please open the Terminal window and enter the following:
- mkdir /home/pi/.config/autostart (this will create an autostart directory)
- nano /home/pi/.config/autostart/dTempControl.desktop (this will open the nano text editor to create and allow you to edit the dTempControl.desktop file)
pi@raspberrypi:~ $ mkdir /home/pi/.config/autostart pi@raspberrypi:~ $ nano /home/pi/.config/autostart/dTempControl.desktop
Once the nano text editor is opened, type or copy the following text into the editor (see photo above):
[Desktop Entry] Type=Application Name=dTempControl Exec=/usr/bin/python3 /home/pi/dTempControl/dTempControl.py
Type ctrl+x, to exit. Answer to "y" to save file before exit and hit return to save the file.
Now, reboot the Raspberry Pi Zero W by typing in sudo reboot. The "dTemp - a Debby Solution" window will be opened when the Raspberry Pi Zero W had restarted. Or, each time the Raspberry Pi Zero W was powered up.
Step 11: Access the Raspberry Pi Zero W From Your Mobile Device
Now that the dTempControl.py programming is running on the Raspberry Pi Zero W. You can view and control the GUI from your Android or iPhone as well as any mobile devices, such as a tablet.
On your mobile device, go to the the Apple App Store or Google Play. Search for "VNC Viewer". Look for the app titled "VNC Viewer - Remote Desktop" by RealVNC. Download and open the app and follow the following to get connected:
- Click OK to let "VNC Viewer" to find and connect devices on your local network
- Scroll through the introductory screens and click "Get Started"
- Click and select "Address Book" on the slide out menu on the left to go to the Address Book page
- Tap the + sign on the upper left hand corner to add a connection
- Type in the IP Address that you wrote down in Step 5 and tap "Save" on the upper right of screen
- Tap "Connect" and after a few moments, an "Identity Check" screen will show up
- Tap "Continue" and an Authentication screen will show up
- Enter Username as "pi", the Password and turn on "Remember Password" selection
- Tap "Continue" to connect
- Go through the tutorial screens to get familiar with how to operate the mobile version of VNC Viewer
- When you are done, the Raspberry Pi Desktop will show up.
- Depending on the resolution of the screen on your mobile phone, you might have to scroll around a little bit to find the "dTemp - a Debby Solution" window.
- You can now see the Desired and Current Temperature from your mobile device. You can also control the Desired Temperature right from your mobile phone!
- Remember, to wait a little while after tapping on the ^ and v button to see the Desired Temperature changed before tapping again.
Note that the VNC connection could time out and you will have to reconnect. Since the connection and password has been saved, you can just go to the address book and tap on the Raspberry Pi Desktop icon for a quick reconnect.
Another thing to note is that if the Raspberry Pi Zero W has been turned off and was disconnected from the network for some time, the IP address for the Raspberry Pi Zero W could be changed when powered back up again. If that happens, you will not be able to connect to it from your mobile phone. You will have to do the following to get a new IP address:
- Use a computer and VNC Viewer to connect to the Raspberry Pi Zero W first as discussed in Step 6.
- From the Raspberry Pi desktop, obtain a new IP address of the Raspberry Pi Zero W as shown in Step 5.
- Open the VNC Viewer on your mobile device and delete the Raspberry desktop icon with the old IP address
- Add a new device with the new IP address to connect.
Step 12: Potential Improvements and Variations to Your Personal Controller
If you have gone this far and have created your Personal Temperature Controller, you would have observed and experienced the advantages of using a Raspberry Pi as a device controller. The Raspberry Pi Zero W is a super low cost controller that is capable of running a feature rich Linux-base OS. Linux provides the connectivity and functions that you would not get with a simple micro-controller at the comparable cost.
Below are some potential improvements and variations:
- Increase program performance - As of this writing, there is a new version of the Raspberry Pi Zero W that has a quad-core 64-bit Arm Cortex-A53 CPU, clocked at 1GHz. There is a slight increase in cost. But with much added processing power of the Raspberry Pi Zero 2 W, the GUI will run a lot quicker and can support more buttons and controls.
- Adding Time of Day control - In addition to using date function in the OS to create a daily log file, we can add code to turn on the heater at a certain time period of day (or even day of the week, etc.). The following code can be used (by replacing the code in line 48) to turn the heater on only between 8AM and 9 PM:
now = datetime.now() timeOfDay = int(now.strftime("%H")) if ((ft < (desiredTemperature - desiredVariance/2))and((timeOfDay>8)and(timeOfDay<21))):
- Use the Controller to control humidity - The same control system can be used to control a humidifier. See the attached file as an example of changing the program for humidity control.
For examples of how the dTempController and other solutions that can be used by folks to improve their daily lives, please visit visit www.debbysolutions.com.