storing/transforming strings? [NRF24L01 Mirf issues]

Hello, I'm in need of some advice as how to store and transform text =)

I am trying to set-up a wireless handshake function (as an easy way to check if the device is still running properly) by "taming" the Mirf libraries for the NRF24L01 2.4Ghz module through a few functions since my project is going to rely heavily on wireless transcommunications - but now that I am done building this stub I realize that I have a big problem.

/// SLAVE unit //


#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>


/// IDENTITY DECLARATION //////////////////
unsigned long IDENTITY = 20000;        ///
unsigned long MASTER_IDENTITY = 99999;///
////////////////////////////////////////


// protocols //
unsigned long question_mark          = 0;
unsigned long exclamation_mark       = 00;


unsigned long handshake              = 1337;
unsigned long EXIT                   = 666;
unsigned long keep_going             = 333;
unsigned long yes                    = 01;
unsigned long no                     = 02;


void setup(){


  Mirf.cePin = 8;
  Mirf.csnPin = 7;
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();

  Mirf.channel = 69;
  Mirf.payload = sizeof(unsigned long);

  Mirf.setRADDR((byte*)IDENTITY);
  Mirf.setTADDR((byte*)MASTER_IDENTITY);


  /// INSERT THE PINMODES HERE ///
  Serial.begin(9600);
  Serial.println("Initiated...");


}

void loop(){
  
  unsigned long listen_buffer = receive_data();
  if (listen_buffer != NULL){

    
    if(listen_buffer == handshake){  // be a polite lil' atmega and answer your fellow uno u_u
     handshake_responder();
    }
  }

}










///// SEND DATA FUNCTION //////
void send_data(unsigned long target, unsigned long data){
  unsigned long time = millis();
  Mirf.setTADDR((byte*)&target);
  Mirf.config();
  delay(1);

  Mirf.send((byte*)&data);
  while(Mirf.isSending()){ 
    if((millis() - time) > 1500){
      Serial.println("Failed to send data.");
      return;
    }
  }
}



///// RECEIVE DATA FUNCTION //////  
unsigned long receive_data(){
  unsigned long time = millis();
  unsigned long received;
  ;
  while(!Mirf.dataReady()){
    if((millis() - time) > 500){
      //Serial.println("Failed to receive anything.");
      return NULL;
    }   
  }
  Mirf.getData((byte*)&received);
  return (received);
}


////////// handshake_send - handshakes stuff, even without hands/////////
void handshake_send(unsigned long target){
  unsigned long handshake_temp;
  unsigned long handshake_identity_buffer;

  send_data(target,handshake);
  delay(1);
  send_data(target,IDENTITY);
  handshake_temp = receive_data();
  if(handshake_temp == handshake){
    Serial.println("Connection established.");
    return;
  }
  else {
    Serial.println("Failed to connect.");
    return;
  }

}

//////// handshake responder, requires a trigger/////
void handshake_responder(){
  unsigned long handshake_temp;
  unsigned long handshake_identity_buffer;
  unsigned long handshake_received;
  //step 1: collect the identity of the unit that initiated the handshake
  handshake_received = receive_data();
  if(handshake_received == NULL){ //
  Serial.println("Handshake: Failed to receive identity.");
    return;
  }
  //step 2: send handshake back
  send_data(handshake_received, handshake);


}

The part that manages identity is new stuff, it used to be:

  Mirf.setRADDR((byte*)"mastr");
  Mirf.setTADDR((byte*)"unit1");
  Mirf.config();

it was less easily configurable but ... It worked.

The reason why I wanted to get away from "text" addresses was because it was going to make my life a hell setting up the master unit as the number of slaves rose (i'm going to make various slave units that will rely on ONE master unit) since i didn't manage to store strings and get them to work with the Mirf.setRADDR() function. So the idea came to mind to make the names all numbers (easier to manipulate), so that an anonymous unit could easily send to the master unit a handshake and THEN disclose it's identity to be answered. (step one "hi!", step two "here's my address", step three "I need the temperature in the living room please").

But the functions Mirf.setRADDR() and Mirf.setRADDR() don't seem to work with my numbers - I can't get my two arduinos to communicate as soon as I start to use them (even when pre-defined).

So I was wondering if anyone had any idea as to how I could store the addresses as variables to be called, aswell as something that could also be sent to another arduino to be used as an address for the Mirf libraries?

Thanks in advance, and sorry for my bad english ^^".

(step one "hi!", step two "here's my address", step three "I need the temperature in the living room please").

Well in theory this is ideal soluction but how do you will deal with the fact that each pipe (nrf only has 5 pipes) needs to know the transmitter address in order to receive anything from it?
To your master be able to ear that "step one "hi!", the master already needs to know his address to be listen from that device.

Thank you for your answer - So in order to receive anything the device must already know who is sending the message in advance?

I'm going to think of what I can do then =) - some kind of sub-identity would probably work right? (naming them all "slave" and one "master" and then assign them an identity through some kind of handshake process - would make transfer FAR slower but it would probably better suit my needs =))

Well back to rewriting it all, have a nice day =)

Thank you for your answer - So in order to receive anything the device must already know who is sending the message in advance?

AFAIK yes.
I suggest you read the datasheet especially page 37 which is about the MultiCeiver.
I believe what you want to do is not easy but don't consider this as a end of study.
A possible solution for you be able to achieve that was dedicate the pipe5 with a specific address that all slaves know from the beginning.Only new slaves try to use pipe5.
Then when they power up they try to speak with the master thought that pipe and send him a new address and node ide.Master receive that new slave "hello" read the data passed which is the new address and assign that new address to a specific Pipe and store that slave in eeprom also.Then the slave change on the fly to that channel and Pipe and store in eeprom that was registed successfully.
But like I say one master can only speak with 5 devices (5Pipes) unless you do a network with nrf

Thanks to you I managed to make it work flawlessly with three devices so far (1 master, 2 slaves) =) - each slave has his own "identity", and will respond in handshake mode to the master device only if his name is called out, and then the master writes to it's EEPROM the device_type's identity (will be useful to do like a routine check of what devices are online to adapt the menu, not displaying unavailable devices - ones that have a NULL identity in memory).

5 devices seem kinda small indeed (great info btw), but it's enough I guess for one room:
1 - desk lamp
2 - fan
3 - heater
4 - ambiance light

And that keeps one last pipe for some kind of extension node to add an extra 4 devices? - that's what you ment by a NRF network correct? :slight_smile:

Anyways thanks again, really, I love my arduinos but being a newbie can be such a pain sometimes and real help from people like you mean a lot ^^.