Guten Tag zusammen, ich will mit zwei Arduinos und zwei NRF24L01+ eine bidirektionale Funkübertragung realisieren. Für den Arduino und das Funkmodul gibt es schon folgende Funktionen: http://tmrh20.github.io/RF24/classRF24.html Die einseitige Übertragung funktioniert auch bereits. Allerdings schaffe ich es nicht, dass ein Modul "gleichzeitig" senden UND empfangen soll. Kann mir bitte jemand weiterhelfen? Ist es vielleicht möglich, dass mit verschiedenen Kanälen zu machen? Habe noch nicht ganz verstande, was es damit auf sich hat.
Das funktioniert nicht. Der Chip kann zur gleichen Zeit entweder senden oder empfangen. Du könntest dir ein zweites Funkmodul hernehmen um auf zwei Frequenzen zu funken. Aber brauchst du wirklich Full-Duplex?
Ich brauche nicht unbedingt full-duplex, also das gleichzeitige Senden und Empfangen von Daten. Aber ich würde gerne umschalten können, zwischen senden und empfangen. Die Funkmodule sind in einer Fernsteuerung und in einem Fahrzeug. Ich möchte die meiste Zeit mit der Fernsteuerung die Befehle versenden. Aber wenn ich eine bestimmte Taste drücke, dann soll die Akkuspannung vom Fahrzeug an die Fernsteuerung gesendet werden.
Das geht doch alles.... Die haben doch extra 6 Rohre, um miteinander quatschen zu können.
Nobody schrieb: > Das geht doch alles.... > Die haben doch extra 6 Rohre, um miteinander quatschen zu können. Aber wie lege ich fest, über welche pipe die miteinander kommunzieren sollen? Bei den Befehlen radio.write und radio.read kann ich leider nicht die pipe auswählen.
Du hast doch selber die Doku hier verlinkt! http://tmrh20.github.io/RF24/classRF24.html#a9edc910ccc1ffcff56814b08faca5535 http://tmrh20.github.io/RF24/classRF24.html#af2e409e62d49a23e372a70b904ae30e1
Nobody schrieb: > Du hast doch selber die Doku hier verlinkt! > http://tmrh20.github.io/RF24/classRF24.html#a9edc910ccc1ffcff56814b08faca5535 > http://tmrh20.github.io/RF24/classRF24.html#af2e409e62d49a23e372a70b904ae30e1 Damit öffne ich die pipes ja nur. Aber beim schreiben oder lesen kann ich diese nicht auswählen. Kann mir jemand sagen, warum das nicht funktioniert? Bevor ich die Taster drücke funktioniert die Übertragung, aber beim Wechseln in den anderen Modus gibt es Probleme. Oft hängt sich der arduino dann auf.
1 | #include <SPI.h> |
2 | #include <nRF24L01.h> |
3 | #include <RF24.h> |
4 | #define CE_PIN 9
|
5 | #define CSN_PIN 10
|
6 | |
7 | const uint64_t pipe = 0xE8E8F0F0E1LL; |
8 | const uint64_t pipe1 = 0xB3B4B5B6F1LL; |
9 | RF24 radio(CE_PIN, CSN_PIN); |
10 | LiquidCrystal lcd(2, 3, 4, 5, 6, 7); |
11 | int senden[2]; |
12 | int empfangen[2]; |
13 | int modus = 0; |
14 | |
15 | void setup() { |
16 | Serial.begin(9600); |
17 | radio.begin(); |
18 | lcd.begin(16, 2); |
19 | }
|
20 | |
21 | void loop() { |
22 | |
23 | |
24 | if (analogRead(A5) >= 30 && modus == 0){ |
25 | modus = 1; |
26 | delay(1000); |
27 | }
|
28 | if (analogRead(A5) >= 30 && modus == 1){ |
29 | modus = 0; |
30 | delay(1000); |
31 | }
|
32 | |
33 | if (modus == 0){ |
34 | radio.stopListening(); |
35 | radio.openWritingPipe(pipe); |
36 | senden[0]=99; |
37 | radio.write( senden, sizeof(senden) ); |
38 | }
|
39 | |
40 | if (modus == 1){ |
41 | radio.openReadingPipe(1,pipe1); |
42 | radio.startListening(); |
43 | radio.read( empfangen, sizeof(empfangen) ); |
44 | Serial.println(empfangen[0]); |
45 | }
|
46 | }
|
1 | #include <SPI.h> |
2 | #include <nRF24L01.h> |
3 | #include <RF24.h> |
4 | #include <LiquidCrystal.h> |
5 | #define CE_PIN 9
|
6 | #define CSN_PIN 10
|
7 | |
8 | const uint64_t pipe = 0xE8E8F0F0E1LL; |
9 | const uint64_t pipe1 = 0xB3B4B5B6F1LL; |
10 | RF24 radio(CE_PIN, CSN_PIN); |
11 | LiquidCrystal lcd(2, 3, 4, 5, 6, 7); |
12 | int senden[2]; |
13 | int empfangen[2]; |
14 | int modus = 0; |
15 | |
16 | |
17 | void setup() { |
18 | Serial.begin(9600); |
19 | radio.begin(); |
20 | lcd.begin(16, 2); |
21 | }
|
22 | |
23 | void loop() { |
24 | |
25 | if (analogRead(A5) >= 30 && modus == 0){ |
26 | modus = 1; |
27 | delay(1000); |
28 | }
|
29 | if (analogRead(A5) >= 30 && modus == 1){ |
30 | modus = 0; |
31 | delay(1000); |
32 | }
|
33 | |
34 | |
35 | Serial.println(modus); |
36 | if (modus == 1){ |
37 | radio.stopListening(); |
38 | radio.openWritingPipe(pipe1); |
39 | senden[0]=23; |
40 | radio.write( senden, sizeof(senden) ); |
41 | }
|
42 | |
43 | if (modus == 0){ |
44 | radio.openReadingPipe(1,pipe); |
45 | radio.startListening(); |
46 | radio.read( empfangen, sizeof(empfangen) ); |
47 | Serial.println(empfangen[0]); |
48 | }
|
49 | }
|
So sende ich Daten zum Roboter und wieder zurück zum ersten Arduino:
1 | #include <SPI.h> |
2 | #include "nRF24L01.h" |
3 | #include "RF24.h" |
4 | |
5 | #define CE_PIN 53 |
6 | #define CSN_PIN 48 |
7 | |
8 | byte inbyte1; |
9 | byte daten1[1]; |
10 | byte daten11[1]; |
11 | |
12 | byte inbyte2; |
13 | byte daten2[1]; |
14 | byte daten22[1]; |
15 | |
16 | RF24 radio(CE_PIN, CSN_PIN); |
17 | |
18 | const uint64_t pipes[2] = {0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL}; |
19 | const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"}; |
20 | typedef enum { role_ping_out = 1, role_pong_back } role_e; |
21 | |
22 | //role_e role = role_ping_out; // Breadboard |
23 | role_e role = role_pong_back; // Roboter |
24 | |
25 | void setup(void) |
26 | {
|
27 | Serial.begin(9600); |
28 | delay(500); |
29 | |
30 | radio.begin(); |
31 | radio.setRetries(15,15); |
32 | |
33 | radio.openReadingPipe(1,pipes[1]); |
34 | radio.startListening(); |
35 | //radio.printDetails(); |
36 | |
37 | if (role == role_ping_out) |
38 | {
|
39 | radio.openWritingPipe(pipes[0]); |
40 | radio.openReadingPipe(1,pipes[1]); |
41 | }
|
42 | |
43 | if ( role == role_pong_back ) |
44 | {
|
45 | radio.openWritingPipe(pipes[1]); |
46 | radio.openReadingPipe(1,pipes[0]); |
47 | }
|
48 | }
|
49 | |
50 | void loop(void) |
51 | {
|
52 | if (role == role_ping_out) |
53 | {
|
54 | inbyte1 = inbyte1+5; |
55 | daten1[0] = inbyte1; |
56 | radio.stopListening(); |
57 | radio.write( daten1, sizeof(daten1)); |
58 | radio.startListening(); |
59 | |
60 | unsigned long started_waiting_at = millis(); |
61 | bool timeout = false; |
62 | |
63 | while ( ! radio.available() && ! timeout ) |
64 | if (millis() - started_waiting_at > 200 ) |
65 | timeout = true; |
66 | |
67 | if ( timeout ) |
68 | {
|
69 | goto weiter; |
70 | }
|
71 | else
|
72 | {
|
73 | radio.read( daten11, sizeof(daten11) ); |
74 | Serial.print("daten11 = "); |
75 | Serial.println(daten11[0]); |
76 | delay(10); |
77 | }
|
78 | |
79 | weiter: |
80 | delay(500); |
81 | }
|
82 | |
83 | if ( role == role_pong_back ) |
84 | {
|
85 | if ( radio.available() ) |
86 | {
|
87 | unsigned long got_time; |
88 | bool done = false; |
89 | while (!done) |
90 | {
|
91 | done = radio.read( daten22, sizeof(daten22) ); |
92 | Serial.print("daten22 = "); |
93 | Serial.println(daten22[0]); |
94 | delay(10); |
95 | }
|
96 | |
97 | inbyte2 = inbyte2+1; |
98 | daten2[0] = inbyte2; |
99 | radio.stopListening(); |
100 | radio.write( daten2, sizeof(daten2)); |
101 | radio.startListening(); |
102 | }
|
103 | }
|
104 | }
|
So ist es für das Breadboard: --------------------------------------- role_e role = role_ping_out; // Breadboard //role_e role = role_pong_back; // Roboter --------------------------------------- Und so für den Roboter: --------------------------------------- //role_e role = role_ping_out; // Breadboard role_e role = role_pong_back; // Roboter --------------------------------------- Für beide das selbe Programm. Gruss
Das was ich bei mir fest vorgebe kannst du dann auch mit einem Taster wechseln. Kannst das Programm bei dir mal testen. Gruss
Ich werde es mal ausprobieren. Aber mit meinem Code funktioniert es auch, wenn ich den Modus in dem Code festlege. Aber wenn ich den Modus per Tastenabfrage festlage, dann gibt es ja eine kleine Zeitspanne, in welcher beide senden/ empfangen. Das ist glaub das Problem, denn das hängt er sich meistens auf.
Hallo allerseits, ich würde da eine völlig anderen Ansatz verfolgen. Wenn Du auf dem Rückkanal keine Echtzeit brauchst, kannst Du Dir die ganze Umschalterei sparen. Schau Dir mal die Funktionen EnableAutoAcknowledge in Verbindung mit EnableAcknowledgePayload an. Du hast die Möglichkeit, bei jedem Datentransfer vom Sender zum Empfänger mit dem AutoAcknowledge, das im Hintergrund automatisch geschieht, 32 Byte zurückzusenden, ohne dabei selbst aktiv die Sende-Empfangsrichtung umzuschalten. Damit kannst Du sogar weit mehr als nur die Akkuspannung messen, das ist die leichteste Übung. Du brauchst nur im Empfänger im entsprechenden Register die Akkuspannung regelmäßig zu aktualisieren, bei jedem Steuerbefehl den du sendest kommt der dann automatisch zurück, den mußt Du im Sender dann nur noch auslesen und auswerten. Gruß wv
wv schrieb: > Schau Dir mal die Funktionen EnableAutoAcknowledge in Verbindung > mit EnableAcknowledgePayload an. Du hast die Möglichkeit, bei jedem > Datentransfer vom Sender zum Empfänger mit dem AutoAcknowledge, das im > Hintergrund automatisch geschieht, 32 Byte zurückzusenden, ohne dabei > selbst aktiv die Sende-Empfangsrichtung umzuschalten. Hallo, meinst du die Funktionen enableAckPayload und setAutoAck ? Ich verstehe noch nicht ganz wie das funktionieren soll. Zunächst muss ich diese Funktion aktivieren und dann sendet es immer automatisch die 32 Byte zurück? Kann ich aber auch bestimmen, was mir zurückgeschickt wird? Und wie kann ich diese 32 Byte auslesen?
mompf schrieb: > Zunächst muss > ich diese Funktion aktivieren Ja > und dann sendet es immer automatisch die > 32 Byte zurück? So ist es. Und das Hin und Her wird so oft ausgeführt, bis beide Seiten zufrieden sind oder max Versuche vergangen sind. > Kann ich aber auch bestimmen, was mir zurückgeschickt > wird? Anders würde es keinen Sinn machen. > Und wie kann ich diese 32 Byte auslesen? In der RxPipe0 Da Datenblatt sagt dir alles. Fang mal mit der Register Beschreibung an (Stichwort AutoAck) und sieh dir die Befehlsliste an. Ich kenne die Arduino Lib nicht, fürchte aber, dass diese Funktionalität nicht drin ist. Da wirst du wohl selbst Hand anlegen müssen.
Vielleicht hilft dir das hier (jetzt oder später) weiter: https://shantamraj.wordpress.com/2014/07/19/exploring-the-auto-ack-feature-of-the-transceiver/ https://shantamraj.wordpress.com/2014/11/30/auto-ack-completely-fixed/
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.