nRF24 RadioHead master/slave : errors with init. of array and ((char*)buf)

Hi, using the client/server exemple of the RadioHead library, I am trying to make a short code to send instructions from a client to a server, for instance to turn on or off a relay switch. I would like to keep it as simple as possible, while making it practical to add various instructions.

On startup, the client try to tells the server "ON" fives times, until it gets a "PONG" in reply.
Then it tells the server "OFF" the same way. On the server side, the content of the message is interpreted to take the appropriate action.

What I tried so far was not allowed by the compiler, and I would like to have some clues about why and how to get around theses errors.

I wrote the errors above the problematic lines:

Master:

#include <SPI.h>
#include <RH_NRF24.h>
RH_NRF24 nrf24;
byte pong; //Utiliser break; et sauver 1 byte?

void setup() {
	Serial.begin(9600);
	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);
	nrf24_request(0);
}

void loop() {}

void nrf24_request(int r) {
	pong = false;
	for (int i = 0; i < 5; i++) { //5 tries
		if (!pong) {
			switch (r) { //send PING
			
				//!!! error:   crosses initialization of 'uint8_t data [4]
				//!!! error: 'uint8_t data [4]' previously declared here
				case 0: uint8_t data[] = "OFF"; break;
				
				//!!! error: jump to case label
				//!!! error: redeclaration of 'uint8_t data []'
				case 1: uint8_t data[] = "ON"; break;
				
			}
			//!!! error: 'data' was not declared in this scope
			nrf24.send(data, sizeof(data));
			nrf24.waitPacketSent();
			uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];
			uint8_t len = sizeof(buf);

			if (nrf24.waitAvailableTimeout(500)) {
				if (nrf24.recv(buf, &len) && (char*)buf == "PONG") { pong = true; } //got pong, stops ping
			} else { delay(1000); } //Slave is not responding
			delay(400);
		}
	}
}

Slave:

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

void setup() {
	Serial.begin(9600);
	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
		
		//!!! error: switch quantity not an integer
			switch ((char*)buf) {
				case 'OFF': Serial.println("got OFF"); break;
				case 'ON': Serial.println("got ON"); break;
			}		
		//!!!
			
			uint8_t data[] = "PONG"; //send PONG
			nrf24.send(data, sizeof(data));
			nrf24.waitPacketSent();
		}
	}
}

Slave:

//!!! error: switch quantity not an integer
	switch ((char*)buf) {
		case 'OFF': Serial.println("got OFF"); break;
		case 'ON': Serial.println("got ON"); break;
	}		
//!!!

You cannot use switch() with a string.

To compare strings use the strcmp() function.

You can't write 'OFF' and 'ON', because Single Quotation Mark (is this the name) is used to declare a single char, and "OFF" and "ON" are strings.

It would be like this:

if(strcmp(buf,"OFF")==0){
	Serial.println("got OFF")
}
else if(strcmp(buf,"ON")==0){
	Serial.println("got ON"); 
}

Master:

//!!! error:   crosses initialization of 'uint8_t data [4]
//!!! error: 'uint8_t data [4]' previously declared here
case 0: uint8_t data[] = "OFF"; break;

//!!! error: jump to case label
//!!! error: redeclaration of 'uint8_t data []'
case 1: uint8_t data[] = "ON"; break;

Declare data in the global scope (before setup()):

uint8_t data[4];

And see above how to compare strings.

Thanks for your reply. But I am still wondering, once it has been declared in the global scope, how to I change the value of data? I tried with "data =" and "data[] =" but it won't change. And I still get errors from both files with the strcmp():

Master:

#include <SPI.h>
#include <RH_NRF24.h>
RH_NRF24 nrf24;
uint8_t data[4];
byte pong; //Use break; in the loop to save one byte?

void setup() {
	Serial.begin(9600);
	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);
	nrf24_request(0);
}

void loop() {}

void nrf24_request(int r) {
	pong = false;
	for (int i = 0; i < 5; i++) { //5 tries
		if (!pong) {
			switch (r) { //send PING
			
			///!! error: incompatible types in assignment of 'const char [4]' to 'uint8_t [4] {aka unsigned char [4]}'
				case 0: data = "OFF"; break;
				case 1: data = "ON"; break;
				
			}
			nrf24.send(data, sizeof(data));
			nrf24.waitPacketSent();
			uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];
			uint8_t len = sizeof(buf);

			if (nrf24.waitAvailableTimeout(500)) {
				if (nrf24.recv(buf, &len) && (char*)buf == "PONG") { pong = true; } //got pong, stops ping
			} else { delay(1000); } //Slave is not responding
			delay(400);
		}
	}
}

