NRF24 problems

im having a really hard time figuring out what is going wrong with my code. i have a master device with 2 slave nrf devices that update to the master when requested by the master. i end up only receiving about 50% of my messages on paddress2. im simple telling the tx code to ask node 1 for status update then ask node 2 for status update in either order. the problem i cannot make it work everything is colliding together almost all the messages are droped. i end up receiving parts of nodes one message on node2 address. there isnt even any tutorial that explain how to do this ive looked.

We're having an even harder time seeing your code.

AWOL:
We're having an even harder time seeing your code.

i know its so large im trying to figure out how to upload it

sorry here is the code. and its real sloppy and messed up, i really would like to focus on the communication issues in the code almost everything else is not complete or wrong. strange this is i get 90 percent of rx2 messages it seems to be working besides trying to talk and listen to rx1 and 2 at the same time. but rx1 is acting strange along with tx talking to rx one is strange. starting at requestPh1(); and readPhResponse(); and requestStatus(); and readResponse(); those are what im working with

rx1.ino (2.97 KB)

tx.ino (15.5 KB)

rx2.ino (4.28 KB)

I only had a brief look at your TX program and I'm not surprised you are having trouble. It would be very difficult to figure out.

Have a look at this Simple nRF24L01+ Tutorial.

Wireless problems can be very difficult to debug so get the wireless part working on its own before you start adding any other features.

The examples are as simple as I could make them and they have worked for other Forum members. If you get stuck it will be easier to help with code that I am familiar with. Start by getting the first example to work

It includes an example for a master and 2 slaves that can easily be extended to a larger number of slaves.

...R

can someone explain to me exactly what the "1" in wirelessSPI.openReadingPipe(1, pAddress2); is doing exactly from what i understand "pipe0" is used by default for writing. so it would make sense that the first reading pipe would be opened on "pipe1" should i use 2 different addresses on the same pipe for heavy traffic like this because these status updates will be going out for each node every 500 to 1000ms.

Robin2:
I only had a brief look at your TX program and I'm not surprised you are having trouble. It would be very difficult to figure out.

Have a look at this Simple nRF24L01+ Tutorial.

Wireless problems can be very difficult to debug so get the wireless part working on its own before you start adding any other features.

The examples are as simple as I could make them and they have worked for other Forum members. If you get stuck it will be easier to help with code that I am familiar with. Start by getting the first example to work

It includes an example for a master and 2 slaves that can easily be extended to a larger number of slaves.

...R

I've look at your "tutorial's" though they are indeed useful they are not similar to what im trying to achieve.

if i simply only request from rx 2 everything is fine i dont think theres much problem with rx2. but in rx1 which is as simple as i could imagine it to be. i get back about 50 percent of my response from rx1. the problem gets even worse when trying to find a way to switch send recv state and get messages from both

If you're having a problem with RF24 comms, then you should post a program that deals exclusively with that problem. The concept is known as MCVE. That's the smallest possible code that actually compiles and clearly demonstrates the problem at hand. Cut out EVERYTHING else as it's just clutter. You're a lot more likely to get help with that rather than asking people to sort through 15KB+ of poorly-organized, messy code.

i have simplified the rx program the best i can but im still not getting optimal results the nrf24 cards are acting strange sometime i have to change the pipe address on both devices to something else to get them to communicate again. sometimes hard restting the power dont work after changing the pipe number from 1 - 2 can break the whole program this dont make sense what wrong with how i have the pipe and addresses setup???

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

const int pinCE = 22;
const int pinCSN = 24;
int state =0;
int statecounter =0;
unsigned long retryRefreshMarker = 0;
float Refresh = 2233.1122;
int updateState = 1;
float requestPh1 = 14.01;
float incomingArray9[32];
float ph1Request = 14.01;
float requestStatusCommand = 88.88;
float ph1Update = 14.14;
RF24 wirelessSPI(pinCE, pinCSN);
const uint64_t pAddress = 0xB00B1E5000F1;
const uint64_t pAddress2 = 0xB00B1E5000F0;

