Componentes · 16 min de leitura

Módulo RF 433 MHz com Arduino: transmissor, receptor e antena

Guia do módulo RF 433 MHz com Arduino: ligue o transmissor FS1000A e o receptor XY-MK-5V, coloque uma antena de 17,3 cm, envie mensagens com RadioHead e clone controles com RCSwitch.

Um módulo RF 433 MHz é o jeito mais barato de adicionar uma ligação sem fio a um projeto com Arduino: um conjunto formado por um transmissor (FS1000A) e um receptor (XY-MK-5V) custa muito pouco, se conecta com um único fio de dados e, com uma antena de fio de 17 cm, leva o sinal a dezenas de metros. Tomadas com controle remoto, campainhas sem fio, controles de portas de enrolar, sensores de porta e janela e os sensores externos de estações meteorológicas também usam, na maioria das vezes, a mesma frequência. Isso significa que, com esses módulos, você pode enviar dados entre dois Arduinos e também ler os códigos dos controles prontos da sua casa e enviá-los de novo a partir de um Arduino.

Neste guia você vai aprender como os módulos funcionam com modulação ASK (OOK), por que a antena deve ter 17,3 cm e como ligá-los a um Arduino Uno, a um ESP32 e a um Raspberry Pi Pico. Depois, vai enviar texto e dados de sensores entre dois Arduinos com a biblioteca RadioHead, ler e clonar o código do controle de uma tomada com a biblioteca RCSwitch, ver como aumentar o alcance e comparar o módulo com o nRF24L01.

O que é um módulo RF 433 MHz e como ele funciona?

O conjunto é formado por duas placas separadas. O pequeno transmissor quadrado FS1000A (também vendido como XY-FST) liga e desliga uma onda portadora de 433,92 MHz de acordo com o sinal no seu pino DATA. O receptor XY-MK-5V, mais comprido, capta esse sinal do ar e o entrega de novo como 0s e 1s no seu pino DATA. Ou seja, os módulos em si não têm protocolo, endereço nem verificação de erros; a única função deles é levar um sinal digital sem fio até o outro lado. Empacotar, verificar e decodificar os dados é trabalho da biblioteca no Arduino. A comunicação é unidirecional: o transmissor só envia, e o receptor só escuta.

CaracterísticaFS1000A (transmissor)XY-MK-5V (receptor)
Frequência433,92 MHz (também existe uma versão de 315 MHz)433,92 MHz
Tensão de alimentação3–12 V5 V
CorrenteCerca de 9–40 mA durante a transmissão (depende da tensão)Cerca de 4 mA
ModulaçãoASK / OOKASK / OOK, receptor super-regenerativo
Taxa de dadosAté ~10 kbps (1–4 kbps na prática)Mesmo limite do transmissor
Potência de saída / sensibilidadeCerca de 10 mW, aumenta com a tensãoCerca de −105 dBm
PinosDATA, VCC, GND + ilha de solda ANTVCC, DATA, DATA, GND + ilha de solda ANT
TamanhoCerca de 19 × 19 mmCerca de 30 × 14 mm

Os dois pinos DATA do receptor são ligados entre si na placa, então tanto faz qual deles você usa. O XY-MK-5V é um receptor super-regenerativo barato, mas pouco seletivo: a frequência dele é definida por uma bobina ajustável na placa, e ele é facilmente afetado por interferências próximas. Não gire o parafuso dessa bobina; se o ajuste de fábrica se perder, o receptor deixa de ouvir o transmissor. Para resultados mais estáveis, receptores super-heteródinos como o RXB6 são mais sensíveis e também funcionam com 3,3 V. O conjunto também é vendido na versão de 315 MHz; o transmissor e o receptor precisam estar na mesma frequência, e o ressonador metálico na placa do transmissor normalmente traz a frequência impressa.

Modulação ASK (OOK): por que você precisa de uma biblioteca?

No OOK (On-Off Keying), a forma mais simples de ASK (Amplitude Shift Keying), a portadora é ligada para um bit 1 e desligada para um bit 0. Parece fácil, mas o receptor tem uma peculiaridade: o controle automático de ganho (AGC) aumenta o ganho ao máximo quando não há sinal, confunde o ruído do ar com dados e solta pulsos aleatórios no pino DATA o tempo todo. Por isso, ligar o transmissor direto no pino TX do Arduino e o receptor no pino RX e tentar se comunicar com Serial.print normalmente termina em caracteres estranhos.

O driver RH_ASK da biblioteca RadioHead resolve esse problema assim: antes de cada pacote, ele envia um preâmbulo de 36 bits e um símbolo de início de 12 bits para que o ganho do receptor se estabilize. Depois, transforma cada byte em dois símbolos de 6 bits balanceados em DC (codificação 4 para 6) e acrescenta um CRC de 16 bits ao fim do pacote. O receptor descarta em silêncio os pacotes cujo CRC não confere, então só os dados íntegros passam. Já a RCSwitch decodifica a codificação por largura de pulso usada pelos chips de controle remoto: cada bit é representado por pulsos que ficam em HIGH e em LOW por tempos definidos.

