Jump to content
43oh

[Energia Library] Nordic nRF24L01+ library


Recommended Posts

Well that's pretty strange.  On a quick side note, I have now written a C++ library for Linux for the BeagleBone Black using libsoc (soon to change to something faster) which enables me .... much quicker turnaround with nRF24L01+, SI24R1 etc. development.  Just so much easier running this kind of stuff from an embedded Linux host.  My interrupt routines can do fprintf(stderr, "IRQ\n"); type of crap with impunity.

 

I discovered an odd quirk-

 

Packets coming from a node "just barely out of range" can sometimes trigger the RX_DR IRQ, and cause the IRQ line to trigger low, but with the RX FIFO still empty.

 

Witness:

IRQ
Weird; FIFO_STATUS was 11; rf_status was 4E
WR: 07 40

A proper packet from a closer node:

IRQ
FIFO_STATUS was 10; rf_status was 00
RX event-
WR: 07 40
Pipe = 0, length = 13
10 06 07 17 00 17 00 00 
FE 03 07 09 3A 

Expect a patch to Enrf24 to be forthcoming.

 

edit:

Looks like Enrf24 actually handles this somewhat gracefully, but there's no good reason for me to go through the routine of reading the payload width and flush_rx et al if rf_status already has the info I need.  So the patch is pretty simple.

edit2:

This might be the nature behind the occasional "rogue" 0-byte packet I see from time to time.  Looks like my msprf24 and Enrf24 libs basically take care of this right.

Link to post
Share on other sites
  • 1 month later...
  • Replies 352
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

Hi folks... So I'm a little new to Energia, but since I wrote a library for the nRF24L01+ digital transceivers for native C-based apps I figured it'd be a great idea to port this to Energia.   I'm r

Ok, so I ported the Enrf library over so that it works with both MSP430 and Stellaris.  Seems to work great.  I am watching the tx rx demo between msp430g2553 (on the RX side), and the StellarPad doin

Okie doke - https://github.com/spirilis/Enrf24   The examples are the same as the ones I posted... I'll write up the API in a wiki page soon.  Alternately, I put documentation in the Enrf24.h file f

Posted Images

  • 1 year later...
  • 2 weeks later...

@@spirilis

 

 


2. Only 1 receive pipe is supported, the MultiCeiver stuff is not (truth is, it's extensible enough that I could add that in the future)

3. Pipe#0 is always using its default (E7E7E7E7E7) address and any data coming in to that addr gets silently flushed.  I recommend not using the E7E7E7E7E7 address for any of your applications.  (This internally has to do with implementing AutoACK properly)

Hi,

 

First off, thanks a lot @@spirilis for this library and the examples, they are working flawlessly. I've been working with them on MSP432 and TM4C129 boards as well. But I am hoping to make a sensor network using the nrF boards with MSP432 and TM4C129, but without the MultiCeiverability, is there any way to establish a star network topology? I only want to make like 2, 3 nodes to connect with a central node to send and receive data. Or do you have a newer version of the Enrf24 library with the ability to open up multiple pipes?

 

Thanks in advance!!

Link to post
Share on other sites
  • 1 month later...

@spirilis thanks for this amazing library!

I was able to communicate arduino and msp430g2553, but just in this case: 

TX: ARDUINO
RX: MSP

If i put msp like tx and arduino RX, it doesn't work... why?

and my second question is: how the power mode works?

when it enter in sleep mode?

how much current it spends in each mode?

Sorry for my english..   :P 

 

Link to post
Share on other sites

Hi, I have been checking the setTXPower method and there is a "hidden" mode.

 

In the .h is declared as:

void setTXpower(int8_t dBm=0); // Only a few values supported by this (0, -6, -12, -18 dBm)

But the code shows an additional mode for param "7":

 

void Enrf24::setTXpower(int8_t dBm)
{
  uint8_t reg, pwr;


  reg = _readReg(RF24_RF_SETUP) & 0xF8;  // preserve RF speed settings
  pwr = 0x06;
  if (dBm >= 7)
    pwr = 0x07;
  if (dBm < 0)
    pwr = 0x04;
  if (dBm < -6)
    pwr = 0x02;
  if (dBm < -12)
    pwr = 0x00;
  _writeReg(RF24_RF_SETUP, reg | pwr);
}

 

Somebody knows if this mode really works and has more transmission power than 0dBM?

Link to post
Share on other sites
  • 2 weeks later...

For weeks now, I have been trying to interface my MSP430G2553's with nRF24l01 transceivers. The sample code for the receiver seems to be working alright. I was able to measure the pin voltages and monitor the current draw of the receiver. However, the transmitter doesn't seem to be working as expected. The CE pin will not go high. Even if I force it high, the transmitter will not draw any current. The only thing I did to change the code was to add a few lines for a flashing LED. This is to ensure that the microcontroller is active when used as a standalone. Here's the code:

#include <SPI.h>
#include <Enrf24.h>
#include <nRF24L01.h>
#include <string.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 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(MSBFIRST);

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

  radio.setTXaddress((void*)txaddr);

//MY ADDITION TO THE CODE (FLASHING LED). THIS ENSURES THE MICROCONTROLLER IS READY/ACTIVE.
   pinMode(P1_0, OUTPUT);
   digitalWrite(P1_0, LOW);
   int x=0;
   volatile int state = HIGH;
   volatile int flag = HIGH;
  digitalWrite(P1_0, state);
  while(x<15)
  {
  digitalWrite(P1_0, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(100);               // wait for a 1/10th second
  digitalWrite(P1_0, LOW);    // turn the LED off by making the voltage LOW
  delay(100);               // wait for 1/10th second
  x=x+1;
  }

//END FLASHING LED


}


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");
  }
}

