Senden einer langen Bit-Sequenz über 433 MHz

  • Moin,

    ich bin gerade dabei die Fernbedienung für unsere Außenbeleuchtung zu klonen und über's Smartphone steuerbar zu machen. Der "RFSniffer" war nicht erfolgreich, deshalb musste ich die Original-Signale mit URH abfangen, um die Bit-Sequenzen extrahieren zu können (bleiben immer gleich).


    Hier ein Beispiel, der Übersicht und Sicherheit halber stark vereinfacht:

    Code
    1111001011111
    1111101010101
    1111101010101
    1111101010101

    Bei einem Tastendruck werden vier Sequenzen, mit jeweils einer Pause von ~213ms gesendet, wobei die letzten drei exakt gleich sind. Ein Bit sollte, im Idealfall, 500μs andauern.


    So in der Art konnte ich es auch schon erfolgreich umsetzen, doch das Problem liegt in der Ungenauigkeit der Zeit. 3/4 des übertragenden Signals sind richtig und stimmen mit dem Original überein, doch "auf der letzten Meile" kommt es zu Ungenauigkeiten und somit falsch ausgewerteter Bits.


    Hier der aktuelle Code:


    Die Idee ist, dass die vier Bit-Sequenzen in einem String sind, der Zeichen für Zeichen durchlaufen wird. Einsen und Nullen setzen den entsprechenden Zustand des Pins und bei einem Leerzeichen wird gewartet.


    Meine Frage ist nun, wie ich diese Ungenauigkeiten zum Ende hin vermeiden kann? Kennt jemand spezielle Python Libs mit besseren "sleep"-Funktionen oder einen effizienteren Ansatz was den Code angeht? Nebenbei versuche ich mich noch an C und WiringPi, das ich sonst auch aus Python heraus ausführen könnte.


    (Ja, wenn die letzten drei Sequenzen immer gleich sind, kann man da auch eine Schleife draus machen. Ästhetische Änderungen kommen noch ;))


    Danke

    Kelvin

  • Der Pi wird durch das Multitasking vom Betriebssystem ständig unterbrochen und ist für solche Echtzeitsachen nicht wirklich geeignet.


    Schick die Sequenz seriell an einen µC und lass den das machen. Mit seinen Timern kannst du das signal sehr viel genauer steuern.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Schick die Sequenz seriell an einen µC und lass den das machen.

    Das wollte ich eigentlich vermeiden, weil ich sowieso schon einen RPi als Zentrale habe und nicht noch extra einen ESP32 bemühen möchte.

    Kelvin

  • Der Pi wird durch das Multitasking vom Betriebssystem ständig unterbrochen und ist für solche Echtzeitsachen nicht wirklich geeignet.

    Ich würde es aus eigener Erfahrung leicht anders ausdrücken:


    Der Pi wird durch das Multitasking vom Betriebssystem ständig unterbrochen und ist für solche Echtzeitsachen absolut nicht wirklich geeignet.


    Schick die Sequenz seriell an einen µC und lass den das machen

    Ich kann in diesem Zusammenhang den Arduino Pro Mini empfehlen. Ein ESP32 ist für solche Aufgaben ebenfalls nicht geeignet.

  • Moin!


    Nur als Ergänzung gedacht.


    Falls du dich doch zu einem MikroController durchringen solltest und du nurazur's Vorschlag folgst.

    Den Arduino Pro Mini gibt es in einer 3,3 Volt- und 5 Volt-Version. Ich würde den 3,3V nehmen. Passt besser zum Raspberry.


    73 de Bernd

    Ich habe KEINE Ahnung und davon GANZ VIEL!!
    Bei einer Lösung freue ich mich über ein ":thumbup:"

    Vielleicht trifft man sich in der RPi-Plauderecke.

  • Zu deinen programmierten sleeps kommen immer noch die Zeiten für die Schleife, die If-Prüfungen und die GPIO.Outputs dazu.

    Du könntest mal testweise die 213 ms verkürzen, um das zu kompensieren.


    Außerdem: Könnte man den Code nicht noch kürzen? Wozu fragst du am Ende noch ein ELSE ab, das ein Continue macht? Außer "0", "1" und " " kann es doch gar nichts geben, oder? Die Abfrage nach " " könnte doch schon das ELSE sein:

    Code
    ...
       else:
          GPIO.output(TRANSMIT_PIN, 0)
          time.sleep(0.213)
    
    GPIO.output(TRANSMIT_PIN, 0)
    ...

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Außerdem: Könnte man den Code nicht noch kürzen?

    Danke, kurz nach dem Erstellen des Themas habe ich den Code noch weiter kastriert, um ihn möglichst effizient zu gestalten. Ich probiere mich auch gerade durch die ganzen Python GPIO-Bibliotheken durch (RPi.GPIO, wiringpi, pigpio, ...).

    Kelvin

  • Also, Python kann man wirklich knicken. Ich habe diverse Bibliotheken ausprobiert, doch konnte teilweise sogar schlechtere Ergebnisse beobachten.


    Jetzt habe ich es mal mit dem ESP32 versucht und konnte das Signal tatsächlich zu 100% reproduzieren. Stichprobenartig konnte ich sogar ein besseres Timing erkennen, als mit der Original-Fernbedienung.


    Hier ein Ausschnitt aus URH. Oben ist das Signal der Fernbedienung, unten das des ESP32. Es ist nur ein Teil des ersten Bursts zu sehen, doch wenn ich die ausgewerteten Binärsequenzen (des gesamten Signals, also 4 Bursts) vergleiche, stimmen diese exakt übereinander.


    Soo, das klingt ja jetzt alles schön und gut und ich habe auch gleich voller Euphorie meinen ESP geschnappt und diesen in der Nähe des Ziel-Empfänger eingeschaltet (Distanz zu meinem Schreibtisch ist zu weit), doch..... nichts!


    Weiß jemand, wo das nächste Problem liegen könnte? An meinem PC, mit UHR und einem DVB-T-Stick empfange ich ein astreines Signal, doch der eigentliche Empfänger bleibt davon unberührt. Habe ich etwas übersehen? Muss die Frequenz exakt übereinstimmen oder kann es auch leichte Abweichungen geben?



    EDIT:

    Fernbedienung: 433,4375 MHz

    ESP32: 433,900 MHz


    Verwendeter Sender: https://www.amazon.de/dp/B01N5GV39I/ (Affiliate-Link)

    Kelvin

    Edited once, last by Kelvin ().

  • Moin Kelvin,


    anscheinend ist dein Empfänger nicht so breitbandig. Was ja auch gut ist!


    Du liegst mit dem ESP ca. 500KHz höher. Die Frequenz des Senders kann man nicht verändern?


    73 de Bernd

    Ich habe KEINE Ahnung und davon GANZ VIEL!!
    Bei einer Lösung freue ich mich über ein ":thumbup:"

    Vielleicht trifft man sich in der RPi-Plauderecke.

  • ja dein Diagramm zeigt es ja ganz deutlich: FB und ESP ueberlappen sich gar nicht, d.h. sie koennen sich auch gar nicht verstehen. 433.42 MHz kenne ich jetzt sonst nur von Somfy.

    Die Frequenz des Senders kann man nicht verändern?

    Bei dem von Kelvin verwendeten Modul geht das nicht, eine Moeglichkeit ist einen 433.42MHz Resonator anstatt des 433.92MHz Resonators zu verwenden. Ich habe das bei meinem Somfy Rolladen mit Erfolg so gemacht.

  • anscheinend ist dein Empfänger nicht so breitbandig.

    FB und ESP ueberlappen sich gar nicht, d.h. sie koennen sich auch gar nicht verstehen.

    Geil. X/ Aber wieder was dazugelernt: Wenn man eine Fernbedienung klonen will, sollte man vor der Bestellung die Frequenz messen, denn 433 MHz Sender ≠ 433 MHz Sender.


    Ich konnte jetzt auf die schnelle auch keine günstigen und fertigen 433.42MHz Sender finden und muss wohl doch etwas selbst löten. Die angegebene Lieferzeit "Zwischen Di, 10. Mrz. und Mi, 15. Apr." hebt meine Laune auch nochmal um einiges ^^ Mal sehen ob ich das Projekt überhaupt noch weiter angehen werde... der Zeit-/Kosten-/Nutzen-Faktor stimmt mit dieser neuen Erkenntnis nicht mehr.


    Den Empfänger werde ich mir auch mal anschauen, dort wird aber nichts einstellbar sein. Das Teil hängt nur an einem Siemens LOGO und sorgt da für den Input.

    Kelvin

  • Die angegebene Lieferzeit "Zwischen Di, 10. Mrz. und Mi, 15. Apr." hebt meine Laune auch nochmal um einiges

    Normalerweise dauert eine Lieferung aus China so ca. 3 Wochen. Im Moment weiss ich nicht ob überhaupt noch Waren aus China kommen, weil die Grenzen alle dicht sind, auch die von Shenzhen nach Hongkong, das ist für Elektronik besonders bloed. :(


    der Zeit-/Kosten-/Nutzen-Faktor stimmt mit dieser neuen Erkenntnis nicht mehr.

    Naja, der Sender alleine kostet 1 EUR, 10 St. Resonatoren 2.26 EUR, das ist jetzt nicht die Welt. Einen brauchst du, die restlichen 9 kannst du wieder verkaufen, weil die Dinger gibts nicht immer auf dem Markt, und es gibt immer wieder Leute die genau in dein Problem hineinrennen. Und Loeten koennen schadet nie! Und wenns dann funktioniert, freust du dich wie ein Schnitzel. Garantiert.

  • Naja, der Sender alleine kostet 1 EUR, 10 St. Resonatoren 2.26 EUR, das ist jetzt nicht die Welt. Einen brauchst du, die restlichen 9 kannst du wieder verkaufen, weil die Dinger gibts nicht immer auf dem Markt, und es gibt immer wieder Leute die genau in dein Problem hineinrennen. Und Loeten koennen schadet nie! Und wenns dann funktioniert, freust du dich wie ein Schnitzel. Garantiert.

    Ja gut, was die Kosten angeht sind es wirklich Peanuts, nur bin ich so ungeduldig. Ich werde mir es aber doch bestellen und dann eben mal eine kleine Pause genehmigen. Danke für den ebay-Link!

    Habe auch gerade noch erfahren, dass in der Familie jemand Somfy Rolladen hat - die könnte ich dann auch noch smart machen :thumbup:

    Kelvin

  • Hallo Kelvin,


    um nochmals kurz auf das Thema der "langen Sequenz" zurückzukommen. Ein µC ist sicherlich die bessere Wahl.


    Wenn's aber mit dem Pi sein soll, dann verändere die Scheduling Policy des sendenden Thread. Üblicherweise ist diese SCHED_RR round robin). Bei SCHED_FIFO liegst Du zum einen in der Klasse der höher prioren Threads, zum anderen werden diese erst freigegeben, wenn die Task es will. D.h., die Chance unterbrochen zu werden ist einfach ausgedrückt "geringer". Ich hatte das zum senden eines sehr langen Datagrams einer Funkklingel verwendet.


    Den Code kannst Du >>> hier <<< sehen. Die relevante Funktion ist void BoostThreadPriority(). Im Prinzip könntest Du aber auch gleich das ganze Programm verwenden und das Alphabet anpassen.


    Schöne Grüße,


    schnasseldag

  • In der Zwischenzeit, bis die Resonatoren kommen, kannst du dich ja mit dem Somfy Protokoll beschäftigen...

    Meine Rollläden verwenden das Somfy RTS Protokoll, welches schon ziemlich lange auf dem Markt ist, und einige Reingenieure haben das Protokoll geknackt.

    Hierzu gibts ein Plugin für pilight.

    Es gibt ein neueres Protokoll von Somfy names TaHoma, welches - soweit ich weiss- nicht so einfach auf den Raspberry übertragbar ist. Du brauchst immer die "Tahoma Box" dazwischen.

    Also aufpassen!

  • Danke euch beiden. Solange es mit der Lieferung andauert (durch Covid-19/Corona verzögert es sich immer mehr), habe ich Zuhause etwas weiter herumgespielt und eine Steckerleiste mit 433.92 MHz gefunden. Die Signale zu duplizieren und mit dem ESP32 zu senden verlief problemlos, trotz noch längerer Bit-Sequenzen (~630 vs. ~430 Bits). Als nächstes probiere ich es dann mal mit dem Pi, da ich ja jetzt ein Gerät mit der richtigen Frequenz gefunden habe und weiß, dass es (mit µC) funktioniert.

    Kelvin

  • Den Code kannst Du >>> hier <<< sehen. Die relevante Funktion ist void BoostThreadPriority().

    Alter Schwede! Es funktioniert!

    Aktuell ist das alles seeeehr stümperhaft und zusammengeflickt, was man der Öffentlichkeit absolut nicht zumuten kann ^^ Das Python-Skript läuft jetzt im Autostart mit systemd, wie ich es auch schon mit meiner Türklingel getan habe.


    Umsetzung: Easy. Das Python-Skript ruft lediglich mit subprocess die kompilierten C++-Dateien auf.

    Performance: Naja, aber noch ok. Es funktioniert, in ca. 70% der Fällen sogar beim ersten Mal, doch für harte Echtzeitanforderungen ist es wirklich nicht ausgelegt (wundert mich aber auch nicht, die Gründe und Alternativen wurden hier bereits benannt). Für meine Zwecke reicht es. Software-technisch werde ich die Signale wohl noch mehrfach senden, damit man nicht selbst mehrfach auf die Tasten drücken muss.


    Zum Steuern benutze ich übrigens diese App: https://play.google.com/store/…f.httprequestwidget&hl=de

    Kelvin

  • Kelvin: Schön, wenn's klappt. Die gekauften 433MHz Geräte wie Funkklingel, Steckdose, Funkschlüssel etc. senden übrigens auch mehrfach hintereinander (denselben) Code. Auf ein einfaches Signal verläßt sich da niemand. Weder der Sender, noch der Empfänger. Letzterer will nämlich auch nicht "aus versehen" ein- oder ausgeschaltet werden.

  • Kelvin : Schön, wenn's klappt. Die gekauften 433MHz Geräte wie Funkklingel, Steckdose, Funkschlüssel etc. senden übrigens auch mehrfach hintereinander (denselben) Code. Auf ein einfaches Signal verläßt sich da niemand. Weder der Sender, noch der Empfänger. Letzterer will nämlich auch nicht "aus versehen" ein- oder ausgeschaltet werden.

    Das konnte ich auch mit "Universal Radio Hacker" entdecken. Im Falle der Brennenstuhl-Steckerleiste ist es:

    Code
    [100000|Einschalt-Code|100000|Einschalt-Code|100000|Einschalt-Code|100000|Einschalt-Code|111111]
    [Einschalt-Code|111111]
    [Einschalt-Code|111111]
    [Einschalt-Code|111111]
    [Einschalt-Code]

    Genau das repliziere ich, kann aber kleine Abweichungen feststellen, wenn es mit dem Pi gesendet wird. Der ESP32 konnte es tatsächlich immer zu 100% korrekt senden, bei dem Pi schleichen sich jedoch mal eine 0 oder 1 zu viel ein. Nervt etwas, werde ich aber noch beheben, indem ich das gesamte Signal mehrfach sende, mit einer kleinen Verzögerung dazwischen.

    Kelvin

  • Du kannst mal die waves-Funktion von pigpio versuchen. Wenn die lang genuge Wellenformen anbietet, die deine gesamte Kommunikation darstellen koennen, dann hat das mehr Aussicht auf Erfolg. Weil die Signale per DMA erzeugt werden, und nicht von der CPU und deren Scheduling abhaengen.