Go Down

Topic: Ready to use RF24 multiceiver  (Read 1 time) previous topic - next topic

Mogaraghu

Oct 22, 2017, 01:44 pm Last Edit: Oct 22, 2017, 01:49 pm by Mogaraghu
Was studying the "starping"example which is part of the  RF24 library. A very well done up code to be used both as a Rx Master and Tx Slaves.
But there were some bugs which prevented it from compiling like the one below : ( The radio.read() stetment returns this error : void value not ignored as it ought to be)
Code: [Select]

      bool done = false;
      while (!done)
      {
        // Fetch the payload, and see if this was the last one.
        done = radio.read( &got_time, sizeof(unsigned long) );

        // Spew it
        printf("Got payload %lu from node %i...",got_time,pipe_num+1);
      }


So sat down and used the code as a template and created three distinct codes - one for the central Master receiver and two slave Transmitters for which the actual working code is given below. This can help anyone trying to establish a  one-to-many RF24 link  without AckPayLoad.
Any bugs ? Not to my knowledge - but when both slaves are sending in data the Serial print of the Master struggles to keep up and expect some missed lines... not sure if this can be avoided at all...

This is the Master receiver code :

Code: [Select]

/*
  This code is for use as a Master receiver which can receive from 5 slaves.
  Adapted and simplified from an example by J. Coliz <maniacbug@ymail.com>
  The original example used a Generic code where the ping or pong back role was decided based on a hardware
  pin status.  Here we do not need that as we have separet codes for ping and pong units.

  The MCU used is a Nano 5V/16Mhz and connects to the nRF24L01+ module which is mounted on a
  socket adaptor that provides a 5V interface. This is better instead of directly trying to power
  RF24 module with 3.3V as when actual transmission happens the current demand is relatively high.
  Suggest keep the connections between Nano and the socket short - around 100mm max.

*/

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

// Set up nRF24L01 radio on SPI bus plus pins 7,8

RF24 radio(7, 8);

// Topology :
// Radio pipe addresses for the nodes to communicate.  Only ping nodes need
// dedicated pipes in this topology.  Each ping node has a talking pipe
// that it will ping into, and a listening pipe that it will listen for
// the pong.  The pong node listens on all the ping node talking pipes
// and sends the pong back on the sending node's specific listening pipe.
// We are planning for only two Ping nodes. This can be increased to 5 in similar fashion

const uint64_t talking_pipes[2] = { 0xF0F0F0F0D2LL, 0xF0F0F0F0C3LL };
const uint64_t listening_pipes[2] = { 0x3A3A3A3AD2LL, 0x3A3A3A3AC3LL };

// Address management :
// The Master pong back unit takes address 1 and rest of Slave ping take 2 to 6

uint8_t node_address = 1;   // This is Master.

const byte rfOkLed = 3;
const byte pinSS = 10;

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

