Temperature and the Rasperry Pi



A Nice Hot Pi

Although I am not in any way an educationalist, I'm currently working a lot with people who are. One of the things getting a bit of attention lately has been STEM in schools (Science, Technology, Engineering and Maths.) In particular I was interested to hear from a primary-school teacher that "coding" is being emphasised by the various directives they get.

By a curious serendipity I needed a cheap server to run a Squid proxy (in a domestic setting). The Raspberry Pi had interested me since its release, but I'd lacked a good enough reason for buying it. Now, however, I pulled the PayPal trigger and bought a Pi3 for £32 (along with a case for £6, a power supply for £7 and a 16GB SD card, preinstalled with NOOBS, for £9).

The Raspberry Pi 3 (Model B) Note the long row of GPIO pins at the top, we'll be using them later

The snazzy official case
Shortly afterwards, a smidge over £50, I had my first Pi. Setup was straightforward, other than that I had to press-gang the TV into temporary use as a  monitor (I didn't have a HDMI-enabled monitor to hand). In short order I had a basic (Debian) linux server on my WiFi network that I could log into remotely via SSH from my desktop. This worked perfectly as a Squid proxy, but that is not the point of this blog post.

I decided to investigate what else I could do with my Pi -- and specifically how it could realistically be used in an educational context. The key word is "realistically"... personally I am convinced at an instinctive level that the Pi is Cool. I wanted one for ages, even though I didn't have anything I could plausibly give as a purpose for it. I like tinkering with computers, that's how I ended up doing what I'm doing. But I'm old enough to know that this is not a universally-held concept. A large percentage of people (many of them classroom teachers) will not be convinced a Pi is any better than the creaky old Windows 7 machine in the corner of the schoolroom. In fact, they will think it is worse, since it will need to be set up, doesn't have a screen, keyboard etc and doesn't come with Word and Powerpoint.

So I started looking into Pi-based projects. There are a lot of these on the web, but many of them are not really suited to a P7 or S1 classroom. Others looked cool to me, but (I acknowledged) would leave non-geeks cold.

I did see a weather-station-based project that looked hopeful however. We're all interested in the weather, especially where I live. A full weather-station looked a bit ambitious for a kick-off, but perhaps temperature monitoring might be a good start.

This (I reflected) is actually more flexible than a weather station in some ways -- temperature monitoring could be used in many cross-curricular areas:
  • keep an eye on the temperature in the classroom and relate it to external events (the heating coming on, the sun shining in a window, the school day ending), 
  • use it for simple science experiments (how can you make hot water cool more quickly for instance), 
  • perhaps applications in cooking, such as monitoring a cool room 
  • could even give info on class pets such as gerbils or fish (if schools still keep rodents)
  • as well as being poked outside to monitor the actual outside temp
  • and no doubt other applications too
For this I am indebted to, and closely followed, the tutorials at this site: https://www.raspberryweather.com/ 

Now, I know nothing about circuits. I can wire a plug and that's about it. So if I could make this work then so could your average child (or teacher).

You will need...

I returned to the pi hut and ordered:
  • A waterproof temperature sensor (model DS18B20, £10) Note that this comes with the needed resistor, I didn't appreciate this and needlessly bought another ten of the things.
  • A full-size "breadboard" for building my circuit on (£6)
  • a Pi T-Cobbler Plus -- this connects the I/O pins of the Pi to the breadboard (£8.50)
  • a bunch of wires (£3.00)

Part 1: Assemble your apparatus

You assemble all this by plugging the blue T-Cobbler into the breadboard so the bins straddle the centre groove, plugging the ribbon cable into the port at the top (it will only fit one way) and pushing the other end of the ribbon cable into the GPIO pins on the pi. Here's the first pitfall -- you can push the cable onto these pins two ways, and I initially picked the wrong way. This will have unwanted effects later on...

We're ready to build a circuit now. (Note that the cobbler and breadboard are not specific to the temperature sensor -- once you've bought them you can use them for adding a bunch of other things, and build other circuits too.)

I carefully followed this wiring diagram from the raspberry weather site:
You can see right away that the diagram has orange, red and black wires coming from its sensor, whereas mine had yellow, red and blue. A bit of research reassured me that blue=black and orange=yellow. My cobbler kit had the labels for some of the pins in different locations to the ones shown on the diagram, but pin 4, ground and 3V were all there somewhere.

(The wires from the sensor are copper strands twisted together, so are a bit tricky to poke into a breadboard hole. Some people advised melting a little solder into the wires, making them less likely to fray as they were pushed into place, but I was keen to avoid adding a soldering iron to the mix if I could. It did take a few goes to get them in their holes though--a bit like threading a needle--so an easier alternative might be to use the cheap wire connector blocks electricians have, with jumper wires going into one end of the block.)

