The Pi-Mometer, a web based thermometer
The Pi-mometer
I wanted to monitor some temperatures around the house. I picked up some digital temperature controllers cheap at a flea market. I have some thermocouple wire, and can easily bead the end with a torch to make any length I want. But, that means physically going to the controller to read the temperature. I can put a Raspberry pi on the web and access it from anywhere in the world. But, the pi doesn't have an analog input. So, thermocouples, RTD's, thermistors and other similar technology present an interface challenge. And, there is no easy way to connect the pi to my temperature controller. But, Maxim makes a digital thermometer chip, the DS18B20. It uses 1 wire interface technology which the pi does support and has software to make things happen. Excellent solution!
So, the DS18B20 is a very cool chip. It requires ground, data and a 3.3 or 5 volt dc supply. Each chip has a unique 64 bit serial number burned into it. If you want to use more than 1 chip, just connect them all in parallel! The power can be sourced from the Pi, or remotely. But, they said 1 wire technology. I see 3 wires! So, here is the cool part. If you are only using 1 or 2 sensors, you can put it into "Parasitic Mode". If you ground the power pin on the chip, you trigger parasitic mode. The normally high data line is used to charge a capacitor inside the chip. This capacitor powers the chip while the data line is low. So, the chip only needs ground and data to work! You now have a sensor good from -55 to +125 degrees centigrade, accurate to 1/2 degree. They go for $4 to $10 at Adafruit.com, and are readily available from other sources.
There is one thing a little tricky about the DS18B20. They all have a unique serial number. But, it is not printed anywhere on the device. It is only available through software. So, take some model airplane paint, nail polish, whatever you can get your hands on, and give every chip a unique mark to identify them. After the software is up and loaded, connect the sensors one at a time. When you connect a new sensor, the software will see it and create a new sub-directory with that serial number. You then enter that serial number in another location in the software, and give that sensor a meaningful name. Inside Temp, Outside Temp, Freezer Temp, whatever fits your project. Also note, any pi will work here! (The Pi Zero W is only $10 and works fine here!)
If you are an old hand at Pi, skip down to the X's....
So, grab your Pi and a soldering iron and let's get building. Since you are reading this, you are already logged in at 835onthe805.net. Go to "Archive", "Raspberry Pi". If you are new to the Pi, there are some files to introduce you to the Pi. Part 1 is a brief description of the history and hardware. Part 2 is a brief description of Linux and how it differs from Windows. Part 3 is a brief description of permissions, something you don't see in Windows.
Part 4, we actually get our hands dirty. We download the latest Raspbian, burn it to an SD card, and power up the Pi. The screen will automatically take you through changing your password, setting the location, connecting to the internet and updating the software. After you reboot, you need to do some configurations. Click the Raspberry in the upper left corner. Then select Preferences, then Raspberry Pi Configuration. A window will pop up. The first tab is "System". You already changed the password. Now, change the Hostname. Assuming you are going to eventually have more than one Pi, they all can not be called "raspberrypi". Use a descriptive name like Cam1, Cam2, Pictures, whatever. TempMon1 or Mon1 might be a good choice here. Next, select the "Interfaces" tab. If you were making a webcam, you would turn on the camera here. Turn on SSH so you can log into the pi from other computers, like the one you are using now. You can then copy commands here and paste them in a terminal logged into the pi. Cut and paste, no typing. Lastly, turn on 1 wire and reboot.
Part 5 is a little more advanced. Every computer on the internet has an IP address. Your router will automatically assign your pi a unique address on your network. This address can change with no warning. If you do a lot of playing with pi's or other systems, you may find it helpful to force a fixed address that will not change. You may want to play with this eventually for the experience
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
So, at this point, you should have a Pi up and running with the latest raspbian, updated, connected to the internet, with SSH and 1 wire turned on. You changed the password and named it TempMon1. You may have assigned a fixed IP.
Reboot.
Here are the 2 sensor configurations:
Gnd, Data, Power

Blue or Black, Gnd Yellow or White, Data Red, Power

You can wire many in parallel

