Forum: Projekte & Code [STM32F4xx] NRF24L01+ Funkmodul Source Code


von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

dieser Code ist keine Lib und kann nicht direkt verwendet werden aber 
wer selbst mit dem Funkmodul NRF24L01+ arbeitet und dieses an einem 
STM32F4xxx betreibt (StdPeriphLibs), der wird vielleicht das ein oder 
andere nützlich finden. Es gibt eine ganze Menge Fallstricke beim 
NRF24L01+ aus China, denn Originale von Nordic sind kaum zu bekommen.

Der NRF24L01 hat kein voll statisches Design! Die SPI Baudrate muss aus 
unerklärlichen Gründen > 1 Mhz sein.

Wird eine Payload nicht abgeholt innerhalb einer "bestimmten Zeit" (bei 
mir > 1s) neigt der Chip dazu "einzufrieren", d.h. er liefert nur noch 
0x00. Obwohl er einen eigenen Quarz hat scheint die interne Statemachine 
ihre Zustände nicht dauerhaft und richtig halten zu können. Also Dinge 
wie: 1. Datensatz kommt. 2. Datensatz 1 Stunde später auslesen klappen 
nicht.

Funktion: Betrieb des Moduls als Receiver für einen externen Sensor, der 
Messwerte liefert.  Mein Code nutzt einen IRQ Pin, um die Payload 
abzuholen, der über EXTI1_IRQn an den NVIC angebunden ist.