A close-up of the wiring on my breadboard. Apologies to anybody who actually knows about circuit etiquette, as I'm sure this looks a mess to you. However, you should be able to make out the links between the GPIO pins and the sensor wires.

And this is the finished assembly (with the Pi just out of shot.
Ok, it was power-on time -- boot up the Pi. Nothing flashed or exploded, but I very quickly started to get a hot smell from the sensor. When touched it was hot enough to burn me. Yikes! Power off!

I saw from the wiring instructions that wiring the sensor incorrectly could have this effect, but I was sure I had everything connected as per the diagram.  A little more research and I realised the ribbon cable was connected to the Pi GPIO pins incorrectly. The white line running down one side of the cable is your guide, to avoid my mistake:

This is the right way to wire it (with, er, the white ribbon to the left).


Note the position of the white line on the ribbon cable in relation to the Pi. This is what you want to avoid your temperature sensor burning your finger (and destroying itself).
Ok, round two. Power-on time, take a dhà. Touching the sensor (cautiously) reassured me it was not going to combust this time. So let's try and get some data!

Logging in to the Pi via the command line "ssh" system is the way to go here. I use a mac, which has an excellent terminal built in and makes this step easy. If you use a windows PC you can use the free "putty" client which is also good. Or you could hook up a keyboard, mouse and screen to the Pi and do this directly on the machine itself.

Many good tutorials exist on ssh-ing into the Pi and editing text files, so I'm going to assume you can do these things. Using the command line for the first time may be daunting, but once you've got the hang of it you'll find it is quite easy. Don't expect to understand everything you type at once, it's quite ok to follow the instructions and worry about comprehension later.

First edit the text file /boot/config.txt (carefully) and add the following line:

              dtoverlay=w1-gpio-pullup,gpiopin=4

...and reboot (sudo shutdown -r). Once you're logged in again, type the following commands (possibly not necessary, but they won't hurt):
              sudo modprobe w1-gpio
      sudo modprobe w1-therm

Now, if everything has gone to plan the probe should be logging temperature to a small text file on the pi. We can read the output by using the "cat" command. This has nothing to do with kittens, sadly, but will spool the contents of a text file to the screen so we can read it.

      cat /sys/bus/w1/devices/28-*******/w1_slave

The asterisks in the path above represent the unique identifier of your sensor. If you type in everything up to and including the "28-" then press "tab" the terminal will auto-complete the correct values for you. If no folder starting with 28- is present, then the sensor is not installed correctly, or is not working, or you have a loose connection in your circuit. Check it's not overheating!

Hopefully you've seen the textfile now though, so you'll know it contains just a couple of lines of text:


The important part of this is the end of the second line, t=15562. This means the probe is detecting a temperature of 15.562 degrees Celsius. Cue mad-scientist laugh, give Igor a hard-earned day off, it lives!

Part 2 - Processing the data

Getting a snapshot of the temperature at the current point in time is all very well, and might be useful in some scenarios (we could display it to an LED screen for instance), but to really make use of the probe we want to capture the data, and then display it graphically. For that we're going to have to make use of a small database, and write some simple Python code.

I've decided to store my temperature data (and a timestamp) in a sqlite database. This is the small-but-powerful database found in all sorts of embedded locations (it's almost certainly in your phone, your smart tv, your broadband router and possibly even your internet-enabled fridge.

It can be installed from the Pi's command-line with:

        sudo apt-get install sqlite3

 (Say yes when prompted.)

When you use a database like sqlite you need to define your table structure before you can start adding data. First, create a new database. This is as simple as doing

sqlite3 temp.db

This says "open a new, blank sqlite3 database called "temp.db". You will notice the command line prompt changes, indicating you are now working "inside" the database. Time to create our simple table -- this will have two columns, one to record the date and time and one to record the temperature as sensed by the probe. Create this table with the following command:

create table temp ( time timestamp, value int);

Then exit the database by typing:

        .quit

(Note the full-stop before the "q".) You should find yourself back in the familiar Pi command line again. If you type the "ls" command to list all files in the folder you should see a new file called temperature.db. Great, we have our database structure created, so now we need to get some data into it. We're going to record the temperature the probe senses every ten minutes, and insert that value into the database. For this, we need to get our hands dirty with a little bit of Python code, and a shell script.

I've split my scripts into three separate files, temp.py, storetemp.sh and make_temp_graph.py.

