Wikijunior:Raspberry Pi/Raspberry Pi Temperature Sensor

From Wikibooks, open books for an open world
Jump to navigation Jump to search

Tutorial by Andrew Oakley
Public Domain 2 July 2016
www.cotswoldjam.org

Getting started[edit | edit source]

This tutorial shows you how to make a temperature sensor which shines red when hot, and blue when cold.

Words you will see on the screen, or that you need to type in, are highlighted like this.

At the end of each line, press ↵ Enter.

Your tutor should have prepared your Raspberry Pi for you and given you a bag of components. Alternatively, you can download the files from: http://cotswoldjam.org/tutorials

The electronics[edit | edit source]

Temperature sensor[edit | edit source]

A DS18B20 waterproof temperature sensor. It has three wires at one end and a metal sensor on the other end. This version is waterproof and the sensor can be dipped in water. A smaller, cheaper, non-waterproof version is also available.

Breadboard[edit | edit source]

A mini breadboard. This has a top and bottom section. All the points along each column in each section are joined, so we can make electrical connections.

Resistors[edit | edit source]

Three resistors. Check the coloured stripes – the two identical ones are 220 Ohms (red red brown) and the odd one out (with a blue stripe) is 4700 Ohms. The more Ohms, the more resistance to electricity. Resistors can be placed either way around.

Light-Emitting Diodes (LEDs)[edit | edit source]

Red and blue LEDs. The short leg is the negative leg. There is also a flat side to the rim of the bulb; this will also indicate which side is negative. LEDs also need a small resistor to prevent them from burning out. We will use a 220 Ohm resistor for each LED.

Jumper wires[edit | edit source]

Jumper wires. You should have six male-to-female jumpers (sticky-outy at one end, inny at the other end) and one male-to-male jumper (outy at both ends). Your wires may be of many different colours.

The circuit[edit | edit source]

Place the components on the breadboard like this.

The LEDs have their negative connector (short leg, flat side) to the right, on the same column as the 220 Ohm resistors.

The temperature sensor has three connectors:

ColourPurposePlacement
Grey (sometimes green or black)Negative or Groundshould be on the left
Yellow (sometimes white)Datashould be in the middle
Red (sometimes brown)Positiveshould be on the right

The 4700 Ohm resistor crosses the columns between the temperature sensor's data connector (centre), and the positive connector (right).

Next, connect three male-to-female jumpers between the temperature sensor and the Raspberry Pi's GPIO pins.

  1. Ground (negative) goes to pin 6 (GND).
  2. Data (middle connector) goes to pin 7 (GPIO4).
  3. 3.3V (positive) goes to pin 1.

Note that pin numbers ("board numbers") and GPIO numbers ("BCM numbers" – Broadcom, the processor maker) are not the same.

Check the diagram.

Now connect the jumpers between the LEDs and the Raspberry Pi.

A male-to-female jumper goes from the positive leg of the blue LED to pin 16 (GPIO23).

Another male-to-female jumper goes from the positive leg of the red LED to pin 18 (GPIO24).

A male-to-male jumper crosses between the resistors in the bottom section, and finally, a male-to-female jumper goes from one of the resistors in the bottom section to pin 14 (GND).

Configuring the Pi for 1-Wire Sensors[edit | edit source]

The temperature sensor uses a 1-Wire interface (positive and negative connectors, plus 1 data connector). We need to turn 1-Wire on.

From the Raspberry Pi desktop, click Menu – Preferences – Raspberry Pi Configuration.

From the Configuration program, click the Interfaces tab at the top. Then find the 1-Wire row and click Enabled. If it's already enabled, that's fine. If it wasn't already enabled, you will be asked to reboot the machine – make sure you reboot.

First program – taking the temperature[edit | edit source]

From the menu, select Programming - Python 3. Then use File, New Window to create a new program and type it in. Alternatively, you can load the ready-made program using File, Open, then scroll sideways and double-click the python folder, then double-click the temperature folder, then click temp1.py and Open.

When typing in the program, make sure you put spaces where they're needed at the start of lines. For example, two spaces before temp=readtemp.readtemp(). Spaces must line up.

import gpiozero, readtemp
from time import sleep

while True:
  temp=readtemp.readtemp()
  print ( "Temp: {}c".format(temp) )
  sleep(0.1)

Run the program by selecting Run menu, Run Module. You should see some temperature readings! Try warming up the sensor by holding it tightly. Stop the program by holding down the Ctrl key and pressing C.

import teaches the computer about new things, using small programs that other people have written. We use the word "library" to decribe this. gpiozero is a library that makes the GPIO pins easy to use. readtemp is a library that makes the temperature sensor easy to use. We also import the sleep command from the time library.

while True: repeats a section forever (keep going while… always!)

temp=readtemp.readtemp() reads the temperature from the sensor, and places the value in Celsius into the variable named temp. Variables are like boxes which can hold numbers or words.

print outputs information to the screen. In this case, a temperature reading.

sleep waits for a number of seconds. We leave a gap of 0.1 of a second between readings. However, readings also take a moment, so the loop doesn't go too fast.

