Temperature Sensor- Writing the code

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:

  1. 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}\)).

  2. 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).

  3. 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