Maker Advent Calendar Day #8: Tracking Temps!
Welcome to day eight of your 12 Projects of Codemas Advent Calendar. Today we’re going to be sensing the temperature of our local environment and using these temperature readings to make fun projects!
Temperature sensors are another component that you'll likely walk past every single day. The thermostat for your home's heating system, whether a traditional version or a modern smart thermostat, will use something similar to what you find in your box today. Ovens, cars, offices and many other everyday items and locations use temperature sensors.
With winter very much here and getting colder every day, it's a great time to learn how to keep an eye on temperature with code and your Pico!
Box #8 Contents
In this box you will find:
- 1x Custom waterproof temperature sensor with male jumper wires
- 1x 4.7k resistor
- 3x Male to male jumper wires
Today we'll use our temperature sensor to measure the ambient temperature in your home, then move on to more exciting projects like sensing liquid temperature and creating an alarm to let you know when your home is getting too cold!
The sensor in your box is a custom version of our popular waterproof temperature sensor. The metal tip houses the sensor inside (specifically a DS18B20-compatible 1-wire sensor) and is sealed within a length of wire, allowing you to dunk this into water and other liquids to check the temperature.
We've added male jumper wires to this version to make it easier to use with a breadboard too.
What is 1-wire?
1-wire is a serial communication protocol for devices to communicate to a controller...
...ergh, let's make that a bit more human! 1-wire allows a special device like our temperature sensor to talk to a controller, like our Pico, enabling it to send data to the Pico to be used in a program.
Despite it's name, you actually need at least two wires to use 1-wire devices, and in some examples (like our sensor) we're using three wires. The name is related to the data communication - you only need one wire to allow the devices to talk to each other both ways.
Construct the Circuit
We're once again going to use the LEDs and buzzer along with the temperature sensor (they just pair so well with so many sensors and components!), so remove the PIR circuit from yesterday leaving just the LEDs and buzzer on the main breadboard.
Your starting circuit should look like this:
Now to add the temperature sensor to the mini breadboard. Your sensor should have three wires - red, yellow and white (the white wire may be black depending on the batch).
Place the wires into the top edge of the mini breadboard in the order white-yellow-red as per the image below:
Next, add the resistor to connect the yellow and red wires, in the same way we show below:
Now we need to add three wires to complete the circuit and connect the sensor to our Pico:
- Connect the left leg to the blue GND lane
- Connect the middle leg to GPIO 26 (physical pin 31)
- Connect the right leg to 3.3V on physical pin 36
Your circuit should look similar to this:
Activity 1: Simple Temperature Sensing
Let's start with a minimal program to take a single temperature reading from the sensor.
This sensor relies on some new imports that do a lot of the hard work for us - the onewire libary and ds18x20 library. Luckily these are now built into MicroPython so we don't need to worry about downloading anything.
We set up the sensor's pin as an input as we've done before with other sensors, however using this particular 1-wire sensor requires some extra code to get it working.
We have to tell MicroPython that we're using a 1-wire DS18B20 sensor with the following line in our code below: sensor = ds18x20.DS18X20(onewire.OneWire(SensorPin))
We also need to scan for 1-wire devices on the GPIO pin we have set up. 1-wire devices such as our sensor have a unique registration number in their read-only memory (rom). The following line in our code below scans for sensors (roms) connected to our pin: roms = sensor.scan().
We then use a while loop which contains a for loop. We used a for loop yesterday with the motion sensor when using the range function, but this time our range will be roms (the number of roms our scan found, which will just be our single sensor). The for loop is saying "for every rom I find, do this".
The code then converts the sensor's temperature reading to centigrade, and then prints this whilst also adding the °C symbol to the end of it. The code commentary should make everything clear - give it a try!
# Imports import onewire, ds18x20, time from machine import Pin # Set the data pin for the sensor SensorPin = Pin(26, Pin.IN) # Tell MicroPython we're using a DS18B20 sensor, and which pin it's on sensor = ds18x20.DS18X20(onewire.OneWire(SensorPin)) # Look for DS18B20 sensors (each contains a unique rom code) roms = sensor.scan() while True: # Run forever sensor.convert_temp() # Convert the sensor units to centigrade time.sleep(2) # Wait 2 seconds (you must wait at least 1 second before taking a reading) for rom in roms: # For each sensor found (just 1 in our case) print((sensor.read_temp(rom)),"°C") # Print the temperature reading with °C after it time.sleep(5) # Wait 5 seconds before starting the loop again
Activity 2: Temperature Indicators
Now that we have the basics covered, let's use these readings to drive our LEDs to give us visual indication of the temperature.
The example below adds our LEDs back in and uses a while loop with multiple if statement conditions to drive the LEDs depending on the temperature - red if it goes below 18°C, amber if it's at a comfortable 18°C-22°C, and green if it's over 22°C.
We've covered while loops, if statements, if/elif and ranges in the previous boxes, so the code in this example should feel very familiar.
Grab a few cups of water at different temperatures (no boiling water!) and try dipping the waterproof end of the sensor into each one, watching the readings change and the different LEDs light up. Keep the Pico end of things as far away as possible...water and electronics aren't the best of friends...
# Imports import onewire, ds18x20, time from machine import Pin # Set up the LED pins red = Pin(18, Pin.OUT) amber = Pin(19, Pin.OUT) green = Pin(20, Pin.OUT) # Set the data pin for the sensor SensorPin = Pin(26, Pin.IN) # Tell MicroPython that we're using a DS18B20 sensor, and which pin it's on sensor = ds18x20.DS18X20(onewire.OneWire(SensorPin)) # Look for DS18B20 sensors (each contains a unique rom code) roms = sensor.scan() while True: # Run forever time.sleep(5) # Wait 5 seconds between readings for rom in roms: # For each sensor found (just 1 in our case) sensor.convert_temp() # Convert the sensor units to centigrade time.sleep(1) # Always wait 1 second after converting reading = sensor.read_temp(rom) # Take a temperature reading print(reading) # Print the reading if reading <= 18: # If reading is less than or equal to 18 red.value(1) # Red ON amber.value(0) green.value(0) elif 18 < reading < 22: # If reading is between 18 and 22 red.value(0) amber.value(1) # Amber ON green.value(0) elif reading >= 22: # If reading is greater than or equal to 22 red.value(0) amber.value(0) green.value(1) # Green ON
Activity 3: Temperature Alarm
We can now introduce our buzzer along with an alarm function in our code again to make a fun temperature alarm project.
Whilst yesterday's motion sensor alarm project is great for spotting people moving in an area, this alarm can be used to keep an eye on the temperature in a specific room/area.
Most of us have thermostats in our homes, but there's great fun to be had creating your own temperature sensing alarm project to monitor a specific area - be it for your own health or monitoring the environment for plants and pets.
The alarm example below is similar to yesterday's motion alarm, using an alarm function to light the LEDs and sound the buzzer when the temperature goes below 18°C - change the 18 to whatever is relevant for your project/scenario.
We've added as many comments as possible to help remind you what each section is doing:
# Imports import onewire, ds18x20, time from machine import Pin, PWM # Set up the LED pins red = Pin(18, Pin.OUT) amber = Pin(19, Pin.OUT) green = Pin(20, Pin.OUT) # Set up the Buzzer pin as PWM buzzer = PWM(Pin(13)) # Start PWM duty to 0% at program start buzzer.duty_u16(0) # Set the data pin for the sensor SensorPin = Pin(26, Pin.IN) # Tell MicroPython that we're using a DS18B20 sensor, and which pin it's on sensor = ds18x20.DS18X20(onewire.OneWire(SensorPin)) # Look for DS18B20 sensors (each contains a unique rom code) roms = sensor.scan() def alarm(): # Our alarm function buzzer.duty_u16(10000) # Buzzer duty (volume) up for i in range(5): # Run this 5 times buzzer.freq(5000) # Higher pitch # LEDs ON red.value(1) amber.value(1) green.value(1) time.sleep(0.2) # wait 1 second buzzer.freq(1000) # Lower pitch # LEDs OFF red.value(0) amber.value(0) green.value(0) time.sleep(0.2) # wait 1 second buzzer.duty_u16(0) # Buzzer duty (volume) off while True: # Run forever time.sleep(5) # Wait 5 seconds between readings for rom in roms: # For each sensor found (just 1 in our case) sensor.convert_temp() # Convert the sensor units to centigrade time.sleep(1) # Always wait 1 second after converting reading = sensor.read_temp(rom) # Take a temperature reading print(reading) # Print the reading if reading < 18: # If reading is less than or equal to 18 alarm() # Call our alarm function
Day #8 Complete!
Another day, another component completed! You now have a temperature sensor in your growing arsenal of parts to make projects with, and we're sure you'll use this one time and time again.
As you're probably starting to realise, a lot of these sensors and components are coded in a very similar way. Sometimes we need the help of imported libraries, sometimes we need resistors/additional hardware, but the fundamental way we write code for them (with loops, if statements and variables) is pretty consistent.
So what did we cover on day #8? Today you have:
- Built a circuit with a temperature sensor
- Learnt how to use a temperature sensor with MicroPython and the Pico
- Used your first 1-wire component and the 1-wire library
- Created a temperature monitor and temperature alarm system
- Learnt more about for loops
As always, keep your circuit safe somewhere until tomorrow (don't take anything apart just yet) and we'll see you again tomorrow for more fun!
We used Fritzing to create the breadboard wiring diagram images for this page.