Bei der SPI Routine ist eine Besonderheit: Der Befehl __DSB() ("Data 
Synchronization Barrier") befindet sich an mehreren Stellen. es hat sich 
in vielen Stunden Analysieren und Probieren herausgestellt, dass die 
Pipeline Struktur der CPU und die unterschiedlichen Busse für SPI und 
GPIO dazu führen können, dass die Befehle nicht zwingend in der 
Reihenfolge an der Hardware ankommen wie beabsichtigt. d.h. die SPI kann 
ggf. schon mit dem Clocken beginnen obwohl der GPIO CE noch gar nicht 
low ist, weil die Statemachine der CPU diesen noch gar nicht bearbeitet 
hat. Der GPIO Speed muss daher auf Fast gestellt werden. __DSB() 
schließt alle Memory Befehle ab.

Wenn es Fragen zum NRF24L01+ Modul gibt werde ich sie gerne beantworten, 
da ich mich schon sehr intensiv damit befasst habe.

Gruss,
Christian

von Christian J. (Gast)


Lesenswert?

Ich muss dazu sagen, dass meine Module weit weg von "stabil" sind und 
zwar alle die ich aus der Bucht bestellt habe. Es geschieht immer wieder 
und vorzugsweise wenn der Sender draußen liegt bei derzeit 2 Grad 
Celsius, dass sie sich "aufhängen", IRQ Pin geht high, nur noch Nullen 
kommen raus.
Oder einfach nur so direkt nach Start, obwohl sie zwischendurch ein paar 
Stunden liefen.

Zu dem Thema "Fu** fake chips" gibt einigen Lesestoff, der belegt, dass 
die originalen Nordic Chips, die das Stück ca 10 USD kosten auf Teufel 
komm raus verbilligt wurden, was letzlich eine Produktion ist, die 
direkt auf den Müll kann. Der Autor sagt schon richtig, dass das einigen 
Haarausfall bewirken kann bei Anwendern.

https://ncrmnt.org/2015/03/13/how-do-i-cost-optimize-nrf24l01/

Vor einigen Jahren haben wir in einem Industrie Design Funkmoule 
eingesetzt, das Stück für über 25 Euro. XBee. Die Dinger funktionieren, 
die zicken nicht rum, die hängen sich nicht auf, sie gehen einfach über 
den gesamten Temperaturbereich.

Aber für < 1 Euro (ich habe für 10 Stück 8 Euro bezahlt) kann man das 
wohl nicht erwarten...

Denn die originalen Chips liegen da doch deutlichst drüber:

https://www.sparkfun.com/products/691

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Anbei ein geprüfter, voll lauffähiger Code, der auch die Möglichkeit 
bietet eine bidirektionale Kommunikation aufzubauen, indem dem PTX Modul 
per ACK Payload Rückinfo gesendet werden. In meinem Fall wird einem an 
der Außenmauer befindlichen Sensor mit Batterieversorgung von der 
Basisstation, je nach deren Batteriezustand mehr oder weniger 
Stromsparen aufgedrückt. Die Kommunikation ist geprüft vom STM32 gegen 
die MIRF Library von maniacbug für den Arduino pro Mini. Ich hänge daher 
die Arduino Routine mit an, je nachdem wer da Problem hat kann sich da 
draus ja vielleicht was abschauen.

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Anbei die Weiterentwicklung, diesmal aber auf dem STM32F103 und der 
StdPeriphLibs. Der CPU M3 Kern spielt nur soweit eine Rolle, wie die Low 
Level Routinen ganz unten im DRV Modul angepasst werden müssen an die 
Hardware. Das Modul DRV ist das Treiber Interface auf das eigene Apps 
aufgesetzt werden können. Als Beispiel dient die Interrupt Routine, die 
die Daten entgegen nimmt und anwendungspezifisch einsortiert.

Ich habe die Routinen sehr fein granuliert, damit die Flexibiltät 
erhalten bleibt. Es sind nahezu alle sinnvollen Funktionen des NRF24L01 
gekapselt aber nur der Enhanced Burst Mode mit Dynamic Payload Size, da 
dieser maximale Möglichkeiten bietet und ebenfalls nur der Mode mit ACK 
der Gegenstation, wahlweise mit oder ohne Payload. "Blindes Senden" ist 
witzlos.

Die RF_Configure stellt das Modul auf eine Grundeinstellung mit der man 
arbeiten kann, alles weitere muss dann ggf. "überschrieben" werden.

Eine Universal Library ist nicht mein Ziel, gewisse Dinge wie Pins usw 
müssen manuell angepasst werden, damit es kein unleserliches #ifdef Grab 
wird. Auch sind die Routinen nicht in jeder Hinsicht Fehlersicher, da 
das den Code aufblähen würde, man muss wissen was man aufruft und was 
vorher aufgerufen werden muss. Eine Einarbeitung in das Datenblatt des 
RF24L01 ist unerlässlich, der STM32Fxxx ist kein Arduino und das RF24L01 
kann durchaus als komplex bezeichnet werden.

Das RF24L01+ hat gegenüber den RFM12B usw. den Vorteil, dass man sich 
nicht mit Filtern, LNA Gains und typischen HF Geschichten auskennen 
muss. Es kann als rein digitale Einheit gesehen werden.

Wichtig: Die "Adressen" (5 Byte) der Module sind KEINESFALLS beliebig 
wählbar. Nimmt man die falschen, gibt es massenweise Fehlempfänge. Die 
Adressen müssen "Manchester konform" sein, eine abwechselnde 0-1 Sequenz 
haben.

Zu den Reichweiten: Die antennenlosen Module sind ausschließlich für 
eine "Hausautomation" geeignet, nach ca 30m ist Schluss. Mit der 100mW 
Variante habe ich aber bereits 500m Freifeld erreicht!

Wie man die Reichweite steigern kann ist hier beschrieben:
http://hackaday.com/2015/08/15/hacking-a-nrf24l01-radio-for-longer-range/

Init ist einfach
1
 /* Das Funkmodul testen */
2
   if (RF_Available()!=SUCCESS)
3
       while (1);
4
   RF_Configure();                   // Funkmodul konfigurieren
5
   RF_Init_Handler();

Compilert sind sie ca 2kb gross.

von Mehmet K. (mkmk)


Lesenswert?

Christian J. schrieb:
> Wichtig: Die "Adressen" (5 Byte) der Module sind KEINESFALLS beliebig
> wählbar.

Als Nachrag dazu: 
https://www.nordicsemi.com/eng/Nordic-FAQ/Silicon-Products/nRF24L01/How-to-choose-an-address

How to choose an address?
(...)
Quick summary:
Use at least 32bit address and enable 16bit CRC.
Avoid addresses that start with 0x00, 0x55, 0xAA and 0xFF

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.