Uma parte do curso “Programação de microcontroladores ARM Cortex M0+ com RP2040” do Embarcados é o projeto final, onde se sugere fazer uso dos principais recursos do RP2040. Estou participando da primeira turma e sou autor do livro texto “Knowing the RP2040”.
O meu projeto, que descrevo aqui, implementa um termostato simples que utiliza um sensor de temperatura DS18B20 para controlar o acionamento de um relé. Uma interface simples com o operador, baseada em um display alfanumérico e um rotary switch (com botão) permite verificar a temperatura atual e configurar as temperaturas de acionamento e desacionamento do relé. Uma EEPROM 24C32 é utilizada para armazenar as temperaturas configuradas.
Destacando, o objetivo do projeto é mostrar os recursos do RP2040. O termostato em si é bastante simplório e o código não inclui as proteções que seriam necessárias para um produto real.
O software foi escrito em C++, basicamente para aproveitar uma biblioteca já existente para o DS18B20. A interação com o hardware é feita usando as funções do SDK oficial.
O código e a documentação podem ser vistos em https://github.com/dquadros/picotermostato
Fazendo coisas ao mesmo tempo
Quem já programou microcontroladores em “bare-metal” conhece a sensação de malabarista: a necessidade de dividir a atenção (o processamento) entre várias tarefas. Em microcontroladores mais simples, sem usar um sistema operacional de tempo real, só temos dois lugares para executar funções, no loop principal e nas interrupções, e apenas uma é executada de cada vez. Os periféricos (UART, SPI, I2C) muitas vezes tratam apenas das tarefas ao nível de bit (são shift-registers especializados) e exigem atenção frequente do processador.
Os arquitetos do RP2040 parecem ter se preocupado bastante com isso. Entre outras coisas, o RP2040 dispõe de:
- Dois processadores (ARM M0+);
- DMA;
- Periféricos com filas (FIFOs) de entrada e saída;
- O recurso de E/S programável (PIO) com oito máquinas de estado que rodam simultaneamente aos processadores;
- Barramentos e memória projetados para reduzir a concorrência por recursos e permitir operações simultâneas.
Funcionamento do termostato
Na iniciação são procurados sensores DS18B20 na rede Onewire, a temperatura utilizada será a média dos até três primeiros sensores encontrados.
O relê é acionado quando a temperatura está menor que a temperatura “Liga” e desligado quando a temperatura é maior que a temperatura “Desliga”.
Por simplificação as temperaturas são apresentadas sem parte decimal.
Apertando o botão do encoder, é ativado o modo de configuração e selecionada a temperatura “Liga”. O eixo do encoder permite incrementar e decrementar a temperatura selecionada. Pressionando o botão do encoder com “Liga” selecionada, a seleção passa para “Desliga”. Pressionando o botão do encoder com “Desliga” selecionada, sai do modo configuração. A temperatura “Liga” tem que ser menor que a “Desliga”. A seleção da temperatura é indicada colocando a legenda em maiúscula.
Lendo a temperatura e usando os dois cores
O sensor DS18B20 utiliza um protocolo chamado OneWire. Cada sensor possui um endereço único, que pode ser determinado por um processo de varredura binária. O envio e recebimento de bits envolve algumas temporizações precisas da ordem de microsegundos.
Ler continuamente os sensores sem interferir em outros processos da aplicação é obtido rodando a leitura e a lógica do termostato em um core e a interface com o operador no outro. Uma critical section controla o acesso às poucas variáveis compartilhadas.
Embora o RP2040 seja um lançamento recente, já existe uma quantidade razoável de código e documentação disponíveis na internet. Para implementar o protocolo OneWire eu utilizei uma biblioteca open source (ver referências).
Ao estudar a biblioteca, reparei que a busca de dispositivos poderia ser otimizada seguindo mais precisamente o algoritmo descrito na documentação oficial. Implementei o acerto e enviei para o responsável, que o incluiu no código. Isso ilustra dois pontos importantes no uso de código open source: revise o código antes de usá-lo e contribua de volta com aperfeiçoamentos.
Otimizando a atualização do display gráfico do termostato
Displays gráficos facilitam a apresentação de informações, mas podem exigir o envio de uma quantidade grande de dados ao display. No projeto foi usado um display monocromático Nokia 5110, com interface SPI. Embora a aplicação não requeira tempos baixos de atualização do display, aproveitei para ilustrar uma técnica de otimização.
Para um melhor desempenho são usados dois buffers de tela e DMA. Desta forma, enquanto uma nova tela é montada em um dos buffers, o display é atualizado pelo DMA com o conteúdo do outro buffer.
Usando um rotary encoder
Um “rotary encoder” tem por objetivo indicar a velocidade e a direção da movimentação do eixo, sem se preocupar com a posição. A forma como ele faz isso é bem engenhosa. Mecanicamente temos dois contatos (A e B) que, com o movimento, serão ligados ou desligados a um terminal comum (normalmente ligado a terra):

