This is only a preview of the March 2016 issue of Silicon Chip. You can view 36 of the 96 pages in the full issue, including the advertisments. For full access, purchase the issue for $10.00 or subscribe for access to the latest issues. Items relevant to "Ultrasonic Garage Parking Assistant":
Items relevant to "1-Wire Digital Temperature Sensor For The Raspberry Pi":
Items relevant to "Delta Throttle Timer For Cars":
Items relevant to "Solar MPPT Charger & Lighting Controller, Pt.2":
Items relevant to "Battery-Pack Cell Balancer For Optimum Charging":
Purchase a printed copy of this issue for $10.00. |
1-Wire Digital
Temperature Sensor For
The Raspberry Pi
By Greg Swain
& Nicholas Vinen
If you just want to measure temperature,
then using a Sense HAT with the Raspberry
Pi (RPi) is overkill. A much cheaper, easier
and more accurate option is to use a Dallas
DS18B20 1-Wire Digital Thermometer
Sensor.
T
HE DALLAS DS18B20 temperature sensor looks just like a TO-92
transistor but is actually much more
complicated. Its internal chip not only
includes a temperature sensor but also
has a 12-bit on-board digital-to-analog
converter, a 1-wire serial interface and
all the necessary control logic. It’s accurate to within ±0.5°C over the range
of -10°C to +85°C and has a full operating temperature range from -55°C
to +125°C.
In addition, each DS18B20 has a
unique 64-bit serial code, which allows multiple DS18B20s to function
on the same 1-Wire bus. If you want to
use multiple sensors, it’s just a matter
of connecting them in parallel.
A waterproofed and pre-wired version of the sensor is available and this
can be purchased from the SILICON CHIP
Online Shop for just $5 plus postage.
The sensor itself is housed in a small
metal tube and is hooked up to a 1metre long cable.
Apart from cost, the big advantage
of the DS18B20 is that it’s far more
accurate than the Sense HAT. It’s not
only inherently accurate but can be
well-separated from the RPi so that
it is unaffected by heat generated by
the RPi’s ARM CPU. As a result, it
doesn’t require time for the readings
to stabilise after switch on and we
don’t need to compensate for heatsoak from the RPi.
Connecting it to the RPi
Interfacing the DS18B20 sensor to
the RPi’s GPIO port couldn’t be easier.
As shown in Fig.1, there are just three
wires to connect: the red wire goes to
the +3.3V pin, the black wire goes to
GND and the yellow data wire goes to
GPIO4. In addition, a 4.7kΩ pull-up resistor must be connected between the
data line and the +3.3V supply.
The easiest way to connect the wires
is to terminate them in 1-way header
sockets which are then plugged into
RPi’s GPIO port. Alternatively, you
can cut two sections from a pin header
socket (eg, Altronics P5380), plug them
into the GPIO port and solder the sensor’s leads to the pins. A small clamp
attached to the case lid can be used to
secure the cable in place.
The 4.7kΩ resistor can be connected
by soldering its leads directly to the
GPIO pads underneath the PCB.
Getting it going
You will need to install Raspbian
on the RPi and set it up as described
in the January and February 2016 is-
RASPBERRY PI
GPIO
TEMPERATURE SENSOR
34 Silicon Chip
GPIO4
Fig.1: here’s how to connect the DS18B20 sensor leads to the Raspberry Pi’s GPIO
port. The red wire goes to +3.3V, the black wire to GND and the yellow data wire
goes to the GPIO4 pin. In addition, a 4.7kΩ pull-up resistor is connected between
GPIO4 and the +3.3V pin.
+3.3V
GND
4.7k PULLUP
RESISTOR SOLDERED
TO +3.3V & GPIO4
PINS UNDERNEATH
RASPBERRY PI PCB
siliconchip.com.au
The Raspberry
Pi connects to
your router via
WiFi and streams
the temperature
readings to a web
server so they can
be accessed over
the internet.
sues of SILICON CHIP. If you don’t have
a Sense HAT module, you can leave
out Steps 8-10 of the January article as
they are not relevant.
Once you’ve done that and connected the DS18B20 temperature sensor,
power up the RPi. You now need to
tell it how to detect the sensor. To do
that, enter the following command in
a terminal window:
sudo nano /boot/config.txt
then move the cursor to the bottom
of the file and add the following line:
dtoverlay=w1-gpio
Hit Ctrl-o and Ctrl-x to save the file
and exit Nano, then reboot (sudo reboot)
the RPi so that the changes take effect.
(Note: on older versions of Raspbian,
it may be necessary to add the lines
w1-gpio and W1_therm to the end of
/etc/modules).
Once the RPi is up and running
again, enter the following commands
into a terminal window:
cd /sys/bus/w1/devices
ls
Your DS18B20 temperature sensor’s
unique ID address will now be listed
siliconchip.com.au
Fig.2: once the DS18B20 has been connected to the RPi, a number of commands
are run in a terminal window to determine its ID address (see text).
in the terminal window followed by
w1_bus_master1 – see Fig.2. If you multiple sensor’s connected in parallel,
then multiple IDs will be listed (one
for each sensor).
In our case, the sensor’s ID is 28011581aefaff and we can now open the
sensor’s file to view the temperature
reading as follows:
cd 28-011581aefaff
cat w1_slave
This will return two lines of data,
as shown in Fig.2. The first line is a
cyclic redundancy check (CRC) and
if it ends in “YES”, then the reading
was successful. The second line displays the temperature reading, in this
case t=23812. This is the temperature
in °C x 1000, so we simply divide by
The 4.7kΩ pull-up resistor can be
directly soldered to the GPIO pins.
1000 to get the temperature: ie, 23812
÷ 1000 = 23.812°C.
Python program
We don’t want to have to go through
this rigmarole every time we want to
March 2016 35
import time
import os
import re
Fig.3: readtemp.py
sensor_names = {"011581aefaff": "indoor"} #Substitute your sensor's ID
def list_onewire_sensors():
path = '/sys/bus/w1/devices'
return [f for f in os.listdir(path) if not os.path.isfile(os.path.join(path, f)) and f.sta
def read_onewire_sensor(name):
path = '/sys/bus/w1/devices'
file = open(os.path.join(path,name,'w1_slave'), 'r')
line1 = file.readline()
line2 = file.readline()
file.close()
if line1.endswith(' YES\n'):
info = re.search('(\\d+)\n?$', line2)
if info and int(info.group(1)) > 0:
return int(info.group(1)) / 1000.0
return '?';
def getmsg(entities):
tm = time.strftime("%d/%m/%Y %H:%M:%S", time.localtime())
msg = "[%s]" % tm
deg = "°" if entities else u"\u00B0"
onewire_sensors = list_onewire_sensors()
for sensor in onewire_sensors:
temp = read_onewire_sensor(sensor);
msg += ' '+( sensor_names[sensor[3:]] if sensor[3:] in sensor_names else sensor[3:])+'
return msg
while True:
print(getmsg(False))
time.sleep(5)
read the temperature, so the answer
is to automate the procedure using a
simple Python program. Better still,
we can then stream the readings to
Apache Web Server on the RPi, so
that we can access the readings over
the internet (or on the local network)
using a web browser.
Let’s get the Python program running first. Fig.3 shows the code – just
download the readtemp.py file from
the SILICON CHIP website to the RPi’s
/home/pi folder, then launch Python 3
from a terminal window using the following commands:
xhost + (if you're running it headless)
sudo idle3 &
Wait until Python 3 launches, then
open /home/pi/readtemp.py and click Run
Module. You should see the temperature
readings appear as shown in Fig.4, with
the reading updated every 5s.
OK, let’s take a closer look at the pro36 Silicon Chip
gram. The new code has two functions
to assist with reading the DS18B20
1-Wire sensor temperature, plus some
extra code to display the results.
The list_onewire_sensors function
scans the /sys/bus/w1/devices directory
for subdirectories starting with “28” and adds the sensor’s name, which
includes its unique serial number, to
an array. The returned array thus contains one entry for each DS18B20 sensor that has been detected.
The read_onewire_sensor function
receives the name of one of the sensors (from the list) and interrogates
that sensor. It reads two lines, both
of which contain the full sensor response. As stated, the first one has a
flag indicating whether the CRC is valid, while the second line contains the
decoded temperature value.
This function reads both lines and,
if the CRC is valid, returns the temperature reading in °C as a floating point
value. If an error occurs, it returns a
string containing a question mark.
We also have a list called sensor_
names which can be used to map the
cryptic unique ID for a given sensor
to a more useful name such as “indoor”, “outdoor”, etc. That way, you
can name the sensors and the temperature for each sensor is then displayed
after its name.
The test script also initialises a
string with the current date and time.
It then calls the first helper function to
get a list of sensors and then, for each
sensor, gets the name and temperature and adds it on to the end of that
string. Finally, that string is printed,
as shown in Fig.4.
If you want to change the update
time, just edit the last line of the script.
Web access
We’ve also adapted the index.py
script originally used last month so
siliconchip.com.au
artswith('28-')]
Fig.5 (above): the temperature readings as displayed
in a web browser. The rapid increase in temperature
was the result of briefly holding the temperature sensor
between two fingers.
': '+('?' if temp == '?' else ('%.3f' % temp)+deg+'C')
played. You can edit the sensor_names =
line to distinguish between them – just
add a comma after each preceding entry and add each additional sensor’s
ID address and name (with everything
enclosed by one set of parentheses).
Apart from adding code to support
the DS18B20 sensors, we’ve also improved the program to give more consistent time intervals between readings. Basically, the page load time has
now been taken out of the equation.
Setting up the web server
Fig.4: this is the output that appears when running readtemp.py in Python on the
RPi. The reading updates about every five seconds but this is easy to change.
that the Apache 2 Web Server could
serve readings from the Sense HAT.
We’ve left the code to display the readings from the Sense HAT in place but
wrapped it with an “exception handler” so that if the Sense HAT isn’t installed, its absence is ignored.
We then use the same code from
the readtemp.py script to append the
DS18B20 reading(s) to the end of each
siliconchip.com.au
line that’s displayed. If you can physically connect both the Sense HAT and
some DS18B20 temperature sensors,
all the readings at any particular instant will be shown on the same line.
If you only have a DS18B20 sensor
connected, its readings will be displayed as shown in Fig.5. And if you
have several DS18B20s connected in
parallel, all their readings will be dis-
Installing and getting the Apache
Web Server going is straightforward –
just follow the step-by-step procedure
described in the February 2016 article. As before, the index.py script (embedded in index.py.zip) can be downloaded from the SILICON CHIP website,
unzipped and copied to /var/www/html.
Don’t forget to set up password access and a dynamic DNS service (eg,
Duck DNS) if you want to access the
temperature readings over the internet.
It’s also a good idea to install Fail2Ban,
to temporarily ban anyone who makes
too many failed log-in attempts.
Once the set-up is complete, you
can browse to the RPi’s web server by
entering your local IP, WAN IP or dynamic DNS address into your browser
to display the temperature readings.
By default, the reading updates every
five seconds but you can easily change
this by altering the two interval=5 values in index.py; eg, interval=30 updates
the reading every 30 seconds.
Alternatively, you can add a switch
to the website address, as described on
SC
page 58 of the February issue.
March 2016 37
|