nrf24l01 - how to send a string with rf24 library ?

Hi, i'm new with the nrf24l01 and i looked at a lot of example but i have not found any one that send a string. almost always sending number.

I found one on the forum about making a serial chat but not really what i'm looking for, because it take a random string from the serial and save every char into a char array and send the array after. Mine is a fixed message to send so i wish to know if there is an easiest way to do it

Need to use rf24 maniacbug Library.

My project is currently using a 433mhz transmitter and i'm sending the next code and i wish to be able to do the same with a nrf24l01 transceiver:

char *msgRF;
msgRF="Z4";
  vw_send((uint8_t *)msgRF, strlen(msgRF));

I need to send a fixed message like "Z4", "A0",... Can I do the same thing with the nrf24l01 ?

Is someone able to write me an example of the easiest way to send this kind of message ?

Thank you

Show us the code you have successfully used to send and receive some other type of data, using the NRF24L01 and the maniacbug library, and we will show you how to modify it to send a character string.

This is the example from maniacbug rf24 Library. it work ok

/*
 Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 version 2 as published by the Free Software Foundation.
 */

/**
 * Example RF Radio Ping Pair
 *
 * This is an example of how to use the RF24 class.  Write this sketch to two different nodes,
 * connect the role_pin to ground on one.  The ping node sends the current time to the pong node,
 * which responds by sending the value back.  The ping node can then see how long the whole cycle
 * took.
 */

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

//
// Hardware configuration
//

// Set up nRF24L01 radio on SPI bus plus pins 9 & 10

RF24 radio(9,10);

// sets the role of this unit in hardware.  Connect to GND to be the 'pong' receiver
// Leave open to be the 'ping' transmitter
const int role_pin = 7;

//
// Topology
//

// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

//
// Role management
//
// Set up role.  This sketch uses the same software for all the nodes
// in this system.  Doing so greatly simplifies testing.  The hardware itself specifies
// which node it is.
//
// This is done through the role_pin
//

// The various roles supported by this sketch
typedef enum { role_ping_out = 1, role_pong_back } role_e;

// The debug-friendly names of those roles
const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"};

// The role of the current running sketch
role_e role;

void setup(void)
{
  //
  // Role
  //

  // set up the role pin
  pinMode(role_pin, INPUT);
  digitalWrite(role_pin,HIGH);
  delay(20); // Just to get a solid reading on the role pin

  // read the address pin, establish our role
  if ( ! digitalRead(role_pin) )
    role = role_ping_out;
  else
    role = role_pong_back;

  //
  // Print preamble
  //

  Serial.begin(57600);
  printf_begin();
  printf("\n\rRF24/examples/pingpair/\n\r");
  printf("ROLE: %s\n\r",role_friendly_name[role]);

  //
  // Setup and configure rf radio
  //

  radio.begin();

  // optionally, increase the delay between retries & # of retries
  radio.setRetries(15,15);

  // optionally, reduce the payload size.  seems to
  // improve reliability
  radio.setPayloadSize(8);

  //
  // Open pipes to other nodes for communication
  //

  // This simple sketch opens two pipes for these two nodes to communicate
  // back and forth.
  // Open 'our' pipe for writing
  // Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading)

  if ( role == role_ping_out )
  {
    radio.openWritingPipe(pipes[0]);
    radio.openReadingPipe(1,pipes[1]);
  }
  else
  {
    radio.openWritingPipe(pipes[1]);
    radio.openReadingPipe(1,pipes[0]);
  }

  //
  // Start listening
  //

  radio.startListening();

  //
  // Dump the configuration of the rf unit for debugging
  //

  radio.printDetails();
}

