Arduino 433 MHz senden und empfangen

In diesem Beitrag wollen wir mit dem Arduino 433 MHz Daten senden und empfangen. Diese Daten können auf Ereignisse beruhen, so wollen wir z.B. auf Tastendrücke eines Senders reagieren. Damit kann einerseits eine einfache Funkfernbedienung z.B. eines Garagentorantriebs dazu genutzt werden Aktionen am Arduino auszulösen. Die Aktionen können beispielsweise das Schalten eines einfachen Relais sein oder wie in unserem Fall für ein späteres Projekt das Ingangsetzen eines Elektromotors. Andererseits lässt sich umgekehrt der Arduino auch als Sender verwenden um zum Beispiel Smarthome Funksteckdosen zu schalten. Wir testen hier verschiedene Sender/Empfänger Kombinationen.

Doch warum eigentlich 433 MHz? Es handelt sich dabei um einen sogenannten ISM Frequenzbereich zu dem beispielsweise auch die weit verbreiteten 2,4 GHz gehören die eigentlich jeder von uns schon mal genutzt hat, denn oft verwendet das heimische WLAN diese Frequenz. Auch 868 MHz sind weit verbreitet. Alle 3 Frequenz-Bereiche werden zum Beispiel oft in Smart-Home Geräten eingesetzt. Der Vorteil in den deutlich niedrigeren 433 MHz (gegenüber den 2,4 GHz) liegt in seiner Einfachheit und damit oft günstigen Komponenten. Niedrigere Frequenz bedeutet in der Regel auch eine höhere Reichweite. So sind beispielsweise 100 m oder mehr möglich. Nachteilig ist natürlich die niedrigere Datenrate. Ob das aber tatsächlich ein Nachteil ist liegt natürlich an der Applikation. Falls nur in unregelmäßigen Abstanden einige Sensorwerte oder ein Schaltbefehl übermittelt werden sollen werden nur einige Byte benötigt. Ein Nachteil gegenüber den 868 MHz ist, dass die 433 MHz so weit verbreitet sind, dass der Frequenzbereich schon oft „voll“ ist, da so viele Geräte (wie z.B. Garagentorantriebe, Wetter-Stationen, Funksteckdosen) diesen Bereich nutzen und sich gegenseitig stören.

Das ganze Thema bezüglich Frequenzen und den jeweiligen Eigenschaften, sowie Vor- und Nachteilen ist sehr umfangreich und würde den Rahmen hier bei Weitem sprengen, so dass wir uns auf die Anwendung konzentrieren 🙂 Weitere Hintergrundinformationen zum Beispiel auf wikipedia.de oder in diesem Thread auf mikrocontoller.net.

Bauteile

Folgende Bauteile wurden verwendet und werden nachfolgend detaillierter vorgestellt:

Mega Pro Minigibt’s bei Amazon*gibt’s bei ebay*
FS1000A 433 MHz Sender/Empfänger Setgibt’s bei Amazon*gibt’s bei ebay*
RXB6 433 MHz Empfängergibt’s bei Amazon*gibt’s bei ebay*
RXB8 433 MHz Empfängergibt’s bei Aliexpress*gibt’s bei ebay*
Funkfernbedienunggibt’s bei Aliexpress*
Übersicht verwendete Bauteile

Kleiner Exkurs zu den Antennen

Bei den Sendern/Empfängern wurde jeweils eine Antenne verwendet, da ohne die Reichweite ehrlich gesagt für die Tonne ist. Dabei ist es nicht ratsam einfach eine Büroklammer oder ein Stück Draht anzulöten (obwohl in diesem Beitrag scheinbar gute/passable Ergebnisse damit erzielt wurden). Denn für guten Empfang/Reichweite sind die folgenden Zusammenhänge wichtig:

Die optimale Antennenlänge \(l\) ist abhängig von der Wellenlänge \(\lambda\) und berechnet sich wie folgt:

$$l=\frac{\lambda}{4}$$

Die Wellenlänge wiederum ist abhängig von der Lichtgeschwindigkeit \(c\) und der Frequenz \(f\) (also in unserem Fall 433 MHz).

$$\lambda=\frac{c}{f}=\frac{299.792.458m/s}{433.000.000/s}\approx17,3cm$$

Deshalb und da sie auch nicht viel kosten wurden diese Antennen* verwendet bzw zum Teil waren sie bei den Empfängern direkt dabei.

Mehr Informationen auf: wikipedia

Mega 2560 Pro Mini

Bei dem Mega 2560 Pro mini handelt es sich um ein Arduino Mega 2560-kompatibles Board. Es ist deutlich kompakter (und günstiger) als der Mega 2560. Er basiert auf dem USB-UART CH340 Chip (Mikro-USB). Mit den 54 digitalen I/O, sowie 16 analoge Eingänge kann man doch schon viel anfangen. Der Flash-Speicher ist mit 256 kB ordentlich und er besitzt 8 kB RAM. Diese und die meisten weiteren Parameter sind identisch mit dem Arduino Mega 2560, da beide den Atmel ATmega 2560 verbaut haben. Ich habe mit diesem Board bisher nur gute Erfahrungen gesammelt.

