By: Megan Mason || 🗓 May 5, 2025
Allow me to introduce Opie, the mobile snowpack temperature array.
Why is it mobile? It's a prototype to test different temperature sensors, sensor configuration, and offers flexibility for short-term experiments and validation tests that disrupt the snowpack.
Why is it named Opie? When wired up, the 8-sensor set up looks like a snow crab, the latin for snow crab is Chionoecetes opilio, so Opie for short!
At CSSL (and other specialized snow monitoring stations) it's common to have a suite of instrumentation that measures the near-surface atmospheric conditions (i.e. standard meteorological variables such as air temperature, relative humidity, wind speed and direction) and a network that monitors the sub-surface, like soil moisture and heat flux. Sites instrumented with radiometers and eddy covariance allow us to quantify the radiation and turbulent energy exchanges between Earth's atmosphere and the ground/snow surface. What's commonly missing in this set up are sensors that help us quantify the energy exchanges happening within a snowpack due to the movement of water vapor caused by changes in vapor pressure and temperature gradients.
Well, we're going to measure it! Thanks to the ease of Raspberry Pi's this experiment came to life quickly. During WY 2025, we conducted five different experiments, each with a slightly tweaked research objective and a steady progression of iterative changes. Read below for to learn how to assemble and program a mobile temperature array for snow, or really anything that you want to know the temperature of.
The primary components of this project are a Raspberry Pi and a set of Resistance Temperature Detectors (RTDs). For this project, you will need these:
Key components:
Raspberry Pi 4b
Micro-SD card
Peripherals:
USB keyboard
USB mouse
Computer monitor with HDMI input
Assembly components:
Electrical, waterproof logger box, ~9x7x5"
Solar panel
Lithium iron phosphate battery
Water-tight power connectors
Power cable
Solder tools
Small flathead screwdriver
Using your 8-layer stackable HAT and set of 8 RTD sensors you're ready for assembly and some programing!
The 8-layer stackable HAT has a small diagram that depicts the order to wire your RTD sensors. The 'RTD#' shows where the two disimmilar colored wires (red vs. silver) need to be, while the remaining red wire goes in the last available spot.
To help with the congestion of wires, I clipped the plastic ends and worked with the bare wire.
In order to use the 8-layer stackable HAT, you'll run through a series of steps to install a program that has many tools to read and configure the RTD sensors. You will work in your terminal and enter some command line text to set this up. Eventually you will run a small script to print the temperature and resistance values.
Prerequisite - Enable I2C through the raspberry pi settings.
Now, working from the from the command line -
Install RTD-RPI program (written by the Sequent Microsystems developers)
~$ git clone https://github.com/SequentMicrosystems/rtd-rpi.git
~$ cd rtd-rpi/
~/rtd-rpi$ sudo make install
Read about your different tooling options:
~$ rtd -h
Run to program the channels for the pt1000 RTDs (default is pt100)
rtd 0 stypewr 1
Confirm this change by running
rtd 0 styperd
The result will be '1' which means the stackable HAT is programed for 1000 ohm RTDs
From here you can print each temperature sensor's temperature (below we'll do it in a more automated fashion).
temperature(0,1) # Update, this is a place filler
The '0' here refers to the first 8-layer stackable HAT, and the '1' refers to the first temperature channel. Use (0,2) to get the second channel and so on.
Let's now set up your python environment and get you ready to generate a script to read temperatures.
For this project, I created a virtual environment to work in python. I named my virtual environment 'rpi'.
python -m venv rpi
I then installed two python packages: ipython so that I could have an interactive python shell to test scrips, and SMrtd (Sequent Microsystems rtd package)
pip install ipython
pip install SMrtd
Here is my automated script to print the temperature, resistance, and a corrected temperature based on an ice bath calibration of 0 degrees C. Note, because I started to work with multiple sets of sensors, I have a separate .json file that holds the raspberry pi serial number and sensor offsets.
import librtd
import json
def get_pi_serial():
with open('/proc/cpuinfo', 'r') as f:
for line in f:
if line.startswith('Serial'):
return line.strip().split(':')[1].strip()
return "00000000"
# Load offsets from file
with open('sensor_offsets.json') as f:
offsets_all = json.load(f)
# Get this Pi’s serial number
pi_serial = get_pi_serial()
# Get this Pi's specific offset dict
offsets = offsets_all.get(pi_serial)
if offsets is None:
raise ValueError(f"No offsets found for Raspberry Pi with serial: {pi_serial}")
# offset_dict = {
# 1: 1.2, # channel 1 offset
# 2: 1.3, # channel 2 offset
# 3: 1.3, # channel 3 offset
# 4: 1.2, # channel 4 offset
# 5: 0.9, # channel 5 offset
# 6: 1.2, # channel 6 offset
# 7: 1.3, # channel 7 offset
# 8: 1.3 # channel 8 offset
# }
# channel 1
t_ch1 = librtd.get(0, 1)
r_ch1 = librtd.getRes(0, 1)
c_ch1 = t_ch1-offsets.get('ch_1')
# channel 2
t_ch2 = librtd.get(0, 2)
r_ch2 = librtd.getRes(0, 2)
c_ch2 = t_ch2-offsets.get('ch_2')
# channel 3
t_ch3 = librtd.get(0, 3)
r_ch3 = librtd.getRes(0, 3)
c_ch3 = t_ch3-offsets.get('ch_3')
# channel 4
t_ch4 = librtd.get(0, 4)
r_ch4 = librtd.getRes(0, 4)
c_ch4 = t_ch4-offsets.get('ch_4')
# channel 5
t_ch5 = librtd.get(0, 5)
r_ch5 = librtd.getRes(0, 5)
c_ch5 = t_ch5-offsets.get('ch_5')
# channel 6
t_ch6 = librtd.get(0, 6)
r_ch6 = librtd.getRes(0, 6)
c_ch6 = t_ch6-offsets.get('ch_6')
# channel 7
t_ch7 = librtd.get(0, 7)
r_ch7 = librtd.getRes(0, 7)
c_ch7 = t_ch7-offsets.get('ch_7')
# channel 8
t_ch8 = librtd.get(0, 8)
r_ch8 = librtd.getRes(0, 8)
c_ch8 = t_ch8-offsets.get('ch_8')
# Print table header
print(f"{'Ch. #':<6}{'Temp (C)':<12}{'Resistance (ohms)':<12}{'Corr_Temp (C)':<12}")
# Print each channel's data
for i, (t, r, c) in enumerate([
(t_ch1, r_ch1, c_ch1), (t_ch2, r_ch2, c_ch2), (t_ch3, r_ch3, c_ch3), (t_ch4, r_ch4, c_ch4),
(t_ch5, r_ch5, c_ch5), (t_ch6, r_ch6, c_ch6), (t_ch7, r_ch7, c_ch7), (t_ch8, r_ch8, c_ch8)
], start=1):
print(f"{i:<6}{t:<12.1f}{r:<12.0f}{c:<12.1f}")
In this repo you'll find a logger script that logs the temperature data at a 5-minute interval.