Leia o valor do sensor de temperatura do Raspberry Pi Pico

Tempo de leitura: 6 minutes

Visão geral

Neste tutorial, leremos o valor do sensor de temperatura do Raspberry Pi Pico. O Raspberry Pi Pico tem sensor de temperatura interno conectado a um dos poucos pinos especiais chamados ADCs ou conversores analógico-digital.

Vamos conectar um display I2C OLED ao Raspberry Pi Pico e ler os dados de temperatura do sensor. Em seguida, exibiremos a temperatura na tela OLED. Você pode usar a equação matemática para converter o valor em Celsius em Fahrenheit. Você pode verificar o Tutorial de primeiros passos do Raspberry Pi para saber mais sobre suas especificações, pinos e detalhes.

 

Lista de Materiais

Você pode comprar a Placa Raspberry Pi Pico junto com o Módulo de Display OLED no link a seguir.

NOME DOS COMPONENTESDESCRIÇÃOQUANTIDADE
Raspberry Pi PicoRP2040 Based Raspberry Pi Pico Microcontroller1
OLED Display0.96″ SSD1306 I2C OLED Display1

 

Configuração de hardware

Como queremos exibir o valor da temperatura no visor OLED, deve haver uma conexão entre o Raspberry Pi Pico e o OLED. O diagrama de conexão é fornecido abaixo.

Conecte o pino SDA e SCL do visor OLED ao pino Raspberry Pi Pico GP8 e GP9, respectivamente. Você pode usar a placa de ensaio para montar o circuito conforme mostrado abaixo.

 

Sensor de temperatura do Raspberry Pi Pico

O sensor de temperatura interno que vem com o Raspberry Pi Pico é conectado a um dos ADCs ou conversores analógico-digital. O pino ADC suporta uma gama de valores, que é determinada pela tensão de entrada aplicada ao pino.

No RP2040 Pico Board, os pinos ADC suportam 12 bits, o que significa que o valor pode ir de 0 a 4095. Mas o código MicroPython pode escalar os valores ADC para uma faixa de 16 bits. Portanto, obtemos efetivamente a faixa de 0 a 65535. O microcontrolador funciona a 3,3 V, o que significa que um pino ADC retornará um valor de 65535 quando 3,3 V for aplicado a ele ou 0 quando não houver tensão. Podemos obter todos os valores intermediários quando a tensão aplicada ao pino está entre 0 e 3,3 V.

Os pinos ADC na placa Pico usam seu próprio esquema de numeração em vez de ir pelo número de pino GPIO. No diagrama de pinos acima, você pode ver os pinos rotulados ADC0, ADC1, ADC2 e ADC_VREF (tecnicamente ADC3), que são os quatro pinos ADC acessíveis externamente. O sensor de temperatura não possui um pino físico na placa, mas é acessado como ADC4.

Lendo o valor da temperatura com código MicroPython

Agora vamos ver o código do sensor de temperatura para Raspberry Pi Pico. Copie o seguinte código e clique no botão de download e execução.

import machine
import utime
 
sensor_temp = machine.ADC(4)
conversion_factor = 3.3 / (65535)
 
while True:
    reading = sensor_temp.read_u16() * conversion_factor 
    temperature = 27 - (reading - 0.706)/0.001721
    print(temperature)
    utime.sleep(2)

A janela Shell começará a exibir o valor da temperatura em graus Celsius.

 

Explicação do código

import machine
import utime
 
sensor_temp = machine.ADC(4)
conversion_factor = 3.3 / (65535)

Primeiro importamos a máquina e o utime. O módulo da máquina fornece a classe ADC() para trabalhar com os pinos ADC.

reading = sensor_temp.read_u16() * conversion_factor

Se você imprimir o valor do valor da temperatura, obterá um número inteiro entre 0 e 65535. Portanto, temos que converter esse valor para as escalas de graus Celsius ou Fahrenheit.