Comprimento da antena de 433 MHz: por que 17,3 cm?

Os módulos não vêm com antena; há apenas uma ilha de solda marcada ANT. Sem antena, um conjunto só funciona a 1–3 metros. A antena simples mais eficiente é um fio reto com um quarto do comprimento de onda: λ = c / f = 300.000.000 / 433.920.000 ≈ 0,69 m, e um quarto disso dá cerca de 17,3 cm. Para módulos de 315 MHz, a mesma conta dá 23,8 cm. Solde uma ponta de um fio rígido (de um só condutor) na ilha ANT e mantenha o fio reto e na vertical; solde um fio do mesmo comprimento também no receptor e aponte as duas antenas na mesma direção.

AntenaComprimentoAlcance aproximado (ao ar livre)Observação
Sem antena—1–3 mSó para testes na bancada
Fio reto (λ/4), transmissor em 5 V17,3 cm20–50 mA opção mais fácil e eficiente
Fio reto (λ/4), transmissor em 9–12 V17,3 cm50–100 m ou maisLinha de visada e altura fazem muita diferença
Antena helicoidal (mola) pronta2–4 cm de comprimentoMenor do que com um fio retoCabe dentro de uma caixa

Ligação do módulo RF 433 MHz: Arduino Uno, ESP32 e Pico

Pino do móduloArduino Uno (RadioHead)Arduino Uno (RCSwitch)ESP32Raspberry Pi Pico
FS1000A VCC5V ou externa de 9–12 V5VVIN (5 V)VBUS (5 V)
FS1000A DATAD12D10GPIO 26GP15
FS1000A GNDGNDGNDGNDGND
XY-MK-5V VCC5V5VVIN (5 V)VBUS (5 V)
XY-MK-5V DATAD11D2 (pino de interrupção)GPIO 27 (por um divisor de tensão)GP14 (por um divisor de tensão)
XY-MK-5V GNDGNDGNDGNDGND
A saída DATA do receptor XY-MK-5V chega a 5 V. Os pinos do ESP32 e do Pico não toleram 5 V, então, ao ligar o receptor a essas placas, sempre coloque um divisor de tensão na linha DATA (por exemplo, 10 kΩ em cima e 20 kΩ embaixo, o que dá cerca de 3,3 V) ou use um receptor que funcione com 3,3 V. Se você alimentar o transmissor com 12 V, nunca deixe essa tensão encostar em um pino da placa e ligue todos os GNDs entre si.

O transmissor funciona bem com um sinal de 3,3 V no pino DATA, então, no ESP32 e no Pico, você pode alimentá-lo com 5 V e ligar o DATA direto em um GPIO. A tensão do transmissor é o que mais afeta o alcance: com 3,3 V o alcance cai bastante, enquanto com 9–12 V ele aumenta várias vezes. Colocar um capacitor cerâmico de 100 nF e um eletrolítico de 10 µF bem ao lado dos pinos VCC e GND do receptor reduz o ruído da alimentação e melhora visivelmente a recepção.

Enviando mensagens entre dois Arduinos com RadioHead

  1. Abra o Gerenciador de Bibliotecas na Arduino IDE, busque por RadioHead e instale a biblioteca de Mike McCauley. Para mais detalhes, veja Como instalar uma biblioteca no Arduino.
  2. Ligue o transmissor ao primeiro Arduino: DATA → D12, VCC → 5V, GND → GND.
  3. Ligue o receptor ao segundo Arduino: DATA → D11, VCC → 5V, GND → GND.
  4. Solde um fio de 17,3 cm na ilha ANT de cada módulo.
  5. Carregue o código do transmissor na primeira placa e o código do receptor na segunda; depois, abra o Monitor Serial do lado do receptor em 9600 baud.
