Sensor de temperatura DS18B20 com Raspberry Pi Pico usando MicroPython

Tempo de leitura: 9 minutes

Neste guia do usuário, aprenderemos como usar um sensor de temperatura DS18B20 com Raspberry Pi Pico no MicroPython. Este é um artigo abrangente no qual discutiremos o sensor e como acessar as leituras de temperatura por meio de um único sensor. Além disso, também exibiremos as leituras de temperatura em um display OLED SSD1306

 

Pré-requisitos

Antes de começarmos esta lição, certifique-se de que você esteja familiarizado e tenha a versão mais recente do Python 3 em seu sistema, tenha configurado o MicoPython no Raspberry Pi Pico e tenha um Ambiente de Desenvolvimento Integrado (IDE) em execução no qual faremos a programação. Usaremos o mesmo Thonny IDE que usamos anteriormente quando aprendemos a piscar e perseguir LEDs em micro-python.

 

DS18B20 Introdução

É um sensor de temperatura que é programável por fio único. É amplamente utilizado para medir a temperatura de soluções químicas e substâncias que estão presentes em um ambiente duro. Uma das vantagens de usar este sensor é que precisamos apenas de um único pino de nossas placas Raspberry Pi Pico para transferir dados. Assim, é extremamente conveniente usar com o microcontrolador, pois podemos medir várias temperaturas usando o menor número de pinos em nossa placa de desenvolvimento.

A tabela abaixo mostra algumas características principais do sensor ds18b120

CaracterísticaValor
Tensão operacional3V-5V
Faixa de temperatura-55°C a +125°C
Precisão±0.5°C
Resolução de saída9bit a 12bit

Principais Características do DS18B20

Diagrama de pinagem

Uma versão à prova d’água deste sensor também está disponível no mercado. As figuras a seguir mostram a pinagem dos sensores DS18B20.

O diagrama a seguir mostra a pinagem do sensor de temperatura DS18B20 normal.

A tabela abaixo lista as configurações de pinos:

PinoDescrição
VCCEste é o pino que alimenta o sensor. 3.3V para placas Raspberry Pi Pico
DataEste pino dá o valor da temperatura
GroundEste pino está conectado com o terra

Detalhes da configuração do pino DS18B20

Este sensor de temperatura também vem em um módulo de pacote único que contém um sensor e um resistor de pull-up. Se você estiver usando um módulo, não precisará conectar um resistor externo de 4,7 K ohms. Porque o módulo já possui um resistor pull-up integrado.

DS18B20 Parasita vs Modo Normal

O sensor DS18B20 pode ser alimentado em dois modos diferentes.

Modo Normal: O sensor é alimentado por uma fonte externa através do pino VDD e resistor pull-up de 4,7K ohm.

Modo Parasita: O sensor obtém energia de sua própria linha de dados. Portanto, nenhuma fonte de alimentação externa é necessária.

Hardware necessário

Agora vamos aprender como conectar o sensor de temperatura com o Raspberry Pi Pico. Vamos precisar dos seguintes componentes.

Componentes necessários:

  • Raspberry PI Pico
  • Sensor DS18B20
  • resistor de 4,7k ohms
  • Protoboard
  • Fios de conexão

Raspberry Pi Pico com diagrama esquemático DS18B20

Como você pode ver no diagrama esquemático abaixo, usamos o DS10B20 no modo normal e alimentamos o sensor com seu pino VCC do pino 3,3V da placa Raspberry Pi Pico.

Conecte o Raspberry Pi Pico com o DS18B20 conforme mostrado no diagrama esquemático abaixo:

Como você pode ver acima, alimentamos o sensor usando o modo normal. O sensor DS18B20 possui três terminais que vimos acima na pinagem. O primeiro terminal é aterrado com a placa Raspberry Pi Pico. A linha de dados do sensor, que é o terminal do meio, é conectada através do GP2 através de um resistor pull-up de 4,7k-ohm. Também podemos escolher qualquer outro pino GPIO. O terceiro terminal é alimentado por 3,3V do Raspberry Pi Pico.

Você pode usar qualquer outro pino GPIO do Raspberry Pi Pico para se conectar ao pino de dados também. Você pode consultar este post para saber mais sobre os pinos Raspberry Pi Pico GPIO:

Instalando Bibliotecas DS18B20

