Thermometer Readings with Raspberry Pi
Okay so as part of my Raspberry Pi Thermostat Project I now have a headless Raspberry Pi that I can SSH into. The next small step is to wire a thermometer to it and begin logging the temperature in my bedroom to learn a thing or two about how hot it is getting up there and how much the temperature varies.
Hardware involved:
- The headless Raspberry Pi I set up in the previous post
- A DS18B20 digital thermometer
- A small breadboard
- Some male-to-female jumper wires
- A 10kΩ resistor
Wiring
For this part I basically just followed this tutorial but with a couple small changes. I used a 10kΩ instead of a 4.7kΩ because it’s what I had around. I also didn’t shell out for the Pi Cobbler. I simply connected the three lines I needed (5V, ground, GPIO 4) directly to the breadboard with jumper wires. I still found the wiring diagram here to be incredibly useful. Mine ended up looking like this:
Making a temperature reading
Once it’s all wired up there are a couple simple steps to reading the temperature. First I had to edit /boot/config.txt
and add this line and then reboot:
dtoverlay=w1-gpio
This enables the Onewire interface that we use to read the thermometer. Next, run the following commands to mount the thermometer device:
sudo modprobe w1_gpio
sudo modprobe w1_therm
The thermometer is now ready to be read. All you have to do is find the right file to read from. To do this, go to /sys/bus/w1/devices
and look for a folder that starts with 28-
followed by a serial number. Copy this serial number because you will need it. If you now do cat /sys/bus/w1/devices/28-{SERIAL NUMBER}/w1_slave
you will get something that looks like this:
79 01 55 00 7f ff 0c 10 14 : crc=14 YES
79 01 55 00 7f ff 0c 10 14 t=23562
The YES
indicates that the temperature reading was successful. The t=23562
is the temperature in Celsius multiplied by 1000. Now we’re in business.
Reading the temperature with Ruby
I wanted to track and log the temperature in my bedroom so the easiest thing to do was write a little ruby script that I would run on a cron. I installed Ruby using RVM and wrote the following module to simply read the temperature and convert it to Fahrenheit so my American brain can understand it.
module Thermometer | |
def self.read | |
serial = ::THERMOMETER_SERIAL | |
file = File.open("/sys/bus/w1/devices/#{serial}/w1_slave") | |
lines = file.read.split("\n") | |
raise ThermometerReadError unless lines[0].end_with? "YES" | |
/t=(?<reading>\d+)/ =~ lines[1] | |
celsius = reading.to_f / 1000 | |
celsius * 1.8 + 32 | |
end | |
end | |
class ThermometerReadError < StandardError | |
end |
Logging the temperature
The last step of this bit was creating a ruby script that would use that thermometer module and spit out a timestamp and the temperature. It looks a little something like this:
#!/home/pi/.rvm/rubies/ruby-2.4.0/bin/ruby | |
require_relative "lib/thermometer.rb" | |
::THERMOMETER_SERIAL = "28-00043d6071ff" | |
temp = Thermometer.read | |
time = Time.now.strftime("%F %R") | |
puts "#{time} > #{temp}" |
All that was left to do was set that script up in a cron job with the output going to a file and I now I have a file that looks like this:
2017-06-07 01:57 > 74.1866
2017-06-07 01:58 > 74.30000000000001
2017-06-07 01:59 > 74.525
2017-06-07 02:00 > 74.6366
2017-06-07 02:01 > 74.86160000000001
2017-06-07 02:02 > 74.975
2017-06-07 02:03 > 75.0866