C++ (Arduino IDE)
1#include <RH_ASK.h>
2#include <SPI.h>                  // RadioHead derlemesi için / needed for RadioHead to compile
3
4RH_ASK rf(2000, 11, 12);          // hız (bps), RX pini, TX pini / speed (bps), RX pin, TX pin
5unsigned int sayac = 0;
6
7void setup() {
8  Serial.begin(9600);
9  if (!rf.init()) Serial.println("RF init hatasi / failed");
10}
11
12void loop() {
13  char mesaj[24];
14  snprintf(mesaj, sizeof(mesaj), "Merhaba %u", sayac++);
15  rf.send((uint8_t *)mesaj, strlen(mesaj));
16  rf.waitPacketSent();            // paket bitene kadar bekle / wait until the packet is sent
17  Serial.print("Gonderildi / sent: ");
18  Serial.println(mesaj);
19  delay(1000);
20}
C++ (Arduino IDE)
1#include <RH_ASK.h>
2#include <SPI.h>                  // RadioHead derlemesi için / needed for RadioHead to compile
3
4RH_ASK rf(2000, 11, 12);          // vericiyle aynı hız / same speed as the transmitter
5
6void setup() {
7  Serial.begin(9600);
8  if (!rf.init()) Serial.println("RF init hatasi / failed");
9}
10
11void loop() {
12  uint8_t buf[RH_ASK_MAX_MESSAGE_LEN + 1];   // +1: metin sonu için / +1 for the string terminator
13  uint8_t len = RH_ASK_MAX_MESSAGE_LEN;      // her turda yeniden ayarla / reset on every pass
14  if (rf.recv(buf, &len)) {                  // yalnız CRC doğruysa true / true only if the CRC is valid
15    buf[len] = '\0';
16    Serial.print("Alindi / received: ");
17    Serial.println((char *)buf);
18  }
19}
ComandoO que faz
RH_ASK rf(2000, 11, 12)Velocidade de 2000 bps, receptor no D11, transmissor no D12; a velocidade tem que ser igual nos dois lados
rf.init()Configura o timer e os pinos; retorna false se algo estiver errado
rf.send(data, length) (envio)Começa a enviar um pacote de até 60 bytes
rf.waitPacketSent()Espera até que o pacote tenha sido transmitido por completo
rf.recv(buf, &len) (recepção)Se houver um pacote novo com CRC válido, copia o pacote para buf, atualiza len e retorna true
RH_ASK_MAX_MESSAGE_LENA maior quantidade de dados que um único pacote pode levar: 60 bytes

No código do receptor, é importante redefinir a variável len a cada repetição: recv() grava nela o tamanho do pacote recebido, e na chamada seguinte esse valor é tomado como o tamanho do buffer; se você não redefinir, as mensagens mais longas ficam cortadas. Se estiver tudo certo, você verá as linhas “Merhaba 0”, “Merhaba 1” uma vez por segundo no Monitor Serial. Se algum número for pulado, alguns pacotes se perderam no caminho; nesse caso, confira a antena e a alimentação.