Para este projeto, precisaremos de duas bibliotecas: ds18x20.py e onewire.py. Copie essas duas bibliotecas e salve-as em seu Raspberry Pi Pico com os respectivos nomes de arquivo. Abra um novo arquivo no Thonny. Copie as bibliotecas fornecidas abaixo. Salve-os no Raspberry Pi Pico com os nomes ds18x20.py e onewire.py na pasta lib.

ds18x20.py

# DS18x20 temperature sensor driver for MicroPython.
# MIT license; Copyright (c) 2016 Damien P. George

from micropython import const

_CONVERT = const(0x44)
_RD_SCRATCH = const(0xBE)
_WR_SCRATCH = const(0x4E)


class DS18X20:
    def __init__(self, onewire):
        self.ow = onewire
        self.buf = bytearray(9)

    def scan(self):
        return [rom for rom in self.ow.scan() if rom[0] in (0x10, 0x22, 0x28)]

    def convert_temp(self):
        self.ow.reset(True)
        self.ow.writebyte(self.ow.SKIP_ROM)
        self.ow.writebyte(_CONVERT)

    def read_scratch(self, rom):
        self.ow.reset(True)
        self.ow.select_rom(rom)
        self.ow.writebyte(_RD_SCRATCH)
        self.ow.readinto(self.buf)
        if self.ow.crc8(self.buf):
            raise Exception("CRC error")
        return self.buf

    def write_scratch(self, rom, buf):
        self.ow.reset(True)
        self.ow.select_rom(rom)
        self.ow.writebyte(_WR_SCRATCH)
        self.ow.write(buf)

    def read_temp(self, rom):
        buf = self.read_scratch(rom)
        if rom[0] == 0x10:
            if buf[1]:
                t = buf[0] >> 1 | 0x80
                t = -((~t + 1) & 0xFF)
            else:
                t = buf[0] >> 1
            return t - 0.25 + (buf[7] - buf[6]) / buf[7]
        else:
            t = buf[1] << 8 | buf[0]
            if t & 0x8000:  # sign bit set
                t = -((t ^ 0xFFFF) + 1)
            return t / 16

onewire.py

# 1-Wire driver for MicroPython
# MIT license; Copyright (c) 2016 Damien P. George

import _onewire as _ow


class OneWireError(Exception):
    pass


class OneWire:
    SEARCH_ROM = 0xF0
    MATCH_ROM = 0x55
    SKIP_ROM = 0xCC

    def __init__(self, pin):
        self.pin = pin
        self.pin.init(pin.OPEN_DRAIN, pin.PULL_UP)

    def reset(self, required=False):
        reset = _ow.reset(self.pin)
        if required and not reset:
            raise OneWireError
        return reset

    def readbit(self):
        return _ow.readbit(self.pin)

    def readbyte(self):
        return _ow.readbyte(self.pin)

    def readinto(self, buf):
        for i in range(len(buf)):
            buf[i] = _ow.readbyte(self.pin)

    def writebit(self, value):
        return _ow.writebit(self.pin, value)

    def writebyte(self, value):
        return _ow.writebyte(self.pin, value)

    def write(self, buf):
        for b in buf:
            _ow.writebyte(self.pin, b)

    def select_rom(self, rom):
        self.reset()
        self.writebyte(self.MATCH_ROM)
        self.write(rom)

    def scan(self):
        devices = []
        diff = 65
        rom = False
        for i in range(0xFF):
            rom, diff = self._search_rom(rom, diff)
            if rom:
                devices += [rom]
            if diff == 0:
                break
        return devices

    def _search_rom(self, l_rom, diff):
        if not self.reset():
            return None, 0
        self.writebyte(self.SEARCH_ROM)
        if not l_rom:
            l_rom = bytearray(8)
        rom = bytearray(8)
        next_diff = 0
        i = 64
        for byte in range(8):
            r_b = 0
            for bit in range(8):
                b = self.readbit()
                if self.readbit():
                    if b:  # there are no devices or there is an error on the bus
                        return None, 0
                else:
                    if not b:  # collision, two devices with different bit meaning
                        if diff > i or ((l_rom[byte] & (1 << bit)) and diff != i):
                            b = 1
                            next_diff = i
                self.writebit(b)
                if b:
                    r_b |= 1 << bit
                i -= 1
            rom[byte] = r_b
        return rom, next_diff

    def crc8(self, data):
        return _ow.crc8(data)

 

MicroPython Raspberry Pi Pico DS18B20: Obtendo valores de temperatura

Depois de fazer o upload das duas bibliotecas mencionadas acima para o nosso Raspberry Pi Pico, vamos programar nossa placa com o sensor ds18b20.

