Go Down

Topic: Display The Node Communication Sequence on Multiceiver nRF24l01 (Read 137 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)

Go Up