Transceiver-Modul RFM69HW Anbindung, Programmierung & Ansteuerung

  • Für meine Anwendung benötige ich also den "Continuous Mode",

    Warum?

    Es geht beides, Packet Mode und Continuous Mode.

    Jetzt verstehe ich nicht, warum du dir die Mühe machst mit dem Continuous Mode, dazu braucht es eine enge Synchronisierung zwischen RFM Modul und dem Raspberry Pi. Wenn das Modul den Takt vorgibt, kann das ziemlich schnell nach hinten losgehen, da beim Raspberry ein Betriebssystem läuft das u.U. die Prioritäten ganz anders setzt, und moeglicheweise genau dann wenn es auf den Takt des RFM Moduls reagieren müsste gerade keine Zeit hat. Du hast allerdings die Moeglichkeit die Taktrate des RFM Moduls per Register einzustellen.


    Ich würde dir daher den Packet Mode empfehlen, solange du nur Pakete senden/empfangen willst die nicht länger als 66 Bytes sind. Hierfür gibt es zahlreiche Python Bibliotheken, z.B >>>hier<<< oder >>>hier<<<. Ein weiterer Vorteil des Packet Mode ist dass du neben dem SPI nur eine zusätzliche Leitung, DIO0 brauchst, welche als Interrupt dient wenn z.B ein Paket angekommen ist. Dann brauchst du nur den FIFO ausleeren und gut ists. Beim Senden ist es ähnlich, du füllst den FIFO mit deinem String über SPI und lässt dann den RFM69 arbeiten. Der kann das ganz alleine.

    Der Treiber von LowPowerLabs ist schon Jahre alt und hat sich bewährt, ist allerdings in C geschrieben. Ich habe meine eigene Version. Ich betreibe den RFM69 mit einem ATMega328 oder einem ATTiny84 dazwischen, weil dann die Kommunikation zum Raspberry Pi einerseits trivial wird (USB oder seriell), und andererseits der Raspberry Pi im 433er ISM Band eine echte Dreckschleuder ist. Die Interferenzen werden einerseits über die Luft (das kann man abschirmen), aber leider auch über die Zuleitungen in den RFM69 eingespeist. Der kleine µC dazwischen ist eine gute Trennung. Ein weiterer Nachteil den RFM69 direkt am Raspberry zu betreiben ist seine doch sehr kleine Massefläche. Du musst dir also über Antennen genaue Gedanken machen, eigentlich kommen bei der kleinen Masse nur Dipol Antennen infrage. Die gekauften Stummel brauchen auch alle ordentlich Massefläche, sonst funktionieren die nicht richtig.

    Und so weiter, und so fort...ich koennte locker ein Buch darüber schreiben. Vielleicht tue ich das sogar einmal.


    Fazit: Wenn du zu dem Ergebnis kommen solltest, dass der Packet Mode für dich infrage kommt, dann solltest du umschwenken. Ich erkenne den Vorteil des Continuous Mode bei deiner Anwendung nicht, aber ich lasse mich sehr gerne belehren!

  • Hallo nurazur,


    Bei meinem Projekt kommt das so genannte POCSAG-Protokoll zum Einsatz. Das ist ein Protokoll, das für die Übertragung von Texten an Funkmeldeempfänger (Pager, oder einfach nur "Piepser") genutzt wird.

    Ich habe also einen Klartext, der erstmal von einem selbst geschriebenen Script in folgende Stücke zerhackt wird:


    Präampel(576 Bit 10101010....), Synchronwort, 8x Batch, wieder Synchronwort, 8x Batch usw....


    So eine Nachricht ist schnell mal 3000 Bit lang oder wesentlich länger (kann beliebig lang sein).

    66 Byte reichen leider nicht aus für meinen Zweck. Allein die Präampel ist schon länger (!)…


    Deswegen der Continuous Mode... da komm ich nicht dran vorbei.


    Quote

    Wenn das Modul den Takt vorgibt, kann das ziemlich schnell nach hinten losgehen, da beim Raspberry ein Betriebssystem läuft das u.U. die Prioritäten ganz anders setzt, und moeglicheweise genau dann wenn es auf den Takt des RFM Moduls reagieren müsste gerade keine Zeit hat. Du hast allerdings die Moeglichkeit die Taktrate des RFM Moduls per Register einzustellen.

    Das könnte gerade so ausreichen, da das POCSAG Protokoll relativ langsam ist mit gerade einmal 1200 b/s.

    Ich nutze auch keine time.sleep Befehle, sondern einen Dummy-Befehl "Variable = 1" in einer While Schleife, die ständig wieder den Pin Status abgreift (man muss eben mindestens einen Befehl in einer while Schleife haben). Das sorgt für eine hohe CPU-Auslastung, aber man kann sich relativ sicher sein, das die Abfrage oft genug durchläuft.


    Quote

    Du musst dir also über Antennen genaue Gedanken machen, eigentlich kommen bei der kleinen Masse nur Dipol Antennen infrage. Die gekauften Stummel brauchen auch alle ordentlich Massefläche, sonst funktionieren die nicht richtig.

    Groundplane. Die bringt ihre Masse selber "mit" :)


    Quote

    Und so weiter, und so fort...ich koennte locker ein Buch darüber schreiben. Vielleicht tue ich das sogar einmal.

    Warum nicht?

    Ich könnte so ein Buch im Moment gebrauchen :P

  • Also, ich habe dazu mehrere Anmerkungen / Empfehlungen:

    Die CPU zu 100% mit Polling auszulasten entspricht am Raspberry Pi nicht unbedingt "state of the Art". Zum Ausprobieren des Konzepts geht das vielleicht gut, aber ob das am Ende zuverlässig funktioniert wage ich sehr zu bezweifeln. Du willst ja mit dem Raspberry noch andere Dinge machen, z.B. Daten verarbeiten, SSH, Netzwerk etc. Da hast du definitiv nicht die 100% CPU Leistung die du benoetigst.


    Was den Packet Mode betrifft habe ich mich falsch ausgedrückt, sorry. Ich meinte mit den verfügbaren Python Treibern ist die Paketlänge maximal 66 Bytes. Aber es ist natürlich moeglich auch im Packet Mode unendlich lange Bitsequenzen zu senden und zu empfangen. Das geht mit dem Signal "FifoLevel" an DIO1, indem du z.B beim Senden Bytes nachschiebst wenn der Fifo halb abgearbeitet ist (wenn sich also das Signal FifoLevel meldet). Habe ich selbst noch nie ausprobiert, aber so wie es im Datenblatt beschrieben wird sollte es relativ einfach umsetzbar sein. Aber ich will dir da auf keinen Fall reinreden.


    Auch im Continuous Mode würde ich einen externen µP bevorzugen, der kann das Polling nämlich zu 100% übernehmen, da er sonst nichts anderes zu tun hat. Aber es spricht auch nichts dagegen eine Interrupt getriebene Loesung zu erarbeiten. Nach meiner Erfahrung sind Interupt getriebene Programme wesentlich zuverlässiger als Polling.


    Zurück zu deiner eingangs gestellten Frage:

    Ich muss das Modul Programmieren und korrekt ansteuern und weiß noch nicht so recht, wie ich das in Python umsetzen kann.

    Du kannst das Problem in mehrere einzelne Aufgaben zerlegen.

    1. Kommunikation mit SPI. Wie hast du getestet dass die Kommunikation tatsächlich funktioniert? Ich mache das indem ich Register schreibe und lese, z.B die Frequenzregister. Die von mir verlinkten Bibliotheken funktionieren, so viel kann ich sagen.


    2. Abarbeiten aller Register wie sie im Datenblatt beschrieben sind und verstehen was sie bewirken. Die meisten Register haben ganz vernünftige Voreinstellungen, so dass man nur etwa ein Dutzend Register programmieren muss. Wenn du Fragen zu bestimmten Registern hast, zoegere nicht sie hier zu stellen. Ich arbeite jetzt schon 5 Jahre mit den Teilen.


    3. Python Sketch schreiben.


    4. Testen...


    Groundplane.

    Ja, das ist der englische Fachausdruck für Massefläche. Nur wirds davon nicht besser, das Groundplane des RFM69 ist für 433 MHz viel zu klein um damit eine vernünftige Whip-Antenne zu bauen.

  • Ich nutze auch keine time.sleep Befehle, sondern einen Dummy-Befehl "Variable = 1" in einer While Schleife, die ständig wieder den Pin Status abgreift (man muss eben mindestens einen Befehl in einer while Schleife haben). Das sorgt für eine hohe CPU-Auslastung, aber man kann sich relativ sicher sein, das die Abfrage oft genug durchläuft.

    Hier unterliegst Du einem Irrtum. Es mag vielleicht zunächst den Anschein haben, daß eine stabilere Kommunikation stattfindet, unter Last wirst Du aber gleichsam eine gestörte Kommunikation verzeichnen. An der Threadpriorität ändert sich durch die While-Schleife nämlich gar nichts, Lediglich den per Sleep aktiv provozierten Jitter des über den Befehl ausgelösten Schedulingprozesses hast Du vermieden. Läuft der Thread als nicht RT_Thread, dann werden Threads der RT-Policy ihn weiterhin unterbrechen. Läuft der Thread als RT_Thread, dann provozierst Du bei den Desktopkerneln sogar einen Zwangsaussetzer aufgrund der Einstellungen von sched_rt_runtime_us und sched_rt_period_us. Ich hatte dazu >>> hier <<< mal etwas geschrieben.