Reading the on-board Temperature of a Raspberry Pi Pico
As well as providing many marvellous ways of interfacing to the world via external sensors, the Raspberry Pi Pico, or more accurately, the RP2040 microcontroller around which the Pico is built, includes an on-board temperature sensor that we can access to get a feel (see what I did there) for the environment.
About the sensor
As we know from reading about the RP2040 microcontroller, it includes an Analogue to Digital Converter (ADC) which can read signals that vary across a (relatively) broad range of input voltage levels and convert them to discrete values that we can read.
The RP2040 has five ADC inputs. Three are connected to the GPIO pins. One is connected to GPIO29 (which isn’t exposed as a header pin) which is used to measure VSYS and one input is dedicated to an internal temperature sensor. Don’t go trying to look for the sensor on the Pico board, it is integrated into the main RP2040 microcontroller chip!
The ADC on the Pico will allow for 12 bit resolution. That means it will return analogue values to a digital range between 0 and 4095. However, we will be scaling those values to a 16 bit range when we read them with MicroPython to between 0 and 65535. So for us, a voltage range between 0v and 3.3v will equal a digital numeric range of between 0 and 65535.
Technically the temperature of 27°C should equal the voltage of 0.706V which should equal 14021 on our numeric range between 0 and 65535.
As our temperature increases, the voltage reading drops by 1.721mV per degree.
Therefore the logical process that we need to follow to arrive at a temperature is;
- Read our 16 bit value. (variable =
reading) - Convert our 16 bit value into the equivalent voltage (variable =
voltage) by multiplying our reading by 3.3/65536. - Solve for the last unknown which is the variable
temperature. Since we know where one point of the linear graph of voltage to temperature is (0.706V at 27°C) and we know thevoltageof our ADC input and we know the rate of change (gradient) of our graph (-1.721mv per °C).
Points to note from the datasheet
The rate of change of the sensor can vary over the temperature range and from device to device, therefore some degree of calibration may be required to gain a more accurate measurement.
Likewise, the sensor is very sensitive to errors in the reference voltage. Any error in the reference voltage will be passed to the measurement. The method to improve accuracy is therefore to add a more accurate and stable external reference voltage.
Code
The code below is a very simple affair that declares our sensor then enters a loop where a reading is taken, converted to a voltage, translated to a temperature and printed. This is repeated every two seconds.
import machine
import time
sensor = machine.ADC(4)
while True:
reading = sensor.read_u16()
voltage = reading * ( 3.3 / 65535)
temperature = 27 - (voltage - 0.706) / 0.001721
print('Temperature: ', temperature)
time.sleep(2)
The output can be adjusted by carefully breathing on the Pico which should raise the temperature slightly.
Temperature: 15.3408
Temperature: 14.87265
Temperature: 15.80894
Temperature: 15.3408
It should be noted that the large number of decimal places in the output is not indicative of a commensurate level of accuracy!