Hello.
I am building a wireless control handset that is using a nRF24 to communicate to the base station. This is all based on Robin2's tutorials.
I've just found a bug and can't figure out what is going on. When the handset is first powered on, the last line of Setup calls a function to send a packet to the base station to confirm that it is powered and ready to go.
In doing some tests I had the serial monitor open on the base station and it would report whenever the radio was available, read the payload into a struct that matched what was transmitted and just dump the contents to the serial monitor. The first time I powered the handset I could see the incoming 'handshake'. But if I then power cycled the handset there was no message in the Serial Monitor to show the incoming handshake. I know the handshake does happen as the handset reports that the transmitted packet was acknowledged. If I power cycle the base station it picks up the handshake message again but only once. Any packets sent after come through and are displayed as expected.
In case there was something wrong with this function I changed the setup to just call my sendRF function. The behaviour of the handset didn't change. At one point I ended up calling my sendRF function twice in the setup, somehow this seems to fix the problem and both packets are shown on the base station when I power cycle the handset.
I don't understand why the base station would always acknowledge the packet but only show radio.available as true once no matter how many times I power cycled the handset when sending a single handshake but acknowledge the packet and show radio.available as true every time I send two packets in a handshake.
sendRF function
//Function to send RF message
void sendRF() {
bool rslt;
rslt = radio.write( &rf_sent_data, sizeof(rf_sent_data) ); //Store result of trying to send RF packet
if (rslt) {
if ( radio.isAckPayloadAvailable() ) {
//Packet sent sucessfully and Ack Payload received.
radio.read(&rf_received_data, sizeof(rf_received_data)); //Read Ack Payload into Struct
Debug_println(" RF Acknowledge");
#ifdef DEBUG
rfDump(); //Call function to dump CAN message to Serial for debugging.
#endif
idAck(); //ID and process the Ack payload.
} else {
//Packet sent sucessfully but no Ack Payload received.
Debug_println(" Acknowledge but no data ");
}
lastRecvTime = millis(); //Stores that last time an RF Ack was received.
} else {
//Packet failed to send
Debug_println(" Tx failed");
}
txPrevMillis = millis();
resetData();
}
Base station code (Stripped down to absolute basics for testing).
// SimpleRx - the slave or the receiver
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN 9
#define CSN_PIN 10
const byte thisSlaveAddress[5] = {'R','x','A','A','A'};
RF24 radio(CE_PIN, CSN_PIN);
//Data struct's for RF messages
//Struct for RF messages
struct RF_Data {
byte dlc; //How many data bytes are included in the message
byte opCode; //CBUS OpCode to ID the message type
byte dat1; //Data 1
byte dat2; //Data 2
byte dat3; //Data 3
byte dat4; //Data 4
byte dat5; //Data 5
byte dat6; //Data 6
byte dat7; //Data 7
byte dat8; //Data 8
};
RF_Data rf_sent_data;
RF_Data dataReceived;
bool newData = false;
//===========
void setup() {
Serial.begin(9600);
delay(1000);
Serial.println("SimpleRx Starting");
setupRF();
}
//Setup RF Module
void setupRF() {
radio.begin(); //Starting the radio communication
radio.setDataRate( RF24_250KBPS ); //Data Rate of transmission
radio.enableAckPayload(); //Enable the Ack payload to receive data from handset
radio.openReadingPipe(1, thisSlaveAddress);//Setting the address at which we will send the data
radio.setPALevel(RF24_PA_MAX); //You can set it as minimum or maximum depending on the distance between the transmitter and receiver.
//resetAck();
radio.writeAckPayload(1, &rf_sent_data, sizeof(rf_sent_data)); // pre-load data
radio.startListening();
}
//=============
void loop() {
getData();
showData();
}
//==============
void getData() {
if ( radio.available() ) {
radio.read( &dataReceived, sizeof(dataReceived) );
newData = true;
}
}
void showData() {
if (newData == true) {
Serial.println("Data received ");
newData = false;
}
}