No Arduino Uno, a RH_ASK usa o Timer1. Como a biblioteca Servo também precisa do Timer1, as duas não compilam no mesmo sketch e aparece o erro “multiple definition of `__vector_11'”; o PWM nos pinos D9 e D10 também para de funcionar. Por padrão, o driver também usa o D10 como pino de habilitação do transmissor (PTT). Se você precisar de um servo, descomente a linha RH_ASK_ARDUINO_USE_TIMER2 no início do RH_ASK.cpp (aí o tone() deixa de funcionar) ou use a biblioteca ServoTimer2.

Enviando dados de sensores: um pacote com struct

Em projetos reais, enviar números é mais eficiente do que enviar texto. Você pode reunir as leituras em uma struct e enviar os bytes dela do jeito que estão. O transmissor abaixo envia, cinco vezes por segundo, o valor de um LDR ou de um potenciômetro no A0 e o estado do botão no D2. O receptor acende o LED do D13 quando o botão remoto é pressionado e percebe os pacotes perdidos.

C++ (Arduino IDE)
1#include <RH_ASK.h>
2#include <SPI.h>
3
4struct __attribute__((packed)) Paket {   // iki tarafta birebir aynı olmalı / must be identical on both sides
5  uint16_t no;                           // paket numarası / packet number
6  int16_t deger;                         // analog değer / analog value
7  uint8_t buton;                         // 1 = basılı / 1 = pressed
8};
9
10RH_ASK rf;                               // varsayılan: 2000 bps, RX 11, TX 12 / defaults
11Paket p = {0, 0, 0};
12
13void setup() {
14  pinMode(2, INPUT_PULLUP);              // buton D2-GND / button D2-GND
15  rf.init();
16}
17
18void loop() {
19  p.no++;
20  p.deger = analogRead(A0);              // örneğin LDR ya da potansiyometre / e.g. LDR or potentiometer
21  p.buton = (digitalRead(2) == LOW);
22  rf.send((uint8_t *)&p, sizeof(p));
23  rf.waitPacketSent();
24  delay(200);
25}
C++ (Arduino IDE)
1#include <RH_ASK.h>
2#include <SPI.h>
3
4struct __attribute__((packed)) Paket {
5  uint16_t no;
6  int16_t deger;
7  uint8_t buton;
8};
9
10RH_ASK rf;
11const int LED = 13;
12uint16_t sonNo = 0;
13
14void setup() {
15  Serial.begin(9600);
16  pinMode(LED, OUTPUT);
17  rf.init();
18}
19
20void loop() {
21  Paket p;
22  uint8_t len = sizeof(p);
23  if (rf.recv((uint8_t *)&p, &len) && len == sizeof(p)) {
24    digitalWrite(LED, p.buton ? HIGH : LOW);   // uzaktaki buton LED'i yakar / remote button lights the LED
25    if (sonNo != 0 && p.no != (uint16_t)(sonNo + 1)) {
26      Serial.println("Paket kaybi / packet lost");
27    }
28    sonNo = p.no;
29    Serial.print(p.no);
30    Serial.print("  A0 = ");
31    Serial.println(p.deger);
32  }
33}

A palavra-chave __attribute__((packed)) impede que o compilador acrescente preenchimento (padding) entre os campos. Isso é importante: a mesma struct pode ocupar 5 bytes em um Arduino Uno e 6 bytes em um ESP32, e os dados ficam deslocados quando duas placas diferentes conversam entre si. Graças ao número do pacote, o receptor consegue contar os pacotes perdidos no meio do caminho. Como os módulos de 433 MHz não têm confirmação de recebimento, é um bom hábito repetir os comandos importantes algumas vezes. Se você colocar um transmissor e um receptor em cada lado, também pode montar uma comunicação com confirmação e novas tentativas usando a classe RHReliableDatagram da RadioHead.

Lendo os códigos de controles prontos com RCSwitch

Muitas tomadas com controle remoto, campainhas sem fio, controles de portas de enrolar e de portões, além de sensores de porta, janela e alarmes PIR, usam chips de código como o EV1527 ou o PT2262. Cada vez que um botão é pressionado, esses chips enviam o mesmo código de 12–24 bits várias vezes seguidas, com intervalos de sincronismo entre eles. A biblioteca RCSwitch (chamada rc-switch no Gerenciador de Bibliotecas) decodifica esses códigos. No Uno, ligue o pino DATA do receptor a um pino de interrupção, ou seja, o D2 ou o D3, e carregue o código abaixo:

C++ (Arduino IDE)
1#include <RCSwitch.h>
2
3RCSwitch rf = RCSwitch();
4
5void setup() {
6  Serial.begin(9600);
7  rf.enableReceive(digitalPinToInterrupt(2));   // alıcı DATA -> D2 (kesme pini) / receiver DATA -> D2 (interrupt pin)
8  Serial.println(F("Kumandanin tusuna bas / press a remote button"));
9}
10
11void loop() {
12  if (rf.available()) {
13    Serial.print(F("Kod / code: "));
14    Serial.print(rf.getReceivedValue());
15    Serial.print(F("  Bit: "));
16    Serial.print(rf.getReceivedBitlength());
17    Serial.print(F("  Protokol / protocol: "));
18    Serial.print(rf.getReceivedProtocol());
19    Serial.print(F("  Darbe / pulse: "));
20    Serial.print(rf.getReceivedDelay());
21    Serial.println(F(" us"));
22    rf.resetAvailable();                         // bir sonraki koda hazırlan / get ready for the next code
23  }
24}

Abra o Monitor Serial e aperte um botão do controle; você verá uma linha como “Kod / code: 5393 Bit: 24 Protokol / protocol: 1 Darbe / pulse: 350 us”. Anote o código, o número de bits, o protocolo e a largura de pulso de cada botão; você vai precisar dos quatro na hora de clonar. Nos controles com EV1527, os primeiros 20 dos 24 bits são o ID do controle e os últimos 4 indicam o botão pressionado, por isso os códigos dos botões de um mesmo controle são muito próximos entre si. No protocolo 1, uma unidade dura cerca de 350 µs: um bit 0 é 1 unidade em HIGH e 3 unidades em LOW, um bit 1 é 3 unidades em HIGH e 1 unidade em LOW, e o sincronismo é 1 unidade em HIGH e 31 unidades em LOW.

Chip do controleEstrutura do códigoA RCSwitch consegue clonar?
EV1527 (código de aprendizado)ID de 20 bits + botão de 4 bits, 24 bits no totalSim
PT2262 / SC226212 bits de três estados (0, 1, F); o endereço é definido com chaves DIPSim
HT6P20BCódigo fixo, protocolo 6 da RCSwitchSim
Chips de código rolante, como o HCS301 (KeeLoq)Código criptografado que muda a cada toqueNão
Chaves de carro, controles de alarme e controles de portão de garagem mais novos usam código rolante (rolling code): o código muda a cada toque, e um código gravado não é aceito uma segunda vez. Tentar clonar esses sistemas não funciona e, em aparelhos de outras pessoas, traz problemas legais. Use este método só nas suas próprias tomadas, campainhas e sensores.

Enviando o código do controle a partir de um Arduino

Para enviar o código que você leu, ligue o pino DATA do transmissor ao D10 e dois botões entre o D4 e o D5 e o GND. Cada vez que você aperta um botão, o Arduino repete o código 10 vezes, igualzinho ao controle; os botões de ligar e desligar da tomada agora ficam no seu Arduino:

C++ (Arduino IDE)
1#include <RCSwitch.h>
2
3RCSwitch rf = RCSwitch();
4const int BTN_AC = 4;            // "aç" butonu D4-GND / "on" button D4-GND
5const int BTN_KAPAT = 5;         // "kapat" butonu D5-GND / "off" button D5-GND
6
7void setup() {
8  pinMode(BTN_AC, INPUT_PULLUP);
9  pinMode(BTN_KAPAT, INPUT_PULLUP);
10  rf.enableTransmit(10);         // verici DATA -> D10 / transmitter DATA -> D10
11  rf.setProtocol(1);             // önce protokol... / protocol first...
12  rf.setPulseLength(350);        // ...sonra okuduğun darbe süresi / ...then the pulse length you read
13  rf.setRepeatTransmit(10);      // her gönderim 10 kez tekrarlanır / each send is repeated 10 times
14}
15
16void loop() {
17  if (digitalRead(BTN_AC) == LOW) {
18    rf.send(5393, 24);           // okuduğun "aç" kodu ve bit sayısı / the "on" code and bit length you read
19    delay(300);
20  }
21  if (digitalRead(BTN_KAPAT) == LOW) {
22    rf.send(5396, 24);           // okuduğun "kapat" kodu / the "off" code you read
23    delay(300);
24  }
25}

Como setProtocol() volta a largura de pulso para o padrão daquele protocolo, sempre chame setPulseLength() depois dele. Se a tomada não responder, primeiro coloque exatamente a largura de pulso que você leu (por exemplo, 320 ou 420 µs) e depois aumente o número de repetições para 15. As tomadas com código de aprendizado oferecem mais um atalho: se você colocar a tomada em modo de aprendizado e enviar qualquer código de 24 bits a partir do Arduino, a tomada guarda esse código na memória. Assim, você pode criar seus próprios códigos sem clonar controle nenhum.

Receptor de 433 MHz com ESP32: controlando um relé com um controle remoto

O ESP32 é uma ótima ponte para ligar controles de 433 MHz ao mundo do Wi-Fi. A RCSwitch também funciona no ESP32 e, como todo GPIO do ESP32 aceita interrupções, você pode ligar o receptor a qualquer pino seguro que quiser. O código abaixo lê os códigos de um receptor ligado ao GPIO 27 (por um divisor de tensão); quando chega o código do seu próprio controle, ele inverte o estado do LED no GPIO 2 ou de um módulo relé. Como um controle envia o código muitas vezes a cada toque, o programa só inverte de novo depois que o código parar de chegar por 600 ms:

C++ (Arduino IDE)
1#include <RCSwitch.h>
2
3RCSwitch rf = RCSwitch();
4const int RX_PIN = 27;              // alıcı DATA, gerilim bölücüyle / receiver DATA, through a divider
5const int ROLE_PIN = 2;             // dahili LED ya da röle girişi / onboard LED or relay input
6const unsigned long KOD = 5393;     // kendi kumandanın kodu / your own remote's code
7bool durum = false;
8unsigned long sonGorulme = 0;
9
10void setup() {
11  Serial.begin(115200);
12  pinMode(ROLE_PIN, OUTPUT);
13  rf.enableReceive(digitalPinToInterrupt(RX_PIN));   // ESP32'de her GPIO kesme alır / every GPIO takes interrupts on the ESP32
14}
15
16void loop() {
17  if (rf.available()) {
18    unsigned long kod = rf.getReceivedValue();
19    Serial.printf("Kod / code: %lu  %u bit  protokol %u\n", kod, rf.getReceivedBitlength(), rf.getReceivedProtocol());
20    if (kod == KOD) {
21      // kumanda kodu art arda tekrarlar; yalnız yeni basışta değiştir / the remote repeats the code; toggle only on a new press
22      if (millis() - sonGorulme > 600) {
23        durum = !durum;
24        digitalWrite(ROLE_PIN, durum ? HIGH : LOW);
25      }
26      sonGorulme = millis();
27    }
28    rf.resetAvailable();
29  }
30}

Dá para construir muita coisa sobre essa base: encaminhe os códigos recebidos para o Home Assistant via MQTT para adicionar sensores de porta baratos de 433 MHz à sua casa inteligente, ou controle tomadas pelo celular com um transmissor no GPIO 26. A RadioHead também é compatível com o ESP32; a única diferença é que você escreve os pinos explicitamente no construtor: RH_ASK rf(2000, 27, 26, 25); (receptor no 27, transmissor no 26 e o 25 como pino livre para o PTT). Se você está começando com o ESP32, dê uma olhada em O que é o ESP32?.

Transmissor de 433 MHz com Raspberry Pi Pico e MicroPython

O MicroPython não tem um equivalente pronto da RCSwitch, mas o tempo do protocolo 1 é tão simples que você mesmo pode escrevê-lo em poucas linhas. Ligue o VCC do FS1000A ao pino VBUS (5 V) do Pico, o DATA ao GP15 e um botão entre o GP16 e o GND. Quando você aperta o botão, o Pico envia os 24 bits a partir do bit mais significativo, assim como a RCSwitch, acrescenta o pulso de sincronismo no fim e repete o pacote inteiro 10 vezes. Se você ainda não sabe instalar o MicroPython no Pico, comece por O que é o Raspberry Pi Pico?.

MicroPython
1from machine import Pin
2import time
3
4tx = Pin(15, Pin.OUT, value=0)        # FS1000A DATA -> GP15
5buton = Pin(16, Pin.IN, Pin.PULL_UP)  # buton GP16-GND / button GP16-GND
6T = 350                               # darbe süresi µs (RCSwitch protokol 1) / pulse length µs (RCSwitch protocol 1)
7
8def darbe(yuksek, dusuk):             # süreler T cinsinden / durations in units of T
9    tx.value(1)
10    time.sleep_us(yuksek * T)
11    tx.value(0)
12    time.sleep_us(dusuk * T)
13
14def gonder(kod, bit=24, tekrar=10):
15    for _ in range(tekrar):
16        for i in range(bit - 1, -1, -1):   # en anlamlı bitten başla / start from the most significant bit
17            if (kod >> i) & 1:
18                darbe(3, 1)                # "1" biti: 3T HIGH, 1T LOW / bit "1"
19            else:
20                darbe(1, 3)                # "0" biti: 1T HIGH, 3T LOW / bit "0"
21        darbe(1, 31)                       # senkron: 1T HIGH, 31T LOW / sync
22
23while True:
24    if buton.value() == 0:                 # butona basıldı / button pressed
25        gonder(5393)                       # okuduğun kodu yaz / put the code you read here
26        time.sleep_ms(300)

Para o processador de 125 MHz do Pico, pulsos de 350 µs são uma velocidade tranquila; os pequenos atrasos do Python ficam bem abaixo da tolerância de tempo de 60% dos receptores RCSwitch. Você pode testar o código na hora colocando ao lado um Arduino rodando o código leitor da RCSwitch: o número que você enviou deve aparecer no Monitor Serial. Do lado do receptor, seria preciso medir e decodificar as larguras de pulso com marcações de tempo; para essa tarefa, um Arduino ou ESP32 rodando a RCSwitch é mais prático.

Alcance e interferência: levando o sinal mais longe

  • Não esqueça a antena: solde um fio reto de 17,3 cm nos dois lados; é o que mais afeta o alcance.
  • Aumente a tensão do transmissor: alimentar o FS1000A com 9–12 V aumenta bastante a potência de saída e o alcance. Não esqueça o GND comum.
  • Diminua a velocidade: usar 1000 bps em vez de 2000 na RadioHead faz cada bit durar mais e permite que o receptor decodifique sinais mais fracos. Configure a mesma velocidade nos dois lados.
  • Linha de visada e altura: paredes de concreto armado, caixas metálicas e uma instalação perto do chão podem reduzir o alcance pela metade; tire as antenas de dentro de caixas metálicas e coloque-as o mais alto possível.
  • Limpe a alimentação: motores, relés e fontes chaveadas deixam o receptor surdo. Dê ao receptor uma alimentação filtrada e mantenha os fios curtos.
  • Use um receptor melhor: um receptor super-heteródino como o RXB6, no lugar do XY-MK-5V, muitas vezes alcança bem mais longe com o mesmo transmissor.
  • Envie de novo: como não há confirmação de recebimento, envie os comandos importantes 3–5 vezes e descarte as duplicatas no receptor usando o número do pacote.

Lembre-se de que 433 MHz é uma faixa compartilhada: a estação meteorológica do vizinho, chaves de carro e campainhas transmitem todas na mesma frequência. Na Europa e na Turquia, a faixa de 433,05–434,79 MHz é liberada para uso sem licença por dispositivos de curto alcance, mas a potência de transmissão é limitada a 10 mW (ERP) e você não deve manter o canal ocupado o tempo todo; as regras variam de país para país (no Brasil, quem define é a Anatel), e nos EUA os controles usam com mais frequência 315 MHz. Enviar dados em intervalos ou só quando algo muda, em vez de continuamente, mantém você dentro das regras e ainda aumenta a duração da bateria; para um transmissor alimentado por bateria, você pode usar a calculadora de autonomia da bateria.

Módulo RF 433 MHz ou nRF24L01?

Módulo de comunicação sem fio nRF24L01 de 2,4 GHz
nRF24L01: uma alternativa de 2,4 GHz que se conecta por SPI, funciona nos dois sentidos e tem verificação de erros embutida no hardware.
CaracterísticaRF 433 MHz (FS1000A + XY-MK-5V)nRF24L01
Frequência433,92 MHz2,4 GHz
ModulaçãoASK / OOKGFSK
SentidoUnidirecional (placas separadas de transmissor e receptor)Bidirecional (um único módulo transceptor)
Taxa de dados1–4 kbps na prática (padrão da RadioHead: 2 kbps)250 kbps – 2 Mbps
ConexãoUm único pino de dadosSPI (7 fios)
AlimentaçãoTransmissor 3–12 V, receptor 5 V1,9–3,6 V
Verificação de errosPor software (CRC da RadioHead)CRC por hardware, confirmação automática e retransmissão
Alcance20–100 m com uma antena de 17,3 cm50–100 m, ~1 km com a versão PA+LNA
Penetração em paredesMelhor (frequência mais baixa)Mais fraca
Funciona com aparelhos prontosControles de tomadas, campainhas e sensoresNão
PreçoMuito baratoBarato

Resumindo: se você precisa enviar dados pequenos, em um só sentido e de vez em quando (um botão, um valor de temperatura, o aviso de que uma porta abriu) ou trabalhar com tomadas e sensores prontos, o módulo de 433 MHz é a solução mais barata e simples. Para um carrinho de controle remoto, um joystick ou redes de sensores com vários nós que precisam de comunicação rápida, bidirecional e com confirmação, o nRF24L01 é a melhor escolha. Se você precisa de alcance de quilômetros, veja os módulos LoRa; para ver todas as opções lado a lado, leia Módulos de comunicação sem fio para Arduino.

Ideias de projetos com módulo RF 433 MHz

  • Campainha sem fio: toque uma melodia dentro de casa quando o botão no portão do jardim enviar um sinal; um buzzer basta para o som.
  • Controlar tomadas a partir de um Arduino: clone os códigos de tomadas com controle remoto e acenda e apague lâmpadas por horário ou nível de luz.
  • Sensor de porta sem fio: coloque uma chave reed e um Arduino pequeno com transmissor na porta; quando a porta abrir, o lado receptor dispara um alarme.
  • Sistema de alarme residencial: monte um sistema de alarme com Arduino que reúna sensores PIR e de porta prontos de 433 MHz em uma central.
  • Estação de sensores no jardim: envie a umidade do solo ou a temperatura para dentro de casa a cada poucos minutos com um transmissor alimentado por bateria.
  • Ponte de 433 MHz para Wi-Fi: controle todos os aparelhos de 433 MHz da sua casa pelo celular e pelo sistema de casa inteligente com um ESP32.

Erros comuns e como corrigi-los

SintomaCausa provávelSolução
Nenhum pacote chega ao receptor (RadioHead)Velocidade ou pinos diferentes entre os dois lados, sem antenaUse o mesmo construtor nos dois lados (2000, 11, 12) e solde um fio de 17,3 cm nos dois módulos
Só funciona a poucos centímetros de distânciaSem antena ou tensão baixa no transmissorColoque uma antena e alimente o transmissor com 5–12 V
Erro multiple definition of `__vector_11'A RadioHead e a biblioteca Servo não conseguem dividir o Timer1Use RH_ASK_ARDUINO_USE_TIMER2 ou ServoTimer2
O PWM no D9 e no D10 não funciona, o aparelho no D10 se comporta de forma estranhaA RH_ASK usa o Timer1 e o D10 (PTT)Deixe esses pinos livres ou escolha outro pino PTT no construtor
A RCSwitch não mostra código nenhumO DATA do receptor está em um pino sem interrupçãoUse o D2 ou o D3 no Uno e no Nano
Aparecem na tela códigos que você não reconheceEstações meteorológicas e sensores dos vizinhos ou ruídoReaja só a códigos, números de bits e protocolos conhecidos
O código clonado não aciona a tomadaA largura de pulso ou o protocolo são diferentes, ou o controle usa código rolanteColoque o valor de getReceivedDelay() em setPulseLength() e aumente o número de repetições
O ESP32 não recebe códigos ou se comporta de forma instávelA saída de 5 V do receptor está ligada direto em um GPIOUse um divisor de tensão ou um receptor de 3,3 V
Os dados falham quando um motor ligaRuído na alimentação e quedas de tensãoDê ao receptor uma alimentação separada e acrescente capacitores de 100 nF + 10 µF
Na hora de solucionar problemas, teste primeiro os dois módulos a 1 metro de distância, com antenas e em 5 V. Se funcionar nessa distância, o problema não é a ligação, e sim o alcance e a interferência; aumente a distância aos poucos e observe o efeito da antena, da tensão do transmissor e da taxa de dados. Se não funcionar de jeito nenhum, confira os pinos, a configuração de velocidade e os exemplos da própria biblioteca.