O sensor de temperatura funciona fornecendo uma tensão ao pino ADC4 que é proporcional à temperatura. Na folha de dados, uma temperatura de 27 graus Celsius fornece uma tensão de 0,706 V. Com cada grau adicional, a tensão é reduzida em 1,721 mV ou 0,001721 V. O primeiro passo para converter a temperatura de 16 bits é convertê-la de volta para volts, o que é feito com base na tensão máxima de 3,3 V usada pelo cartão Pico.

temperature = 27 - (reading - 0.706)/0.001721

Com esta conversão, o valor da temperatura mantém um valor entre 0 e 3,3. Mais uma vez, temos que fazer a segunda conversão, que traz a temperatura para a escala Celsius.

fahrenheit_degrees = celsius_degrees * 9 / 5 + 32

Se quiser converter o valor da temperatura de graus Celsius para Fahrenheit, você pode usar esta equação matemática.

 

Exibindo os valores de temperatura do Raspberry Pi Pico em OLED

Agora vamos escrever um código adicional para exibir o valor da temperatura na tela OLED. Para isso, precisamos primeiro escrever um código de driver OLED, pois o driver SSD1306 não está disponível.

Todo o código está dividido em 2 partes.

1. SSD1306.py
2. Main.py

 

SSD1306.py

Abra uma nova guia e copie o código a seguir. Salve o arquivo com o nome SSD1306.py.

# MicroPython SSD1306 OLED driver, I2C and SPI interfaces
 
from micropython import const
import framebuf
 
 
# register definitions
SET_CONTRAST = const(0x81)
SET_ENTIRE_ON = const(0xA4)
SET_NORM_INV = const(0xA6)
SET_DISP = const(0xAE)
SET_MEM_ADDR = const(0x20)
SET_COL_ADDR = const(0x21)
SET_PAGE_ADDR = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP = const(0xA0)
SET_MUX_RATIO = const(0xA8)
SET_COM_OUT_DIR = const(0xC0)
SET_DISP_OFFSET = const(0xD3)
SET_COM_PIN_CFG = const(0xDA)
SET_DISP_CLK_DIV = const(0xD5)
SET_PRECHARGE = const(0xD9)
SET_VCOM_DESEL = const(0xDB)
SET_CHARGE_PUMP = const(0x8D)
 
# Subclassing FrameBuffer provides support for graphics primitives
# http://docs.micropython.org/en/latest/pyboard/library/framebuf.html
class SSD1306(framebuf.FrameBuffer):
    def __init__(self, width, height, external_vcc):
        self.width = width
        self.height = height
        self.external_vcc = external_vcc
        self.pages = self.height // 8
        self.buffer = bytearray(self.pages * self.width)
        super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)
        self.init_display()
 
    def init_display(self):
        for cmd in (
            SET_DISP | 0x00,  # off
            # address setting
            SET_MEM_ADDR,
            0x00,  # horizontal
            # resolution and layout
            SET_DISP_START_LINE | 0x00,
            SET_SEG_REMAP | 0x01,  # column addr 127 mapped to SEG0
            SET_MUX_RATIO,
            self.height - 1,
            SET_COM_OUT_DIR | 0x08,  # scan from COM[N] to COM0
            SET_DISP_OFFSET,
            0x00,
            SET_COM_PIN_CFG,
            0x02 if self.width > 2 * self.height else 0x12,
            # timing and driving scheme
            SET_DISP_CLK_DIV,
            0x80,
            SET_PRECHARGE,
            0x22 if self.external_vcc else 0xF1,
            SET_VCOM_DESEL,
            0x30,  # 0.83*Vcc
            # display
            SET_CONTRAST,
            0xFF,  # maximum
            SET_ENTIRE_ON,  # output follows RAM contents
            SET_NORM_INV,  # not inverted
            # charge pump
            SET_CHARGE_PUMP,
            0x10 if self.external_vcc else 0x14,
            SET_DISP | 0x01,
        ):  # on
            self.write_cmd(cmd)
        self.fill(0)
        self.show()
 
    def poweroff(self):
        self.write_cmd(SET_DISP | 0x00)
 
    def poweron(self):
        self.write_cmd(SET_DISP | 0x01)
 
    def contrast(self, contrast):
        self.write_cmd(SET_CONTRAST)
        self.write_cmd(contrast)
 
    def invert(self, invert):
        self.write_cmd(SET_NORM_INV | (invert & 1))
 
    def show(self):
        x0 = 0
        x1 = self.width - 1
        if self.width == 64:
            # displays with width of 64 pixels are shifted by 32
            x0 += 32
            x1 += 32
        self.write_cmd(SET_COL_ADDR)
        self.write_cmd(x0)
        self.write_cmd(x1)
        self.write_cmd(SET_PAGE_ADDR)
        self.write_cmd(0)
        self.write_cmd(self.pages - 1)
        self.write_data(self.buffer)
 
 
