Arduino Uno NRF24L01+ Test Code
--------------------------------
(c) NRFTestGuy 07'2016
Free for private non-commercial usage.
Also works with the Windows App NRF24_Tester
available here:
Beitrag "NRF24L01 - Testprogramm für Windows PC"
Prerequisites
---------------
- Arduino Uno (Arduino Micro, Arduino Nano)
must be set up to run at 16 MHz
The Arduino as a board is not absolutely required. You can
use a naked ATMega328p running at 16 MHz with RS232
connection to your computer. Just use the port pins PB0-PB5
(as documented in the Fritzing schematic) and the RX/TX
lines.
- USB Connection to Arduino's USB Port
- NRF24L01+ wired to the Arduino (see Fritzing schematic)
- A Terminal Application on your PC
(connect at baud rate 115200 baud, 8 bit, 1 stop, no parity)
- A Programmer (such as AVRDude) to put the HEX file via USB
connection on your Arduino
- program the hex file in your ATMega328
This is how the terminal output should look like:
Arduino Uno - NRF24L01+ Test
Version 0.10 (c) NRFTestGuy
(Build xxx xx xxxx xx:xx:xx)
-----------------------------------
T: Transmit Data
R: Receive Data
F: Fast Transmit
G: Fast Receive
L: NRF24 Loopback Test
O: Continuous Loopback Test
S: Show Parameters
A: Required Pin Assignments
config:0x2D status:0x0E mem:127
-----------------------------------
>
...also ein SPI-RS232-USB-VirtualCom Konverter mit Funktionsgarantie für
NRF24. Interessant. Funktioniert das auch performant mit 1Mbit und
2Mbit? HW/Handshake beim RS232?
Lars R. schrieb:> ...also ein SPI-RS232-USB-VirtualCom Konverter
Nein. Ein Arduino (Mega328-) Code zur prinzipiellen Funktions-
überprüfung. Man lese den Titel (--> Test Program)
Lars R. schrieb:> mit Funktionsgarantie für NRF24.
Willst du ein Zertifikat?
Lars R. schrieb:> Funktioniert das auch performant mit 1Mbit
Ja. Im Fast Mode werden Pakete nicht angezeigt sondern nur
ein minimalistischer Funktionsablauf gezeigt der das Senden/
Empfangen von Paketen bestätigt. Die Netto-Datenrate (payload)
liegt bei 1 Mbit etwa bei 1200 Paketen (a 32 Bytes) pro Sekunde.
Mit Arduino-Lib wird das wohl nicht so funktionieren.
Im nicht-fast Mode wird das empfangene Paket angezeigt. Durch
die Ausgabe via Terminal wird die Transfer-Rate heruntergebremst.
Lars R. schrieb:> und 2Mbit?
Nein weil Bitrate festverdrahtet ist auf 1 Mbit.
NRFTestGuy schrieb:> Lars R. schrieb:>> mit Funktionsgarantie für NRF24.>> Willst du ein Zertifikat?
Nein, so war das nicht gemeint.
> Lars R. schrieb:>> Funktioniert das auch performant mit 1Mbit>> Ja. Im Fast Mode werden Pakete nicht angezeigt sondern nur> ein minimalistischer Funktionsablauf gezeigt der das Senden/> Empfangen von Paketen bestätigt. Die Netto-Datenrate (payload)> liegt bei 1 Mbit etwa bei 1200 Paketen (a 32 Bytes) pro Sekunde.> Mit Arduino-Lib wird das wohl nicht so funktionieren.
Ein Mehrwert (der ursprünglich nicht von Dir absichtigt war), entsteht,
wenn man das NRF24 komfortabel über UART oder virtualCOM konfigurieren
kann und dann eine transparente UART-Verbindung hat. Wobei die
Verbindung auch nicht komplett transparent sein braucht; nur so, dass
man auf einfache Weise eine Datenverarbeitung anbinden kann.
2Mbit müssen es für mich nicht sein, aber weniger als 1MBit Over-the-air
ist für manche Anwendungen zu wenig. Da geringen Datenraten sind dann
die RFM performanter.
> Lars R. schrieb:>> und 2Mbit?>> Nein weil Bitrate festverdrahtet ist auf 1 Mbit.
Wo? Bei der Beschaltung des nrf24?
Lars R. schrieb:> Wo? Bei der Beschaltung des nrf24?
Auch eine Software kann "festverdrahtet" sein. Im Gegensatz
zu konfigurierbar oder parametrisierbar.
Lars R. schrieb:> wenn man das NRF24 komfortabel über UART oder virtualCOM konfigurieren> kann und dann eine transparente UART-Verbindung hat.
Das war absolut nicht Sinn der Übung.
Du würdest sicherlich auch bei Kommunikation Wert darauf legen
einen zuverlässigen Partner jederzeit zur Verfügung zu haben.
Dieses Stück Programm erfüllt genau diesen Anspruch.
..."fest kodiert", um Verwirrungen vorzubeugen; gerade bei HW-bezogenen
Projekten.
...schon klar, wie geschrieben. Ich wollte nur noch einen anderen Weg
aufzeigen. Wie im anderen Thread bereits geschrieben wurde: Wenn man
sich für die Nutzung eines NRF24 selbst in das NRF24 einarbeiten muss,
weil Dein Projekt für die Nutzung nicht vorgesehen ist, dann braucht man
Dein Projekt auch nicht, weil man sich ohnehin selbst einarbeiten muss.
Natürlich war das Projekt sinnvoll für Dich. Nur, wenn die
Projekteigenschaften derart sind, dass dieses Projekt nur für Dich einen
Vorteil hatte und haben kann und dies auch so bleiben soll, so stellt
sich die Frage, warum Du das Material dazu hier überhaupt online und zur
Diskussion stellst. Vielleicht ist mir das entgangen. Etwa für den Fall,
dass man ein paar NRF24 herumliegen hat, sich nicht einarbeiten will,
weil man ohnehin die Nutzung nicht plant, aber trotzdem mal schauen
will, ob sie noch funktionieren?
Lars R. schrieb:> so stellt> sich die Frage, warum Du das Material dazu hier überhaupt online> und zur Diskussion stellst
Ich stelle es zur Verfügung. Zur Diskussion stelle ich es nicht,
(wo wäre diese Bemerkung zu finden?) habe nicht dazu aufgerufen,
habe aber auch nichts dagegen.
Hier zwei Beispiel-Aufbauten welche einwandfrei funktionieren
(entsprechend der Eingangs gezeigten Schaltung).
Hervorzuheben wären die jeweils vorhandenen Abblock-
Kondensatoren die den NRF24 erst auf den Arduinos
funktionssicher machen. Man darf sich keinesfalls alleine auf
die Stabilisierung und Entstörung der Versorgung von den
Arduinos zum NRF24 hin verlassen.
Diese Aussage mag nur teilweise zutreffen da es bekanntlich
eine grosse Auswahl von mehr oder weniger verschieden
hergestellten Arduinos gibt (Bauteil- bzw Layout-Streuungen).
Aber zwei zusätzliche Kondensatoren kosten nichts und geben
die Sicherheit dass an dieser Stelle nichts im Argen liegt.
NRFTestGuy schrieb:> Im nicht-fast Mode wird das empfangene Paket angezeigt. Durch> die Ausgabe via Terminal wird die Transfer-Rate heruntergebremst.
Darf ich noch einmal darauf zurück kommen?
Auf welchen Wert wird die Transfer-Rate bei Ausgabe via Terminal aktuell
heruntergebremst?
Kannst Du abschätzen, was mit Deinem Design mit einem STM32-Arduino
(32Bit, 72MHz, HW-SPI) möglich ist?
> Ja. Im Fast Mode werden Pakete nicht angezeigt sondern nur> ein minimalistischer Funktionsablauf gezeigt der das Senden/> Empfangen von Paketen bestätigt. Die Netto-Datenrate (payload)> liegt bei 1 Mbit etwa bei 1200 Paketen (a 32 Bytes) pro Sekunde.
1200*32*8=0.3Mbit Ist diesbezüglich trotz deaktivierter Terminalausgabe
das Bottleneck der ATMega328p?
Lars R. schrieb:> Darf ich noch einmal darauf zurück kommen?
Ja sicher.
Lars R. schrieb:> Auf welchen Wert wird die Transfer-Rate bei Ausgabe via Terminal aktuell> heruntergebremst?
Das ist nicht relevant, auch schlecht messbar. Dahingehend habe
ich nichts optimiert, daher ist ein Rückschluss auf das maximal
Mögliche nicht ermittelbar.
Lars R. schrieb:> Kannst Du abschätzen, was mit Deinem Design mit einem STM32-Arduino> (32Bit, 72MHz, HW-SPI) möglich ist?NRFTestGuy schrieb:> Die Netto-Datenrate (payload)> liegt bei 1 Mbit etwa bei 1200 Paketen (a 32 Bytes) pro Sekunde.
Das trifft es schon ganz gut. Die Begrenzung liegt an der SPI
Datenrate mit der man den NRF speisen darf. Und die liegt zufällig
bei den 8...10 MBit/s die ein AVR kann.
Eine leichte Verbesserung wird man noch mit SPI-DMA auf einem ARM
erreichen können, und das "Umkopieren" des Datenblocks mag auch
noch etwas schneller vonstatten gehen. Also alles in allem
vielleicht 1500-2000 Pakete/s .....
Lars R. schrieb:> 1200*32*8=0.3Mbit
So darf man nicht rechnen, denn der Overhead den der NRF braucht
ist enorm (siehe Timing-Diagramme). Und man darf nicht übersehen
dass bei jedem Paket ein Acknowledge dabei ist, eine Garantie dass
die Daten korrekt, fehlerfrei angekommen sind. Wenn man das nicht
braucht geht es ohne Ack nochmal schneller.
Lars R. schrieb:> mit Deinem Design
hat das nicht viel zu tun (ich schliesse ja den NRF auch nur an
das SPI an) ausser dass ich schon immer Speed wollte und ich
dahingehend vielleicht etwas "optimierend" arbeite, keine
Arduino-Lib auch nur anrühre ...
NRFTestGuy schrieb:> Eine leichte Verbesserung wird man noch mit SPI-DMA auf einem ARM> erreichen können, und das "Umkopieren" des Datenblocks mag auch> noch etwas schneller vonstatten gehen. Also alles in allem> vielleicht 1500-2000 Pakete/s .....>> Lars R. schrieb:>> 1200*32*8=0.3Mbit>> So darf man nicht rechnen, denn der Overhead den der NRF braucht> ist enorm (siehe Timing-Diagramme). Und man darf nicht übersehen> dass bei jedem Paket ein Acknowledge dabei ist, eine Garantie dass> die Daten korrekt, fehlerfrei angekommen sind. Wenn man das nicht> braucht geht es ohne Ack nochmal schneller.
Das hatte ich nicht bedacht, weil ACK für mich nicht wichtig ist. Ja, es
ist dann schon performant wenn 1500-2000 Pakete mit ACK übertragen
werden und ohne ACK mehr.
Um mal zu sehen was beim NRF24 theoretisch "geht" hier
eine Abschätzung zur Datenrate:
Ein gesamtes Paket besteht aus
Preamble 1
Address 5
Packet control field 2 (9 bit, unklar)
Payload 32
CRC 2
---------------
Summe 42 Bytes
42 x 8 = 336 bits
336 bits @ 1MBit/s --> 336 usec
wenn man annimmt dass die Codierung auf dem HF-Träger nicht
redundand ist.
Hinzu kommt eine interne Verarbeitungszeit der Maschine
für ein Paket die offensichtlich fest 130usec dauert.
Das Mindeste für einen ACK-Transfer von 32 Bytes bei
1MBit/sec wären also 466usec, Overhead des Mikrocontrollers
nicht mitgerechnet.
Zurückgerechnet auf die maximal mögliche Datenrate wären
das 2145 Blöcke/s (à 32 Bytes netto ergibt 68640 Bytes/s)
rein bezogen auf das was der NRF24 zu leisten vermag.
Bei 2 MBit/sec kann man das nochmal etwas schneller werden
aber die 130usec Verarbeitungszeit bleiben wohl fest.
Für Das "Abholen" (oder Senden) eines Blocks mit dem
Mikrokontroller (beschränkt durch die SPI Datenrate 10MBit/sec
des NRF24) wären dann noch mindestens 25usec zusätzlich
erforderlich. Nehmen wir mal für SPI Kommandierung und
Interrupt-Latenz noch 5usec dazu ergibt das für ein gesamtes
Paket 466+30usec = 496usec oder umgerechnet 2016 Blöcke/s
(ergibt eine Netto-Datenrate von gut 64 KBytes pro Sekunde).
Falls ich etwas nicht richtig betrachtet habe korrigiert mich.
In Deiner Kalkulation habe ich keinen Rechenfehler gefunden.
Falls man jedoch die Shockburst-Features und ACK nicht benötigt, so ist
die minimale Packetgröße:
Preamble 1
Address 3
Payload 32
============
36 Byte = 288Bit
http://yveaux.blogspot.de/2014/07/nrf24l01-sniffer-part-1.html
Mit Shockburst und ACK in Bits:
Preamble 8 (1 Byte)
Address 24 (3 Byte)
Packet control field 9
Payload 256 (32Byte)
CRC 8 (1 Byte)
---------------
305 Bits
Die Variante ohne Shockburst finde ich nicht deshalb interessant, um
die letzten Prozente an Performanz heraus zu holen, sondern weil man
ohne Shockburst auch Pakete mit fehlerhaftem CRC empfangen kann.
Lars R. schrieb:> sondern weil man> ohne Shockburst auch Pakete mit fehlerhaftem CRC empfangen kann.
An welche Anwendung (mit ohne ACK) denkst du da?
Mir fällt da momentan nur Audio Streaming ein wo es nicht auf
das letzte Bit ankommt, oder Nahfeld-Kommunikation beliebiger
Art wo die Übertragung an sich sowieso sicher(er) ist.
Mir leuchtet nicht so recht ein was man mit geschrotteten
Empfangspaketen machen kann .....
Hier wurde mit dem ESP8266 erwartungsgemäß gemessen und visualisiert,
dass der Empfang von 2.4GHz-Signalen je nach Umgebung (die sich ggf auch
noch verändert) lokal stark schwankt:
https://youtu.be/aqqEYz38ens?list=PLDRymMFQl3Nktk_pjlUP_wbLIXre3sody&t=168
Eine Antenne kann zu einem Zeitpunkt aber immer nur an einer Stelle
sein...
Lars R. schrieb:> Daher der Wunsch nach einem UART-Umsetzer.
Nimmst du die Arduino-Lib und schreibst deinen "Dreizeiler"
zum Kommunizieren mit der RS232.
NRFTestGuy schrieb:> Lars R. schrieb:>> Daher der Wunsch nach einem UART-Umsetzer.>> Nimmst du die Arduino-Lib und schreibst deinen "Dreizeiler"> zum Kommunizieren mit der RS232.
Diesbezüglich ergeben sich Fragen:
Ist die Lib für den Betrieb ohne Shockburst vorgesehen?
Ist die Lib auch performant genug und holt wirklich jedes Paket aus dem
NRF?
Nutzt sie dafür den IRQ?
Gibt es diesbezüglich Stolpersteine mit dem Arduino, die eine hohen
Durchsatz verhindern können? (Habe noch nichts mit Arduino gemacht)
Am Besten ist wohl der Betrieb am STM32-Arduino für 2,50EUR von Ebay?
Wahrscheinlich benötige ich auch noch eine einmalige Synchronisation
zwischen den Empfangern.
Mein Eindruck war, dass es mit einem "Dreizeiler" nicht getan ist. Daher
habe ich das erst einmal liegen lassen.
Lars R. schrieb:> Diesbezüglich ergeben sich Fragen:
.... die ich dir nicht beantworten kann, die sich aber
durch ein Studium der (offenen) Quellen und der Arduino-API
klären lassen können.
Lars R. schrieb:> Mein Eindruck war, dass es mit einem "Dreizeiler" nicht getan ist.
Dafür habe ich ja auch nicht Dreizeiler geschrieben sondern
"Dreizeiler".
Bei der Arduino Gemeinde ist alles immer soooooooo einfach .....
Eben deshalb. Die Lib ist dafür nicht vorgesehen. Es geht nicht mit
einem Dreizeiler und auch nicht mit einem "Dreizeiler" ;)
Achso. Oder meintest Du die ganze Aussage ironisch? Falls ja, dann
Zustimmung.
Du wirst mit RS232-Umsetzung vermutlich sowieso nicht die
"Performanz" (gibt's das?), Performance herausholen können
die du dir wünschst.
Nicht einmal mit einem FT2232 der direkt SPI könnte, denn
das USB Protokoll lässt nur einzelne Transfers (mehrere
Kommandos + IRQ Polling + 1 Nutzdatenblock) im 1ms-Zeitraster
zu die die ganze Kommunikation stark ausbremsen.
Alles selbst schon durchgemacht. Deshalb habe ich diesen
Ansatz schon mal nicht umgesetzt, nicht zuletzt wegen des
Aufwands ein Testinterface mit FT2232 aufzubauen.
NRFTestGuy schrieb:> Du wirst mit RS232-Umsetzung vermutlich sowieso nicht die> "Performanz" (gibt's das?), Performance herausholen können> die du dir wünschst.>> Nicht einmal mit einem FT2232 der direkt SPI könnte, denn> das USB Protokoll lässt nur einzelne Transfers (mehrere> Kommandos + IRQ Polling + 1 Nutzdatenblock) im 1ms-Zeitraster> zu die die ganze Kommunikation stark ausbremsen.>> Alles selbst schon durchgemacht. Deshalb habe ich diesen> Ansatz schon mal nicht umgesetzt, nicht zuletzt wegen des> Aufwands ein Testinterface mit FT2232 aufzubauen.
Da sehe ich kein Problem, zumindest nicht beim Empfangen. Die Daten
landen im Buffer. Beim Senden kann es sein, das man mit dem Schreiben
von lediglich 32Byte nicht die volle Performance erzielt. Aber dazu gibt
es Optionen im Treiber. Vielleicht könnte man ja auch mehrere Pakete auf
einmal schicken? Ein paar Byte SRAM hat der uC schließlich auch.
Der Ablauf wäre wie folgt:
PC sendet "C" (oder ähnliches): Es folgen Konfigurationsdaten
PC sendet "T": Es folgen 32 Byte Daten
Idealerweise hat der uC HW-Handshake für UART. Dieses kann man am PC
auswerten. Falls der uC kein Handshake hat (AtMega), so müsste der uC
jedesmal ein "R" für Ready schicken.
Alternativ legt man fest, dass der uC eine bestimmte Menge Daten pro
Zeit auf jeden Fall vom PC empfangen und über NRF24 wegsenden kann.
Beim Empfänger würde der uC einfach alles auf den UART schreiben. Der PC
muss es eben schnell genug aus dem Buffer holen. Das sollte bei diesen
Transferraten passen. (Auch hier bestünde zusätzlich die Möglichkeit für
Handshake, wenn es der uC könnte. Ich denke jedoch, dass es auch ohne
geht)
USB->SPI->NRF24 sehe ich auch nicht.
Anmerkung:
Die Idee, dass der uC dem PC jede Übertragung mir "R" bestätigt, wird
wohl nix.
Aber selbst ohne hardware-Handshake-Funktionalität könnte der uC die
entsprechende Handshake-Leitung des USB-Uart-Interfaces über einen IO
schalten, wenn sein Buffer fast voll ist und er mit dem Wegsenden der
Daten über das NRF24 nicht hinterher kommt.
NRFTestGuy schrieb:> Lothar schrieb:>> Ja.>> Mach ich aber nicht. Kannst du dir bei Nordic selbst abholen.> NRFTestGuy = Arduinoquäler
War nicht anders zu erwarten.