void setup(void)
{
  Serial.begin(115200);
  printf_begin();
  printf("RF24 Module ROLE: Master (Pong)\n\r");
  printf("ADDRESS : 1\n\r");

  pinMode(pinSS, OUTPUT);
  SPI.begin();
  radio.begin();
  radio.setChannel(108);
  radio.setDataRate( RF24_1MBPS );
  radio.setPALevel(RF24_PA_MAX);
  radio.setRetries(5, 10);

  // The pong node listens on all the ping node talking pipes
  // and sends the pong back on the sending node's specific listening pipe.
  radio.openReadingPipe(1, talking_pipes[0]);
  radio.openReadingPipe(2, talking_pipes[1]);

  radio.startListening();
  radio.printDetails();                // Dump the configuration of the rf unit for debugging

  pinMode(rfOkLed, OUTPUT);
  digitalWrite(rfOkLed, HIGH);
  delay(2000);
  digitalWrite(rfOkLed, LOW);
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

void loop(void)
{
  // Pong back Master.  Receive each packet, display it out, and send it back

  uint8_t pipe_num;
  unsigned long got_time;
  
  if ( radio.available(&pipe_num) )
  {
    radio.read( &got_time, sizeof(unsigned long) );          // Fetch the payload
    printf("Got payload %lu from node %i...", got_time, pipe_num + 1);
  }
   delay(5);                                                // Without this the above print does not complete most times..

  radio.stopListening();                                     // Get ready to send
  radio.openWritingPipe(listening_pipes[pipe_num - 1]);
  uint16_t pipe_id = listening_pipes[pipe_num - 1] & 0xffff; // Retain the low 2 bytes to identify the pipe for the spew

  if (radio.write( &got_time, sizeof(unsigned long)))
  {
    digitalWrite(rfOkLed, HIGH);
    printf("Sent response to %04x.\n\r", pipe_id);
  }
  else
  {
    digitalWrite(rfOkLed, LOW);
  }

  radio.startListening();                                    // Now, resume listening so we catch the next packets.
}


//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


This is Slave 01 Transmitter code :

Code: [Select]

/*
  This code is for use as Slave transmitter to a Master receiver which can
  receive from 5 such slaves. Adapted and simplified from an example by J. Coliz <maniacbug@ymail.com>
  The original example used a Generic code where the ping or pong back role was decided based on a hardware
  pin status.  Here we do not need that as we have separet codes for ping and pong units.

  The MCU used is a Nano 5V/16Mhz and connects to the nRF24L01+ module which is mounted on a
  socket adaptor that provides a 5V interface. This is better instead of directly trying to power
  RF24 module with 3.3V as when actual transmission happens the current demand is relatively high.
  Suggest keep the connections between Nano and the socket short - around 100mm max.

*/

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

// Set up nRF24L01 radio on SPI bus plus pins 7,8

RF24 radio(7, 8);

// Topology :
// Radio pipe addresses for the nodes to communicate.  Only ping nodes need
// dedicated pipes in this topology.  Each ping node has a talking pipe
// that it will ping into, and a listening pipe that it will listen for
// the pong.  The pong node listens on all the ping node talking pipes
// and sends the pong back on the sending node's specific listening pipe.

const uint64_t talking_pipe = 0xF0F0F0F0D2LL;
const uint64_t listening_pipe = 0x3A3A3A3AD2LL;

// Address management :
// The Master pong back unit takes address 1 and rest of Slave ping take 2 to 6

uint8_t node_address = 2;   // This is slave no 1.

const byte rfOkLed = 3;
const byte pinSS = 10;

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

void setup(void)
{
  Serial.begin(115200);
  printf_begin();
  printf("RF24 Module ROLE: Slave 01 (Ping)\n\r");
  printf("ADDRESS : 2\n\r");

  pinMode(pinSS, OUTPUT);
  SPI.begin();
  radio.begin();
  radio.setChannel(108);
  radio.setDataRate( RF24_1MBPS );
  radio.setPALevel(RF24_PA_MAX);
  radio.setRetries(5, 10);

  radio.openWritingPipe(talking_pipe);      // Write to RxMaster on our talking pipe
  radio.openReadingPipe(1, listening_pipe); // Listen to RxMaster on our listening pipe

  radio.startListening();
  radio.printDetails();                       // Dump the configuration of the rf unit for debugging

  pinMode(rfOkLed, OUTPUT);
  digitalWrite(rfOkLed, HIGH);
  delay(2000);
  digitalWrite(rfOkLed, LOW);
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

void loop(void)
{
  radio.stopListening();                     // Stop listening so we can send

  unsigned long time = millis();
  //printf("Now sending %lu...", time);
  radio.write( &time, sizeof(unsigned long) );  // WRITE TO MASTER

  radio.startListening();                    // Now, Resume listening

  unsigned long started_waiting_at = millis(); // Wait here until we get a response, or timeout (250ms)
  bool timeout = false;
  while ( ! radio.available() && ! timeout )
    if (millis() - started_waiting_at > 250 )  timeout = true;

  if ( timeout )                              // Transmission failed...
  {
    printf("Failed, response timed out.\n\r");
    digitalWrite(rfOkLed, LOW);
  }
  else
  {
    unsigned long got_time;
    radio.read( &got_time, sizeof(unsigned long)); // READ FROM MASTER
    printf("Got response %lu, round-trip delay: %lu\n\r", got_time, millis() - got_time);
    digitalWrite(rfOkLed, HIGH);
  }

  delay(900);                                // Adjust the interval of sending here..
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


The code for Slave 02 is same as above - except that you need to change the talkingPipe  as 0xF0F0F0F0C3LL and listeningPipe as 0x3A3A3A3AC3LL and node_address to 3.


bidhanpodder

Thanks a lot! I am looking after for this solution.

Robin2

Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up