Os módulos RF 433 MHz dão aos seus projetos um braço sem fio por muito pouco dinheiro e estão entre os poucos módulos que conseguem conversar com os aparelhos de controle remoto prontos da sua casa. Depois de entender a lógica do controle sem fio, você aprende com facilidade outros métodos, como controles remotos IR e Bluetooth. No app BlueGrays você encontra projetos como comunicação entre dois Arduinos, acionar uma lâmpada de 220 V com controle remoto, sensor de porta com chave reed e alarme de movimento com ESP32, com esquema do circuito e código passo a passo.

Perguntas frequentes

Qual é o alcance de um módulo RF 433 MHz?

Sem antena, um conjunto só funciona a 1–3 metros. Com uma antena de fio de 17,3 cm soldada nos dois lados e o transmissor alimentado com 5 V, dá para chegar a 20–50 metros ao ar livre, e a mais de 100 metros com o transmissor em 9–12 V. Em ambientes fechados, paredes e interferências reduzem bastante esses números.

Qual deve ser o comprimento de uma antena de 433 MHz?

A antena simples mais eficiente é um fio reto de um quarto de onda: cerca de 17,3 cm para 433 MHz e 23,8 cm para 315 MHz. Solde o fio na ilha ANT do módulo e mantenha-o reto e na vertical; as antenas do receptor e do transmissor devem apontar na mesma direção.