Novamente é algo complicado de monitorar continuamente com o processador: as mudanças podem ser rápidas e pode ser necessário um mecanismo de debounce para descartar mudanças geradas por falha nos contatos.
Aqui eu usei o recurso da PIO. Um programa executando em uma máquina de estado monitora continuamente os dois sinais e notifica o processador das mudanças.
Novamente aproveitei código já disponível na internet, neste caso um driver criado pela Pimori (ver referências). O código original é bastante genérico, para este projeto eu usei o código da PIO mas refiz o código que roda no ARM para o meu caso específico.
Usando uma EEPROM
Para o software utilizar ao ligar as últimas temperaturas configuradas é necessário que elas sejam salvas em memória não volátil. Um recurso não disponível no RP2040 é memória EEPROM. É possível salvar dados na memória Flash usada para programas, mas (a) não me sinto confortável com a memória de programa ser alterada durante a execução e (b) aqui está a oportunidade de usar mais um periférico do RP2040 (o I2C).
A interface do RP2040 com uma memória 24C32 não apresenta grandes dificuldades sendo implementada de forma simples (exceto pelo uso do “page mode” na escrita). No page mode é enviado um endereço inicial e múltiplos bytes a serem escritos a partir deste endereço. A complicação é que o incremento do endereço opera somente em uma página (no caso de 32 bytes). Uma escrita que envolva mais de uma página precisa ser quebrada em várias operações (uma por página), aguardando o fim da escrita entre elas.
No lado da aplicação ilustrei como solucionar um problema comum no uso de EEPROM: a corrupção dos dados provocada pela falta de alimentação durante a escrita. São gravadas duas cópias da configuração, com um checksum. Ao detectar inconsistência em uma cópia a outra é usada.
Conclusão
Este projeto do termostato é bastante simplista na implementação, mas demonstra:
- O uso de entradas e saídas digitais
- O uso de SPI com DMA e interrupção (display)
- O uso dos dois cores ARM do RP2040
- O uso da PIO para monitorar entradas digitais (rotary encoder)
- O uso de I2C (na comunicação com a EEPROM)
Quem quiser montar e brincar com o software, os componentes são facilmente achados (e não são caros) e as ferramentas podem ser baixadas gratuitamente.
Brinde
As primeiras 10 pessoas que adquirirem o livro “Knowing the RP2040” até o final de abril 2023 e pelo link abaixo terão um desconto especial: https://leanpub.com/rp2040/c/Embarcados_42
Referências
- Curso: Programação de microcontroladores ARM Cortex M0+ com RP2040 https://embarcados.com.br/treinamento-online-programacao-de-microcontroladores-arm-cortex-m0/
- Livro Knowing the RP2040 (disponível apenas em inglês): https://leanpub.com/rp2040
- Datasheet sensor DS18B20 https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf
- Biblioteca para o DS18B20: https://github.com/adamboardman/pico-onewire
- Descrição sucinta do rotary encoder: http://dqsoft.blogspot.com/2020/07/usando-um-rotary-encoder.html
- Driver para rotary encoder: https://github.com/pimoroni/pimoroni-pico/tree/main/drivers/encoder
- Documentação oficial do RP2040 (inclui links e instruções para instalação das ferramentas de desenvolvimento): https://www.raspberrypi.com/documentation/microcontrollers/






Gostei muito do post! Há muita informação, principalmente nos links de referências. O seu Github está bastante informativo também e bem completo. Parabéns e obrigado pelas informações compartilhadas.
O que não encontrei, foi o curso de programação informado no primeiro link de referência. Esse curso ainda está disponível?
Quanto ao livro, gostei bastante do conteúdo e pretendo adquiri-lo o mais breve possível, ainda com o desconto. Parabéns pela publicação!
Grande abraço.
A primeira turma deste curso encerrou no início do ano, não estou a par de quando será a próxima edição. Obrigado pelos elogios!