UART-RPI é um projeto de comunicação serial utilizando a Raspberry Pi e o NodeMCU através da UART. Apesar de ser uma comunicação de curto alcance e em geral lenta, ecom esta integração, é possível recuperar informações de sensores instalados no NodeMCU e transmiti-los para a raspberry. É importante por alguns motivos, entre eles, a aquisição de dados dos sensores é mais simples ser realizada na NodeMCU e também, na disponibilidade de outro sistema de aquisição, neste caso, mais barato, conseguimos economizar GPIOs do nosso sistema central.
Segue abaixo a estrutura de diretórios do projeto
├── nodemcu
│ └── uart.ino
├── README.md
└── rpi
├── display.s
├── examples
│ └── countdown.c
├── lib
│ ├── fileio.s
│ ├── gpio.s
│ ├── lcd.s
│ └── utils.s
├── LICENSE
├── makefile
└── uart
└── uart.c
- Raspberry Pi 0
- NodeMCU ESP8266
- Windows 10
- Ubuntu
- Raspbian
- Arduino IDE
- GCC Compiler
- VSCode
- Assembly
- C
Possui a macro open_file para abertura de arquivos. Recebe no R0, o descritor do arquivo aberto, no R1, o modo de abertura do arquivo.
Possui a macro nanosleep para fazer o programa parar durante o tempo específicado. R0 é um ponteiro para quantidade de segundos e R1 é um ponteiro para quantidade de nanossegundos.
Possui macros para configurar pinos como entrada e saída, alterar o nível lógico no modo de saída e ler o nível lógico em determinado pino. A sessão de pinos tem seu array configurado da seguinte maneira:
Biblioteca principal para o controle do LCD
Programa principal para execução do contador. O valor do contador fica registrado em R1, e as flags para pausar/continuar e reiniciar contagem, estão nos registradores R6 e R5, respectivamente
Para facilitar a construção do programa, existe um makefile dentro da pasta rpi, onde é possível executar:
$ make uart
Para construção do executável. Logo em seguida basta utilizar:
$ sudo ./uartx
para executar o programa
uart: cuart
cuart: uart/uart.c lib/lcd.s
gcc -o uartx uart/uart.c lib/lcd.s -lwiringPi
Abaixo está presente os dispositivos utilizados, suas características e documentação utilizada para desenvolvimento do projeto
A plataforma NodeMCU é uma placa de desenvolvimento que combina o chip ESP8266, uma interface usb-serial e um regulador de tensão 3.3V. Mais dados sobre sua documentação podem ser encontrados aqui.
Alguns pinos utilizados na NodeMCU estão listados na tabela abaixo:
| Pino | Descrição |
|---|---|
| D0 | Sensor Digital 1 |
| D1 | Sensor Digital 2 |
| A0 | Sensor Analógico 1 |
| TX | Envio comunicação serial |
| RX | Recebimento comunicação serial |
Baseada no processador BCM 2385, possui 54 I/O de propósito geral (GPIO), além daqueles utilizados para comunicação com o display, estão sendo utilizados mais dois para comunicação serial: TX/RX. É importante notar que, o GPIO 1 não está posicionado no PINO 1. As informações da placa são mostradas na tabela abaixo, junto da descrição sobre o uso de cada GPIO.
| Pino | GPIO | Descrição |
|---|---|---|
| 8 | 14 | TX |
| 10 | 15 | RX |
Devido a alguns lixos gerados na saída serial da NodeMCU foi realizado um processo de inicialização. Quando a raspberry pi inicia, fica aguardando o envio de um conjunto de palavras em sequência específica para identificar que a inicialização foi feita com sucesso.
Para troca de informações entre os dispositivos, foram definidos comandos. Cada informação é enviada com 1 byte, onde os três bits mais significativos indicam um comando:
| B2 | B1 | B0 | Descrição |
|---|---|---|---|
| 0 | 0 | 1 | Solicita status da NodeMCU |
| 0 | 1 | 0 | Solicita status do sensor |
| 0 | 1 | 1 | Solicita valor do sensor |
Os bits mais significativos B7-B3, indicam qual sensor vai ser executado o comando: 0 - 31 (32 sensores).
Como mostrado na figura, temos a SBC controlando a exibição de informações no display, enquanto se comunica através da UART com a NodeMCU que possui e faz a aquisição dos dados dos sensores.
Os valores dos sensores e seus status foram armazenados em dois vetores de 32 posições. Uma vez que a informação está presente, é recuperada de maneira genérica pela estrutura da informação, onde é separado informação e sensor associado. Desta forma, caso se queira adicionar um novo sensor, basta garantir que a informação vai estar presente na posição escolhida para o mesmo.
A NodeMCU fica constantemente ouvindo o seu canal RX, e toda vez que recebe um pedido, efetua os procedimentos anteriores para retornar a resposta.
Pode-se emitir os comandos através do terminal, onde são enviados e processados pela NodeMCU através de comunicação serial utilizando o protocolo UART. Como o processo é assíncrono, é realizada uma espera ocupada de até 1 segundo (aproximadamente), de forma que se não houver nenhum tipo de resposta, é dado como um erro de tempo excedido (timeout). vez que a informação retorne, ela é exibida no terminal e no display de LCD caso esteja conectado. Devido a presença de sistema operacional na Raspberry Pi Zero, para realizar um acesso aos dispositivos presentes na placa, é necessário realizar o mapeamento de memória, onde é exigido a chamada de algumas system calls para realizar esse acesso. Para outros dispositivos, como o acionamento do relógio interno, o sistema operacional oferece uma interface amigável.
Para estabelecer a comunicação UART, utilizam-se as bibliotecas wiringPi e wiringSerial dedicadas a mapeamento de GPIOs em hardwares Raspberry. A taxa de transmissão é definida como 9600. A imagem abaixo ilustra a função responsável por mapear e retornar o valor da porta serial que representa a mini UART.
A partir da instrução serialOpen é possível obter o endereço através da porta ttyS0 a qual a UART está atribuída, este, é salvo na variável inteira serial_port. Caso o valor obtido seja negativo, isso significa que não foi possível abrir o dispositivo conectado, uma mensagem de enviada ao usuário e a função é encerrada. Outro possível erro é falhar em abrir a biblioteca wiringPI, o qual pode ser detectado através do valor '-1' ao chamar a instrução wiringPiSetup. Uma vez que se obtém a porta com sucesso, isto é, sem falhas associadas a comunicação ou a biblioteca em si, o valor é retornado.
Após o mapeamento feito anteriormente, já é possível realizar a comunicação serial. Porém, antes de tudo, é necessário realizar um tratamento de dados indesejáveis que são lançados aleatoriamente durante a execução da NodeMCU.
Para ignorar os caracteres aleatórios, é enviado uma palavra-chave 'UNLOCK'. A ideia desta palavra-chave é que, após ser lida completamente, a comunicação está limpa e pode-se requisitar dados da NodeMCU sem risco de receber informações errôneas. O algoritmo de verificação é consideravelmente simples. O objetivo é permanecer em looping enquanto a chave não for enviada. Para isso, requisita-se um caractere do NodeMCU com a instrução serialGetchar e este é comparado com o atual caractere da palavra 'unlock'. Se houver igualdade, o contador é iterado e avança para a próxima comparação, caso contrário, o contador é zerado e a comparação volta para o primeiro passo. O motivo disso é óbvio: Querendo ou não, a palavra-chave é uma maneira arriscada de resolver o problema em questão, pois há uma pequena, mas real, probabilidade do lixo enviado a UART coincidir com os caracteres estabelecidos em 'unlock'. Uma vez que a comunicação está livre de dados aleatórios, pode-se requisitar as informações do NodeMCU.
Os dados são requisitados através da interação com o usuário. Há 3 opções possíveis: '1' para solicitar o estado atual da NodeMCU, '2' para obter o estado atual do sensor digital e '3' para obter o valor registrado pelo sensor, cada opção escolhida é enviada para o NodeMCU através da instrução serialPutchar. O próximo passo é captar a informação devolvida ao UART, porém, é necessário um pequeno sleeping durante a execução devido a rapidez da comunicação. Esta função de sleeping é feita manualmente através de um contador de 0 a 1 bilhão.
Por fim, requisita-se os dados devolvidos pela NodeMCU e printa-se na tela do visor LCD utilizando os recursos em Assembly integrados ao código em C.
- Na pasta rpi/ execute:
$ make uart
- Em seguida execute o programa
$ sudo ./uartx
- Na pasta nodemcu/ abra o arquivo uart.ino na Arduino IDE:
- Configure as bibliotecas do NodeMCU
- Descarregue o código na pltaforma
O protótipo construído é um sistema digital utilizando plataformas de desenvolvimento IoT, em que se pode adicionar até 32 sensores analógicos e/ou digitais e exibir as respectivas informações em um display de LCD.
A comunicação serial, apesar de simples, mas só permite a comunicação entre dois dispositivos. Caso seja necessário enviar ou receber informações de mais dispositivo se torna inviável, necessitando do uso de outros protocolos, como o caso do i2c;
Comparado a protocolos como i2c e SPI, pode haver uma diferença de velocidade de até 10 vezes, fazendo o protocolo UART ser mais lento e algumas vezes inviável dependendo da aplicação.







