Back

Activity 2.9: Sensors Lie

The Messy Real World — Day 2 of 4

divider

Activity 2.9

Sensors Lie

Key Concepts

Calibration

Averaging

Unit Conversion

Yesterday's Knob Was Honest

A potentiometer has no units. It reports a position, and you decided what that meant — a bar height, a pause length. Whatever you chose was correct by definition.

Today's sensor claims to measure something real. That makes it possible for it to be wrong.

This Is Not a Temperature

Terminal window
14299

It is a count from the ADC, exactly like yesterday's. Nothing about it is in degrees yet. Converting it is your job, not the sensor's.

And It Will Not Hold Still

Terminal window
14312
14098
14401
14205
14388

Five readings. Nothing moved. Nothing got warmer.

One degree is worth about 198 counts on this sensor. So a 300-count wobble is 1.5°C of nonsense.

Averaging

The wobble is random, so it cancels. Take twenty readings in quick succession and divide by twenty.

total = total + sensor.read_u16()
...
return total // samples

The accumulator pattern from Activity 1.21, doing real work on real hardware.

Two Conversions

volts = reading / 65535 * 3.3
celsius = (volts - 0.5) * 100

Counts to volts is arithmetic you can derive: the full range of 65535 spans 3.3V.

Volts to degrees you cannot derive — it comes from the datasheet. This sensor puts out 10mV per degree, offset by 500mV so it can report temperatures below zero.

Now Check It Against Reality

Your program will confidently print a temperature. There is a thermometer on the wall.

If they disagree, one of them is wrong and you do not yet know which. Finding out is engineering.

Today's Objectives

  • Reading a temperature sensor on an analog pin
  • Averaging several samples to steady a jittery reading
  • Converting raw ADC counts into real units
  • Checking a calculated value against reality

Key Terms

Calibration
Comparing what a sensor reports against a known reference, and correcting the difference.
Averaging
Taking several readings and using their mean, so random wobble cancels out.
Datasheet
The manufacturer's document describing exactly how a component behaves — where the volts-to-degrees rule comes from.
Offset
A fixed amount added to a reading to correct a consistent error.

'F' → Fullscreen

divider

Build

Leave the five-LED array and the potentiometer wired. Create a new MicroPython program named 2-9-temperature.


Task 1: Read the Raw Sensor

  • Wire the TMP36 to A1, with its outer legs on 3V3 and GND.
  • Print the raw reading in a loop.
  • Do not touch anything. Watch the number change anyway.

Check the orientation twice before you plug in the power. A TMP36 wired backwards gets hot enough to burn your fingers. The flat face tells you which way round it goes.

The SparkFun IoT RedBoard RP2350 with the pin labeled A1 outlined on the bottom headerCircuit diagram of a TMP36 temperature sensor with its outer legs on 3V3 and GND and its middle leg connected to analog pin A1, with a warning about checking orientation before powering up
[PHOTO PLACEHOLDER — Task 1: TMP36 Wired, Flat Face Visible]
Sensors Lie
from machine import Pin, ADC
import time
temp_sensor = ADC(Pin(41))
while True:
print(temp_sensor.read_u16())
time.sleep(0.2)

Task 2: Steady It

  • Write read_average(sensor, samples) that adds up several readings and returns their mean.
  • Print one raw sample and the twenty-sample average side by side.
  • Watch which one holds still.
Sensors Lie
from machine import Pin, ADC
import time
temp_sensor = ADC(Pin(41))
def read_average(sensor, samples):
total = 0
for i in range(samples):
total = total + sensor.read_u16()
time.sleep(0.01)
return total // samples
while True:
print("one sample:", temp_sensor.read_u16(), " average of 20:", read_average(temp_sensor, 20))
time.sleep(0.5)

Task 3: Turn Counts Into Degrees

  • Write to_volts(reading), using the fact that 65535 counts spans 3.3V.
  • Write to_celsius(volts) from the sensor's rule: 10mV per degree, with a 500mV offset.
  • Print all three numbers together, so you can see the chain.