void loop(void)
{
  //
  // Ping out role.  Repeatedly send the current time
  //

  if (role == role_ping_out)
  {
    // First, stop listening so we can talk.
    radio.stopListening();

    // Take the time, and send it.  This will block until complete
    unsigned long time = millis();
    printf("Now sending %lu...",time);
    bool ok = radio.write( &time, sizeof(unsigned long) );
    
    if (ok)
      printf("ok...");
    else
      printf("failed.\n\r");

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

    // Wait here until we get a response, or timeout (250ms)
    unsigned long started_waiting_at = millis();
    bool timeout = false;
    while ( ! radio.available() && ! timeout )
      if (millis() - started_waiting_at > 200 )
        timeout = true;

    // Describe the results
    if ( timeout )
    {
      printf("Failed, response timed out.\n\r");
    }
    else
    {
      // Grab the response, compare, and send to debugging spew
      unsigned long got_time;
      radio.read( &got_time, sizeof(unsigned long) );

      // Spew it
      printf("Got response %lu, round-trip delay: %lu\n\r",got_time,millis()-got_time);
    }

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

  //
  // Pong back role.  Receive each packet, dump it out, and send it back
  //

  if ( role == role_pong_back )
  {
    // if there is data ready
    if ( radio.available() )
    {
      // Dump the payloads until we've gotten everything
      unsigned long got_time;
      bool done = false;
      while (!done)
      {
        // Fetch the payload, and see if this was the last one.
        done = radio.read( &got_time, sizeof(unsigned long) );

        // Spew it
        printf("Got payload %lu...",got_time);

	// Delay just a little bit to let the other unit
	// make the transition to receiver
	delay(20);
      }

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

      // Send the final one back.
      radio.write( &got_time, sizeof(unsigned long) );
      printf("Sent response.\n\r");

      // Now, resume listening so we catch the next packets.
      radio.startListening();
    }
  }
}
// vim:cin:ai:sts=2 sw=2 ft=cpp

those lines in the above code are used to send the time (millisecond) to the other nrf24l01:

    // Take the time, and send it.  This will block until complete
    unsigned long time = millis();
    printf("Now sending %lu...",time);
    bool ok = radio.write( &time, sizeof(unsigned long) );

lets think i want to send a fixed message "Z4" instead of the time. How will I do it ?

Thank you

In this:

bool ok = radio.write( &time, sizeof(unsigned long) );

radio.write() is doing EXACTLY the same thing as vw_send() in this:

char *msgRF;
msgRF="Z4";
  vw_send((uint8_t *)msgRF, strlen(msgRF));

In other words: send(address_of_data, number_of_bytes);

Thank you. after some testing and more forum search here, it work.

This work for the transmitter

char hello[] = "A1";
radio.write(&hello,strlen(hello) );

And this work for the receiver

int len=0;
char gotmsg[]="";
      
len = radio.getDynamicPayloadSize();
radio.read( &gotmsg, len );

Serial.println(gotmsg);
int len=0;
char gotmsg[]="";
     
len = radio.getDynamicPayloadSize();
radio.read( &gotmsg, len );

Don't do this ! You are creating and initializing an array of length 1 byte and then immediately exceeding the array bounds. You will overwrite memory and wipe out other data.

Instead use something like

char gotmsg[MAXSIZE];  //where MAXSIZE is larger than the length of any possible message.

Strange... I sent "A1" from arduino #1 and it print out "A1" on screen on arduino #2, this way.

But it is better to avoid error.

I guess I can do this: using the current size of the incoming payload to initialize the array ?

int len=0;
     
len = radio.getDynamicPayloadSize();

char gotmsg[len]="";

radio.read( &gotmsg, len );

or knowing the max payload size is 32, should I always do this char gotmsg[31]="";

Thank you

Question:

What is the best way to declare an empty array ? can i do both ?

char array[2]=""; //for an empty array of size 2

or without =""

char array[2]; //for an empty array of size 2

Either way is OK, but the first initializes the array to be a valid character string of length zero, with a maximum length of one.

The second does not initialize the array, which will later cause problems if you make the mistake of assuming that it is a valid character string.

With the RadioHead library, the exemple for NRF24 shows how to send a string between two modules:

I changed it slightly to best fit my needs. The master sends a simple string for up to ten times, or until it is correctly repeated by the slave.

Master

#include <SPI.h>
#include <RH_NRF24.h>
RH_NRF24 nrf24;
uint8_t data[4];

void setup() {
	Serial.begin(9600);
	Serial.println("Master");
	if (!nrf24.init()) Serial.println("init failed");
	if (!nrf24.setChannel(1)) Serial.println("setChannel failed");
	if (!nrf24.setRF(RH_NRF24::DataRate2Mbps, RH_NRF24::TransmitPower0dBm)) Serial.println("setRF failed");
	
	nrf24_request(1); delay(5000);
	nrf24_request(0);
}

void loop() {}

void nrf24_request(int r) {
	for (int i = 0; i < 10; i++) {
		switch (r) { //send PING
			case 0: strcpy((char*)data, "OFF"); break;
			case 1: strcpy((char*)data, "ON"); break;
		}
		nrf24.send(data, sizeof(data));
		nrf24.waitPacketSent();
		uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];
		uint8_t len = sizeof(buf);
		
		Serial.print("sent:");
		Serial.println((char*)data);

		if (nrf24.waitAvailableTimeout(500)) {
			if (nrf24.recv(buf, &len)) {
				if (!strcmp((char*)buf, (char*)data)) { //PONG: Slave repeated the message, exit loop
					Serial.print("break on loop #"); Serial.println(i);
					break;
				}
			}
		
		} else { Serial.println("Waiting for slave"); delay(1000); }
		delay(400);
	}
}

Slave

#include <SPI.h>
#include <RH_NRF24.h>
RH_NRF24 nrf24;

void setup() {
	Serial.begin(9600);
	Serial.println("Slave");
	if (!nrf24.init()) Serial.println("init failed");
	if (!nrf24.setChannel(1)) Serial.println("setChannel failed");
	if (!nrf24.setRF(RH_NRF24::DataRate2Mbps, RH_NRF24::TransmitPower0dBm)) Serial.println("setRF failed");
}

void loop() {
	nrf24_listen();
}

void nrf24_listen() {
	if (nrf24.available()) {
		uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];
		uint8_t len = sizeof(buf);
		if (nrf24.recv(buf, &len)) { //got PING
			if (!strcmp((char*)buf, "OFF")) { Serial.println("got 0"); } //ACTION
			else if (!strcmp((char*)buf, "ON")) { Serial.println("got 1"); }
			nrf24.send(buf, len); //PONG: Repeat the instruction to Master
			nrf24.waitPacketSent();
		}
	}
}