Go Down

Topic: Display The Node Communication Sequence on Multiceiver nRF24l01 (Read 421 times) previous topic - next topic

totagsayogya

Jun 13, 2018, 01:42 am Last Edit: Jun 21, 2018, 02:03 pm by totagsayogya Reason: add more decription
Hallo, I'm here creating a project about multiciver communication using nRF24l01. I have succeeded in doing so, but I am having trouble knowing the order of incoming data on the receiving node. Does anyone know how to display the order of nodes that send data on the receiver and can be displayed on the serial monitor.

So in my project is using 6 nodes which one as a Host/Master node, 1 node for Gate/Router, and the rest as end node. basically I need to know the order communuication of end node with the router and the router sending to host/master node then it would display in serial monitor.

The code that I made myself in here

Whandall

Yes, use available(&).

Like in this sketch that needs to filter incoming pipes to reload AckPayload data.

Code: [Select]
#include <RF24.h>

const byte rAddress[] =  "1Node" "2Node" "3Node" "4Node" "5Node";
byte ackData = 1;
byte theMessage[32];

RF24 radio(8, 10);

void loadAckData(byte pipe) {
  radio.writeAckPayload(pipe, &ackData, sizeof(ackData));
  ackData++;
}

void setup(void) {
  Serial.begin(9600);
  radio.begin();
  radio.setChannel(108);
  radio.setDataRate(RF24_2MBPS);
  radio.enableDynamicPayloads()
  radio.enableAckPayload();
  for (byte i = 0; i < 5; i++) {
    radio.openReadingPipe(i + 1, &rAddress[i * 5]);
  }
  loadAckData(2);
  loadAckData(3);
  loadAckData(4);
  radio.startListening();
}

void loop(void) {
  byte pipeNum = 0;
  if (radio.available(&pipeNum)) {
    if (pipeNum == 2 || pipeNum == 3 || pipeNum == 4) {
      loadAckData(pipeNum);
    }
    byte len = radio.getDynamicPayloadSize();
    radio.read(theMessage, len);
    Serial.print(F("received ["));
    Serial.print(len);
    Serial.print(F("] "));
    for (int x = 0; x < len; x++) {
      if (theMessage[x] < 16) {
        Serial.write('0');
      }
      Serial.print(theMessage[x], HEX);
    }
    Serial.print(F(" via "));
    Serial.println(pipeNum);
  }
}

Posting your code could help to help you.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

totagsayogya

I'm sorry for late reply, I've upload my code. So basicaly in multireciever it must enable the ACK payload? In that code I try to using like this

Code: [Select]

