Talking to a USB nRF24L01

Finally identified (by stumbling across it) something associated with the unwanted truncation of ASCII strings sent FROM the Arduino/nrf24L01+ combination TO the USB CH340T/NRF24L01+ dongle transceiver.

Earlier, I mentioned that if I were to use the arduino to try send "abcdefghijklmnopqrstuvwxyz" from arduino to the computer, the incoming message at the computer (dongle) side would be truncated.... like "abcdefghijklm".

However, doing the reverse by sending "abcdefghijklmnopqrstuvwxyz" from the computer (dongle) to the arduino was not a problem (ie. no truncation).

Interestingly (but not understanding it yet), the problem so far appears to be in the code where I set transmit and receive pipe addresses. I'll briefly discuss what I found as follows:

The original code I used for setting pipe addresses was like this:

byte addresses[][6] = {"AAAAA", "AAAAB"};  //with radioNumber set to zero, the tx pipe will be 'AAAAA', which is basically HEX'4141414141', which is remote DESTINATION address for our transmitted data. The rx pipe code is the local receive address, which is what the remote device needs to set for the remote devices 'tx' pipe code.

Anyway, note the '6' in [][6]. I used that value of '6' because the code I used is obtained from RF24 library tutorials. It's something to do with the maximum number of pipe addresses for NRF24L01+.

Interestingly, if I change the '6' to a larger value such as '14', then the number of text characters than can be received (in one hit) at the USB ch340T/NRF dongle (computer side) grows to 29.

But, 14 is the highest value I can use right now. If I use a value like '15' or higher, then communications won't occur - ie. transmission from the arduino no longer occurs. I need to stick with '14' for now.

So, at the moment, if I send 32 text characters "abcdefghijklmnopqrstuvwxyzabcde" from computer (USB ch340T/NRF dongle) to arduino, then the arduino receives the full payload.

And, if I use the arduino to send "abcdefghijklmnopqrstuvwxyzabcde" to the USB dongle, then the USB dongle will receive 1 non-text character, and 29 text characters.... such as "[02]abcdefghijklmnopqrstuvwxyzabc". So, basically, it's missing the last "d" and "e". The [02] could be a start of text character, but don't yet know how that got in there.

Anyway, the dongle being able to receive 29 text characters in one hit is certainly much better than previously receiving 13 text characters.

If anyone can explain how transmit and receive address configuration can cause this message truncation effect, then that would be tremendous. What I mean is ... if I use this declaration:

byte addresses[][6] = {"AAAAA", "AAAAB"};

then the message received by the USB ch340T/nrf dongle gets clipped to 13 text characters.

If I then change the line to:

byte addresses[][7] = {"AAAAA", "AAAAB"};

then the message received gets clipped to 15 text characters.

If I then change (again) the line to:

byte addresses[][8] = {"AAAAA", "AAAAB"};

then the message received gets clipped to 17 text characters.

So whatever the value (eg. N) I put into the square bracket, the incoming message gets clipped to (N-6)*2 + 13 characters.

This means.....

byte addresses[][14] = {"AAAAA", "AAAAB"};

would correspond to (14-6)*2 + 13 = 29 text characters received only (if the incoming message were to have more than 29 text characters).

The interesting thing is ..... if I go back to my original line, with a '6' ie....

byte addresses[][6] = {"AAAAA", "AAAAB"};

..... then there is no truncation issues for plain arduino/nrf to arduino/nrf communications. The truncations only occur when the USB dongle receives from an arduino/nrf. And, I didn't ever expect that the settings of TX and RX pipe addresses would be linked to message truncations.

Overall, the situation is pretty good now. Much better than before.

I'll just include the code that I'm now using for the transmitting arduino MEGA2560 (with it's NRF24L01+ module, using digital pin 9 for "CE", and digital pin 53 for "CSN").

/* Modified by Kenny - Mon-3-Oct-2016 - for the purpose of getting an arduino MEGA2560 (with NRF24L01+ 2.4GHz transceiver module) to communicate with a Windows desktop PC fitted with a CH340T/NRF24L01+ USB module */

/*
* Getting Started example sketch for nRF24L01+ radios
* This is a very basic example of how to send data from one node to another
* Updated: Dec 2014 by TMRh20
*/

#include <SPI.h>
#include "RF24.h"

char * outchar = "abcdefghijklmnopqrstuvwxyzabcde\0";


/* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 9 & 53, which are CE & CSN pins  */
RF24 radio(9, 53);
/**********************************************************/

byte addresses[][14] = {"AAAAA", "AAAAB"};  //with radioNumber set to zero, the tx pipe will be 'AAAAA', which is basically HEX'4141414141', which is remote DESTINATION address for our transmitted data. The rx pipe code is the local receive address, which is what the remote device needs to set for the remote devices 'tx' pipe code.

// Used to control whether this node is sending or receiving
bool role = 0;

void setup() {
  Serial.begin(9600);
  Serial.println(F("RF24/examples/GettingStarted"));
  Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));

  radio.begin();
  radio.setDataRate(RF24_2MBPS);   //choosing 2 Mega bit per second radio frequency data rate   //radio frequency data rate choices are:  //RF24_250KBPS    //RF24_2MBPS  //RF24_1MBPS
  radio.setChannel(4);   // this channel '4' will set a RF frequency of 2.404 GHz, aka 2404 MHz.


  // Set the PA Level low to prevent power supply related issues since this is a
  // getting_started sketch, and the likelihood of close proximity of the devices. RF24_PA_MAX is default.
  radio.setPALevel(RF24_PA_LOW);


  radio.openWritingPipe(addresses[0]);
  radio.openReadingPipe(1, addresses[1]);

  // Start the radio listening for data
  radio.startListening();
}

void loop() {


  /****************** Ping Out Role ***************************/
  if (role == 1)  {  //transmit role

    radio.stopListening();                                    // First, stop listening so we can talk.


    Serial.println(F("Now sending"));

    unsigned long time = micros();                             // Take the time, and send it.  This will block until complete
    if (!radio.write( &outchar, strlen(outchar)+2)) {
      Serial.println(F("failed"));
    }

    radio.startListening();                                    // Now, continue listening

    unsigned long started_waiting_at = micros();               // Set up a timeout period, get the current microseconds
    boolean timeout = false;                                   // Set up a variable to indicate if a response was received or not


    // Try again 1s later
    delay(1000);
  }



  /****************** Pong Back Role ***************************/

  if ( role == 0 )   //initial role is '0', ie. listening
  {
    unsigned long got_time;

    if ( radio.available()) {  //'available' means whether valid bytes have been received and are waiting to be read from the receive buffer
      // Variable for the received timestamp
      while (radio.available()) {                                   // While there is data ready
        radio.read( &got_time, sizeof(unsigned long) );             // Get the payload
      }

      radio.stopListening();                                        // First, stop listening so we can talk
      radio.write( &got_time, sizeof(unsigned long) );              // Send the final one back.
      radio.startListening();                                       // Now, resume listening so we catch the next packets.
      Serial.print(F("Sent response "));
      Serial.println(got_time);
    }
  }




  /****************** Change Roles via Serial Commands ***************************/

  if ( Serial.available() )
  {
    char c = toupper(Serial.read());
    if ( c == 'T' && role == 0 ) {
      Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
      role = 1;                  // Become the primary transmitter (ping out)

    } else if ( c == 'R' && role == 1 ) {
      Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
      role = 0;                // Become the primary receiver (pong back)
      radio.startListening();

    }
  }


} // Loop