Like a lot of people who have bought a Raspberry Pi, one of my projects is to create a multi-sensor temperature gauge. In my case, the idea is to semi-automate the greenhouse, measuring the temperature at different points (inside, outside and within the inner greenhouse) to open vents when it gets to the right temperature.
Obviously, to many people this will be “simple” but, not being an experience Python programmer, nor being someone who has built lots of hardware circuits, I’m starting at a pretty novice level.
Anyway, having “borrowed” code from a number of sources, I have developed a multi-threaded piece of code that reads the temperature from 1-Wire Waterproof DS18B20 sensors.
The Raspberry Pi has a (relatively) limited number of GPIO ports and so a significant benefit of using 1-Wire technology is that you only need a single data port for all of the sensors. In practice there are (in my case) three connections to the Raspberry Pi, 3.3v, GND and the Data Port and the DS18B20 sensors can be connected in parallel all to the same ports on the Raspberry Pi. So, I can run three wires from my Raspberry Pi to a cluster of sensors in the greenhouse (or I can run power to the greenhouse and connect the Raspberry Pi there. (Note that when I get around to adding the greenhouse automation, I’ll probably need power there but then my thought is to use a battery and solar panel but that’s for much later).
So, where have I got to.
Connecting the Sensors to the Raspberry Pi
First I worked it all out with a single sensor.
Connect the sensor to the Pi (best to do it with the power disconnected). The DS18B20 has three wires (red, black and yellow). Red is connected to 3.3v (Pin 1), black to GND (Pin 6) and yellow to GPIO 4 (Pin 7). You also need to connect a pull-up resistor (between 4.7k ohm to 10k ohm) between the 3.3v and GPIO 4.(This stops the data line floating and being less accurate to read).
Identifying the Sensors
The DS18B20 sensors each have a unique identity and I needed to find that identity in order to read the data.
Now you need to update the Pi to read the temperature sensor. to do this you need to add
to /boot/config.txt .
(The simplest way is to edit the file using nano) and then reboot the Pi (sudo reboot). The 1-wire system is then enabled and you will be able to see the sensor.
It will exist as a directory 28-xxxx in a directory /sys/bus/w1/devices but to find it you will need to initiate the 1-wire system which you do by typing the following commands at the Pi CLI:
sudo modprobe w1-gpio
sudo modprobe w1-therm
then change to the directory and see what other directories are there:
and the serial number of the device will pop up (28-xxxxxxxxx) and you can read the directory using cat
which will produce a stream of output which includes whether the temperature has been successfully read and the temperature in 1000ths degrees C.
I did this with two devices and ended up with two sensors:
28-0316001a0fff and 28-0316001bb5ff
Code to Read, Print and Save the Temperature
Then I wrote the following code:mttemp
A brief explanation of the code:
Lines 1 – 10 import the necessary functions and define the 1-Wire system to the software.
Lines 12 – 29 read the content to the 1-wire file for the device defined and return the temperature in degrees C.
Lines 35 – 61 are the main loop of the program, reading the temperature, printing the sensor’s id, the current time and the temperature it to the screen and saving it to a file defined by the device identifier. The information is only printed and saved if the temperature changes. The file is opened and closed each time the data is written so that in the event of a failure of some sort, the file is probably not corrupt.
Lines 63 and 64 are two calls to the main body of the programme with the device identifier and the frequency with which the temperature is to be read (in this case every second).
I multi-threaded it because it seemed the simplest way to be able to have multiple sensors, obviously I could have just duplicated the code for different sensors but that would have made it more difficult to add sensors. All I have to do with this code is to add more threads with the appropriate device identifier.
I’m running it on a Raspberry Pi B+ so obviously the multi-threading isn’t doing much but it seems to be able to read the temperature about every second. Obviously I could make it run less often by changing the value of sleeptime.
The basic code seems OK but there are problems:
- This code seems to work fine when running under the Python 2 Emulator under the Raspberry Pi but when run from the Command Line using the “python” command, it halts with an error message (undefined exception – or something like that);
- There’s no way of halting the programme, I’m not quite sure what the best way to kill it is, obviously I don’t want to have to connect a terminal so I’ll need some exception to stop it running cleanly.
These are things to add.
If you have comments, feel free, I’m still learning.