dparson55 / NRFLite

nRF24L01+ library with AVR 2 pin support, requiring very little code along with YouTube videos showing all available features.
MIT License
161 stars 27 forks source link

Software based two way communication sometimes fails #49

Closed dparson55 closed 4 years ago

dparson55 commented 4 years ago

Rob asks:

I've been getting started with NRFLite - for fun I've built a 4 wheel drive robot [4 stepper motors & drivers] and I'm using your libraries to send data to it - this is working fine. I then added a LIDAR VL53L0X on a servo to scan ahead and send the data back - this also works fine except the data is only received intermittently...I'm probably doing this in the dumbest way possible - if you can point me at any doc/refs etc which may help I'd really appreciate it;

Here's roughly what I'm doing....

On the transmitter

loop
{
   TXData
   delay
   RXData
   delay
}

On the robot - it only sends data after a full left/right or right/left scan - so sends data twice second at most;

loop
{
   RXData
   delay
   if(data is ready to send)
   {
      TXData
   }
}

for RX and TX I've copied the examples ish;

void  TXData()
{
  if(_radio.send(DESTINATION_RADIO_ID, &_radioDataTX, sizeof(_radioDataTX), NRFLite::REQUIRE_ACK))
  {
    Serial.println("TXData ok");
  }
  else
  {
    Serial.println("TXData failed");
  }
}

bool RXData()
{
  bool ret = false;

  if (_radio.hasData())
  {
    _radio.readData(&_radioDataRX); // Note how '&' must be placed in front of the variable name.   
    Serial.println("RXData ok");   
    ret = true;
  }

  return ret;
}
dparson55 commented 4 years ago

One limitation with these radios is they cannot send and receive data at the same time, they need to be in either RX or TX mode. After looking at your code my first thought is the radio on the transmitter side is not in RX mode when the robot attempts to send data.

When send is called, internally NRFLite puts the radio into TX mode and leaves it there. So on your transmitter, when data is sent and a wait is performed via delay, the radio will not be able to receive any data from the robot during this entire time. The moment hasData is called the radio will go back into RX mode, and data can be received again. Considering this, if the size of the two delays are the same, the radio on the transmitter side will only be able to receive data about half the time.

To solve the problem, change your loops to follow the logic below. It's subtle but with this change the radio on both the transmitter and robot sides will almost always be in RX mode, allowing either to send data to the other when needed. Note how all the delays are gone and during every loop iteration you are checking, and can respond to, any new data.

loop
{
  if (shouldTransmit) // set this to true during a button press or certain amount of time passing or some other event
  {
    shouldTransmit = false
    TXData
  }

  RXData
}

Read through the example TwoWayCom_SoftwareBased_RX for more detail.