n=0;
void loop() 
{   
  if ( Radio.available(&pipeNum) )
  {   

      if (pipeNum == 1)//Data from node 2
      {
        Radio.read(&Data_2, sizeof(Data_2));
        Data.id[n] = Data_2.id; n++;//this to make the order
        Data.value_2 = Data_2.value_2;
        Data.h = Data_2.h;
        Data.dat[0] = Data_2.dat;
      }

      if (pipeNum == 2) //Data from node 3
      {
        Radio.read(&Data_3, sizeof(Data_3));
        Data.id[1] = Data_3.id;
        Data.value_3 = Data_3.value_3;
        Data.h = Data_3.h;
        Data.dat[1] = Data_3.dat;
      }
     
      if (pipeNum == 3) //Data from node 4
      {
        Radio.read(&Data_4, sizeof(Data_4));
        Data.id[2] = Data_4.id; n=n+1;
        Data.value_4 = Data_4.value_4;
        Data.h = Data_4.h;
        Data.dat[2] = Data_4.dat;
      }
  if (n == 2) n=0;
        Data.id[3] = '1';//Node 1 as a router


using array char to make the order, but it cannot show in serial monitor node master

Whandall

I can not comment non compiling snippets, but the selection via reception pipe seems sensible.

So basicaly in multireciever it must enable the ACK payload?
Nope. The Ackpayload feature was used only as a meaningful example for the pipe selection.

using array char to make the order, but it cannot show in serial monitor node master
I do not understand what that means.

Show your current code.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

totagsayogya

This is my code in node 1(as a router), which Data.id (array with char type) brings Data_(Node).id (char type)

Code: [Select]

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

//Create up to 6 pipe addresses P0 - P5;  the "LL" is for LongLong type
const uint64_t
Node[] = {0xB3B4B5B6F1LL, 0xB3B4B5B6CDLL, 0xB3B4B5B6A3LL, 0xB3B4B5B60FLL, 0xB3B4B5B605LL  };

uint64_t HOST    = 0x7878787878LL;
uint64_t BC      = 0x1910000000LL;

uint8_t  CE   = 9;
uint8_t  CSN  = 10;
int n,i       = 0;

unsigned int x;
float baca_volt, volt;
byte pipeNum;


//Format data between Node 1 and HOST
struct payload
{
  char node[3];
  char id[4];
  float value_1;
  float value_2;
  float value_3;
  float value_4;
  int h;
  long dat[3];
};
payload Data;

//Format data Node 1 and  other Node
struct payload_1
{
  char node[3];
  int h;
};
payload_1 Data_1;

//Format data Node 2 with Node 1
struct payload_2
{ char node[3];
  char id;
  float value_2;
  int h;
  long dat;
};
payload_2 Data_2;

//Format data Node 3 with Node 1
struct payload_3
{ char node[3];
  char id;
  float value_3;
  int h;
  long dat;
};
payload_3 Data_3;

//Format data Node 4 with Node 1
struct payload_4
{ char node[3];
  char id;
  float value_4;
  int h;
  long dat;
};
payload_4 Data_4;

RF24 Radio(CE, CSN);

void setup()   
{
  Serial.begin(9600);
 
  Radio.begin();
  Radio.setChannel(108); 
  Data.id [4] ='1';
  Data.h=1;
  Radio.openWritingPipe(HOST);
  Radio.write(&Data, sizeof(Data) );

  // Open up to six pipes for PRX to receive data
  Radio.openReadingPipe(0,HOST);
  Radio.openReadingPipe(1,Node[0]);
  Radio.openReadingPipe(2,Node[1]);
  Radio.openReadingPipe(3,Node[2]);
  Radio.startListening(); // Start listening for messages
}

void loop() 
{   
  if ( Radio.available(&pipeNum) )
  {   
      if (pipeNum == 0)//Data from Host
      {
        Radio.read(&Data, sizeof(Data) );
        Data_1.node[0] = Data.node[0];
        Data_1.node[1] = Data.node[1];
        Data_1.node[2] = Data.node[2];
        Data_1.h = Data.h;
      }
     
      if (pipeNum == 1)//Data from node 2
      {
        Radio.read(&Data_2, sizeof(Data_2));
        Data.id[n] = Data_2.id; n=n+1;
        Data.value_2 = Data_2.value_2;
        Data.h = Data_2.h;
        Data.dat[0] = Data_2.dat;
      }
     
      if (pipeNum == 2) //Data from node 3
      {
        Radio.read(&Data_3, sizeof(Data_3));
        Data.id[n] = Data_3.id; n=n+1;
        Data.value_3 = Data_3.value_3;
        Data.h = Data_3.h;
        Data.dat[1] = Data_3.dat;
      }
     
      if (pipeNum == 3) //Data from node 4
      {
        Radio.read(&Data_4, sizeof(Data_4));
        Data.id[n] = Data_4.id; n=n+1;
        Data.value_4 = Data_4.value_4;
        Data.h = Data_4.h;
        Data.dat[2] = Data_4.dat;
      }
      if (n==3) n=0;
      Data.id[3] = '1';     
     
     
//Command for sending 1000 data
   if (Data.node[0] == 'P')
   {
    if (Data.h == 0)
    {
      if (Data.node [1] == '1')
      {
        for (i=0;i<=1000;i++)
        {
          delay(100);
          Data.h =2;
          Data.id[0] = '1';
          Radio.stopListening();
          Radio.openWritingPipe(HOST);
          Radio.write(&Data, sizeof(Data));
          Serial.print("Data ke: ");
          Serial.print(i);
        }
      }
      Radio.stopListening();
      Radio.openWritingPipe(BC);
      Radio.write(&Data_1, sizeof(Data_1));
    }

    if (Data.h == 1)
    {
      Radio.stopListening();
      Radio.openWritingPipe(HOST);
      Radio.write(&Data, sizeof(Data));
    }
  }//Data.node [0] == 'P'

//Program for checking battery
  if (Data.node[0] == 'B')
  {   
    if (Data.h == 1)//Data flag from Node
    {
    //ukur voltase
    baca_volt=analogRead(A1);
    volt=(5*5*baca_volt/1023)-0.2;

    i=i+1;
   
    Serial.print(Data.node);
    Serial.print("Data ke: ");
    Serial.print(i);
    Serial.print(' ');
    Serial.print(volt);
    Serial.print("V  ");
    Serial.print("Hop ke-");
    Serial.print(Data.h);
    Serial.println(' ');
    Data.h=2;
   
    Radio.stopListening();
    Radio.openWritingPipe(HOST);
    Radio.write(&Data, sizeof(Data));
    }//Data.h = 1

    if (Data.h == 0)//Data flag from Host
    {
      Radio.stopListening();
      Radio.openWritingPipe(BC);
      Radio.write(&Data_1, sizeof(Data_1) );
      Serial.println("BC");
    }   
  }//Data.node = 'B'   
  else
  {
    Radio.stopListening();
    Radio.openWritingPipe(HOST);
    Radio.write(&Data, sizeof(Data));
  }

//Open Listening for all Pipe 
  Radio.openReadingPipe(0,HOST);
  Radio.openReadingPipe(1,Node[0]);
  Radio.openReadingPipe(2,Node[1]);
  Radio.openReadingPipe(3,Node[2]);
  Radio.startListening();
  }//Radio.available
}

totagsayogya


Whandall

The abysmal naming makes it impossible for me to guess what you try to do.
Your identical duplicate structs are... strange.

I have no idea what your program should do but doesn't.

Code like the following has no place in a communication program

Code: [Select]
    if (Data.node [1] == '1') {
        for (i=0;i<=1000;i++)
        {
          delay(100);
          Data.h =2;
          Data.id[0] = '1';
          Radio.stopListening();
          Radio.openWritingPipe(HOST);
          Radio.write(&Data, sizeof(Data));
          Serial.print("Data ke: ");
          Serial.print(i);
        }
      }
      Radio.stopListening();

One hundred seconds without listening, but stopListening is called 1002 times.

You call stopListening once when you change from receiving to standby.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

totagsayogya

this is I add some comment may help a little

Code: [Select]

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

//Create up to 6 pipe addresses P0 - P5;  the "LL" is for LongLong type
const uint64_t
Node[] = {0xB3B4B5B6F1LL, 0xB3B4B5B6CDLL, 0xB3B4B5B6A3LL, 0xB3B4B5B60FLL, 0xB3B4B5B605LL  };

uint64_t HOST    = 0x7878787878LL;
uint64_t BC      = 0x1910000000LL;

uint8_t  CE   = 9;
uint8_t  CSN  = 10;
int n,i       = 0;

unsigned int x;
float baca_volt, volt;
byte pipeNum;


//Format data between Node 1 and HOST
struct payload
{
  char node[3];//This part is command from master node to another
  char id[4];//The list of node identity I try to order
  float value_1;//baterry value of node 1
  float value_2;//baterry value of node 2
  float value_3;//baterry value of node 3
  float value_4;//baterry value of node 4
  int h;//this is the mark/flag to figure it's from master node(0) or end node(1)
  long dat[3];//list of data has come per node
};
payload Data;

//Format data Node 1 and  other Node
struct payload_1
{
  char node[3];
  int h;
};
payload_1 Data_1;

//Format data Node 2 with Node 1
struct payload_2
{ char node[3];
  char id;
  float value_2;
  int h;
  long dat;
};
payload_2 Data_2;

//Format data Node 3 with Node 1
struct payload_3
{ char node[3];
  char id;
  float value_3;
  int h;
  long dat;
};
payload_3 Data_3;

//Format data Node 4 with Node 1
struct payload_4
{ char node[3];
  char id;
  float value_4;
  int h;
  long dat;
};
payload_4 Data_4;

RF24 Radio(CE, CSN);

void setup()   
{
  Serial.begin(9600);
  Radio.begin();
  Radio.setChannel(108); 
  Data.id [4] ='1';//the identity of node 1(more like address in simple way)
  Data.h=1;//this is for flag if the value 1 is ready to send back to master node, if 0 is command from master node
  Radio.openWritingPipe(HOST);
  Radio.write(&Data, sizeof(Data) );

  // Open up to six pipes for PRX to receive data
  Radio.openReadingPipe(0,HOST);
  Radio.openReadingPipe(1,Node[0]);
  Radio.openReadingPipe(2,Node[1]);
  Radio.openReadingPipe(3,Node[2]);
  Radio.startListening(); // Start listening for messages
}

void loop() 
{   
  if ( Radio.available(&pipeNum) )
  {   
      if (pipeNum == 0)//Data from Host
      {
        Radio.read(&Data, sizeof(Data) );
        Data_1.node[0] = Data.node[0];//Data.node is a command to do from master node to another node
        Data_1.node[1] = Data.node[1];
        Data_1.node[2] = Data.node[2];
        Data_1.h = Data.h;
      }
     
      if (pipeNum == 1)//Data from node 2
      {
        Radio.read(&Data_2, sizeof(Data_2));
        Data.id[n] = Data_2.id; n=n+1;//In this part I try to order the incoming node communication
        Data.value_2 = Data_2.value_2;//The battery value of node 2
        Data.h = Data_2.h;//this value is 0, because it's from end node
        Data.dat[0] = Data_2.dat;//This is part the counting  per data
      }
     
      if (pipeNum == 2) //Data from node 3
      {
        Radio.read(&Data_3, sizeof(Data_3));
        Data.id[n] = Data_3.id; n=n+1;
        Data.value_3 = Data_3.value_3;
        Data.h = Data_3.h;
        Data.dat[1] = Data_3.dat;
      }
     
      if (pipeNum == 3) //Data from node 4
      {
        Radio.read(&Data_4, sizeof(Data_4));
        Data.id[n] = Data_4.id; n=n+1;
        Data.value_4 = Data_4.value_4;
        Data.h = Data_4.h;
        Data.dat[2] = Data_4.dat;
      }
      if (n==3) n=0;
      Data.id[3] = '1';
      Radio.stopListening();   
     
     
//Command for recieve data from another node and send to master node
   if (Data.node[0] == 'P')
   {
    if (Data.h == 0)//the command from master node
    {
      if (Data.node [1] == '1')//this part I like to test the communication by node sending continue with 100ms delay
      {
        for (i=0;i<=1000;i++)
        {
          delay(100);
          Data.h =2;
          Data.id[0] = '1';
          Radio.openWritingPipe(HOST);
          Radio.write(&Data, sizeof(Data));
          Serial.print("Data ke: ");
          Serial.print(i);
        }
      }
      Radio.openWritingPipe(BC);// write broadcast to another node telling command from master node
      Radio.write(&Data_1, sizeof(Data_1));
    }

    if (Data.h == 1)// this part if data recieve from another node and send to master node
    {
      Radio.openWritingPipe(HOST);
      Radio.write(&Data, sizeof(Data));
    }
  }//Data.node [0] == 'P'

//Program for checking battery
  if (Data.node[0] == 'B')
  {   
    if (Data.h == 1)//Data flag from another node
    {
    //ukur voltase
    baca_volt=analogRead(A1);
    volt=(5*5*baca_volt/1023)-0.2;

    i=i+1;
   
    Serial.print(Data.node);
    Serial.print("Data ke: ");
    Serial.print(i);
    Serial.print(' ');
    Serial.print(volt);
    Serial.print("V  ");
    Serial.print("Hop ke-");
    Serial.print(Data.h);
    Serial.println(' ');
    Data.h=2;
   
    Radio.openWritingPipe(HOST);
    Radio.write(&Data, sizeof(Data));
    }//Data.h = 1

    if (Data.h == 0)//Data flag from master
    {
      Radio.openWritingPipe(BC);
      Radio.write(&Data_1, sizeof(Data_1) );
      Serial.println("BC");
    }   
  }//Data.node = 'B'   
  else
  {
    Radio.openWritingPipe(HOST);
    Radio.write(&Data, sizeof(Data));
  }

//Open Listening for all Pipe 
  Radio.openReadingPipe(0,HOST);
  Radio.openReadingPipe(1,Node[0]);
  Radio.openReadingPipe(2,Node[1]);
  Radio.openReadingPipe(3,Node[2]);
  Radio.startListening();
  }//Radio.available
}



Whandall

Good names need very little comments, your names are as already stated abysmal.
Code: [Select]
  char node[3];//This part is command from master node to another
  char id[4];//The list of node identity I try to order
  float value_1;//baterry value of node 1
  float value_2;//baterry value of node 2
  float value_3;//baterry value of node 3
  float value_4;//baterry value of node 4
  int h;//this is the mark/flag to figure it's from master node(0) or end node(1)
  long dat[3];//list of data has come per node

There is nothing to be sorted, the ids are sorted like the values with ascending node number.

Duplicate identical structs suck, please give some arguments for their usage.

There is still that one hundred second delay in the middle of the code,
which is sending 1001 identical packets (seems crazy to me).

You only have to repeat openReadingPipe when the address is changed.

Code: [Select]
      if (Data.node [1] == '1')//this part I like to test the communication by node sending continue with 100ms delay

Then why don't you care whether any write fails?
Despite the fact that this 'test' blocks the whole program for 100 seconds.

Code: [Select]
      Radio.openWritingPipe(BC);// write broadcast to another node telling command from master node
      Radio.write(&Data_1, sizeof(Data_1));

This does not deserve the name broadcast, it's a personal unicast needing ack.

I have no idea what your code should do, but does not.

From your usage of LL addresses it seems you use the outdated ManiacBug library.
I would suggest using http://tmrh20.github.io/RF24/index.html
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

totagsayogya

The part I want to display the sequnece communication aren't those but this :

Code: [Select]

  if (pipeNum == 1)//Data from node 2
      {
        Radio.read(&Data_2, sizeof(Data_2));
        Data.id[n] = Data_2.id; n=n+1;//In this part I try to order the incoming node communication
........


and I want to display it on master node with this:

Code: [Select]

Serial.print(Data.id[0]);
Serial.print(Data.id[1]);
Serial.print(Data.id[2]);
Serial.print(Data.id[3]);


I upload again my files abut it.

So this I try to figure when more than node send data almost in same time and I use multireciever and make the sequence of communication between end node and the router (node 1) and figure out how much battery cost.

Whandall

You don't describe what you want to achieve besides

Quote
So this I try to figure when more than node send data almost in same time and I use multireciever and make the sequence of communication between end node and the router (node 1) and figure out how much battery cost.
I see no connection between the order of reception and path cost.
I see no path information in the packets (maybe hidden in some node/dat/val fields.

You don't describe why your code does not meet your expectations.

You don't bother to change anything suggested, like names, identical structures, 100 seconds of deafness,

Code: [Select]
        for (i=0;i<=1000;i++)
        {
          delay(100);//this is not in second, but in milisec
but it is multiplied by 1000 which makes it 100 seconds.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

totagsayogya

yeah I know it no connection between the order of communication and the battery cost, I just want to know the information like that showing in my serial monitor. that for function i use to test the communication what if I send data 1000 times in that delay and how much battery drain.

this project is I want to know many information about the multireciever in nrf24

Whandall

I asked a couple of times in what respect your program doesn't fit your expectations,
nor have you told us what expectations you have.

Your 'test' is crap IMHO and makes all other nodes believe the master died.

You don't even look at the outcome of any send, so don't claim
this project is I want to know many information about the multireciever in nrf24
The order of incoming packets is probably rather random, I would not try to rely on any sequences.

If you are unable to describe what you want and what you don't get, I can not even try to help you.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

totagsayogya

Yeah I'm sorry for my question or my answer doesn't like what you want, this is my first time I use forum in the internet for asking programs. But my problem actually is the order of communication but it seems we are far away disccussing and make it to explain all of program. But your explaination makes me think more I've to improve my coding and how to explain to anoter person.

Back to what you telling about pipeNum, thank you very much. :smiley-lol:

Whandall

Study the datasheet, it's all in there, some information is hidden in notes and footnotes,
you will have to read it a couple of times probably.

Reading the library documentation (or browsing the library code) can help also.

From your usage of LL addresses it seems you use the outdated* ManiacBug library.
I still suggest using http://tmrh20.github.io/RF24/index.html.

* outdated = with known errors, slow, ...
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Go Up