If you've never done any programming before, this code may look a little intimidating, but hopefully the comments will give you a general idea of what's going on. (Comments in code are any line that starts with a hash -- # -- the computer ignores them so we can use them to remind ourselves what's going on.)

This project is more about giving you a sense about the possibilities of coding on the Pi than teaching you "how to code". I am trying to address the feeling people who have never done anything particularly "techy" get when hearing about "code" or "programming". It's really just telling the computer to do things (in a logical way); don't expect to understand each line at this stage, but it's often helpful to jump in to a working example instead of trying to understand everything at an abstract level first. Enough introduction: here's the code for temp.py:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import re

# "devicefile" is the location of the textfile the probe
# generates on the Pi's disk. 
devicefile="/sys/bus/w1/devices/28-000008aab693/w1_slave"

# the block of code that starts with "def" is called a function
# it is a small self-contained bit of logic: in this case it
# extracts the temperature value from all the other text in
# the devicefile
def getTemperature():
 fobj = open(devicefile,"r")
 data = fobj.read()
 fobj.close()
 
 m = re.search('t=(\d+)',data)
 temp = int(m.group(1))
 return temp
 
# this code says, "when run from the command line, print out
# the temperature"
if __name__ == '__main__':
 temp = getTemperature()
 print temp

We can run this newly-created script from the command line by typing python temp.py:

pi@my-pi:~ $ python temp.py 
17250

pi@my-pi:~ $ 

Not very exciting, but you can see the temperature in my office right now is 17.2ºC.

The next step is saving that info into our database. For that I've used a shell script rather than a Python program, just for a bit of variety. (Shell scripts are a way of packaging up what you type at the command prompt in such a way you can automate it later on.) Here are the contents of storetemp.sh:

#!/bin/bash

# get the date and time, in the form YYYY-MM-DD HH:MM:SS
ts=$(date +'%Y-%0m-%0d %0H:%0M:%0S')

# get the current temperature using the temp.py script we wrote before
temp=$(/home/pi/temp.py)

# insert these two bits of info into our temperature table in our database
sqlite3 /home/pi/temp.db "INSERT INTO temp (time,value) VALUES ('${ts}', ${temp});"




We now use a built-in timer/scheduler on the Pi called cron which reliably runs a program as often as we want. I've set my Python program to run every 10 minutes - so every 10 minutes a new line is added to the table in the database that has the date and time, and the current temperature:

        2017-07-25 10:30 | 21011

The actual cron job looks like this:


0,10,20,30,40,50 * * * * /home/pi/storetemp.sh

And at any time we can view the contents of the database by typing:

        sqlite3 temp.db "SELECT * FROM temperature"

Progress! And you could stop there -- it would be perfectly possible to use something like Excel (or even pencil and paper) to plot the temperature over time. But we can use Python to take things a little further and have it generate a temperature graph for us. For this, we need to make a new Python program (short programs like this are often referred to as "scripts"). Python provides something called matplot lib that is designed to make every sort of graph you could imagine. We only need a simple line graph, fortunately, although even that uses more code than you might imagine. Here is the code for make_temp_graph.py:

#!/usr/bin/python

# we need to import various "extra" python modules
# to connect to a database and make a graph
import sqlite3
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from dateutil import parser
from matplotlib import style
style.use('fivethirtyeight')


# connect to our database and get all the data we stored
con = sqlite3.connect("temp.db")
c = con.cursor()
c.execute('SELECT time,value FROM temp')
data = c.fetchall()


# we're going to store two lists, a list of dates and 
# a list of temperature values for that date
dates = []
values = []

# store each row in our lists. Notice I'm dividing the 
# temperature by 1000 before saving it, so I get (for 
# example) 17.5 and not the raw value of 17500 returned 
# by the probe
for row in data:
 dates.append(parser.parse(row[0]))
 values.append(row[1]/1000.0)


# here's where we start using matplot lib to make our graph
# using the values we just retrieved
fig = plt.figure()
plt.plot_date(dates,values,"-")

# add text and format the axes
plt.gca().xaxis.set_major_formatter(matplotlib.dates.DateFormatter("%H:%M %d/%m"))
ax = fig.add_subplot(111)
fig.autofmt_xdate(rotation=45)
ax.set_xlabel('time')
ax.set_ylabel('degrees C')
fig.suptitle('Office temperature')

fig.tight_layout()
plt.tight_layout()

# save the graph to a file (called 'temp.png')
plt.savefig('temp.png')


(As an exercise you could try changing the labels on the chart axes.)

Now whenever I run python make_temp_graph.py a new image file ("temp.png") is created on the pi. If you are ssh-ing into the pi remotely (like me) you need to transfer this from the pi to your own machine to view it. I used the scp utility to do this. And here is the finished product, a record of the temperature in my office for the past few days:

You can see the clear diurnal pattern, and also some steep morning peaks which are probably due to the central heating.

Part 3 -- Next Steps

You could take this project further -- for instance, you could use the built-in webserver a Pi has to make a temperature graph available to anybody on the network. Or even to anybody on the internet. You could make the graph dynamic, so people could ask to see only a subset of the data ("show me how the temperature changed over time on Tuesday"). But hopefully this detour has inspired you to start tinkering for yourself.

Comments

Popular posts from this blog

procmail and .forward

Apple No More?

Setting XCode brace options