Um transmissor e um receptor de 433 MHz conseguem se comunicar nos dois sentidos?

Com um único par, a comunicação só vai do transmissor para o receptor. Se você colocar um transmissor e um receptor em cada lado, dá para trabalhar nos dois sentidos, e a classe RHReliableDatagram da RadioHead ainda acrescenta confirmações e novas tentativas nessa montagem. Mesmo assim, módulos que já são bidirecionais desde o início, como o nRF24L01 ou o HC-12, são mais práticos para isso.

Dá para clonar o controle de um carro ou de um portão de garagem com um módulo de 433 MHz?

Chaves de carro e controles de garagem modernos usam código rolante: o código muda a cada toque e um código gravado é recusado, então a RCSwitch não consegue cloná-los. Já os controles de código fixo de tomadas, campainhas e sensores podem ser clonados. Use este método só nos seus próprios aparelhos; tentar acessar sistemas de outras pessoas traz problemas legais.

O módulo RF 433 MHz funciona com o ESP32?

Sim. Você pode alimentar o transmissor FS1000A com 5 V e ligar o pino DATA direto em um GPIO; um sinal de 3,3 V é suficiente. Como a saída do receptor XY-MK-5V é de 5 V, você deve acrescentar um divisor de tensão ou escolher um receptor que funcione com 3,3 V, como o RXB6. As bibliotecas RCSwitch e RadioHead são compatíveis com o ESP32.