Eliminating the flashing LED doesn't solve the problem.

Other symptoms vary depending on if the IC is on the launchpad or standalone. On the launchpad, the CE and MISO pin remain at about half supply voltage. Standalone, they remain low. The most significant observation (only happens for standalone) is that the MOSI pin stays at 3.3V as expected, but pulses toward 0V every second or so repeatedly. During this short pulse duration, the transceiver tries to draw some current, but then shuts off immediately. The CE pin remains low for the most part. However, I was able to get a measurable voltage (in the mV range) during this odd pulse time.

If I am correct in my assumptions, hardware setup remains the same between receiver and transmitter. Any help here would be greatly appreciated.

Link to post
Share on other sites

Or possibly, the transmitter is only supposed to draw current during the short time when it transmits a bit? In that case, it is working correctly from an electrical perspective. However, the overall system doesn't work. There is no response from the receiver. Being completely new to all of this, I don't know where to take it from here?

Link to post
Share on other sites

I have used this library with both custom MSP430G2553 boards and the LaunchPad.  Hardware setup is the same whether receiver or transmitter.  Among the possible problems and solutions are the following:

  • Bad nRF24 - the very first one I bought was bad
  • damaged pin on MSP430 - don't apply 5V to a pin - this is a 3V3 device
  • nRF24 wired wrong or wrong pin in software - easy to do
  • poor transmission between modules - too far apart, object in between, or even too close together.
  • modules set on different channel or other incompatibility in way software is set up

In general though, I  have found the library easy to use and reliable.  I suggest you concentrate on getting the examples working first without any modification.  I haven't tried it with Energia V18, you might try Energia V17.  The following are the pins I normally use:

  nRF pin  pin#    Std color   F5529LP pin   G2553 pin
  -------  ----    ---------   -----------   ---------
  Vcc         1    Red         3V3           3V3      
  GND        20    Black       GND           GND      
  CSN         9    Yellow      P4.2          P2_1     
  CE          8    Green       P2.7          P2_0     
  MOSI       15    White       P3.0          P1_7      
  SCK         7    Orange      P3.2          P1_5      
  IRQ        10    Brown       P4.1          P2_2      
  MISO       14    Purple      P3.1          P1_6     

I use the same wire color every time to ease checking that the connection is correct.

If CE is not going high then try setting up a simple pin toggling program (e.g. the "hello world" pin wiggling and check with multimeter) to see if it works without the library.  This will tell you if the CE pin on the MSP430 has been damaged.  If so, changing to a different pin will fix it until you get a new $2 chip.

EDIT:  Some multimeters can be quite slow to update.  When toggling pins to see if they are reaching a full on state, keep the toggling frequency to 1 Hz so the meter can keep up.  For monitoring an application like the one above an oscilloscope or logic analyzer is a better tool.

Edited by Fmilburn
Link to post
Share on other sites

I did try switching the IC codes. Still, whichever chip the transmitter code is on, the CE pin will not go high and will not activate. Either chip will work fine with the receiver code. I also tried switching the nRF21L01's, but still could not isolate the problem to any specific piece of hardware. Should the CE pin be high on the transmitter? I noticed, during the short duration when it is transmitting a bit, the CE pin briefly pulses high, but only barely in the mV range.

 

Also, the transmitter code is supposed to send two bits in the loop. This brief pulsing effect seems to happen when transmitting each bit. I know this because I added the flashing LED code to the end of the loop to indicate when it is cycling back to the beginning of the loop. I get two shorts pulses (One pulse: 3.3V to 0V and back to 3.3V on the MOSI pin) before the LED flashes. Then, it cycles back, emits 2 short pulses, flashes the LED, and so on.

Here's the modified loop code:

void loop () {

  Serial.print("Sending packet: ");
  Serial.println(str_on);
  radio.print(str_on);
  radio.flush();  // Pulsing on MOSI pin (3.3V to 0V and back to 3.3V)
  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();  // Pulsing on MOSI pin (3.3V to 0V and back to 3.3V)
  dump_radio_status_to_serialport(radio.radioState());  // Should report IDLE
  delay(1000);
  int x = 0;
   while(x<15)
  {
  digitalWrite(P1_0, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(100);               // wait for a 1/10th second
  digitalWrite(P1_0, LOW);    // turn the LED off by making the voltage LOW
  delay(100);               // wait for 1/10th second
  x=x+1;
  }
 
}

 

By the way, I did try Energia 17 and 18 with the same results.

Link to post
Share on other sites

How do you know it works as a receiver if you don't have anything working as a transmitter - what are you receiving without a transmission?  Have you gone back and double checked that one of my suggestions isn't the cause?  I can assure you that the library works when connected properly with the nRF24L01+ modules I have and a G2553 LaunchPad.

The datasheet for the nRF24L01+ has all the details and can be found with a google search - it uses SPI.  SPI keeps the chip select pin high until it is ready to transmit and then pulls it low.  It then returns to high following transmission.  The code for the library is in Enrf24.cpp.  Look inside at the code, e.g.

void Enrf24::_writeReg(uint8_t addr, uint8_t val)
{
  digitalWrite(_csnPin, LOW);
  rf_status = SPI.transfer(RF24_W_REGISTER | addr);
  SPI.transfer(val);
  digitalWrite(_csnPin, HIGH);
}

It pulls it low before transmitting then returns to high.

One more suggestion - if you do a search on the internet you will find various people have found this helps:  https://forum.arduino.cc/index.php?topic=376068.0  I include a decoupling capacitor in my designs and normally power the radio from a battery.  Nonetheless, I have also had success powering off of the LaunchPad.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...