One way to showcase such applications in an educational context could be to control science experiments which require long term measurements and data collection.
One of the easiest measurement sensors to connect to a Raspberry Pi is the DS18B20 digital thermometer,. It can be read out via a multi-device 1-wire bus that is directly supported by a driver in the Linux kernel. Several sensors can be connected in parallel to the same data-wire and read out individually over the bus interface by their hard-coded IDs. All we need to connect one or more DS18B20 sensors to a Raspberry Pi, is to connect the VCC pin to 3.3V, GND to GND and data to GPIO4 on the Raspberry Pi GPIO header as well as connect a 4.7k Ohm resistor between the VCC and data lines of the sensor. The sensor is available among others as a basic board mounted package as well as a water-proof assembly with a ca. 1m long isolated cable.
The whole setup can be assembled without any soldering, using some prototyping tools from Adafruit Industries, a great supplier of electronics parts for hacking, making and education, based in NYC but who also ships world-wide.
In addition to the Raspberry Pi with CF card, micro-usb cellphone charger and EW-7811Um USB wifi adapter (see configuration here), the shopping list for this project includes:
- small prototyping breadboard
- assembled Pi Cobbler breakout & ribbon cable
- breadboard wires
- DS18B20 & 4.7k resistor
- 2 x waterproof packaged DS18B20
For the experiment, we want to connect at least 3 temperature sensors to simultaneously monitor:
- inside/room temperature (board mounted sensor)
- outside temperature
- heater temperature
Using the data collected for inside & outside temperature and a lot of simplifying assumptions, we could for example estimate the amount of thermal flow out of the room and thus how much heating energy the room has used during the measurement period. Or try to reverse-engineer the control function of the heater thermostat by looking at the relationship of outside, inside and heater feed temperature.
Our house is a roughly 120 year old apartment building with a radiator based central heating system. There are exposed riser pipes which distribute the hot water from the boiler in the basement to the radiators and the apartments above us. This is the place where we can connect the heater temperature sensor, as it will show the feed temperature, regardless of whether the radiator in the room is turned on or off. Tin-foil can make a great heat-conducting sleeve to connect the sensor to the tube. The outside sensor is simply stuck outside the window with the cable pinched by the window frame in less than professional manner...
Once we have carefully assembled all the parts, powered up the Raspbery Pi and made sure that none of the sensors are starting to overhead from wrong polarity, we can test if the driver is working properly:
pi@my-pi ~ $ sudo modprobe w1-gpio pi@my-pi ~ $ sudo modprobe w1-therm pi@my-pi ~ $ cd /sys/bus/w1/devices pi@my-pi /sys/bus/w1/devices $ ls 28-000005303678 28-000005604c61 28-000005610c53 w1_bus_master1 pi@my-pi /sys/bus/w1/devices $ cat 28-*/w1_slave 79 01 4b 46 7f ff 07 10 0a : crc=0a YES 79 01 4b 46 7f ff 07 10 0a t=23562 83 00 4b 46 7f ff 0d 10 5b : crc=5b YES 83 00 4b 46 7f ff 0d 10 5b t=8187 5c 02 4b 46 7f ff 04 10 e6 : crc=e6 YES 5c 02 4b 46 7f ff 04 10 e6 t=37750
In order to make sure that the drivers for the GPIO 1wire interface and the DS18B20 protocol are loaded at boot-time going forward, we need to add them to /etc/modules:
sudo -s echo w1-gpio >> /etc/modules echo w1-therm >> /etc/modules
Then we create the following simple driver class in temp_sensor.py that is going to be used to read and record the sensor data in the second part of this tutorial:
#!/usr/bin/python import re class TempSensor(): """ Read data from DS18B20 Temperature sensor via 1-wire interface. """ _DRIVER = "/sys/bus/w1/devices/%s/w1_slave" _TEMP_PATTERN = re.compile("t=(\d+)") def __init__(self, sensor_id): self._id = sensor_id def _read_data(self): data_file = open(self._DRIVER % (self._id, ), "r") try: return data_file.read() finally: data_file.close() def get_temperature(self): data = self._read_data() # data should contain 2 lines of text like this: # 86 01 4b 46 7f ff 0a 10 5e : crc=5e YES # 86 01 4b 46 7f ff 0a 10 5e t=24375 # # Temperature reading is value of t= in milli-degrees C m = self._TEMP_PATTERN.search(data) if not m: raise IOError("Invalid data for sensor " + self._id) return float(m.group(1)) / 1000.0 if __name__ == '__main__': import sys for sensor_id in sys.argv[1:]: sensor = TempSensor(sensor_id) print sensor.get_temperature()
In order to test the driver, we can also execute it directly:
Here we can also identify which ID corresponds to which sensor in our setup. Since it is winter right now, we can assume that 23.5C is the inside temperature, 7.8C the outside and 39.5C is the temperature of the heating pipe. If testing first on a workbench, we can also touch one of the sensors and see which one of the sensor readings is going up towards 37C as a consequence.
pi@my-pi $ ./python/temp_sensor.py 28-000005303678 28-000005604c61 28-000005610c53 23.562 7.812 39.562
Right now, we can simultaneously measure the current temperature in each of the 3 zones, but in the next part, we are going to record time-series based measurements into a database for graphing and further analysis.