Qual é a diferença entre os módulos de 433 MHz e de 315 MHz?

As duas versões são construídas do mesmo jeito; só a frequência de operação muda. Na Europa e na Turquia, os controles usam principalmente 433,92 MHz, enquanto 315 MHz é comum nos EUA e em alguns países da Ásia. O transmissor e o receptor, ou o controle que você quer clonar, precisam estar exatamente na mesma frequência.

Ver todos os projetos
Comunicação unidirecional entre 2 Arduinos
#57Intermediário
Premium

Comunicação unidirecional entre 2 Arduinos

Faça dois Arduinos conversarem por um único fio: ao pressionar o botão de um, o LED do outro acende; ao pressionar de novo, ele apaga. A placa transmissora informa que o botão foi pressionado com uma

4.4(37)
50
Comunicação bidirecional entre 2 Arduinos
#58Intermediário
Premium

Comunicação bidirecional entre 2 Arduinos

Dois Arduinos se conectam por fios e conversam entre si: ao pressionar o botão de um, a luz do outro acende; ao pressionar novamente, ela apaga. As duas placas executam o mesmo programa, então ambas e

4.5(20)
26
Acender uma lâmpada de 220V com controle remoto
#21Avançado
Premium

Acender uma lâmpada de 220V com controle remoto

