Temperature Sensor- Writing the code#
Write up the code found below.
import board
import pwmio
import time
import math
import analogio
import digitalio
buzzer = pwmio.PWMOut(board.GP0, variable_frequency = True)
greenLED = digitalio.DigitalInOut(board.GP1)
greenLED.direction = digitalio.Direction.OUTPUT
redLED = pwmio.PWMOut(board.GP2)
tempsensor = analogio.AnalogIn(board.GP26)
def read_temp():
val = tempsensor.value
mvolts = (val / 65535.0) * 3.3 * 1000
temp = mvolts/ 10.0
return temp
while True:
temp = read_temp()
print((temp,))
if temp >= 27 and temp < 32:
greenLED.value = False
buzzer.duty_cycle = 2**13
redLED.duty_cycle = 2**15
for i in range(360):
sinval = math.sin(i*(3.142/180))
buzzer.frequency = 400 + int(200*(sinval))
time.sleep(0.001)
elif temp >= 32:
greenLED.value = False
buzzer.duty_cycle = 2**15
for i in range(360):
sinval = math.sin(i*(3.142/180))
buzzer.frequency = 500 + int(300*(sinval))
redLED.duty_cycle = 2**15 + int(30000*(sinval))
time.sleep(0.001)
else:
buzzer.duty_cycle = 0
greenLED.value = True
redLED.duty_cycle = 0
time.sleep(1)
Once you run the code, you should see a value for the ambient temperature printed into the serial every second.
If you heat up the sensor (e.g. by grabbing it with your fingers) you should see this temperature increase. If it goes over 27\(^{\circ}\)C, the buzzer will sound and the red LED will come on. If it goes over 32\(^{\circ}\)C, the red LED will start flashing and the buzzer will sound.
Reading Analog inputs
Since the LM35 is an analog input, we require a new module analogio.
As you can see, this module functions very similarly to pwmio
- we only require the analogio.AnalogIn()
function to define our pin as an analog input.
Note
As well as board.GP26
, you can also use board.A0
or board.GP_A0
to refer to the ADC0 pin. The same applies to the other ADC pins but with GP27
replaced by A1
and GP28
replaced by A2
.
In order to get an actual temperature, we use the read_temp()
function to convert our now digital value for the voltage back into a temperature. There are 3 main steps to this:
While the Pico’s ADC has a 12-bit resolution (reading values from 0 - 4095), CircuitPython requires that our analog readings have 16-bit resolution (reading values from 0 - 65535). This mapping is done automatically within the
analogio
module - we don’t actually gain any resolution as it merely involves multiplying our 12-bit values by 16 (\(2^{12} \times 16 = 2^{16}\)).To get back to a value in mV, we divide by 65535 (giving our data range of 0 - 1) and then multiply by 3.3V (converting the range to 0 - 3.3V). We can then multiply by 1000 to get a value in mV (range is now 0 - 3300mV).
Finally, we can divide this by 10 to get a temperature (since 10mV = 1\(^{\circ}C\))
As the loop runs, the temp
variable is updated every second with the current measured temperature. This value is then printed into the serial monitor and used to determine whether the lights need to be switched and/or the buzzer sounded.
Using the plotter
You may rightly be thinking it’s strange that we used print((temp,))
instead of the standard print(temp)
. This is so that our data can be read and shown by the plotter in Mu. Mu requires that data be given as a tuple - AKA in the form (variable_1, variable_2)
. With only one variable, we still need the brackets and comma but leave the second part blank.
Under construction