Hello,
I hope the wizards here can stomach another nRF24L01 question. I have read numerous forum posts here and elsewhere, and the Nordic datasheet, and spent days tinkering, and now I have no hair left because I've pulled it all out.
I have an Arduino ("Master") which communicates via nRF24L01 link with two Arduino "slave" units. Each slave will gather data from local sensors. In response to a once-per-minute single character request from the master, each slave will send its data package: first slave A, then slave B. (The master Arduino itself is controlled by the "real" master, a RasPi which is connected to it by a wired serial link.)
Master code:
<
/*Dual telemetry master transmitter v.2 --> filename transmitter-12*/
#include "RF24.h"
RF24 radio(9, 10);
const byte slaveAddress[2][5] = {
{'R', 'x', 'A', 'A', 'A'},
{'R', 'x', 'A', 'A', 'B'}
};
struct dataStruct {
char id;
float t1;
float t2;
float t3;
} payload;
void setup() {
Serial1.begin(9600);
Serial1.println(F("*** Master starting v.12***"));
radio.begin();
delay(1000);
radio.setPALevel(RF24_PA_HIGH);
radio.setDataRate( RF24_250KBPS );
radio.setRetries(10, 15); // delay, count
}
void loop() {
if (Serial1.available()) {
int command = Serial1.read();
radio.stopListening();
if (command == 'A') {
Serial1.println(F("Req receiver A"));
radio.openReadingPipe(1, slaveAddress[0]);
radio.openWritingPipe(slaveAddress[0]);
radio.write( &command, sizeof(command));
} else if (command == 'B') {
Serial1.println(F("Req receiver B"));
radio.openReadingPipe(1, slaveAddress[1]);
radio.openWritingPipe(slaveAddress[1]);
radio.write( &command, sizeof(command));
}
radio.startListening();
delay(100); //Allow time for slave to respond
if ( !radio.available() ) {
Serial1.print(F("No response"));
} else {
radio.read( &payload, sizeof(payload) );
Serial1.print(F("Command recd: "));
Serial1.println(command);
Serial1.println(payload.id);
Serial1.println(payload.t1, 2);
Serial1.println(payload.t2, 2);
Serial1.println(payload.t3, 1);
}
}
} // main loop
Slave A code:
<
/*Dual telemetery slave receiver, v.2, unit A --->filename receiver-12a*/
#include "RF24.h"
RF24 radio(9, 10); //CE and CSN pins to Arduino pins 9 and 10
const byte slaveAddress[5] = {'R', 'x', 'A', 'A', 'A'};
struct dataStruct {
char id = 'A';
float t1 = 1.23;
float t2 = 3.14;
float t3 = 6.89;
} payload;
char command;
int SIG_LED = 3; //Arduino pin for signal LED
void setup() {
pinMode(SIG_LED, OUTPUT);
digitalWrite(SIG_LED, LOW);
radio.begin();
radio.setPALevel(RF24_PA_LOW); //options MIN LOW HIGH MAX
radio.setDataRate( RF24_250KBPS );
radio.setRetries(3, 10); // delay, count
radio.openWritingPipe(slaveAddress);
radio.openReadingPipe(1, slaveAddress);
radio.startListening();
}
void loop() {
if ( radio.available()) {
while (radio.available()) {
radio.read( &command, sizeof(command) );
}
if (command == 'A') {
radio.stopListening();
signal_send(); //flash LED three times as signal that the slave is sending data pkg
radio.write( &payload, sizeof(payload) );
radio.startListening();
}
}
} // Loop
void blink_led(int ms) {
digitalWrite(SIG_LED, HIGH);
delay(ms);
digitalWrite(SIG_LED, LOW);
}
void signal_send() {
blink_led(10);
delay(100);
blink_led(10);
delay(100);
blink_led(10);
}
(Slave B code is the same except for the address, which is {'R', 'x', 'A', 'A', 'B'}
The routines above work... sort of. But there are peculiarities to the operation which demonstrate beyond doubt that there is some aspect(s) of the nRF radio operation (or the library routines) of which I am completely ignorant. To illustrate by a sequence of events:
First data request "A" sent --> slave unit A flashes but no data response is rec'd
Second data request "A" sent --> slave A flashes and correct data rec'd at master
Subsequent "A" data requests --> slave A flashes and correct data rec'd
Request "B" sent --> slave B flashes but data from A received at master
Second and subsequent "B" requests --> B flashes and correct data rec'd
Request "X" sent --> no flash, but data from B received!
Second and subsequent "X" requests --> no flashes and nothing received.
In other words, it appears that data packages are cached somewhere. The returned data package is always one request "behind."
I can accommodate this cryptic behavior via the Python script, by simply sending a dummy request, ignoring the returned data, then sending the "real" request. But I don't want to do this because I don't understand what's going on, and IME routines which just happen to work despite fundamental misunderstanding of their operation are likely to blow up at inopportune times.
Any help?
(Thanks to Robin2, BTW, for the excellent tutorial which got me up and running on a single master/slave system which works like a champ.)
Thanks....!!
Steve