FS1000A 433 MHz Sender/Empfänger Set

Arduino 433 MHz

Das FS1000A Sender/Empfänger Set ist ein Low-Cost Set welches für weniger als 5 € zu haben ist. Die wichtigsten technischen Daten lauten

  • Betriebsspannung: 3,5 – 12 VDC (Sender) / 5 VDC (Empfänger)
  • Reichweite: 20 – 200 m
  • Übertragungsrate: 4 kB/s (AM)
  • Sendeleistung: 10 mW
  • Empfindlichkeit: -105 dBm

RXB6 433 MHz Empfänger

Der RXB6 ist ebenso wie der RXB8 unten ein bekannter Vertreter unter den Empfängern.

  • Betriebsspannung: 3 – 5,5 VDC
  • Empfindlichkeit: -116 dBm

RXB8 433 MHz Empfänger

Beim RXB8 hatte ich die meisten positiven Erfahrungen im Netz gelesen und war deshalb bei diesem Modul am hoffnungsvollsten.

  • Betriebsspannung: 4,5 – 5,5 VDC
  • Empfindlichkeit: -114 dBm

Bezüglich der Empfindlichkeit deckt sich der Wert auf dem Papier schon mal mit den Berichten aus dem Netz, denn bezogen auf die Empfindlichkeit hat er den besten/kleinsten Wert im Vergleich zum RXB6 (-116 dBm) und dem FS1000A (-106 dBm).

Funkfernbedienung

Hierbei handelt es sich um keine besonders namhaften Produkte, sondern einfach um günstige aus Fernost, welche aber problemlos funktionierten. Getestet wurde aber auch noch eine „Industriefernbedienung“. Allerdings konnte die im Gegensatz zu den Low-Cost Fernbedienungen nicht zum Laufen gebracht werden. Das würde ich allerdings nicht unbedingt auf die Qualität schieben sondern eher auf den internen Standard bzw. das interne Protokoll, das vermutlich einfach nicht kompatibel mit den verwendeten Software Bibliotheken ist.

Schaltplan

TODO: Fritzing

Sender

Sender-Einheit
Modul PinVerbunden mit
VCC5V
GNDGND
DATAD8
Pinbelegung Sender/Arduino

Empfänger

Empfänger-Einheit (hier ist zum Test mal kurz der D1 Mini eingesprungen)
Modul PinVerbunden mit
VCC5V
GNDGND
DATAD2
Pinbelegung Empfänger/Arduino

Software

Nun bauen wir das Programm schrittweise auf. In diesem Teil des Blogs kommt zunächst die Auswertung des Sensors und das Anzeigen der Werte auf dem Display. Für die ungeduldigen hier der vollständige Code des gesamten Projekts auf github. Dies beinhaltet, aber bereits den letzten Stand des gesamten Projekts und ist deshalb abweichend und umfangreicher als das u.g. Aber natürlich kann man sich dort auch das rauspicken, was man gerade benötigt.

Benutzte Bibliotheken

Folgende Bibliotheken wurden installiert:

  • RadioHead (V1.122 verwendet. Die Bibliothek ist von github nach hier umgezogen worden und muss nun als .zip manuell in das Arduino-libraries Verzeichnis entpackt werden)
  • RCSwitch (V2.6.4 verwendet. github)

Final und in Kombination mit der Fernbedienung ist nur die RCSwitch Bibliothek relevant. Falls sich Arduino’s untereinander Daten schicken können beide eingesetzt werden.

Code für Arduino 433 MHz

Das Programm ist simpel aufgebaut und nah an den Beispielen aus der jeweiligen Bibliothek dran. Zu Beginn hatte ich die RadioHead getestet mit der zwar die Arduinos untereinander kommunizieren können, aber die Signale der Fernbedienung nicht empfangen werden konnten. Ich bin dann zu der RCSwitch Bibliothek übergegangen. Da bis dahin aber schon mal eine Bibliothek mit dem oben beschriebenen Aufbau funktionsfähig war war es mir zu schade den bis dahin erreichten Fortschritt über den Haufen zu werfen. Ich habe deshalb die Programmteile die zur später nicht mehr verwendeten RadioHead Bibliothek gehören als Kommentar drin gelassen und hoffen die verwirren nicht zu sehr.

Sender

// #include <RH_ASK.h>
// #ifdef RH_HAVE_HARDWARE_SPI
//     #include <SPI.h>
// #endif

// RH_ASK driver(/*uint16_t speed*/2000, 
//             /*uint8_t rxPin*/9, 
//             /*uint8_t txPin*/8, 
//             /*uint8_t pttPin*/10);

