Electron, nRF24L01 and Pro Mini

I forgot to answer you on the range, I only need in the neighborhood of about 20 feet. What type of range were you successful with?
Thanks

Now can you link to or post the Arduino code that does work for you?

The range was only a few hundred feet indoors. If all you need is 20 feet then it should work.

This is some code that I intially tested with a couple of Mega boards and the nRF24L01 radios. I was able to receive Hello World on the RX board.

http://starter-kit.nettigo.eu/2014/connecting-and-programming-nrf24l01-with-arduino-and-other-boards/

Ok, you might have been missing the line that tells the code which pins are the interrupt and CSN lines.

Change your CE Pin on the NRF24 to connect to D6 on the Electron.
Make sure the CSN Pin on the NRF24 connted to A2 on the Electron.

Try this Example Server Code

#include <RHReliableDatagram.h>
#include <RH_RF24.h>
#include <SPI.h>
#include "cellular_hal.h"
STARTUP(cellular_credentials_set("freedompop.foggmobile.com", "", "", NULL));

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Set up nRF24L01 radio on SPI bus, and pins(D6) & (A2) Photon
RH_RF24 driver(D6,A2);

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, SERVER_ADDRESS);

void setup()
{
  Serial.begin(9600);
  if (!manager.init())
    Serial.println("init failed");
  // Defaults after init are 434.0MHz, modulation GFSK_Rb5Fd10, power 0x10
}

uint8_t data[] = "And hello back to you";
// Dont put this on the stack:
uint8_t buf[RH_RF24_MAX_MESSAGE_LEN];

void loop()
{
  if (manager.available())
  {
    // Wait for a message addressed to us from the client
    uint8_t len = sizeof(buf);
    uint8_t from;
    if (manager.recvfromAck(buf, &len, &from))
    {
      Serial.print("got request from : 0x");
      Serial.print(from, HEX);
      Serial.print(": ");
      Serial.println((char*)buf);

      // Send a reply back to the originator client
      if (!manager.sendtoWait(data, sizeof(data), from))
        Serial.println("sendtoWait failed");
    }
  }
}

Try this new client code:

// rf24_reliable_datagram_client.pde
// -*- mode: C++ -*-
// Example sketch showing how to create a simple addressed, reliable messaging client
// with the RHReliableDatagram class, using the RH_RF24 driver to control a RF24 radio.
// It is designed to work with the other example rf24_reliable_datagram_server
// Tested on Anarduino Mini http://www.anarduino.com/mini/ with RFM24W and RFM26W

#include <RHReliableDatagram.h>
#include <RH_RF24.h>
#include <SPI.h>
#include "cellular_hal.h"
STARTUP(cellular_credentials_set("freedompop.foggmobile.com", "", "", NULL));

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Set up nRF24L01 radio on SPI bus, and pins(D6) & (A2) Photon
RH_RF24 driver(D6,A2);

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, CLIENT_ADDRESS);

void setup()
{
  Serial.begin(9600);
  if (!manager.init())
    Serial.println("init failed");
  // Defaults after init are 434.0MHz, modulation GFSK_Rb5Fd10, power 0x10
}

uint8_t data[] = "Hello World!";
// Dont put this on the stack:
uint8_t buf[RH_RF24_MAX_MESSAGE_LEN];

void loop()
{
  Serial.println("Sending to rf24_reliable_datagram_server");

  // Send a message to manager_server
  if (manager.sendtoWait(data, sizeof(data), SERVER_ADDRESS))
  {
    // Now wait for a reply from the server
    uint8_t len = sizeof(buf);
    uint8_t from;
    if (manager.recvfromAckTimeout(buf, &len, 2000, &from))
    {
      Serial.print("got reply from : 0x");
      Serial.print(from, HEX);
      Serial.print(": ");
      Serial.println((char*)buf);
    }
    else
    {
      Serial.println("No reply, is rf24_reliable_datagram_server running?");
    }
  }
  else
    Serial.println("sendtoWait failed");
  delay(500);
}

Thanks for the time you spent putting this together. The RX or client code though has to be built for an arduino mini pro. Sorry for the confusion.

Thank you

This is code on the Arduino Mini Client:

// -*- mode: C++ -*-
// Example sketch showing how to create a simple addressed, reliable messaging client
// with the RHReliableDatagram class, using the RH_NRF24 driver to control a NRF24 radio.
// It is designed to work with the other example nrf24_reliable_datagram_server
// Tested on Uno with Sparkfun WRL-00691 NRF24L01 module
// Tested on Teensy with Sparkfun WRL-00691 NRF24L01 module
// Tested on Anarduino Mini (http://www.anarduino.com/mini/) with RFM73 module
// Tested on Arduino Mega with Sparkfun WRL-00691 NRF25L01 module
#include <RHReliableDatagram.h>
#include <RH_NRF24.h>
#include <SPI.h>
#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2
// Singleton instance of the radio driver
//RH_NRF24 driver;
  RH_NRF24 driver(9, 10);   // For RFM73 on Anarduino Mini
// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, CLIENT_ADDRESS);
void setup() 
{
  Serial.begin(9600);
  if (!manager.init())
    Serial.println("init failed");
  // Defaults after init are 2.402 GHz (channel 2), 2Mbps, 0dBm
}
uint8_t data[] = "Hello World!";
// Dont put this on the stack:
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];
void loop()
{
  Serial.println("Sending to nrf24_reliable_datagram_server");
    
  // Send a message to manager_server
  if (manager.sendtoWait(data, sizeof(data), SERVER_ADDRESS))
  {
    // Now wait for a reply from the server
    uint8_t len = sizeof(buf);
    uint8_t from;   
    if (manager.recvfromAckTimeout(buf, &len, 2000, &from))
    {
      Serial.print("got reply from : 0x");
      Serial.print(from, HEX);
      Serial.print(": ");
      Serial.println((char*)buf);
    }
    else
    {
      Serial.println("No reply, is nrf24_reliable_datagram_server running?");
    }
  }
  else
    Serial.println("sendtoWait failed");
  delay(500);
}

And make sure you wire the NRF24 to the Ardunio Mini like this:

Not sure if it will work but maybe.

Basically copying the wiring to the Mini like this guy did here:

@RWB Thanks very much for your help on this. I tried as you suggested and found that it did not work “sendtoWait failed” is the serial print result. I will keep digging and looking around for a solution.

I appreciate your time

@jackpot, I promised I'd walk you through the lib contribution process.

But I just realised that this formerly internal thread is publicly accessible now so you could have a first look here

And if anything is still unclear, I'll be there and try to answer these questions.

Hope that helps for now

Thanks @ScruffR I appreciate it and Illl take a look:grin:

I would try the non raeliable datagram code because it’s more likely to work.

If that fails go for the RFM95 modules since they for sure work.

1 Like

I’m late to the discussion. I have many nights’ experience battling with radios.

I can confirm it works well if you follow my old nRF24L01 directions carefully in this post. You’ll easily get 20 feet range. My sample code dials down the data rate and that helps to get more range too.

(Alternatively, you can use RFM69 - modules are around $4 - and that is confirmed to work between Photon and Pro Mini. Sample code and reference in my post here.. However, @RWB provided links to other viable options too.)

To help make it easier, at the end I’m including some stripped down code to show you how the nRF24 code works on the Photon (in my case the Photon is exclusively the Receiver, except for sending acks, and I have a Pro Mini as the sender). If you find the example code from my instructions you’ll be able to figure it out.

PS: I can’t be sure about this theory. I have experienced the nRF24 radios working great for a few days to a few weeks, then would not successfully TX/RX for a few days and without inteference or restarting start to work again by itself. My theory is that WiFi routers in the area change channels that then conflict with the chosen channel (and because the system doesn’t continually broadcast the WiFi router, if it was smart enough, wouldn’t even know to avoid the channel). You can do some research on that and choose a higher number channel that puts you above most routers.

#include "particle-rf24/particle-rf24.h" //REMEMBER you need to PLUS and add the files in Web IDE or locally. 
//See https://community.particle.io/t/photon-nrf24l01-library-use-particle-rf24/21217?u=rwb&source_topic_id=32652


//RF section

/*
  PINOUTS
  http://docs.spark.io/#/firmware/communication-spi
  http://maniacbug.wordpress.com/2011/11/02/getting-started-rf24/

  PHOTON        SHIELD SHIELD    NRF24L01+
  GND           GND              1 (GND)
  3V3 (3.3V)    3.3V             2 (3V3)
  D6 (CSN)      9  (D6)          3 (CE)
  A2 (SS)       10 (SS)          4 (CSN)
  A3 (SCK)      13 (SCK)         5 (SCK)
  A5 (MOSI)     11 (MOSI)        6 (MOSI)
  A4 (MISO)     12 (MISO)        7 (MISO)

  NOTE: Also place a 10-100uF cap across the power inputs of
        the NRF24L01+.  
 */

// Set up nRF24L01 radio on SPI bus, and pins 9 (D6) & 10 (A2) on the Shield Shield
RF24 radio(D6,A2);



// NOTE: the "LL" at the end of the constant is "LongLong" type
const uint64_t pipes[2] = { 0xe7e7e7e7e7LL, 0xc2c2c2c2c2LL };

int16_t rec[1] = {99}; //for ack payload
int16_t lastmessage = 0; //for checking if a new message has arrived



//=========================SETUP===========================================
void setup(void) {
 
  radio.begin();
  delay(100);
  radio.setPALevel(RF24_PA_MAX); //RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX
  radio.setDataRate(RF24_250KBPS);   //for distance change to 250kbps
  radio.setChannel(1);  
  radio.setAutoAck(true);
  radio.enableAckPayload();
  radio.enableDynamicPayloads();
//  radio.setPayloadSize(8);
  
  radio.setRetries(15, 3);


  radio.openWritingPipe(pipes[1]); // note that our pipes are the same above, but that
  radio.openReadingPipe(1, pipes[0]); // they are flipped between rx and tx sides.
  radio.startListening();
  radio.printDetails();
  Serial.println("Radio started.");

}



//=========================MAIN LOOP===========================================
void loop() {


  rec[0] = message[4]; //for next ack show prior message number received
  lastmessage = message[4];

  if ( radio.available() )
  {

    
    if (radio.available()) //handy tip change due to TMRH20 library. see https://forum.arduino.cc/index.php?topic=302380.0
    {
      
      radio.writeAckPayload( 1, rec, sizeof(int16_t) );
      radio.read( message, sizeof(message) ); // Fetch the payload, and see if this was the last one.
      PrintValues();
    }


      radio.startListening();
   
  } //end of radio logic


 

}
3 Likes

From more experience, these NRF24’s are cheap and generally work well. But occasionally you’ll run into one that either doesn’t work at all, works inconsistently or only at close range. To save yourself some headache and wasted time, test those radios on a known working system, e.g. two Arduinos until you have a working Particle system. If you’ve confirmed the hardware works, then shift one of the radios to your Electron.

3 Likes

Just as a side note. I also struggled around with these radios and I got strange behaviour. In the end it turns out, that my PC-USB connector did not provide enough power. Attaching a battery/powersupply fixed my problems.

2 Likes

@bloukingfisher and @Pixinger Thank you both for your reply and the valuable information. I have been swapping out radios as you suggest with 'known good" hardware. Ill keep plugging along and investigate the rfm69 and the power issues suggested by both of you.

Thanks again for your time

BTW on the power issues, take note of the advice in the code to use a cap. Personally, I tested 10uF, 47uF and 100uF. In the end, it seemed like 10uF was working fine on the nRF24 whether powered from USB or a battery setup. The RFM69 didn't seem to have a problem without an additional cap when using it at low-medium power setting (say up to ~17). At max power setting (31) however, it would fail in a 'hang' situation when powered from battery (but fine with USB)

Sounds like the NRF2401+ radios are cheap but plagued with tons of issues.

I would just avoid them after hearing about all the troubles.

@bloukingfisher Thanks for pointing that out. For testing purposes I am using a dedicated 3.3v 3a power supply that is powering only the radio. I seem to be able to send my payload from the pro mini to the photon at this point and it is working great. When I use the same RX code on the Electron it does not work at all. Go figure!

@RWB, noted. Thank you

@jackpot I’ve not tested it on an Electron but I know on the Photon at one point I had concerns about the Photon’s wifi antenna. With a little separation between the devices (talking about inches) it was working fine. To rule out a problem with interference on the Electron’s cellular connection, can you check in serial if you receive the RX while turning off all radio functions?

Also, does your radio code use acks? Would be interesting to check on the Pro Mini whether it receives an ack back from the Electron indicating that the radio successfully received the message. You’ll see in my stripped down sample code that I use an ack on the Photon side to let the Pro Mini know the message was received.

1 Like

@bloukingfisher I see where you have used the ack in your code. No, I have not used it in my code but will try to add it. I will also take a look at what you suggest with the cellular radio.

Thank you again