Vejamos agora um exemplo para mostrar o funcionamento do sensor. Vamos conectar nosso sensor ds18b20 com o Raspberry Pi Pico conforme mostrado acima no diagrama de conexão. Veremos um código de script MicroPython e depois de carregá-lo em nossa placa, veremos as leituras atuais de temperatura impressas no terminal shell MicroPython.

Código MicroPython DS18B20

Agora vamos ver o script MicroPython para DS18b20 para obter as leituras do sensor. Copie o código a seguir para o arquivo main.py e carregue o arquivo main.py para o Raspberry Pi Pico.

Este script do MicroPython lê os valores de temperatura do DS18B20 e os imprime no console do shell do MicroPython.

import machine, onewire, ds18x20
from time import sleep
 
ds_pin = machine.Pin(2)
 
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))
 
roms = ds_sensor.scan()
 
print('Found DS devices')
print('Temperature (°C)')
 
while True:
 
  ds_sensor.convert_temp()
 
  sleep(1)
 
  for rom in roms:
 
    print(ds_sensor.read_temp(rom))
 
  sleep(3)

 

Como o Código Funciona?

Importando Bibliotecas
Primeiramente, estaremos importando o módulo da máquina. Também importamos o módulo de sono para que possamos adicionar um atraso entre nossas leituras. Além disso, importe uma biblioteca wire e ds18x20 que acabamos de enviar para nossa placa.

import machine, onewire, ds18x20
from time import sleep

Em seguida, criaremos uma instância da classe Pin com um nome de objeto ds_pin e definiremos GP2 como o pino da linha de dados DS18B20. O método DS18X20()

ds_pin = machine.Pin(2)
 
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))

O método scan() varre todos os sensores DS18B20 conectados ao pino ds_sensor e salva o endereço de 64 bits de cada sensor em uma variável de lista que é “roms”. Mais tarde, usaremos esses endereços para ler a temperatura do sensor um por um.

roms = ds_sensor.scan()
 
print('Found DS devices')

Depois disso, chame o objeto no método convert_temp() antes de ler a temperatura do sensor usando seu endereço exclusivo.

Para ler a temperatura, use o procedimento read_temp() no objeto ds_sensor e passe um endereço que está armazenado na lista de roms. O sensor de temperatura DS18B20 fornece saída de dados no tipo de dados float. As leituras de temperatura atuais serão impressas no terminal shell a cada 3 segundos.

while True:
 
  ds_sensor.convert_temp()
 
  sleep(1)
 
  for rom in roms:
 
    print(ds_sensor.read_temp(rom))
 
  sleep(3)

 

Demonstração

Para testar o script MicroPython para DS18B20 com Raspberry Pi Pico, carregue o arquivo main.py em sua placa.

Você verá os valores de temperatura no console do shell atualizando constantemente para novos valores a cada 3 segundos.

 

Valores do sensor Raspberry Pi Pico Display DS18B20 no display OLED

Nesta seção, veremos como exibir os valores de temperatura DS18B20 em um display OLED SSD1306 0,96 usando MicroPython e Raspberry Pico.

Você também pode gostar de ler:

Biblioteca MicroPython de exibição OLED SSD1306

Já carregamos a biblioteca BME280 MicroPython para o Raspberry Pi Pico. Para um display OLED, também precisaremos carregar uma biblioteca para o Raspberry Pi Pico.

  • Para fazer isso com sucesso, abra seu Thonny IDE com seu Raspberry Pi Pico conectado ao seu sistema. Vá para  Tools > Manage Packages. Isso abrirá o Thonny Package Manager.

  • Pesquise “ssd1306” na barra de pesquisa digitando seu nome e clicando no botão “Pesquisar no PyPI”.

  • A partir dos seguintes resultados de pesquisa, clique no destacado abaixo: micropython-ssd1306

Instale esta biblioteca.

Após alguns momentos, esta biblioteca será instalada com sucesso. Agora estamos prontos para programar nosso Raspberry Pi Pico com display OLED.

Conectando a tela OLED SSD1306 com Raspberry Pi Pico e DS18B20

Precisaremos dos seguintes componentes para conectar nosso Raspberry Pi Pico ao display OLED e DS18B20.

  • Raspberry Pi Pico
  • Sensor DS18B20
  • Tela OLED SSD1306
  • Fios de conexão

