I'm trying to create an instant messenger using arduino, NRF24L01 chip and the library RF24 by TMRH20. It's designed for 2 arduino board.
here's the problem with my messenger : most of the time, the receiver doesn't receive the message, and sometime he receive it but everything is mixed up, like a bad encoding error...
here is the code: http://pastebin.com/TP53VyeH
to try it you need 2 arduino board, plugged on 2 different usb port. For one of the board, you have to change the number on line 10.
ps : on my station, if I try the "GettingStarted_HandlingData", everything work fine, so the problem isn't my arduinos...
You are grabbing the data directly into a String object, not its buffer.
radio.read( &message, sizeof(message) );
This is bad, as not only is the String class about 6 bytes long, you have overwritten the bytes that store the pointer to its buffer. So when you read the String, its pointer is now located in some arbitrary location. You will be reading whatever is there and this could be other variables, registers, and even GPIO pins. (your application could be very corrupt at this point).
You need to use a character buffer.
EDIT:
it seems that the message get cut after 32 character, and not 50... No idea why. I tried replacing 50 with 200, and the message still get cut after 32 character.
You should use radio.getPayloadSize()
to ensure your data can receive the largest packet possible. Also, if you need to send larger amounts of data, or want to send smaller packets you can use radio.setPayloadSize()
. However, there is a maximum of 32 bytes.
radio.startListening();
char buffer[ radio.getPayloadSize() ]; //Note: an array like this is a GCC extension, not standard C++
if(radio.available()) {
radio.read( &buffer, radio.getPayloadSize() );
}
message = buffer; //Not really needed, you can just use the buffer.
Using a loop doesn't seem right, the radio.available()
is if a whole packet is received. Looping here would only discard all but the last packet. You should maybe loop the whole receive side (after radio.startListening();
) so you can print/process each packet as they come in.
You can't really use a String object as it does not recognize the new data (its length will not update if you use its internal buffer directly). I have a patch I'm trying to get merged into the core at the moment, that would allow something like this:
message.buffer( radio.getPayloadSize() );
radio.read( message.c_str(), radio.getPayloadSize() );
message.validate(); //Allow String to detect new contents (Not in the core yet).
I will however post this question as another reason why it would be a good addition.