class SSD1306_I2C(SSD1306):
    def __init__(self, width, height, i2c, addr=0x3C, external_vcc=False):
        self.i2c = i2c
        self.addr = addr
        self.temp = bytearray(2)
        self.write_list = [b"\x40", None]  # Co=0, D/C#=1
        super().__init__(width, height, external_vcc)
 
    def write_cmd(self, cmd):
        self.temp[0] = 0x80  # Co=1, D/C#=0
        self.temp[1] = cmd
        self.i2c.writeto(self.addr, self.temp)
 
    def write_data(self, buf):
        self.write_list[1] = buf
        self.i2c.writevto(self.addr, self.write_list)
 
 
class SSD1306_SPI(SSD1306):
    def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):
        self.rate = 10 * 1024 * 1024
        dc.init(dc.OUT, value=0)
        res.init(res.OUT, value=0)
        cs.init(cs.OUT, value=1)
        self.spi = spi
        self.dc = dc
        self.res = res
        self.cs = cs
        import time
 
        self.res(1)
        time.sleep_ms(1)
        self.res(0)
        time.sleep_ms(10)
        self.res(1)
        super().__init__(width, height, external_vcc)
 
    def write_cmd(self, cmd):
        self.spi.init(baudrate=self.rate, polarity=0, phase=0)
        self.cs(1)
        self.dc(0)
        self.cs(0)
        self.spi.write(bytearray([cmd]))
        self.cs(1)
 
    def write_data(self, buf):
        self.spi.init(baudrate=self.rate, polarity=0, phase=0)
        self.cs(1)
        self.dc(1)
        self.cs(0)
        self.spi.write(buf)
        self.cs(1)

 

main.py

Após fazer o upload do SSD1306.py, crie uma nova guia novamente e copie o código a seguir. Salve este código como um nome main.py

# Display Image & text on I2C driven ssd1306 OLED display 
from machine import Pin, I2C
from ssd1306 import SSD1306_I2C
import machine
import utime
 
sensor_temp = machine.ADC(4)
conversion_factor = 3.3 / (65535)
 
WIDTH  = 128                                            # oled display width
HEIGHT = 64                                             # oled display height
 
i2c = I2C(0, scl=Pin(9), sda=Pin(8), freq=200000)       # Init I2C using pins GP8 & GP9 (default I2C0 pins)
print("I2C Address      : "+hex(i2c.scan()[0]).upper()) # Display device address
print("I2C Configuration: "+str(i2c))                   # Display I2C config
 
 
oled = SSD1306_I2C(WIDTH, HEIGHT, i2c)                  # Init oled display
 
while True:
    reading = sensor_temp.read_u16() * conversion_factor
    temperature = 27 - (reading - 0.706)/0.001721
    print(temperature)
 
    # Clear the oled display in case it has junk on it.
    oled.fill(0)       
    
    # Add some text
    oled.text("Temp: ",6,8)
    oled.text(str(round(temperature,2)),50,8)
    oled.text("*C",95,8)
    utime.sleep(2)
 
 
    # Finally update the oled display so the image & text is displayed
    oled.show()

Depois de executar o código, o display OLED começará a exibir o valor da temperatura na tela OLED.

É assim que você pode ler os dados de temperatura usando o código do sensor de temperatura MicroPython para Raspberry Pi Pico Board.