1

I have 3 nodes in my system. One centralNode and two sensor nodes (right and left).
Sensor nodes transmit data to the centralNode and receive from it. centralNode may transmit to both nodes and receive from them.

I'm using an Arduino nano for central node and Uno and Mega for sensor nodes. I'm using nRF24's base module (with regulators and caps and all) but one node does not have base module (Although I've given it a descent 3.3 V and bypass caps).

Here is my problem:
1- It seems the centralNode can't detect which nodes data it is receiving. I can sometimes get it to work using different delays for sensorNodes but again, on reset it messes up the data. How can I detect which data's reading the centralNode is receiving?

2- How can I use radio.available(??) I've put 0, 1 , 2 and pipe addresses in ?? but it does not work (prints garbage data) radio.available's API

Here are the codes: centralNode:

/*
   Testing multi-node functionality of nRF24l01+
   This is centralNode code

   BOM
   1 Arduino Nano centralNode
   1 Ardiuno Uno rightSensorNode
   1 Arduino Mega leftSensorNode
   3 nRF24l01+
*/

#include <SPI.h>
#include "RF24.h"
#include <printf.h>

#define CEpin 6
#define CSpin 7

RF24 radio(CEpin, CSpin);
byte addresses [][6] = {"1Node", "2Node", "3Node"};

int rightNodeCount = 0;
int leftNodeCount = 0;
void setup() {
  Serial.begin(115200);
  Serial.println(F("This is the central node"));
  printf_begin();
  radio.begin();
  radio.setPALevel(RF24_PA_MAX);

  radio.openWritingPipe(addresses[0]);
  radio.openReadingPipe(1, addresses[1]);
  radio.openReadingPipe(2, addresses[2]);
  radio.startListening();
  radio.printDetails();
}

void loop() {
  if (radio.available()) {
    radio.read(&rightNodeCount, sizeof(rightNodeCount));
    radio.read(&leftNodeCount, sizeof(leftNodeCount));
  }
  //  if (radio.available(1)) {
  //    radio.read(&leftNodeCount, sizeof(leftNodeCount));
  //  }
  Serial.println("centralNode is reporting:");
  Serial.print("centralNode address : ");
  Serial.println((char *)addresses[0]);

  Serial.print("rightNode address : ");
  Serial.println((char *)addresses[1]);
  Serial.print("rightNodeCount = ");
  Serial.println(rightNodeCount);

  Serial.print("leftNode address : ");
  Serial.println((char *)addresses[2]);
  Serial.print("leftNodeCount = ");
  Serial.println(leftNodeCount);

  Serial.println("---END OF REPORT---\n\n\n\n");
  delay(500);
}

rightSensorNode:

/*
   Testing multi-node functionality of nRF24l01+
   This is rightSensorNode code

   BOM
   1 Arduino Nano centralNode
   1 Ardiuno Uno rightSensorNode
   1 Arduino Mega leftSensorNode
   3 nRF24l01+
*/

#include <SPI.h>
#include "RF24.h"
#include <printf.h>

#define CEpin 7
#define CSpin 8

RF24 radio(CEpin, CSpin);
byte addresses [][6] = {"1Node", "2Node", "3Node"};

int rightNodeCount = 0;
void setup() {
  Serial.begin(115200);
  Serial.println(F("This is the right node"));
  printf_begin();


  radio.begin();
  radio.setPALevel(RF24_PA_MAX);

  radio.openWritingPipe(addresses[1])

  radio.printDetails();

}

void loop() {
  rightNodeCount++;
  Serial.println("Sending data to centralNode");
  Serial.print("rightNode address : ");
  Serial.println((char *)addresses[1]);
  Serial.print("rightNodeCount = ");
  Serial.println(rightNodeCount);
  radio.write(&rightNodeCount, sizeof(rightNodeCount));

  Serial.println("---END OF REPORT---\n\n\n\n");
  delay(1000);
}

leftSensorNode:

/*
   Testing multi-node functionality of nRF24l01+
   This is leftSensorNode code

   BOM
   1 Arduino Nano centralNode
   1 Ardiuno Uno rightSensorNode
   1 Arduino Mega leftSensorNode
   3 nRF24l01+
*/