Ligue e desligue uma lâmpada de casa com o controle da TV, sem sair do sofá. O Arduino lê o sinal de luz invisível do controle; o botão de ligar aciona o relé e acende a lâmpada, e o botão de silencia

4.4(22)
30
Sensor de porta com chave reed
#38Iniciante
Premium

Sensor de porta com chave reed

Saiba se a porta está aberta ou fechada só de olhar uma luz. Você fixa um pequeno ímã na porta e uma chave sensível ao ímã no batente; quando a porta está fechada, os dois ficam lado a lado e o LED ve

4.7(34)
44
Ligar e desligar LEDs com receptor IR e controle remoto
#17Intermediário
Premium

Ligar e desligar LEDs com receptor IR e controle remoto

É como controlar três lâmpadas separadas sem sair da poltrona: os botões 1, 2 e 3 do controle remoto acendem os LEDs azul, vermelho e verde, e os botões 4, 5 e 6 os apagam na mesma ordem. O botão de l

4.7(45)
66
Controle remoto universal IR com ESP32 (receptor IR + controle remoto + 3 LEDs + buzzer + OLED)
#143Avançado
Premium

Controle remoto universal IR com ESP32 (receptor IR + controle remoto + 3 LEDs + buzzer + OLED)

Com o ESP32, você pode ler os sinais de um controle remoto IR comum e usá-lo para controlar seu próprio dispositivo! Neste projeto, usamos um receptor infravermelho (protocolo NEC, 38 kHz) para captar os sinais de um controle IR de 20 botões. Definimos ações diferentes para cada botão: os botões 1, 2 e 3 ligam e desligam três LEDs separados; o botão PWR apaga todos; e os números 4–9 exibem indicações especiais no OLED.

4.5(9)
16
Controle de LED pelo celular via Bluetooth
#34Iniciante
Premium

Controle de LED pelo celular via Bluetooth

Um pequeno ensaio para acender e apagar as luzes do seu quarto pelo celular. O módulo Bluetooth repassa ao Arduino as letras enviadas pelo celular; uma letra acende o LED vermelho, outra acende o verd

4.8(68)
89