#include <RCSwitch.h> // https://github.com/sui77/rc-switch/
RCSwitch mySwitch = RCSwitch();

void setup()
{
    Serial.begin(9600); // optional: aber praktisch fuer debug ausgaben ;)
    while (!Serial) ; 
    delay(200);
   
    Serial.print(">>>>>>>>>>>>>>>>>>>> (Neu-)Start ...");
    pinMode(LED_BUILTIN, OUTPUT);

    // if (!driver.init()) {
    //     Serial.println("init failed");
    // }
    
    mySwitch.enableTransmit(8);
}

void loop()
{
    static int ledState = HIGH;

    // const char *msg = "hello";

    // driver.send((uint8_t *)msg, strlen(msg));
    // driver.waitPacketSent();

    mySwitch.switchOff("11111", "00010");

    digitalWrite(LED_BUILTIN, ledState);
    ledState = !ledState;
    delay(500);
}
Vollständig anzeigen

Empfänger

// #include <RH_ASK.h> // https://github.com/PaulStoffregen/RadioHead
// #ifdef RH_HAVE_HARDWARE_SPI
//     #include <SPI.h>
// #endif

// RH_ASK driver(/*uint16_t speed*/2000, 
//             /*uint8_t rxPin*/9, 
//             /*uint8_t txPin*/8, 
//             /*uint8_t pttPin*/10);

#include <RCSwitch.h> // https://github.com/sui77/rc-switch/
RCSwitch mySwitch = RCSwitch();

void setup()
{
    Serial.begin(9600); // optional: aber praktisch fuer debug ausgaben ;)
    while (!Serial) ; 
    delay(200);

    // #ifdef RH_HAVE_SERIAL
    //     Serial.print("RH_HAVE_SERIAL YES");
    // #endif
    Serial.print(">>>>>>>>>>>>>>>>>>>> (Neu-)Start ...");
    pinMode(LED_BUILTIN, OUTPUT);

    // if (!driver.init()) {
    //     Serial.println("init failed");
    // }

    mySwitch.enableReceive(0);  // interrupt nr 0 liegt auf D2 beim arduino mega pro mini
}

void loop()
{
    // uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
    // uint8_t buflen = sizeof(buf);
    // static int i;
    // if (driver.recv(buf, &buflen)) // Non-blocking
    // {
    //     i++;
    //     Serial.print(i);
    //     // Message with a good checksum received, dump it.
    //     driver.printBuffer(" Got:", buf, buflen);
    // }

    if (mySwitch.available()) {
    
        Serial.print("Received ");
        Serial.print( mySwitch.getReceivedValue() );
        Serial.print(" / ");
        Serial.print( mySwitch.getReceivedBitlength() );
        Serial.print("bit ");
        Serial.print("Protocol: ");
        Serial.println( mySwitch.getReceivedProtocol() );

        mySwitch.resetAvailable();
    }
}
Vollständig anzeigen

Test/Ergebnis

Es wurde zunächst die Arduino Sender / Empfänger Kombination mit der jeweiligen Bibliothek ausprobiert, anstatt direkt mit der Funkfernbedienung zu arbeiten. Das Problem ist nämlich, dass es zu viele Stellen gibt die Ärger machen können. Klappt die Übertragung nicht dann ist meist das Ergebnis: Es kommt nichts an und die erwartete Ausgabe erscheint einfach nicht am seriellen Monitor. Die Ursache kann aber vielfältig sein und gerade beim Funk kann man schlecht mal eben mit dem Multimeter/Oszilloskop nachmessen bis wohin denn etwas noch funktioniert. Liegt es an der Verkabelung, am Programm, an der Bibliothek oder ist ein Modul kaputt? Deshalb zunächst der Test mit den Beispielprogrammen aus den Bibliotheken und den beiden Arduinos jeweils einer als Sender und einer als Empfänger.

Als der eine Arduino dem andern Daten schicken konnte (und die üblichen, aber lösbaren Startschwierigkeiten beseitigt waren 🙂 ) kam dann die Fernbedienung mit der RCSwitch-Bibliothek zum Zuge.

Das Ergebnis auf der Anzeige sieht dann so aus:

Damit wären wir für den ersten Teil fertig. In folgenden Teilen widmen wir uns der Datenloggerfunktion und dem Stromverbrauch für die Vorbereitung zur mobilen Anwendung.

Die Screenshots stellen das integrierte Terminal der Entwicklungsumgebung VS Code dar. Damit kann IMHO die Produktivität bei der Programmierung mit Arduino & Co deutlich gesteigert werden. Einen Artikel dazu und wie man es einrichtet findet ihr hier: https://blog.db-es.com/2023/07/25/arduino-programmieren-wie-die-profis-mit-vs-code/


Beitrag veröffentlicht

in

von

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert