Decoding a message (should be simple)

I am using NRF24 to send messages from one to another Arduino.

The code looks like this

if(condition){
  unsigned long message = 10;
  RF24NetworkHeader header(node04);     // (Address where the data is going)
  bool ok = network.write(header, &message, sizeof(message)); // Send the data
  }

On the receiver side it looks like this:

network.update();
   while ( network.available() ) {     // Is there any incoming data?
   RF24NetworkHeader header;
   unsigned long message;
   network.read(header, &message, sizeof(message)); // Read the incoming data

   if (message == 10){
   do something;
   }

If I want to do something at a receiving site, I need to write an if statement and specifically tell Arduino what to do.

What I would like is a code that would tell receiving site, what to do.

Example.
I want to turn on RGB led and buzzer.
r = 255
g = 050
b = 0
buzzer = 1

I would like to send a code 2550500001 and the receiving arduino would decode it.

I know how to make the code. Message = r10000000 + g100000 + etc...

Question: Is there some way to decode this message?

Thank you

Send a struct containing the values to be used by the receiver. That way you send a single message that is easily decoded and used. Alternatively add delimiters between the data items that you send and parse it in the receiver code using the delimiters

Personally I would favour using a struct because it allows you to use meaningful variable names within it

Examples

Sending a struct

// SimpleTx - the master or the transmitter

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

//not all #defines used but here for documentation
#define CE_PIN   9
#define CSN_PIN 10
#define MOSI_PIN 11
#define MISO_PIN 12
#define SCK_PIN 13

const byte slaveAddress[5] = {'R', 'x', 'A', 'A', 'A'};

RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

char txNum = '0';

struct data
{
  byte pinState;
  byte temperature;
} sentData;

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000;

void setup()
{
  Serial.begin(115200);
  Serial.println("SimpleTx Starting");
  radio.begin();
  radio.setDataRate( RF24_250KBPS );
  radio.setRetries(3, 5); // delay, count
  radio.openWritingPipe(slaveAddress);
}

void loop()
{
  currentMillis = millis();
  if (currentMillis - prevMillis >= txIntervalMillis)
  {
    sentData.pinState = !sentData.pinState;
    sentData.temperature = sentData.temperature + 1;
    send();
    prevMillis = millis();
  }
}

void send()
{
  bool rslt;
  rslt = radio.write( &sentData, sizeof(sentData) );
  if (rslt)
  {
    Serial.println("  Acknowledge received");
  }
  else
  {
    Serial.println("  Tx failed");
  }
}

Receiving a struct

// SimpleRx - the slave or the receiver

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

//not all #defines used but here for documentation
#define CE_PIN   9
#define CSN_PIN 10
#define MOSI_PIN 11
#define MISO_PIN 12
#define SCK_PIN 13

const byte thisSlaveAddress[5] = {'R', 'x', 'A', 'A', 'A'};

RF24 radio(CE_PIN, CSN_PIN);

struct data
{
  byte pinState;
  int temperature;
} receivedData;

bool newData = false;

void setup()
{
  Serial.begin(115200);
  Serial.println("SimpleRx Starting");
  radio.begin();
  radio.setDataRate( RF24_250KBPS );
  radio.openReadingPipe(1, thisSlaveAddress);
  radio.startListening();
}

void loop()
{
  getData();
  showData();
}

void getData()
{
  if ( radio.available() )
  {
    radio.read( &receivedData, sizeof(receivedData) );
    newData = true;
  }
}

void showData()
{
  if (newData == true)
  {
    Serial.print("Data received\tpinState : ");
    Serial.print(receivedData.pinState);
    Serial.print("\t");
    Serial.print("temperature : ");
    Serial.println(receivedData.temperature);
    newData = false;
  }
}

you could use sscanf() to parse your code "2550500001" , e.g.

void setup() {
  Serial.begin(115200);
  char data[]="2550500001";
  int r,g,b,buzzer;
  if(sscanf(data,"%3d%3d%3d%1d",&r,&g,&b,&buzzer)==4) {
    Serial.println(r);
    Serial.println(g);
    Serial.println(b);
    Serial.println(buzzer);   
  }
  else     
  Serial.println("invalid data");
}

void loop() {}

a run gives

09:30:30.128 -> 255
09:30:30.128 -> 50
09:30:30.128 -> 0
09:30:30.128 -> 1

alternativly you could send a code such as "R255G50B0BUZZER1" and use sscanf() to parse it, e.g.

  if(sscanf(data,"R%dG%dB%dBUZZER%d",&r,&g,&b,&buzzer)==4) {

I'll bet that works. But, as has been discussed here many times (strict C++ typing, undefined behavior, etc), that should probably be replaced with a read() into a uint8_t buffer followed by a memcpy() into receivedData.

EDIT:
Sorry, my bad. The read function uses memcpy().

Thank you,

this is exactly what I was looking for, googling and searching like crazy, and nothing :smiley:

The closest I got was this, but I did not know how the % and other symbols work, so Thank you.

int thousands, hundreds, tens, ones;
int x = 9431;
thousands = (x % 10000) / 1000;
hundreds = (x % 1000) / 100;
tens = (x % 100) / 10;
ones = (x % 10);

Note that when % is used in sscanf() it means something completely different to when it is used in an expression such as ones = (x % 10);

Thank you, was just reading many threads about sscanf(), I am pretty used to parsing with https://regex101.com/ so this looks a bit similar, so I think I will get it to work. Thanks

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.