One or two sensors, you can go 1 wire "Parasitic Mode" The resistor can be at the Pi, 2 wires to the sensors. Either mode, 3.3V or 5V supply can be used.

The Pi ports look like this

Open a terminal window on this computer. Type in ssh pi@tempmon1 Enter.
You should see a notice that you are logging into an unknown location and asks you to type yes to proceed. After entering yes, it should ask for your password. Enter it. If you assigned a fixed IP, that should work in place of tempmon1 as well. You are now remotely logged into the pi. It is as if your keyboard and monitor were connected to the pi. You are at what is known as the "Command Prompt". You type in commands here to execute them on the pi. Copy and Paste works well here, saves a lot of typing and avoids errors. All the following are commands you execute on the pi from this terminal.
We need to load the program that accesses the sensors. We need to add a line to the bottom of the config.txt file located in the boot sub-directory. We will use a handy small text editor called nano. Since we are editing a system file that we do not have permission to change, we precede nano with sudo to over ride the block. Enter the following:
sudo nano /boot/config.txt
You should see a new page with the contents of the config.txt file, ready to be modified. Use the arrow keys to get to the bottom of the file.
If you are using 3 wires, enter dtoverlay=w1-gpio
If you are using data and ground, enter dtoverlay=w1-gpio,pullup=1
Type Ctrl O to save the file, and Ctrl X to exit nano. You have just modified config.txt.
sudo shutdown -h now will power down the pi. Attach one sensor and power back up.
When the pi is back up, enter ssh pi@tempmon1 to get back into the pi.
Enter the following:
sudo modprobe w1-gpio
sudo modprobe w1-therm
cd /sys/bus/w1/devices
ls
You should see a sub-directory 28-xxxxx, the 12 characters after 28- are the unique serial number of this sensor. Write this sub-directory name down and identify which sensor made it.
cd 28-xxxxxx change to this sub-directory just created, then enter
cat w1_slave
You should see 2 lines. The first should end in yes. The second is the temperature in centigrade!
Shutdown the pi, attach the next sensor and repeat above to get it's address and test it.
When all the sensors are connected, serial numbers recorder, and tested, we need to create the Python program to read the sensors and update the temperatures.
cd /home/pi makes sure you are in the right directory
nano thermometer.py open the text editor to create a file named thermometer.py,
containing:
copy below and paste into text editor
import os
import glob
import time
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'
def read_temp_raw():
f = open(device_file, 'r')
lines = f.readlines()
f.close()
return lines
def read_temp():
lines = read_temp_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0
temp_f = temp_c * 9.0 / 5.0 + 32.0
return temp_c, temp_f
while True:
print(read_temp())
time.sleep(1)
Ctrl O to save the file and Ctrl W to exit the text editor.
We now have a Pi that will read all the temperature sensors and update the values with thermometer.py
Now, we need to install Apache so the pi can put up a web page
sudo apt-get install apache2 -y
When it finishes, go to TempMon1/, or it's IP address from a browser, like Mozilla or Chrome. You should see a default page come up to verify Apache is working.
Now, we need to change file ownership so we can modify it.
cd /var/www/html
ls -al
sudo chown pi: index.html pi now owns index.html and can edit it with HTML commands
Now, we need to install PHP
sudo apt-get install php7.3 libapache2-mod-php7.3 -y
sudo mv index.html index.html.bak rename index file to make it unavailable
sudo nano index.php create new php file for web page
<?php echo "hello world"; ?> static data
<?php echo date('Y-m-d H:i:s'); ?> dynamic data
<?php phpinfo(); ?> php info
Ctrl O to save, Ctrl X to exit. only copy the data inside the < > characters,not the rest of the line.
Go back to your browser and enter TempMon1/ or the pi's IP address again. Instead of the Apache default page, you should see hello world, the date and time, and the PHP version info. Now, lets change it to output our sensor value.
cd /var/www/html
sudo nano index.php delete previous 3 lines entered and add below:
<?php
if (!defined("THERMOMETER_SENSOR_PATH")) define("THERMOMETER_SENSOR_PATH", "/sys/bus/w1/devices/28-02157169acff/w1_slave");
// Open resource file for thermometer
$thermometer = fopen(THERMOMETER_SENSOR_PATH, "r");
// Get the contents of the resource
$thermometerReadings = fread($thermometer, filesize(THERMOMETER_SENSOR_PATH));
// Close resource file for thermometer
fclose($thermometer);
// We're only interested in the 2nd line, and the value after the t= on the 2nd line
preg_match("/t=(.+)/", preg_split("/\n/", $thermometerReadings)[1], $matches);
$temperatureC = $matches[1] / 1000;
$temperatureF = (($temperatureC * 9) / 5) + 32;
// Output the temperature
print 'Internal House Temperature, '.$temperatureC.' C, '.$temperatureF.' F';
?>
You need to change the 28-02157.... to match your sensor serial number.
Change print 'Internal House Temperature, to whatever you are measuring.
sudo reboot
Now, going to TempMon1/ should show you the sensor name you created, and temp in C and F.
If you have 3 sensors, use this program instead.
<?php
if (!defined("THERMOMETER_SENSOR1_PATH")) define("THERMOMETER_SENSOR1_PATH", "/sys/bus/w1/devices/28-02157169acff/w1_slave");
if (!defined("THERMOMETER_SENSOR2_PATH")) define("THERMOMETER_SENSOR2_PATH", "/sys/bus/w1/devices/28-0115717880ff/w1_slave");
if (!defined("THERMOMETER_SENSOR3_PATH")) define("THERMOMETER_SENSOR3_PATH", "/sys/bus/w1/devices/28-0215712dd3ff/w1_slave");
// Open resource file for thermometer
$thermometer1 = fopen(THERMOMETER_SENSOR1_PATH, "r");
$thermometer2 = fopen(THERMOMETER_SENSOR2_PATH, "r");
$thermometer3 = fopen(THERMOMETER_SENSOR3_PATH, "r");
// Get the contents of the resource
$thermometerReadings1 = fread($thermometer1, filesize(THERMOMETER_SENSOR1_PATH));
$thermometerReadings2 = fread($thermometer2, filesize(THERMOMETER_SENSOR2_PATH));
$thermometerReadings3 = fread($thermometer3, filesize(THERMOMETER_SENSOR3_PATH));
// Close resource file for thermometer
fclose($thermometer1);
fclose($thermometer2);
fclose($thermometer3);
// We're only interested in the 2nd line, and the value after the t= on the 2nd line
preg_match("/t=(.+)/", preg_split("/\n/", $thermometerReadings1)[1], $matches1);
$temperature1C = $matches1[1] / 1000;
$temperature1F = (($temperature1C * 9) / 5) + 32;
preg_match("/t=(.+)/", preg_split("/\n/", $thermometerReadings2)[1], $matches2);
$temperature2C = $matches2[1] / 1000;
$temperature2F = (($temperature2C * 9) / 5) + 32;
preg_match("/t=(.+)/", preg_split("/\n/", $thermometerReadings3)[1], $matches3);
$temperature3C = $matches3[1] / 1000;
$temperature3F = (($temperature3C * 9) / 5) + 32;
// Output the temperature
print "Internal House Temperature, ".$temperature1C." C, ".$temperature1F." F <br />\r\n ";
print "Outside Temperature , ".$temperature2C." C, ".$temperature2F." F <br />\r\n ";
print "Aux Temperature , ".$temperature3C." C, ".$temperature3F." F";
?>
Again, you have to change the 28-xxx values with your sensor addresses, and change the print command to indicate what the sensors are measuring. I'm sure you see a pattern here. You can modify this program for 2 sensors, or more than 3 sensors. It will take about 1 second per sensor for the program to read all the sensors.
You should now have a Raspberry Pi, accessible from anywhere in your local network, that reads temperatures and displays them on a web page with name and temp in C and F.
If you want to access them from outside your network, you need to get into your router and do a port forward from some obscure port number to port 80 of your pi. Putting your modem's IP address in a browser followed by : and the port number you assigned should bring up your temperatures. Router software differs, so you may have to play with yours to figure it out. Google may help.
Jim Albrecht K2BHM