void setup()
{
  Serial.begin(9600);
  wirelessSPI.begin();
  wirelessSPI.setAutoAck(1);
  wirelessSPI.enableAckPayload();
  wirelessSPI.setRetries(5, 15);
  // wirelessSPI.openReadingPipe(1, pAddress);
  wirelessSPI.openReadingPipe(1, pAddress2);
  wirelessSPI.openWritingPipe(pAddress2);
  // wirelessSPI.stopListening();
  Serial.println("hello");
}

void loop() {
if (state == 1){
   readPhResponse();
 //  Serial.println("hi");
}
  
  if (millis() - retryRefreshMarker > 400) {
  if (updateState == 1){
   requestPh1Value();
   // requestStatus();
    updateState = 1;
   //  retryRefreshMarker = millis();
  }
  if (millis() - retryRefreshMarker > 500) {
requestStatus();
    retryRefreshMarker = millis();
    updateState = 1;
 
  }
}
}

void requestPh1Value() {
  //wirelessSPI.flush_tx();
  wirelessSPI.stopListening();
  wirelessSPI.openWritingPipe(pAddress2);
  //Serial.println("sending request");
  float Array2[1] = {ph1Request};
  if (!wirelessSPI.write( &Array2, sizeof(Array2))) {
    Serial.println("send failed");
    retryRefreshMarker = millis();
  }
  else {
 //  Serial.println("send successful");
    state = 1;
   
  }
}

void requestStatus() {
  //Serial.println("requesting status");
  wirelessSPI.stopListening();
  wirelessSPI.openWritingPipe(pAddress);
  float Array[1] = {requestStatusCommand};
  if (!wirelessSPI.write( &Array, sizeof(Array))) {
    Serial.println("status request failed");
  }
  else {
  Serial.println("status request sent");
     state = 1;
  }
}


 void readPhResponse() {
  if (statecounter >= 20){
    state = 0;
    statecounter = 0;
    //Serial.println("hi");
  }
  statecounter ++;
    wirelessSPI.stopListening();
  //  wirelessSPI.openReadingPipe(3, pAddress);
     wirelessSPI.openReadingPipe(1, pAddress2);
    wirelessSPI.startListening();
    while (wirelessSPI.available()) {
   //  Serial.println("starting phreadResponse");
      wirelessSPI.read( &incomingArray9, sizeof(incomingArray9) );
      float incomingResponse2 = float(incomingArray9[0]);
      wirelessSPI.flush_rx();
      //Serial.println(incomingArray9[0]);
      if (incomingResponse2 == ph1Update) {
        Serial.println("updated ph");
      }
                  if (incomingResponse2 == Refresh) {
           
              Serial.println("dose response");

            }
      else {
   //     Serial.println("read failed");
      }
    }
  }

i simply want to call “requestPh1Value();” every 500ms and “requestStatus();” every second without them working against each other. there must be somtehing very wrong with the logic

in this program im posting now i have requeststatus(); "aka “paddress2” pretty much working but i cannot get a response from requestPh1Value(): “paddress” paddress is getting the messagebut failing at sending the response it just fail… but it works if i disable paddress2?

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

const int pinCE = 22;
const int pinCSN = 24;
int state = 0;
int statecounter = 0;
unsigned long retryRefreshMarker = 0;
float Refresh = 2233.1122;
int updateState = 1;
float requestPh1 = 14.01;
float incomingArray9[32];
float ph1Request = 14.01;
float requestStatusCommand = 88.88;
float ph1Update = 14.14;
RF24 wirelessSPI(pinCE, pinCSN);
const uint64_t pAddress = 0xB00B1E5000F1;
const uint64_t pAddress2 = 0xB00B1E5000F2;

void setup()
{
  Serial.begin(9600);
  wirelessSPI.begin();
  wirelessSPI.setAutoAck(0);
  wirelessSPI.enableAckPayload();
  wirelessSPI.setRetries(2, 15);
  Serial.println("hello");
}