Sensors Lie
from machine import Pin, ADC
import time
temp_sensor = ADC(Pin(41))
def read_average(sensor, samples):
total = 0
for i in range(samples):
total = total + sensor.read_u16()
time.sleep(0.01)
return total // samples
def to_volts(reading):
return reading / 65535 * 3.3
def to_celsius(volts):
return (volts - 0.5) * 100
while True:
raw = read_average(temp_sensor, 20)
volts = to_volts(raw)
print("raw:", raw, " volts:", round(volts, 3), " C:", round(to_celsius(volts), 1))
time.sleep(1)

Task 4: Argue With the Wall

  • Compare your number against a real thermometer in the room. Write both down.
  • If they disagree, work out by how much, and put that correction in OFFSET.
  • Re-run and check that you now agree.

An offset is a blunt instrument — it assumes your sensor is wrong by the same amount at every temperature, which may not be true. It is still what real instruments do, and it is honest as long as you know that is the assumption you made.

Sensors Lie
from machine import Pin, ADC
import time
temp_sensor = ADC(Pin(41))
OFFSET = 0.0
def read_average(sensor, samples):
total = 0
for i in range(samples):
total = total + sensor.read_u16()
time.sleep(0.01)
return total // samples
def to_volts(reading):
return reading / 65535 * 3.3
def to_celsius(volts):
return (volts - 0.5) * 100
while True:
raw = read_average(temp_sensor, 20)
celsius = to_celsius(to_volts(raw)) + OFFSET
print("raw:", raw, " volts:", round(to_volts(raw), 3), " C:", round(celsius, 1))
time.sleep(1)

Task 5: Temperature on the Bar

  • Bring the array and show_bar() back in from Activity 2.8.
  • Write a more general scale(value, low, high, steps) that works on any range, not just 0–65535.
  • Pick a COOL and WARM temperature to span, and drive the bar from the reading.
  • Warm the sensor with your fingers and watch the bar climb.
Sensors Lie
from machine import Pin, ADC
import time
leds = [
Pin(28, Pin.OUT),
Pin(29, Pin.OUT),
Pin(30, Pin.OUT),
Pin(31, Pin.OUT),
Pin(32, Pin.OUT),
]
temp_sensor = ADC(Pin(41))
OFFSET = 0.0
COOL = 18
WARM = 30
def read_average(sensor, samples):
total = 0
for i in range(samples):
total = total + sensor.read_u16()
time.sleep(0.01)
return total // samples
def to_volts(reading):
return reading / 65535 * 3.3
def to_celsius(volts):
return (volts - 0.5) * 100
def scale(value, low, high, steps):
if value <= low:
return 0
if value >= high:
return steps
return int((value - low) / (high - low) * (steps + 1))
def show_bar(leds, count):
for i in range(len(leds)):
if i < count:
leds[i].value(1)
else:
leds[i].value(0)
while True:
raw = read_average(temp_sensor, 20)
celsius = to_celsius(to_volts(raw)) + OFFSET
show_bar(leds, scale(celsius, COOL, WARM, len(leds)))
print("C:", round(celsius, 1), " bar:", scale(celsius, COOL, WARM, len(leds)))
time.sleep(1)
[PHOTO PLACEHOLDER — Task 5: Bar Climbing as the Sensor Is Warmed by Hand]

Challenge (Optional): Highest and Lowest of the Day

  • Track the warmest and coolest temperatures seen since the program started, the way you tracked your knob's range in 2.8.
  • Print all three: now, high, low.
divider

Checkpoint

Your finished program should print something close to this, and hold steady:

Terminal window
raw: 14298 volts: 0.72 C: 22.0
raw: 14301 volts: 0.72 C: 22.0
raw: 14522 volts: 0.731 C: 23.1
  • The averaged reading changes by only a count or two when nothing is happening
  • Your temperature agrees with a real thermometer to within a degree or so
  • Pinching the sensor makes the number climb within a few seconds, then fall again when released
  • The bar climbs as the sensor warms and never goes below empty or above full
divider

Reflection

Answer the following questions before submitting your work.

  1. Yesterday the knob had no units and you decided what its reading meant. The TMP36 claims to measure something real. Explain why that makes the raw number less trustworthy rather than more.
  2. One degree is worth about 198 counts, and a still sensor wobbles by a few hundred. Use those two numbers to explain why averaging twenty samples was worth doing.
  3. Your calculated temperature probably disagreed with the wall thermometer. Name two different things that could cause that, and describe how you would tell which one it was.
divider

Submit

Submit the required files to the appropriate dropbox.

Activity Complete