Temperature

This example is a Jupyter notebook which graphs the current temperature using a PCT2075 temperature sensor. The graph is updated in real-time with temperature values and we've added horizontal lines across the X-axis to show temperature maximum and minimum thresholds.

While this notebook is designed for the PCT2075 sensor, you can easily implement one of the many temperature sensors available on the Adafruit website. Be sure to check if it has a CircuitPython library first!

Adafruit PCT2075 Temperature Sensor - STEMMA QT / Qwiic

PRODUCT ID: 4369
The Adafruit PCT2075 Temperature Sensor is a 'code compatible' drop in replacement for a very...
$4.95
IN STOCK

STEMMA QT / Qwiic JST SH 4-pin Cable - 100mm Long

PRODUCT ID: 4210
This 4-wire cable is a little over 100mm / 4" long and fitted with JST-SH female 4-pin connectors on both ends. Compared with the chunkier JST-PH these are 1mm pitch instead of...
$0.95
IN STOCK

Wiring

We'll be using the PCT2075 sensor to precisely measure temperature. The MCP2221 and PCT2075 both have STEMMA QT connectors, so you can either wire it up on a breadboard or use a STEMMA QT cable.

Try to avoid hot plugging I2C sensors. The MCP2221 doesn't seem to like that. Remove USB power first.

Make the following connections between the MCP2221 and the PCT2075:

  • Board 3V to sensor VCC (red wire)
  • Board GND to sensor GND (black wire)
  • Board SCL to sensor SCL (blue wire)
  • Board SDA to sensor SDA (yellow wire)

In the Jupyter file browser, click Upload. From the file browser, select the PCT2075.ipynb example.

Click the Run button to execute the first cell. This cell will install the adafruit-circuitpython-pct2075 library required for this example and set an environment variable so Blinka knows we're using the MCP2221

The next cell imports CircuitPython modules (such as board and busio) and initializes the I2C connection with the sensor. To verify that your board is properly initialized, it will also print a temperature reading from the PCT2075.

Click the cell containing the code to graph the temperature sensor. The graph should update every 5 seconds with a new reading. 

Code Walkthrough

Let's walk through this notebook, cell-by-cell, to understand how this code works.

First, we import all the required libraries for the notebook. We'll be using matplotlib to plot the temperature data from our sensor. We'll also invoke the special %matplotlib notebook magic to tell matplotlib we're using a Jupyter notebook.

Download: file
%matplotlib notebook
from datetime import datetime
import matplotlib.pyplot as plt
from collections import deque
from matplotlib.animation import FuncAnimation

Next we declare some constants like HISTORY_SIZE (how many sensor samples we're displaying on the graph), and INTERVAL (the graph's update interval, in seconds). We'll also declare MAX_TEMP and MIN_TEMP which are used to generate horizontal lines across the x-axis for displaying the maximum and minimum temperature values.

Download: file
# How many sensor samples we want to store
HISTORY_SIZE = 100

# Graph update interval (in seconds)
INTERVAL = 5

# Maximum Temperature (in degrees C)
MAX_TEMP = 30

# Minimum Temperature (in degrees C)
MIN_TEMP = 10

Our code plots and displays 100 sensor readings at a time. We store these readings in a list-like object called a deque container datatype. If you've never seen this datatype before, don't worry - it's very similar to a list object except it's "optimized for fast fixed-length operations" and support a maxlen argument which sets the maximum possible size of a deque. When the deque grows beyond its maxlen size, it pops objects off of its opposite end (like a FIFO stack).

We use one deque to store sensor readings (temp_data) and another deque to store time-stamps (x_time)

Download: file
# Global x-axis array
x_time = deque(maxlen=HISTORY_SIZE)

# Temperature data
temp_data = deque(maxlen=HISTORY_SIZE)

Next up, let's make a new plot and give it a title. 

Download: file
# Create new plot
fig, ax = plt.subplots()

# Global title
fig.suptitle("PCT2075 Temperature", fontsize=14)

In the animate method, we'll poll the temperature sensor and store it in the temp_data deque. Using the CPython datetime module, the code takes the current time and formats it using strftime for display on the x-axis as ticks.

Download: file
# Read the temperature sensor and add the value to the temp_data array
temp_data.append(pct.temperature)

# Grab the datetime, auto-range based on length of accel_x array
x_time.append(datetime.now().strftime('%M:%S'))

The next chunk of code clears the axis, constrains the y-axis to display a maximum value of 50 degrees celsius and 0 degrees celsius. It also adds a descriptive label to the Y-Axis.

Download: file
# Clear axis prior to plotting
ax.cla()

# Constrain the Y-axis
plt.ylim(top=50,bottom=0)

# Y-Axis label
plt.ylabel('Temperature\n(c)')

We'll use the autofmt_date method to rotate and align the x-axis tick labels. Then, let's add a grid so we can see our data better.

Download: file
fig.autofmt_xdate()
ax.grid(True, linestyle=':', linewidth=0.5)

Next up, plot the temperature graph and two dotted horizontal lines across the x-axis to represent  maximum and minimum temperature values.

Download: file
# Add a horizontal minimum line across the X-axis
plt.axhline(y=MAX_TEMP, color='r', linestyle=':', label='Max. Temperature')

# Add a horizontal maximum line across the X-axis
plt.axhline(y=MIN_TEMP, color='b', linestyle=':', label='Min. Temperature')

Let's add a legend to the graph. This will make it easy to discern which line is which if we look back at it later, or if the notebook is shared with a colleague or friend. 

Matplotlib's ax.legend() method automatically creates a legend for your graph, provided each plot has a label attached to it.

Download: file
# Add a legend to the graph
ax.legend()

We'll pause the plot's output for INTERVAL seconds

Download: file
# Pause the plot for INTERVAL seconds 
plt.pause(INTERVAL)

Finally, this method "makes an animation by repeatedly calling a function", animate. We provide it the fig we generated earlier and the function we'd like to animate.

Download: file
ani = animation.FuncAnimation(fig, animate)
This guide was first published on Dec 24, 2019. It was last updated on Dec 24, 2019. This page (Temperature) was last updated on Apr 01, 2020.