# Kitchen Thermometer - Python likes Turkey a micro:bit

As we enter the final week of no blocks November, we're bringing you a practical project that might come in very handy for roasting your favorite seasonal dish. And if turkey's not your thing, there are countless uses for this project, culinary and otherwise!

**Check out the demonstration video here:**

## The Common Thermistor

If you've been through our JumpStart Python projects, the basics of this code will be very familiar to you! Your JumpStart kit included a **thermistor** for measuring external temperatures. It turns out that common kitchen *probe thermometers* use exactly the same **thermistor** technology!

You may already have one of these like the one shown here, but if not they can be purchased online for around $10. Search for replacement probes (opens in a new tab). I happened to have an old one sitting in a kitchen drawer, the cheap display unit it had once plugged into having long since stopped working. Wouldn't it be cool to breathe life back into this thing?!

## Connecting a Thermistor to the Micro:bit

In * JumpStart* you used a discrete thermistor component. Connecting a kitchen probe is just as easy. The two pins of the device are connected to the contacts of the 1/8" plug at the end of the cable. For the code below, I connected to

**pin0**and

**GND**.

## Calibration

A thermistor is a variable resistor whose value changes based on temperature. Common thermistors are NTC devices, which stands for "Negative Temperature Coefficient". That means that as the temperature **rises**, the resistance value **decreases**. Different thermistors respond differently based on their materials and construction, so you'll need to **calibrate** yours to get an accurate temperature reading. To do this, you need another thermometer to use as a standard of measurement.

Calibrating for an accurate temperature measurement is pretty simple. You just need to take three measurements at different temperatures at the **high**, **low**, and **medium** levels of the range you're interested in measuring. I used a glass of ice water, room temp water, and hot tap-water for my three calibration points. A standard method for accurate thermistor calculations is the Steinhart-Hart Equation (opens in a new tab). It uses three coefficients that are calculated from the three measured calibration points. You could use an Ohmmeter as shown in the picture above to measure the resistance for the R1, R2, and R3 resistances needed. Search for Steinhart Hart Calculator (opens in a new tab) and you'll find some online forms that can calculate the coefficients for you (cal_a, cal_b, cal_c). Once you have those three coefficients, the Python code to get the temperature in Celsius based on measured resistance is:

```
def calc_temp(r):
# Use the Steinhart-Hart equation
t_inv = cal_a + cal_b * math.log(r) + cal_c * math.log(r)**3
t_kelvin = 1 / t_inv
t_celsius = t_kelvin - 273.15
return t_celsius
```

## Measuring Resistance with the Micro:bit

You can use the built-in pullup resistor feature of the micro:bit to help measure the resistance of the thermistor. As we mentioned our the Buttons and Switches article, the pullup resistance is about 13k Ohms. The Python code to convert an ADC reading to resistance with that pullup enabled is:

```
def adc_to_r(val):
# Convert ADC reading with pullup resistor to Resistance value
return val * (13000 / (1024 - val))
```

With this code, you can use the micro:bit to measure the three calibration values as raw ADC values. Then in your code you can convert those to resistances (R1, R2, R3) and run the calibration calculation.

## Calculating the Coefficients

The Python code to calculate the three coefficients is as follows. Note that the calibration temperatures are **measured in Celsius**, and converted to Kelvin using the constant

*K = 273.15*.

```
def calibrate():
global cal_a, cal_b, cal_c
L1 = math.log(R1)
L2 = math.log(R2)
L3 = math.log(R3)
Y1 = 1 / (T1 + K)
Y2 = 1 / (T2 + K)
Y3 = 1 / (T3 + K)
g2 = (Y2 - Y1) / (L2 - L1)
g3 = (Y3 - Y1) / (L3 - L1)
cal_c = (g3 - g2) / ( (L3 - L2) * (L1 + L2 + L3) )
cal_b = g2 - cal_c * (L1*L1 + L1*L2 + L2*L2)
cal_a = Y1 - (cal_b + L1*L1 * cal_c) * L1
```

## Wrap-up and Remix ideas

We're going for maximum "style points" in the *code below*, doing the *calibration* AND the measurements right on the micro:bit. The neat thing is, this is a pretty accurate little measuring tool! And if you've worked through the Temperature Sensor project in JumpStart Python, you'll know exactly how to turn this into a * wireless thermometer* - you could even add an

**alarm**when the temperature reaches a desired level!

```
from microbit import *
import math
# Measured calibration constants
T1 = 1.67
A1 = 955
T2 = 18.3
A2 = 910
T3 = 56
A3 = 685
K = 273.15 # Kelvin offset from Celsius
def calibrate():
global cal_a, cal_b, cal_c
L1 = math.log(R1)
L2 = math.log(R2)
L3 = math.log(R3)
Y1 = 1 / (T1 + K)
Y2 = 1 / (T2 + K)
Y3 = 1 / (T3 + K)
g2 = (Y2 - Y1) / (L2 - L1)
g3 = (Y3 - Y1) / (L3 - L1)
cal_c = (g3 - g2) / ( (L3 - L2) * (L1 + L2 + L3) )
cal_b = g2 - cal_c * (L1*L1 + L1*L2 + L2*L2)
cal_a = Y1 - (cal_b + L1*L1 * cal_c) * L1
def calc_temp(r):
# Use the Steinhart-Hart equation
t_inv = cal_a + cal_b * math.log(r) + cal_c * math.log(r)**3
t_kelvin = 1 / t_inv
t_celsius = t_kelvin - K
return t_celsius
def adc_to_r(val):
# Convert ADC reading with pullup resistor to Resistance value
return val * (13000 / (1024 - val))
# Calculate resistance constants for calibration
R1 = adc_to_r(A1)
R2 = adc_to_r(A2)
R3 = adc_to_r(A3)
calibrate()
pin0.set_pull(pin0.PULL_UP)
while True:
# Read the raw ADC value
val = pin0.read_analog()
# display.scroll(str(val)) # Calibration
# Convert to resistance
r = adc_to_r(val)
# Calculate temperature
t = calc_temp(r)
# Convert to rounded string and display
t_str = str(round(t))
display.scroll(t_str)
```