O display OLED possui 4 terminais que iremos conectar com o Raspberry Pi Pico. Como o display OLED requer uma tensão de operação na faixa de 3,3-5V, conectaremos o terminal VCC com 3,3V que será comum com a placa e o sensor. O SCL do display será conectado com o pino SCL do módulo e o SDA do display será conectado com o SDA do módulo. O aterramento de todos os três dispositivos será mantido em comum.

Pinos I2C Raspberry Pi Pico

Raspberry Pi Pico tem dois controladores I2C. Ambos os controladores I2C são acessíveis através dos pinos GPIO do Raspberry Pi Pico. A tabela a seguir mostra a conexão dos pinos GPIO com os dois controladores I2C. Cada conexão do controlador pode ser configurada através de vários pinos GPIO conforme mostrado na figura. Mas antes de usar um controlador I2C, você deve configurar no software quais pinos GPIO você deseja usar com um controlador I2C específico.

Controlador I2CPinos GPIO
I2C0 – SDAGP0/GP4/GP8/GP12/GP16/GP20
I2C0 – SCLGP1/GP5/GP9/GP13/GP17/GP21
I2C1 – SDAGP2/GP6/GP10/GP14/GP18/GP26
I2C1 – SCLGP3/GP7/GP11/GP15/GP19/GP27

As conexões entre os três dispositivos que estamos usando podem ser vistas abaixo.

Usamos as mesmas conexões especificadas na tabela acima. No entanto, você também pode usar outras combinações de pinos SDA/SCL

SSD1306 OLED DisplayRaspberry Pi Pico
VCC3.3V
SDAGP0 (I2C0 SDA)
SCLGP1 (I2C0 SCL)
GNDGND
DS18B20Raspberry Pi Pico
VCC3.3V
DataGP2
GNDGND

 

Esquemático Raspberry Pi Pico com OLED e DS18B20

Siga o diagrama esquemático abaixo e conecte-os de acordo.

Raspberry Pi Pico com diagrama de conexão ds18b20 e OLED
Raspberry Pi Pico com diagrama de conexão ds18b20 e OLED

Código MicroPython: Exibindo leituras DS18B20 no display OLED

import machine, onewire, ds18x20
from machine import Pin, I2C
from time import sleep
from ssd1306 import SSD1306_I2C

i2c=I2C(0,sda=Pin(0), scl=Pin(1), freq=400000)
oled = SSD1306_I2C(128, 64, i2c)

ds_pin = machine.Pin(2)
 
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))
 
roms = ds_sensor.scan()
 
print('Found DS devices')
print('Temperature (°C)')
 
while True:
 
  ds_sensor.convert_temp()
 
  sleep(1)
 
  for rom in roms:
 
    print(ds_sensor.read_temp(rom))
    oled.fill(0)
    oled.text("Temperature (C)", 0, 16)
    oled.text(str(ds_sensor.read_temp(rom)), 0, 35)
    oled.show()
 
  sleep(3)

Como funciona o código?

Na seção, explicaremos o código MicroPython que é usado para exibir os valores do sensor no OLED.

Biblioteca de importação

Importaremos o ssd1306, que é a biblioteca de exibição OLED que instalamos anteriormente. Isso nos ajudará a acessar todas as funções definidas dentro dele.

from ssd1306 import SSD1306_I2C

Inicializar OLED

Os dados dos pinos SCL e SDA são salvos no objeto ‘i2c’ que irá se conectar ao barramento I2C e auxiliar na comunicação entre os dois dispositivos

Agora, vamos criar um objeto ‘oled’ de SSD1306_I2C que usa a largura, altura e o objeto i2c como parâmetros.

oled = SSD1306_I2C(128, 64, i2c)

Limpa o display OLED com a rotina led.fill().

oled.fill(0)

Pegue amostras de temperatura do sensor DS18B20 e imprima-as no terminal shell.

ds_sensor.convert_temp()
 
  sleep(1)
 
  for rom in roms:
 
    print(ds_sensor.read_temp(rom))

Por fim, exiba o texto junto com a leitura do sensor no OLED.

oled.text("Temperature (C)", 0, 16)
oled.text(str(ds_sensor.read_temp(rom)), 0, 35)

No final, chame o método show() no método oled para que as alterações sejam exibidas no OLED. Adicione um atraso de 3 segundos entre cada leitura.

oled.show()
 
  sleep(3)

 

Demonstração

Carregue o código acima como um arquivo .py para Raspberry Pi Pico. Pressione o botão de execução para fazer upload do código para o módulo Raspberry Pi Pico. Você verá os valores de temperatura do DS18B20 no display OLED da seguinte forma: