Jump to content
spirilis

[Energia Library] Nordic nRF24L01+ library

Recommended Posts

I have 2 modules and tried with both of them. The modules are atleast 2 years old and I think those might be destroyed by ESD as they were lying in a box with other misc electronics stuff.

 

 

I'll order a new ones and try with those when they arrive. In the mean time I think I could hook up the modules to bus analyzer at work to see that are those responding at all. Thanks for the quick answers.

Share this post


Link to post
Share on other sites

I just tested the modules with arduino at work and seems like those are working ok. I can read the registers, send data etc.

 

If I do fresh install of energia from the windows installer do I need to patch it to get the modules working? I have been reading from this forum and from some blogs that energia has to be patched to get SPI working correctly.

If energia needs to be patched how it is done? I earlier replaced energia SPI files with github SPI files but it didn't help to get the modules working.

Share this post


Link to post
Share on other sites

The patch is needed to get serial and SPI working together. It is done against the Energia core files for the msp430 platform. Follow the info in my other thread (pretty sure I posted a link to it in this thread)

 

Sent from my Galaxy Note II with Tapatalk

 

 

Share this post


Link to post
Share on other sites

Patching the usci_isr_handler seemed to work. Now both modules are working and sending data through two 6inch concrete walls. I'm more than happy about the transmission distance of these small modules.

 

Thanks again.

Share this post


Link to post
Share on other sites

@@spirilis, this library is truly great, I have played around with it with great success.

 

I am looking into having a broadcasting system in my deployment, and would thus require an additional pipe in the library. Would you be so kind to point me in the right direction, how to go about implementing it. But it is a simple idea of having a pipe with the device address as done now, plus an additional broadcast pipe.

 

The final idea is to implement a simple distance vector routing algorithm on the system then.

Share this post


Link to post
Share on other sites

@@spirilis, this library is truly great, I have played around with it with great success.

 

I am looking into having a broadcasting system in my deployment, and would thus require an additional pipe in the library. Would you be so kind to point me in the right direction, how to go about implementing it. But it is a simple idea of having a pipe with the device address as done now, plus an additional broadcast pipe.

 

The final idea is to implement a simple distance vector routing algorithm on the system then.

Well now you gave me a use-case for that, I'll see about extending the library a bit :)

 

Sent from my Galaxy Note II with Tapatalk

 

 

Share this post


Link to post
Share on other sites

Could someone please suggest tested and working setup with StellarPad? I tried a couple of different wirings, but all I am getting from Rxdemo is "NO TRANSCEIVER PRESENT". Thanks a lot!

Share this post


Link to post
Share on other sites

Could someone please suggest tested and working setup with StellarPad? I tried a couple of different wirings, but all I am getting from Rxdemo is "NO TRANSCEIVER PRESENT". Thanks a lot!

Well, I was going to test it on mine (barely took it out of the box, have had it almost a year now) but Energia is complaining about not knowing about SPI.h .... so I dunno.  I never tested it, someone else did.  I also see now that Energia on the Stellaris does weird stuff with the SPI Slave Select pin, or tries to auto-manage it or something.

Share this post


Link to post
Share on other sites

Ok, got it working, had to restart Energia to get it to start looking at the lm4f directory for hardware libraries...

 

This sketch worked with my Nordic Boosterpack, default pinouts (P2.0/P2.1/P2.2 in MSP430 land, which is PA_5, PA_6, PA_7 in Stellaris LP land)

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

Enrf24 radio(PA_5,PA_6,PA_7);

void setup() {
  SPI.begin();
  radio.begin();
  radio.setCRC(true, true);
  radio.setTXaddress("myrf1");
}

void loop() {
  radio.print('1');
  radio.flush();
  delay(500);
  radio.print('0');
  radio.flush();
  delay(250);
}

I had another device (F5172 launchpad, app written in C not using Energia, but that shouldn't matter worth a snot here) listening at RF address "myrf1" for those packets, flipping its LED on/off as needed.  The Stellaris LP does a proper job transmitting data with this config.

 

So that is nRF24 pins:

Vcc = 3.3V

GND = GND

CE = PA_5

CSN = PA_6

IRQ = PA_7 (this isn't used for an actual IRQ, but monitored with digitalRead() internally to wait for a transmit to complete)

SCK/MOSI/MISO in the usual spots (PB_4/PB_7/PB_6 respectively, i.e. SPI module #2, default for the default SPI lib that ships with Energia)

Share this post


Link to post
Share on other sites

 

Hello,
Is it possible this library be used with Arduino?
For example: Arduino <--------> MSP430 Lanchpad or Arduino <--------> Stellaris Lanchpad.
What is Arduino compatible library: Mirf or RF24?

 

Shouldn't be any problem using this to interface with another MCU, just make sure the settings match ... that's for you to figure out, but here are defaults for some of the ancillary params:

 

Dynamic Payload Sizes = ON

CRC settings should match (default = ON w/ 8-bit CRC)

AutoACK should be ON

Address Length defaults to 5-bytes

Share this post


Link to post
Share on other sites

Shouldn't be any problem using this to interface with another MCU, just make sure the settings match ... that's for you to figure out, but here are defaults for some of the ancillary params:

 

Dynamic Payload Sizes = ON

CRC settings should match (default = ON w/ 8-bit CRC)

AutoACK should be ON

Address Length defaults to 5-bytes

Thank Spirlis!
 
I will try to enable communication with the Arduino UNO and Mirf library.
I noticed that your library is more similar to Mirf library.
Do you already have an example of the Arduino Mirf by which I can do testing?

Share this post


Link to post
Share on other sites

I tried this example which I found at the following link: http://arduino-info.wikispaces.com/nRF24L01-Mirf-Examples , but without success.

/**
 * An Mirf example which copies back the data it recives.
 *
 * Pins:
 * Hardware SPI:
 * MISO -> 12
 * MOSI -> 11
 * SCK -> 13
 *
 * Configurable:
 * CE -> 8
 * CSN -> 7
 *
 */

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

void setup()
{
  Serial.begin(9600);
  
  Mirf.init();
  
  // name the receiving channel - must match tranmitter setting!
  Mirf.setRADDR((byte *)"TX_01");
  
  // just a single byte is transmitted
  Mirf.payload = 1;

  // we use channel 90 as it is outside of WLAN bands 
  // or channels used by wireless surveillance cameras 
  Mirf.channel = 0; // chanel 0
  
  // now config the device.... 
  Mirf.config();  
  
  // Set 1MHz data rate - this increases the range slightly
  Mirf.configRegister(RF_SETUP,0x06);
}

void loop()
{

  byte c; 

  // is there any data pending? 
  if( Mirf.dataReady() )
  {
     // well, get it
     Mirf.getData(&c);

    // ... and write it out to the PC
     Serial.print(c);
  }
}

Example of sending for MSP430.

#include <Enrf24.h>
#include <nRF24L01.h>
#include <string.h>
#include <SPI.h>

Enrf24 radio(P2_0, P2_1, P2_2);  // P2.0=CE, P2.1=CSN, P2.2=IRQ
//const uint8_t txaddr[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x01 };
const uint8_t txaddr[] = "TX_01";

const char *str_on = "ON";
const char *str_off = "OFF";

void dump_radio_status_to_serialport(uint8_t);

void setup() {
  Serial.begin(9600);

  SPI.begin();
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(1); // MSB-first

  radio.begin();  // Defaults 1Mbps, channel 0, max TX power
  dump_radio_status_to_serialport(radio.radioState());

  radio.setTXaddress((void*)txaddr);
}

void loop() {
  Serial.print("Sending packet: ");
  Serial.println(str_on);
  radio.print(str_on);
  radio.flush();  // Force transmit (don't wait for any more data)
  dump_radio_status_to_serialport(radio.radioState());  // Should report IDLE
  delay(1000);

  Serial.print("Sending packet: ");
  Serial.println(str_off);
  radio.print(str_off);
  radio.flush();  //
  dump_radio_status_to_serialport(radio.radioState());  // Should report IDLE
  delay(1000);
}

void dump_radio_status_to_serialport(uint8_t status)
{
  Serial.print("Enrf24 radio transceiver status: ");
  switch (status) {
    case ENRF24_STATE_NOTPRESENT:
      Serial.println("NO TRANSCEIVER PRESENT");
      break;

    case ENRF24_STATE_DEEPSLEEP:
      Serial.println("DEEP SLEEP <1uA power consumption");
      break;

    case ENRF24_STATE_IDLE:
      Serial.println("IDLE module powered up w/ oscillators running");
      break;

    case ENRF24_STATE_PTX:
      Serial.println("Actively Transmitting");
      break;

    case ENRF24_STATE_PRX:
      Serial.println("Receive Mode");
      break;

    default:
      Serial.println("UNKNOWN STATUS CODE");
  }
}
Communication MSP430 <-> MSP430, Stellaris <-> Stellaris and Stellaris <-> MSP430 works great.
?xcellent library Spirlis :)
The problem is that currently I do not have two arduino's to try Arduino <-> Arduino to know if the problem is to Mirf library.

Share this post


Link to post
Share on other sites

Thanks!  It may actually be possible to get Enrf24 working under Arduino too if you edit the Enrf24.cpp and change #include <Energia.h> to #include <Arduino.h> ... never actually tried it though.  IIRC there's nothing fancy TI-related about the code.

 

Actually I might just do that in the code for good.  Energia comes with an Arduino.h that just #include's "Energia.h" anyhow.

edit: Git version has this change now.  https://github.com/spirilis/Enrf24

Share this post


Link to post
Share on other sites

Thanks!  It may actually be possible to get Enrf24 working under Arduino too if you edit the Enrf24.cpp and change #include <Energia.h> to #include <Arduino.h> ... never actually tried it though.  IIRC there's nothing fancy TI-related about the code.

 

Actually I might just do that in the code for good.  Energia comes with an Arduino.h that just #include's "Energia.h" anyhow.

edit: Git version has this change now.  https://github.com/spirilis/Enrf24

Thanks!
I made a test with Arduino and MSP430 lanchpad!
Arduino works in the role of transmitter but does not work in the role of receiver.
 
Here are the results of testing:
 
Arduino_TX ------> MSP430_RX
post-31374-0-59637700-1380654945_thumb.png
 
MSP430_TX ------>ARDUINO_RX
post-31374-0-81348900-1380654959_thumb.png
 
Very rarely happens when switching on the console to appear next result.
post-31374-0-27908100-1380655197_thumb.png
 
Arduino _TX code
#include <Enrf24.h>
#include <nRF24L01.h>
#include <string.h>
#include <SPI.h>

//Enrf24 radio(P2_0, P2_1, P2_2);  // P2.0=CE, P2.1=CSN, P2.2=IRQ
Enrf24 radio(8, 7, 4);
const uint8_t txaddr[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x01 };

const char *str_on = "ON";
const char *str_off = "OFF";

void dump_radio_status_to_serialport(uint8_t);

void setup() {
  Serial.begin(9600);

  SPI.begin();
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(1); // MSB-first

  radio.begin();  // Defaults 1Mbps, channel 0, max TX power
  dump_radio_status_to_serialport(radio.radioState());

  radio.setTXaddress((void*)txaddr);
}

void loop() {
  Serial.print("Sending packet: ");
  Serial.println(str_on);
  radio.print(str_on);
  radio.flush();  // Force transmit (don't wait for any more data)
  dump_radio_status_to_serialport(radio.radioState());  // Should report IDLE
  delay(1000);

  Serial.print("Sending packet: ");
  Serial.println(str_off);
  radio.print(str_off);
  radio.flush();  //
  dump_radio_status_to_serialport(radio.radioState());  // Should report IDLE
  delay(1000);
}

void dump_radio_status_to_serialport(uint8_t status)
{
  Serial.print("Enrf24 radio transceiver status: ");
  switch (status) {
    case ENRF24_STATE_NOTPRESENT:
      Serial.println("NO TRANSCEIVER PRESENT");
      break;

    case ENRF24_STATE_DEEPSLEEP:
      Serial.println("DEEP SLEEP <1uA power consumption");
      break;

    case ENRF24_STATE_IDLE:
      Serial.println("IDLE module powered up w/ oscillators running");
      break;

    case ENRF24_STATE_PTX:
      Serial.println("Actively Transmitting");
      break;

    case ENRF24_STATE_PRX:
      Serial.println("Receive Mode");
      break;

    default:
      Serial.println("UNKNOWN STATUS CODE");
  }
}

Arduino_RX code

#include <Enrf24.h>
#include <nRF24L01.h>
#include <string.h>
#include <SPI.h>

//Enrf24 radio(P2_0, P2_1, P2_2);
Enrf24 radio(8, 7, 4);
const uint8_t rxaddr[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x01 };

const char *str_on = "ON";
const char *str_off = "OFF";

void dump_radio_status_to_serialport(uint8_t);

void setup() {
  Serial.begin(9600);

  SPI.begin();
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(1); // MSB-first
  
  radio.begin();  // Defaults 1Mbps, channel 0, max TX power
  dump_radio_status_to_serialport(radio.radioState());

  radio.setRXaddress((void*)rxaddr);
  
  pinMode(A0, OUTPUT);
  digitalWrite(A0,LOW);
  
  radio.enableRX();  // Start listening
}

void loop() {
  char inbuf[33];
  
  dump_radio_status_to_serialport(radio.radioState());  // Should show Receive Mode
 while (!radio.available(true));
    
  if (radio.read(inbuf)) {
   Serial.print("Received packet: ");
   Serial.println(inbuf);

 if (!strcmp(inbuf, str_on))
      digitalWrite(A0, HIGH);
    if (!strcmp(inbuf, str_off))
      digitalWrite(A0, LOW);
  }
 
}

void dump_radio_status_to_serialport(uint8_t status)
{
  Serial.print("Enrf24 radio transceiver status: ");
  switch (status) {
    case ENRF24_STATE_NOTPRESENT:
      Serial.println("NO TRANSCEIVER PRESENT");
      break;

    case ENRF24_STATE_DEEPSLEEP:
      Serial.println("DEEP SLEEP <1uA power consumption");
      break;

    case ENRF24_STATE_IDLE:
      Serial.println("IDLE module powered up w/ oscillators running");
      break;

    case ENRF24_STATE_PTX:
      Serial.println("Actively Transmitting");
      break;

    case ENRF24_STATE_PRX:
      Serial.println("Receive Mode");
      break;

    default:
      Serial.println("UNKNOWN STATUS CODE");
  }
}
 

Share this post


Link to post
Share on other sites

 

Thanks!
I made a test with Arduino and MSP430 lanchpad!
Arduino works in the role of transmitter but does not work in the role of receiver.

 

Strange... Maybe doublecheck the code again?  I did a perusal through the Enrf24 source, I don't see any reason it wouldn't work.  It's using all the arduino-abstracted calls like digitalRead, digitalWrite et al.  From what I've been able to gather, the nRF24L01+ provides its own pullup on the IRQ line, but if you'd like to try a variation, go into Enrf24.cpp and find the Enrf24::begin() function...

 

In here:

/* Initialization */
void Enrf24::begin(uint32_t datarate, uint8_t channel)
{
  pinMode(_cePin, OUTPUT);
  digitalWrite(_cePin, LOW);
  pinMode(_csnPin, OUTPUT);
  digitalWrite(_csnPin, HIGH);
  pinMode(_irqPin, INPUT);
  digitalWrite(_irqPin, LOW);  // No pullups; the transceiver provides this!

Change pinMode(_irqPin, INPUT); to pinMode(_irqPin, INPUT_PULLUP);

 

It is possible the nRF24's pullup goes to 3.3V or something, in which case the arduino might not see it as a proper "HIGH" level (it should, but, hard to say).  Let me know if this helps, if so I should make it default behavior for the library (since it won't hurt things on the MSP430 or Stellaris platforms).

Share this post


Link to post
Share on other sites

I made the changes as you said but again does not work.

/* Initialization */
void Enrf24::begin(uint32_t datarate, uint8_t channel)
{
  pinMode(_cePin, OUTPUT);
  digitalWrite(_cePin, LOW);
  pinMode(_csnPin, OUTPUT);
  digitalWrite(_csnPin, HIGH);
  //pinMode(_irqPin, INPUT);
  pinMode(_irqPin, INPUT_PULLUP);
  digitalWrite(_irqPin, LOW);  // No pullups; the transceiver provides this!
Maybe the problem is that the Arduino is powered with 5V while nRF24L01+ with 3.3?

Share this post


Link to post
Share on other sites

 

I made the changes as you said but again does not work.

/* Initialization */
void Enrf24::begin(uint32_t datarate, uint8_t channel)
{
  pinMode(_cePin, OUTPUT);
  digitalWrite(_cePin, LOW);
  pinMode(_csnPin, OUTPUT);
  digitalWrite(_csnPin, HIGH);
  //pinMode(_irqPin, INPUT);
  pinMode(_irqPin, INPUT_PULLUP);
  digitalWrite(_irqPin, LOW);  // No pullups; the transceiver provides this!
Maybe the problem is that the Arduino is powered with 5V while nRF24L01+ with 3.3?

 

The nRF24L01+ is 5V-tolerant so that shouldn't matter here.  So long as you are powering the nRF24L01+ with the 3.3V power source right?

Share this post


Link to post
Share on other sites

The nRF24L01+ is 5V-tolerant so that shouldn't matter here.  So long as you are powering the nRF24L01+ with the 3.3V power source right?

Yes the module is powered by the 3.3V line Arduinoto. Do not look to what could be the problem. However the problem is somewhere around IRQ because transmission works great.

Share this post


Link to post
Share on other sites

  I'm getting this error while compiling for the Stellaris ,

Enrf24_RXdemo.ino:46:20: error: 'P1_0' was not declared in this scope

What are the changes that are to be made to the example sketch (pin changes in the constructor) ? 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


×