Another NRF24L01 Sketch – string send/receive

In a previous post I described a very simple setup to send and receive data using the NRF24L01 breakouts that can be purchased (very!) inexpensively on eBay.  I wanted to show another sketch, using basically the same physical setup, to send and receive text from one arduino to another.  Forgive the mostly copy-and-paste nature of this post, if you are just looking for the code, scroll to the bottom.

You will need (hardware):
(2) nrf24L01 2.4ghz wireless transcievers
(2) Arduino Uno (or compatible)
Recommended: male-female jumpers for connecting nrf24L01 modules to Arduino

You will need (software):
Arduino IDE
RF24 libraries by maniacbug (https://github.com/maniacbug/RF24)

The image below shows the view of the nrf24L01 from the top.  Note: the pins are on the bottom-side.  The image shows the top-side.

This is what the breakout looks like from the top.
This is what the breakout looks like from the top.

For this sketch, both arduino boards will need to be setup like this:

fritzing drawing of nrf24l01 connections

fritzing drawing of nrf24l01 connections
closeup of nrf24l01 to arduino connections
closeup of nrf24l01 to arduino connections

Upload the send and receive sketches to corresponding Arduinos physically configured as above.  The sending unit will take a string and break it down into individual characters, then send each character until the end of the string is reached.  After that, it sends a ‘termination message’, in this case, the integer ‘2’.  This tells the receiving end that the message is complete.  The sending unit then powers down it’s radio for one second, then powers it back up and runs through the loop again.

You will see some comments in the code about this delay period causing some occasional lost data when sending.  I’m hoping someone with more experience with the nrf24 radios can comment on this and provide some code improvements, but this method seems to work well for the most part.  I have added an alternative receive-side sketch below that checks for a proper message length as a sort of ‘checksum’ function.

On the receiving end, the sketch begins listening for available messages.  Once it begins receiving characters, it begins appending them to the receive string.  It continues to append characters until it receives the termination character (again, the integer ‘2’ in this case, but you could set it to something else).  It then prints the complete string to serial.

There is a second version of the receive sketch (receive_string_withChecksum) that also checks the final string length against an expected message length.  If the actual received message length does not match the expected length, the string is rejected and the radio begins listening for a new message.  Obviously, this will only work if you expect a message of a certain fixed size every time.

 

25 thoughts on “Another NRF24L01 Sketch – string send/receive”

    1. I am getting same error on same line.

      “error: void value not ignored as it ought to be”
      on line: ” done = radio.read(msg, 1);”

      Any solution to this?

  1. Nice clean example! I have the same, it does not always transmit the whole string (i.e. losing some of the starting characters sometimes. Did you manage to fix that?

    thx,

    Leo

  2. I guess losing starting character is a timing issue

    if you add a delay(); after powerup .

    In my arduino , it never lost the “H” in this example ….

  3. in send …

    void loop(void){
    String theMessage = “Hello there!”;
    int messageSize = theMessage.length();
    radio.powerUp();
    delay(1);
    ………………
    ……………

    Before sends something …. powerup first ……

  4. Excellent and exactly what I was looking for. I’m fairly new to programming at more than a basic level.

    Could you please explain a few of the lines in the code of the receiver for me? Most of this makes sense to me and I have not found an explanation in the searches I’ve done.

    if (radio.available()){
    bool done = false;
    done = radio.read(msg, 1);

    I’m unclear as to most of the purpose of the lines 2 & 3.

    So, my questions are:
    ——————–
    Why is the array defined in the radio.read(msg, 1) function without an array element of [0] defined? Does it automatically assign index 0 the value if used without the brackets? Would this work on a larger array?
    ———————

    Why do we need to bother setting the “done” Boolean in this example?

    Does the radio.read(msg, 1) set the boolean variable to ‘TRUE’ and how does that help later in the sketch?

    would replacing:
    bool done = false;
    done = radio.read(msg, 1);

    with a single line after the if statement that said
    radio.read(msg,1);

    accomplish the same thing?

    ———————-

    Thanks in response for your reply.

    1. The first arg of the read() function is a pointer. The function place the content of the payload in this variable. The payload can be from 1 to 32 byte. So if you transmit 1 byte throught the nrf24l01 you will get your data at the begining of the pointer, and then in msg[0]. If the payload was 4 bytes, you will access to the differents bytes by masg[0], msg[1], msg[2] and msg[3].

      In case of the read() function gone wrong you will get a 0 value in your variable. But you don’t know if a problem happened. So, by reading the return value of the function, you are able to detect if this 0 value is the true value received by your nrf24l01.

  5. This sent and receive text all in one code.


    /*
    1) I am not English. so no comments needed about spelling
    2) IF you find error or improvement please email me.
    3) andre.witbank@gmail.com
    4) I found code at http://shanes.net/another-nrf24l01-sketch-string-sendreceive/

    */
    //Libraries needed
    #include
    #include
    #include
    #include

    /* 1 - GND
    2 - VCC 3.3V ONLY!!!
    3 - CE to Arduino pin 9
    4 - CSN to Arduino pin 10
    5 - SCK to Arduino pin 13
    6 - MOSI to Arduino pin 11
    7 - MISO to Arduino pin 12
    8 - NA
    This sketch receives and sent strings from nrf24
    and prints them out via serial.
    */
    int msg[1]; //Holding your sent message
    #define CE_PIN 9
    #define CSN_PIN 10
    RF24 radio(CE_PIN, CSN_PIN);
    // Radio pipe addresses for the 2 nodes to communicate.
    const uint64_t pipe = 0xE8E8F0F0E1LL;

    String theMessage = ""; //Received Message
    String inputString = ""; //Hold incoming Message from Serial

    void setup(void) {
    Serial.begin(57600);
    while (!Serial) {} //Needed for Leonardo
    radio.begin(); //Start the radio
    radio.setRetries(15, 15); // optionally, increase the delay between retries & # of retries
    radio.setPayloadSize(8);// optionally, reduce the payload size.
    radio.openWritingPipe(pipe);
    radio.openReadingPipe(1, pipe);
    radio.startListening();
    }

    void loop(void) {
    if (radio.available()) { //Wait for incoming message from radio
    receiveText(); //Call funtion to receive message
    }
    }

    void receiveText() {
    radio.read(msg, 1); //Read radio 1 char at a time
    char theChar = msg[0]; //Stor it in theChar
    if (msg[0] != 2) { //If you get \n char then
    theMessage.concat(theChar); //link all together
    }
    else { //If done then
    Serial.println(theMessage); //Print to serial
    theMessage = ""; //Clear Message
    }
    }
    //This is same as EXAMPLE CODE it just works this better. NO ERRORS
    void serialEvent() { //if something happens in serial do this
    while (Serial.available()) { //Do till you get all from serial
    char inChar = (char)Serial.read(); // get the new byte:
    delay(3); //*****I add this else you get broken messages******
    inputString += inChar;// add it to the inputString:
    }
    sentText(); //Call function to sent message to other radio
    }

    void sentText() {
    radio.stopListening(); // First, stop listening so we can talk.
    // String theMessage = inputString; //
    int messageSize = inputString.length(); //Calculate String length
    for (int i = 0; i < messageSize; i++) { //Sending 1 char at a time to other radio
    int charToSend[1]; //Hold the char to be send
    charToSend[0] = inputString.charAt(i); //First char stored
    bool ok = radio.write(charToSend, 1); //Sent char
    if (ok) //This is not needed but will make you feel better
    Serial.println("OK...");
    else
    Serial.println("ERROR...");
    }
    msg[0] = 2; //send the 'terminate string' value...
    radio.write(msg, 1);
    inputString = ""; // clear the string
    radio.startListening(); // Now, continue listening
    }

    1. If i may ask if you can explain pipe address. i still dont understand. how do you know which radio is talking? Only had it 2 days now.

      1. I can’t get this code to work. I am getting error
        error: name lookup of ‘i’ changed for ISO ‘for’ scoping [-fpermissive] (if you use ‘-fpermissive’ G++ will accept your code)
        name lookup of ‘i’ changed for ISO ‘for’ scoping [-fpermissive]
        .
        I have installed Arduino IDE 1.6.5. Can any one give some tips? I am new at this.

        Thanks for any advise

  6. Hi,

    If your getting intermittent data loss i.e. instead of receiving “Hello there!” you get “ello there!” then check the earthing to the crystal chassis. The best way to test is when the issue is occurring, take a small wire and hold it between ground and the crystal casing, this should resolve the issue.

    Regards,
    Ant

  7. Hi,

    After some advice as I am fairly new to the Arduino having mostly worked on the MSP430. This tutorial was very helpful and me and a friend have 2 Uno’s talking to each other very well.

    We have made a small sub-board (100n Cap on 3v3 rail) that the nRF24L01+ sits on, this is then placed in some breadboard and works well with the Unos. Then we tested this with 1 Uno and genuine Arduino Nano V3 wiring it in the same way using the small sub-board, but this fails to produce any form of communication.

    I will add we had also made a further board for the Nano with a separate 3v3 rail from a small L78L33 regulator for the nRF24L01+ with a common ground, but this also did not work, hence why we tried the basic breadboard test. I don’t think the 3v3 rail from the Nano is perfect and will probably cause transmission losses as Max 50mA, but there should be some form of communication even if intermittent.

    Any advice on this issue would be appreciated?

    Best regards,
    Ant

  8. Prints only:
    ello there!
    ello there!
    ello there!
    ello there!
    ello there!
    ello there!
    ello there!
    ello there!
    ello there!
    ello there!
    ello there!
    ello there!
    ello there!
    ello there!
    ello there!

    one char is everlost, some advice for me? please write me e-mail

  9. But, if i delete delay(1000) between radio power up/down then:

    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!
    Hello there!

    but it must be very quick, if isn’t first char is still lost

  10. GOT IT! Little help for all, who have problems with NRF24L01. If it have strange behaviour, i mean sometime work sometime not, lost packets annoying errors “No radio available” etc… TRY: add electrolytic capacitor between 3,3V and GND (I used first what i had handy and it was “47uF/16V”, also works with 1uF, 10uF and similar values). Wireless modules working now much much better. Happy development! ^_^

  11. Hello guys,

    i am working on the project where I am making a network4 nrf24l01 transceivers, such that one can broadcast the text message from one transceiver at the base station to all the other transceivers connected to it. After receiving the message, the transceiver should reply back to the base station in same manner.
    I am using 4 nrf24l01 and 4 Arduino Uno boards.
    Have you used RF24 Network library?
    I need your some guidance in the coding. What should be the code at base station and what could be the code at other node?
    Please help..It’s urgent!!!
    Thank you

Leave a Reply to Neil Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>