Site menu IoT: controle remoto de 433MHz (parte 2)

IoT: controle remoto de 433MHz (parte 2)

(Este texto é uma continuação da parte 1.)

Transmissão

O objetivo final é recepção de um keyfob para fins de automação residencial, mas já que veio um modulozinho de TX junto com o de RX, a nobreza obriga a testá-lo. Transmitir é, no geral, muito mais fácil que receber, porque você sabe exatamente o que está enviando.

Codificação

Para começar, desenvolvemos um script de TX de alto nível. Por "alto nível" entenda a conversão do código para uma lista de transições de sinal, sem realmente lidar com hardware. A ideia era gerar uma "transmissão" que pudesse ser decodificada pelos scripts de teste citados no capítulo anterior desta série, para ter uma certeza razoável que estamos no caminho certo.

A propósito, este é o script RX, levemente modificado em relação aos do capítulo anterior e.g. ele lê dados via stdin, não de arquivo.

Hardware

O módulo de rádio TX que veio no kit é baseado no chip SYN115, o mais comum que há. Este só funciona em 3.3V, ou seja, não precisamos de conversor de nível para ligar num ESP32 ou RP2040, mas a potência também é limitada (10mW ou 10dBm segundo o datasheet). A conexão é tão simples quanto o módulo RX: positivo, negativo, pino de dados e antena. A saída 3.3V de um módulo ESP32 típico pode ser usada para alimentar o rádio, acho que não é necessário uma fonte externa.

No ESP32, poderíamos fazer "bit banging", porém o microcontrolador possui um recurso denominado RMT, que gera formas de onda digitais com zero esforço de CPU e precisão de 12.5ns. Basta passar uma lista. Foi originalmente concebido para controles infravermelhos, mas serve para qualquer fim, até para piscar um LED.

Em C, o RMT pode ser usado inclusive para RX, obsoletando parcialmente o trabalho que fizemos no capítulo anterior usando interrupções. Infelizmente, o MicroPython suporta RMT apenas para escrita no momento, então a conversão do receptor para RMT ainda está no futuro.

Uma vez que não precisamos de interrupções, fiz uso do pino 2 do ESP32 que costuma estar ligado a um pequeno LED azul na plaquinha, assim posso ver quando (ou se) a transmissão está acontecendo.

Transmissão, para valer

E aqui está o script de TX completo.

Nos primeiros testes, o script "funcionou" porém o receptor só ouvia 10% das transmissões, se tanto. Depois de checar os suspeitos usuais (mau contato, tentar outro módulo, tentar outra antena), estava quase conformado que o módulo TX era simplesmente ruim.

Uma última tentativa deu muito certo: enviar o mesmo código 2 ou 3 vezes, assim como os keyfobs fazem. Deste jeito, o RX passou a decodificar com sucesso praticamente 100% das mensagens.

Segundo os datasheets dos keyfobs, o preâmbulo inicial é a seqüência "100000...00000", ou seja, um pulso de 300µs-500µs seguido por silêncio de uns 10ms. Meu script fazia o mesmo. Usando o analisador lógico, verifiquei que esse pulso inicial não era suficiente para calibrar o RX, que continuava aceitando ruído durante o período de silêncio. (Do jeito que nosso RX por software opera, ele espera por um longo silêncio como marcador de início de mensagem.)

A hipótese é que o RX só estava devidamente calibrado na recepção da segunda cópia do código, por isso a transmissão repetida funcionou tão bem. Para testar a hipótese, aumentei bastante a largura do pulso inicial e tornei a enviar apenas uma cópia, o que funcionou igualmente bem.

Voltando ao analisador lógico, constatei que o mesmo acontece com o keyfob: às vezes a primeira cópia do código tem um preâmbulo de ruído em vez de silêncio. Então, a transmissão repetida e/ou um preâmbulo mais longo são necessários. Talvez seja uma deficiência do meu módulo RX (SYN480R), quiçá outros funcionem melhor?

Testando nosso transmissor "pirata" com o portão da garagem, vi que também não funcionava 100% das vezes usando apenas um pulso longo no preâmbulo. Transmitir múltiplas vezes o mesmo código, tal qual o keyfob faz, é o que resolve. Seja porque o portão tem a mesma deficiência de RX, seja porque o controlador espera receber diversas vezes o mesmo código para ter certeza.

Uma vez que estamos usando RMT, temos razoável confiança que o "timing" dos pulsos transmitidos é preciso. Com base nisto, podemos diagnosticar a imprecisão introduzida pelo RX de software: +/-25µs. Para fazer melhor que isto, teríamos de usar C em vez de Python (ou esperar o RMT de leitura funcionar no Python).

Se estiver apreciando a história, siga para a parte 3.