#include <SPI.h>
#include "RF24.h"
#include <printf.h>

#define CEpin 7
#define CSpin 8

RF24 radio(CEpin, CSpin);

byte addresses [][6] = {"1Node", "2Node", "3Node"};

int leftNodeCount = 0;
void setup() {
  Serial.begin(115200);
  Serial.println(F("This is the left node"));
  printf_begin();

  radio.begin();
  radio.setPALevel(RF24_PA_MAX);

  radio.openWritingPipe(addresses[2]);


  radio.printDetails();

}

void loop() {
  leftNodeCount++;
  Serial.println("Sending data to centralNode");
  Serial.print("leftNode address : ");
  Serial.println((char *)addresses[2]);
  Serial.print("leftNodeCount = ");
  Serial.println(leftNodeCount);
  radio.write(&leftNodeCount, sizeof(leftNodeCount));

  Serial.println("---END OF REPORT---\n\n\n\n");
  delay(1000);
}
5
  • 1
    Have thought about embedding an ID into the transmission and appending each transmission with a checksum?
    – Andy aka
    Jun 11, 2017 at 10:57
  • @Andyaka 1- Good idea but I have already 32 byte limitation in packet transmission. 2- I think nRF24 does have default CRC checksum. Jun 11, 2017 at 11:05
  • Without an ID, you cannot reliably detect the transmission source or do you have a cunning plan that you haven't mentioned?
    – Andy aka
    Jun 11, 2017 at 11:07
  • @Andyaka I guess TMRH's RF24 library's available() method does take this issue into account. I don't know how to use it. tmrh20.github.io/RF24/… Jun 11, 2017 at 11:33
  • You could use the pipe addresses as the ID for a small number of nodes by using a different one for each. Jun 11, 2017 at 11:51

1 Answer 1

2

Each sensor point should send its address to the central point and this is how the central point knows the source of the message. Then after the central point receives a message, after if (radio.available()) command receive the data just once (not twice) and then use another if statement to determine which sensor has sent a message (by reading the sent address) and then print.

pseudo code:

if (radio.available())
{
    radio.read(&RXbuffer, sizeof(RXbuffer));
    if(RXbuffer.address == sensor1_address)
    {
        print "this is sensor 1"
        print RXbuffer.address;
        print RXbuffer.data;
    }
    else if(RXbuffer.address == sensor2_address)
    {
        print "this is sensor 2"
        print RXbuffer.address;
        print RXbuffer.data;
    }
}

In your code (inside if (radio.available())) you are trying to receive rightNodeCount and lefteNodeCount eventhough at that time just one of them was received.

EDIT:

It seems that RF24 uses dedicated pipes to know the source of the information. The following code should work:

pseudo code:

unsigned char pipe_num;

if (radio.available(&pipe_num))
{
    radio.read(&data, sizeof(data));

    if(pipe_num == 1)
    {
        print "this is sensor 1";
        print data;
    }
    else if (pipe_num == 2)
    {
        print "this is sensor 2";
        print data;
    }
}
5
  • Thanks but in this method, you are sending an struct I guess? As I said, nRF has 32 Byte limitation in each packet so it would be wasteful use of bandwidth. I'm suspecting that this issue can be solved using radio.available(&pipeNum) method but I don't know how...tmrh20.github.io/RF24/… Jun 11, 2017 at 11:35
  • Here I have used a structure as an example (pseudo code). You can create a union data type to be able to use a structure and an array interchangeably. Or you can use just a simple array. It depends totally on your application.
    – Macit
    Jun 11, 2017 at 14:01
  • I have edited my answer to use pipes. It should work. If not feel free to share and inform us of your progress.
    – Macit
    Jun 11, 2017 at 14:33
  • It seems finally I got it. Actually it seems the client should not pass the desired pipeNum to the available(&pipeNum) method. You first declare a uint8_t pipeNum; then the available method fills the pipe number it is listening to into the pipeNum variable. Do you also confirm this? Jun 12, 2017 at 8:22
  • @Zeta.Investigator Oops it seems that pipeNum is filled automatically. It is loaded by the number of the pipe that has received the message. So you are right. Look at the code above.
    – Macit
    Jun 12, 2017 at 10:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.