void loop() {
  if (state == 1) {
    readPhResponse();
    //  Serial.println("hi");
  }
////////////////////////////////////////////////////////////it all starts here
  if (millis() - retryRefreshMarker > 400) {
    if (updateState == 1) {
      requestPh1Value();
      // requestStatus();
      updateState = 0;
    //  retryRefreshMarker = millis();
    }
    if (millis() - retryRefreshMarker > 500) {
      requestStatus();
      retryRefreshMarker = millis();
      updateState = 1;
    }
  }
}
/////////////////////////////////////////////////////////request ends here
void requestPh1Value() {  /////first address send command to request a value
  //wirelessSPI.flush_tx();
  wirelessSPI.stopListening();
  wirelessSPI.openWritingPipe(pAddress2);
  //Serial.println("sending request");
  float Array2[1] = {ph1Request};
  if (!wirelessSPI.write( &Array2, sizeof(Array2))) {
    Serial.println("send failed");
    retryRefreshMarker = millis();
  }
  else {
    //  Serial.println("send successful");
    state = 1;   /////if message was sent then change this state to run readResponse();

  }
}

void requestStatus() {
  //Serial.println("requesting status");
  wirelessSPI.stopListening();
  wirelessSPI.openWritingPipe(pAddress);
  float Array[1] = {requestStatusCommand};
  if (!wirelessSPI.write( &Array, sizeof(Array))) {
    Serial.println("status request failed");
  }
  else {
    Serial.println("status request sent");
    state = 1;
  }
}


void readPhResponse() {
  if (statecounter >= 3) {
    state = 0;
    statecounter = 0;
    //Serial.println("hi");
  }
  statecounter ++;
  wirelessSPI.stopListening();
  wirelessSPI.openReadingPipe(1, pAddress);
  wirelessSPI.openReadingPipe(2, pAddress2);
  wirelessSPI.startListening();
  while (wirelessSPI.available()) {
    //  Serial.println("starting phreadResponse");
    wirelessSPI.read( &incomingArray9, sizeof(incomingArray9) );
    float incomingResponse2 = float(incomingArray9[0]);
    wirelessSPI.flush_rx();
    Serial.println(incomingArray9[0]);
    if (incomingResponse2 == ph1Update) {
      Serial.println("updated ph");
    }
    if (incomingResponse2 == Refresh) {

      Serial.println("dose response");

    }
    else {
      //     Serial.println("read failed");
    }
  }
}

ive been working on this for a week i dont know what else to do

ive simplified the code so many times and the results are the same. this new code is probably a lot easier to read. RX1 is working perfectly"so it seems" RX2 IS receiving the messages but failing to send the reply them. i take it im not opening the reading pipe properly. from what i read in the datasheet multiple pipes up to 6 pipes can be open for reading at once.

tx_simplified.ino (2.62 KB)

rx2_module_2_simple.ino (1.52 KB)

rx_module_1_simple.ino (1.48 KB)

@notsolowki, I count 6 Replies that you have posted in succession without allowing time for anyone to respond.

I have no intention of trying to make sense of all that.

In Reply #6 you say

I've look at your "tutorial's" though they are indeed useful they are not similar to what im trying to achieve

.

If you were to describe the way in which the requirements of your project differ from the closest example in my Tutorial it would give me a useful pointer about how to help.

...R

notsolowki:
ive simplified the code so many times and the results are the same.

I haven't tried to trace through the code yet, but I see glaring error right off the bat. It's an extraordinarily bad idea to try comparing 'float' variable for equality.

The NRF24’s implementation of multiple “pipes” is somewhat bizarre and bass-ackwards (IMO). Their apparent usefulness decreases as you understand more about how they work (always a good idea to read the datasheet). The best option for a simple application such as this is usually to stick to a single pipe.

Your handling of the 2 remotes is not well organized. I’d recommend using a state variable to ping-pong between them. Handle one at a time and see the request / response process all the way through to successful completion or timeout / failure before moving to the next remote. This way you’ll always know which remote you’re working with at any given time. I’ve done this with 2 remotes and an update period of 250ms (each remote polled every 500ms) without any problems. You can probably do it even faster.

After implementing a correct overall structure for the request / response process, you need decide on the exact technique. If you can use it, by far the simplest method is to take advantage of the slave’s ackPayload capability. The only down-side to this technique is that the response data is always one step behind the data currently available. But, if you’re polling regularly, and the data doesn’t change very quickly that really doesn’t matter. @Robin2’s tutorial illustrates the technique here:

If you really must have the data present at the request time, then use the technique here: http://forum.arduino.cc/index.php?topic=421081.msg2899629#msg2899629

But, the first step to using either technique will be to clean up the high level structure.