Second program – lighting the LEDs[edit | edit source]

Change the program, or load in the temp2.py file:

import gpiozero, readtemp
from time import sleep

cold=22
hot=32
blueled=gpiozero.PWMLED(23)
redled=gpiozero.PWMLED(24)
blueled.on()
redled.on()

while True:
  temp=readtemp.readtemp()
  
  hotness=(temp-cold)/(hot-cold)
  if hotness>1:
    hotness=1
  if hotness<0:
    hotness=0
    
  print ( "Temp: {}c - Hotness {}".format(temp,hotness) )
  blueled.value=1-hotness
  redled.value=hotness
  sleep(0.1)

Run the program by selecting Run menu, Run Module. The red and blue LEDs will change their brightness depending on the temperature! Stop the program with CTRL+C and try changing the values of cold and hot. Body temperature is about 37°C (98.6°F), an ice cube is 0°C (32°F) and a typical room temperature is 22 degrees Celsius (71.6 degrees Fahrenheit).

gpiozero.PWMLED tells the computer that we have an LED connected, and that we will change the brightness using Pulse Width Modulation – flashing it on and off very quickly!

We set the brightness to a level (hotness) depending on the temperature between cold and hot.

If the temperature is hot or above, only red lights up (hotness is set to 1). If it's cold or below, only blue (hotness is set to 0). If it's in between, the brightness of blue and red will be dim or bright depending on temperature – that's the maths that does (temp-cold) divided by (hot-cold). Try working out the maths with a pencil or a calculator!

So hotness is always a decimal number between 0 (cold) and 1 (hot). We use a neat maths trick for the blue LED to get the "reverse" of the brightness; 1 minus hotness. When hotness is 0.8, the blue LED's brightness is: 1 − 0.8 = 0.2

Advanced programmers[edit | edit source]

Have a look at the readtemp.py library to find out how we get the readings from the temperature sensor. Find the file /sys/bus/w1/devices/28-something/w1_slave and output the readings from the terminal using the cat command.

Alter the code for readtemp.py library to use Fahrenheit rather than Celsius.

Files[edit | edit source]

Cjam-temperature-tutorial.pdf[edit | edit source]

The original PDF for this tutorial is on Wikimedia Commons: Cjam-temperature-tutorial.pdf

readtemp.py[edit | edit source]

# readtemp
# by Andrew Oakley 2016-07 Public Domain www.aoakley.com
# A module to read the temperature in Celcius from a DS18B20 thermometer
# connected via the 1-Wire interface on a Raspberry Pi
# You must enable dtoverlay=w1-gpio in /boot/config.txt
# or enable 1-Wire interface in Preferences - Raspberry Pi Configuration
# Default pin is GPIO4
# Connect ground & 3.3V, then connect data wire to GPIO4

import glob
from time import sleep

# Initialise the private global variable
_readtemp_device_file=""

# Find the thermometer file
def readtemp_init():
  global _readtemp_device_file
  base_dir = '/sys/bus/w1/devices/'
  glob_folder=glob.glob(base_dir + '28*')
  if len(glob_folder)<1:
    raise Exception("Cannot find DS18B20 thermometer")
  else:
    device_folder = glob_folder[0]
    _readtemp_device_file = device_folder + '/w1_slave'

# Read all the data from the thermometer
def _readtemp_raw():
  global _readtemp_device_file
  f = open(_readtemp_device_file, 'r')
  lines = f.readlines()
  f.close()
  return lines

# Extract the Celcius value from the thermometer data
def readtemp():
  if _readtemp_device_file == "":
    readtemp_init()

  lines = _readtemp_raw()
  tries = 0
  while lines[0].strip()[-3:] != 'YES' and tries<10:
    sleep(0.2)
    lines = _readtemp_raw()
    tries = tries+1
  if tries<10:
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
      temp_string = lines[1][equals_pos+2:]
      temp_c = float(temp_string) / 1000.0
      return temp_c
  else:
    raise Exception("Cannot get reading from DS18B20 thermometer")

temp1.py[edit | edit source]

import gpiozero, readtemp
from time import sleep

while True:
  temp=readtemp.readtemp()

  print ( "Temp: {}c".format(temp) )

  sleep(0.1)

temp2.py[edit | edit source]

import gpiozero, readtemp
from time import sleep

# Minimum and maximum temperatures
# Try changing these!
cold=22
hot=32

# Which pins are the LEDs connected to?
blueled=gpiozero.PWMLED(23)
redled=gpiozero.PWMLED(24)

# Turn on the LEDs
blueled.on()
redled.on()

while True:
  # Find the temperature
  temp=readtemp.readtemp()

  # Calculate a value between 0 and 1 representing hotness
  hotness=(temp-cold)/(hot-cold)
  if hotness>1:
    hotness=1
  if hotness<0:
    hotness=0
  print ( "Temp: {}c - Hotness {}".format(temp,hotness) )

  # Set the brightness of the LEDs
  blueled.value=1-hotness
  redled.value=hotness

  sleep(0.1)