Slave:

//nrf24_slave.ino:23:23: error: invalid conversion from 'uint8_t* {aka unsigned char*}' to 'const char*' [-fpermissive]
//In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:25:0, from C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI/SPI.h:17, from nrf24_slave.ino:1:
//c:\program files (x86)\arduino\hardware\tools\avr\avr\include\string.h:125:12: error:   initializing argument 1 of 'int strcmp(const char*, const char*)' [-fpermissive]
//extern int strcmp(const char *, const char *) __ATTR_PURE__;
//            ^

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

void setup() {
	Serial.begin(9600);
	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
		
		//!!! error:
			if(strcmp(buf,"OFF")==0){ Serial.println("got OFF"); }
			else if(strcmp(buf,"ON")==0){ Serial.println("got ON"); }	
		//!!!
			
			uint8_t data[] = "PONG"; //send PONG
			nrf24.send(data, sizeof(data));
			nrf24.waitPacketSent();
		}
	}
}

To change the value of a string, use strcpy().

Example of modifying the value of string data to "OFF":

strcpy(data,"OFF");

And to solve your problem,
Replace this:

uint8_t data[4];

with this:

char data[4];

Thank you. I definitely need to learn more about char, strings and arrays. I still get error with both codes though;

Slave:

nrf24_slave.ino: In function 'void nrf24_listen()':
nrf24_slave.ino:29:23: error: invalid conversion from 'uint8_t* {aka unsigned char*}' to 'const char*' [-fpermissive]
In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:25:0,
                 from C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI/SPI.h:17,
                 from nrf24_slave.ino:7:
c:\program files (x86)\arduino\hardware\tools\avr\avr\include\string.h:125:12: error:   initializing argument 1 of 'int strcmp(const char*, const char*)' [-fpermissive]
 extern int strcmp(const char *, const char *) __ATTR_PURE__;
            ^
nrf24_slave.ino:30:27: error: invalid conversion from 'uint8_t* {aka unsigned char*}' to 'const char*' [-fpermissive]
In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:25:0,
                 from C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI/SPI.h:17,
                 from nrf24_slave.ino:7:
c:\program files (x86)\arduino\hardware\tools\avr\avr\include\string.h:125:12: error:   initializing argument 1 of 'int strcmp(const char*, const char*)' [-fpermissive]
 extern int strcmp(const char *, const char *) __ATTR_PURE__;
            ^

Master:

nrf24_master.ino: In function 'void nrf24_request(int)':
nrf24_master.ino:30:33: error: invalid conversion from 'char*' to 'const uint8_t* {aka const unsigned char*}' [-fpermissive]
In file included from nrf24_master.ino:2:0:
C:\Users\W7\Documents\Arduino\libraries\RadioHead/RH_NRF24.h:539:10: error:   initializing argument 1 of 'virtual bool RH_NRF24::send(const uint8_t*, uint8_t)' [-fpermissive]
     bool send(const uint8_t* data, uint8_t len);
          ^

Please, replace all uint8_t with char (and uint8_t* with char*).

And test again.

I found the solution, I just needed to add (char*) in front and treat them as strings

Slave:

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

void setup() {
	Serial.begin(9600);
	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 OFF"); }
			else if (!strcmp((char*)buf, "ON")) { Serial.println("got ON"); }	
			
			uint8_t data[] = "PONG"; //send PONG
			nrf24.send(data, sizeof(data));
			nrf24.waitPacketSent();
		}
	}
}

Master:

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

void setup() {
	Serial.begin(9600);
	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(3000);
	nrf24_request(0);
}

void loop() {}

void nrf24_request(int r) {
	for (int i = 0; i < 5; i++) { //5 tries
		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);

		if (nrf24.waitAvailableTimeout(500)) {
			if (nrf24.recv(buf, &len) && !strcmp((char*)buf, "PONG")) { break; } //got pong, stops
		} else { delay(1000); } //Slave is not responding
		delay(400);
	}
}