nRF24L01+ does not transmit..

Go To Last Post
45 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have been trying to get these NRFs to work for quite a while now. I tried mirf, nrf24 Master (arduino), Davide Geroni's code (ported/modified to my setting) and could not get it to work. Then I came across a piece of code that is RAW - uses Hex notations of registers and their values - decreases readability - but it looked simpler than most of the code that I have seen. I read the tutorial of Brennen (succinctly written) and got to figure out the NRFs - Thanks a million, Brennen for your great work.

Scene:
I am trying to send 4 bytes of data from one AVR board (Atmega 8 - AT8) to another AVR board (Atmega328p - AT328). Both the boards are running at 16 MHz. AT8 board is the transmitter and AT328 is the receiver. The boards are wired to nRF on prototyping boards with jumpers and hookup wires. 

The transmitter side register setting:

 

--------------- Transmitter ----------------
Reg : 0x00    Val : 0x08 ---> Config register set to 0x08 (Enable CRC, No Power Up) ** Tried other recommended setting 0x38**
Reg : 0x01    Val : 0x00 ---> Auto ack register set to 0x00 (disable auto ack for all pipes)
Reg : 0x02    Val : 0x01 ---> Enable receive pipe reg set to 0x01 (Pipe 0 enabled)
Reg : 0x03    Val : 0x03 ---> Address width set to 0x03  - 5 bytes
Reg : 0x04    Val : 0x00 ---> Retries setup set to 0x00
Reg : 0x05    Val : 0x02 ---> RF Channel set to 2
Reg : 0x06    Val : 0x07 ---> RF power Setup, set to 0x07 (1 MBPS, Max Power)
Reg : 0x11    Val : 0x04---> Set TX Payload size, set to 4 bytes

Tramsmit address : JJJJJ ---> Transmit address set to 4A-4A-4A-4A-4A
Reg : 0x00    Val : 0x0A ---> Config register set to 0x0A (0000-1010 - To power up the chip) ** And consequently to the note with (**) above, to 0x3A**
--------------------------------------------------

Reg : 0x07    Val : 0x0f
Reg : 0x07    Val : 0x0e --->   [Space available in TX buffer]
TX - Status : 1110
Reg : 0x07    Val : 0x0e --->   [Space available in TX buffer]
TX - Status : 1110
Reg : 0x07    Val : 0x0f --->   [TX buffer-Full]
TX - Status : 1111
Reg : 0x07    Val : 0x0f
TX - Status : 1111
Reg : 0x07    Val : 0x0f
.
.
.
the status reads 1111 (f) continuously - TX_DS bit does not get set

I searched through the net and after reading a very good Brennen's tutorial on the nRF, found a simple and straight forward code on the net that is just the bare-bone code that is said to work. Please see below.

/*
 * NRF24L_TX.c
 *
 * Created: 23-Sep-14 8:09:51 AM
 *  Author: Ravi Upadhyaya
 */ 


/*
 * NRF24L_RX.c
 *
 * Created: 22-Sep-14 5:37:45 PM
 *  Author: Ravi Upadhyaya
 */ 

#ifndef F_CPU
#define F_CPU      16000000L
#endif

#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>

#include "spi.h"
#include "nrf.h"
#include "serial.h"

#define USDELAY      50

void writeRegister(uint8_t ui8Reg, uint8_t ui8Val)
{
   CSN_LO;
   readWriteSPI(0x20+ui8Reg);
   readWriteSPI(ui8Val);
   CSN_HI;
}

uint8_t readRegister(uint8_t ui8Reg)
{
   uint8_t      ui8Val;
   char achBuffer[9];
   
   CSN_LO;
   readWriteSPI(ui8Reg);
   ui8Val = readWriteSPI(0xFF);
   CSN_HI;

   itoa(ui8Reg, achBuffer, 16);
   writeStringSerial("Reg : "); writeStringSerial(achBuffer); 
   itoa(ui8Val, achBuffer, 16);
   writeStringSerial("    Val : "); writeStringSerial(achBuffer); writeStringSerial("\r\n");

   return ui8Val;
}


void configureTX()
{
   uint8_t i, data[5], ui8Val;

   CE_LO;
   
   writeRegister(CONFIG, 0x08);      // Write Config Register  (0x00), CRC Enabled, Power off, PTX enabled (0x38)
   readRegister(CONFIG);            // Read Config Register;

   // Shouldn't have to do this, but it wont TX of you don't
   writeRegister(ENAA, 0x00);      // Write auto acknowledge RX register - disable auto ack on all channels
   readRegister(ENAA);
   
   writeRegister(ENRXADDR, 0x01);      // Enable Receive pipe 0
   readRegister(ENRXADDR);

   writeRegister(SETUPAW, 0x03);      // Write Addr width to a 5 byte address (0x03 = 5 bytes)
   readRegister(SETUPAW);

   writeRegister(SETUPRETRIES, 0x00);      // Write retries register, disable auto retries
   readRegister(SETUPRETRIES);

   writeRegister(RFCHANNEL, 0x02);      // Write RF Channel Red - set it to channel 2
   readRegister(RFCHANNEL);
      
   writeRegister(RFSETUP, 0x07);      // Write RF Data rate register - set it to 1 MBPS
   readRegister(RFSETUP);
   
   writeRegister(PAYLOADWIDTH, 0x04);      // Write payload width register - set it to 4 bytes
   readRegister(PAYLOADWIDTH);

//==================================================================================   
   CSN_LO;
   readWriteSPI(SETTXADDR);            // Set transmitter address (0x10) 
   for(i=0; i<5; i++)
      readWriteSPI(0x4A);         // Receiver Address : 0x4A4A4A4A4A
   CSN_HI;
   _delay_us(USDELAY);

   CSN_LO;
   readWriteSPI(READTXADDR);
   for(i=0;i<5;i++)
      data[i] = readWriteSPI(0xff);
   CSN_HI;
   
   writeStringSerial("\r\nTramsmit address : ");
   for(i=0;i<5;i++)
      writeSerial(data[i]);      // Should print JJJJJ
   writeStringSerial("\r\n");
   _delay_us(USDELAY);
//==================================================================================

   writeRegister(CONFIG, 0x0A);      // Power up the chip and TX      (0x3A)
   readRegister(CONFIG);
   
   _delay_us(150);
}


int main(void)
{
   uint8_t ui8Status;
   char buffer[10];
   initSerial();
   writeStringSerial("--------------- Transmitter ----------------\r\n");
   initSPI();
   configureTX();
   writeStringSerial("--------------------------------------------------\r\n\r\n");

   writeRegister(STATUS, 0x7E);   // Write status register, clear of all the interrupts
   readRegister(STATUS);
      
   //the data sheet says that this is supposed to come up 0 after PWR, but that doesn't
   CSN_LO;
   readWriteSPI(0xE1);         // Clear TX_FIFO register
   CSN_HI;
   _delay_us(USDELAY);

    while(1)                  // Recieve data
    {      
      // 4 byte PAYLOAD
      CSN_LO;
      readWriteSPI(TXPAYLOAD);         // Set TX Payload Register
      readWriteSPI(0x41);
      readWriteSPI(0x42);
      readWriteSPI(0x43);
      readWriteSPI(0x44);
      CSN_HI;
      _delay_us(USDELAY);
      // Pulse CE to start transmission
      CE_HI;
      _delay_us(15);
      CE_LO;

      _delay_us(USDELAY);
   
      ui8Status = readRegister(STATUS);
      itoa(ui8Status, buffer, 2);
      writeStringSerial("TX - Status : "); writeStringSerial(buffer); writeStringSerial("\r\n"); 
      
      writeRegister(STATUS, 0x7E);         // Reset the TX_DS interrupts
      
   _delay_us(150);
    }
}

The receiver side register settings and output is below.

 

 ------- RECEIVER ----------------------------
Reg : 0x00     Val : 0x09 ---> Config register set to 0x08 (Enable CRC, No Power Up, PRX)
Reg : 0x01     Val : 0x00 ---> Auto ack register set to 0x00 (disable auto ack for all pipes)
Reg : 0x02     Val : 0x01 ---> Enable receive pipe reg set to 0x01 (Pipe 0 enabled)
Reg : 0x03     Val : 0x03 ---> Address width set to 0x03  - 5 bytes
Reg : 0x05     Val : 0x02 ---> RF Channel set to 2
Reg : 0x06     Val : 0x07 ---> RF power Setup, set to 0x07 (1 MBPS, Max Power)
Reg : 0x11     Val : 0x04 ---> Set RX Payload size, set to 4 bytes

Receiver address : JJJJJ ---> Receiver address set to 4A-4A-4A-4A-4A

Reg : 0x00     Val : 0x0b---> Config register set to 0x0A (0000-1011 - To power up the chip)
----------------------------------------------------------------
Reg : 0x07     Val : 0x0e ---> RX-FIFO Empty
RX - Status : 1110

Reg : 0x07     Val : 0x0e
RX - Status : 1110

Reg : 0x07     Val : 0x0e
RX - Status : 1110

Reg : 0x07     Val : 0x0e
RX - Status : 1110
.
.
.
Continues for ever...

The receiver side code is given below.

 

/*
 * NRF24L_RX.c
 *
 * Created: 22-Sep-14 5:37:45 PM
 *  Author: Ravi Upadhyaya
 */ 

#ifndef F_CPU
#define F_CPU      16000000L
#endif

#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>

#include "spi.h"
#include "nrf.h"
#include "serial.h"

#define USDELAY         50

void writeRegister(uint8_t ui8Reg, uint8_t ui8Val)
{
   CSN_LO;
   readWriteSPI(0x20+ui8Reg);
   readWriteSPI(ui8Val);
   CSN_HI;
}

uint8_t readRegister(uint8_t ui8Reg)
{
   uint8_t      ui8Val;
   char achBuffer[9];
   
   CSN_LO;
   readWriteSPI(ui8Reg);
   ui8Val = readWriteSPI(0xFF);
   CSN_HI;
   
   itoa(ui8Reg, achBuffer, 16);
   writeStringSerial("Reg : "); writeStringSerial(achBuffer);
   itoa(ui8Val, achBuffer, 16);
   writeStringSerial("     Val : "); writeStringSerial(achBuffer); writeStringSerial("\r\n");

   return ui8Val;
}

void configureRX()
{
   uint8_t i, ui8RXAddr[5];
   
   writeRegister(CONFIG, 0x09);      // Config register - set CRC Enabled, Power Off, PRX enabled (0x39)
   readRegister(CONFIG);
   
   writeRegister(ENAA, 0x00);      // Write Auto Ack Register (0x01) - disable auto ack on all channels
   readRegister(ENAA);

   writeRegister(ENRXADDR, 0x01);      // Write Enable receive pipe register - set Pipe-0 for reception of payload
   readRegister(ENRXADDR);

   writeRegister(SETUPAW, 0x03);      // Write addr width register, set to 5 byte address
   readRegister(SETUPAW);

   writeRegister(RFCHANNEL, 0x02);      // Write RF channel register - set it to channel 2
   readRegister(RFCHANNEL);

   writeRegister(RFSETUP, 0x07);      // Set RF Data rate register - set it to 1 MBPS
   readRegister(RFSETUP);

   writeRegister(PAYLOADWIDTH, 0x04);      // Write Payload width register - set payload size to 4 bytes
   readRegister(PAYLOADWIDTH);

//=========================================================================================

   CSN_LO;
   readWriteSPI(SETRXADDR);            // Set receiver address (0x10) - For pipe 0
   for(i=0; i<5; i++)
      readWriteSPI(0x4A);         // Receiver Address : 0x4A4A4A4A4A
   CSN_HI;
   _delay_us(USDELAY);

   CSN_LO;
   readWriteSPI(READRXADDR);            // Read Receiver address
   for(i=0;i<5;i++)
      ui8RXAddr[i] = readWriteSPI(0xff);
   CSN_HI;
   writeStringSerial("\r\nReceiver address : ");
   for(i=0; i<5; i++)
      writeSerial(ui8RXAddr[i]);      // Should print J J J J J 
   writeStringSerial("\r\n");
   _delay_us(USDELAY);

//============================================================================================

   writeRegister(CONFIG, 0x0B);      // Write config register - Power up the chip ()x3B)
   readRegister(CONFIG);
   
   CE_HI;
   _delay_ms(150);
}


int main(void)
{
   uint8_t         i, ui8Status=0x00;
   char         buffer[10] = {'\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'}, achStatus[10];
   
   initSerial();

   writeStringSerial("------- RECEIVER ----------------------------\r\n");
   initSPI();
   configureRX();
   writeStringSerial("----------------------------------------------------------------\r\n");
    while(1)
    {

      CSN_LO;
      
      ui8Status = readRegister(0x07);
      itoa(ui8Status, achStatus, 2);
      writeStringSerial("RX - Status : "); writeStringSerial(achStatus); writeStringSerial("\r\n");
      
      CE_HI;
      readWriteSPI(READRXPAYLOAD);
      for(i=0; i<4; i++)
         buffer[i] = readWriteSPI(0xff);
      CE_LO;
      CSN_HI;

      writeStringSerial(buffer);
      writeStringSerial("\r\n");

      CSN_LO;
      readWriteSPI(FLUSHRXFIFO);         //Flush RX-FIFO
      CSN_HI;
   _delay_us(USDELAY);

      writeRegister(STATUS, 0x40);      // Reset interrupt

   _delay_us(USDELAY);

    }
}

I am frustrated no-end since this is not working. Appreciate any help/suggestions in fixing this issue. 

Note : I have added the 0x0 to the output values manually - as you can see in the code, the 0x0 does not happen when you itoa :)

Checked the FIFO status of the transmitter just before it transmits. It is as follows.

 

--------------- Transmitter ----------------
Reg : 0    Val : 8
Reg : 1    Val : 0
Reg : 2    Val : 1
Reg : 3    Val : 3
Reg : 4    Val : 0
Reg : 5    Val : 2
Reg : 6    Val : 7
Reg : 11    Val : 4

Tramsmit address : JJJJJ
Reg : 0    Val : a
--------------------------------------------------

Reg : 7    Val : f
Reg : 0x17    Val : 0x01 ---> Space available in the TX FIFO buffer, TX_FIFO is not empty   
TX - FIFO-Status : 1
Reg : 0x17    Val : 0x01 ---> Space available in the TX FIFO buffer, TX-FIFO is not empty
TX - FIFO-Status : 1
Reg : 0x17    Val : 0x21 ---> TX FIFO  full bit is set
TX - FIFO-Status : 100001
Reg : 0x17    Val : 0x21
TX - FIFO-Status : 100001
Reg : 0x17    Val : 0x21
TX - FIFO-Status : 100001
Reg : 0x17    Val : 0x21
TX - FIFO-Status : 100001
.
.
.
Outputs continuously the above tx-fifo 

Till TX_DS is set, I am not sure if the data is transmitted. 

 

Thanks for any input.

 

 

Last Edited: Fri. Oct 16, 2015 - 12:48 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please find pictures of the boards below. Do the length of the jumper wires matter? The pics are not good, but you can get the idea.

 

ATMEGA8 Board with NRF given below.

 

 

ATMEGA328P and nRF24L01 image given below

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Ravi,

 

The nRF24L01 units are meant to be powered at 3.3 volts, but I see your have declared F_CPU at 16 MHz which is a frequency on the megas requiring 5 volts. Do you have a separate 3.3 volt supply for the nRF24L01s?

 

Cheers,

 

Ross

 

Ross McKenzie ValuSoft Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your code is hard to read since you don't use any of the nRF register names.

It's easier to start with simple settings - no AA & no CRC to verify the modules work.

Another debugging tip is to put a LED+resistor between power & IRQ on the modules, so you can see if/when the tx and rx irqs fire.

 

You can safely tie CE & CSN to simplify the code and wiring.  You can also tie CE high, but to switch between Tx and Rx mode you'll have to power down (set the PWR_UP bit to 0).

 

There's also lots of discussion about these modules on my blog that might help:

http://nerdralph.blogspot.ca/201...

 

I have no special talents.  I am only passionately curious. - Albert Einstein

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes Ross - There is a 3.3V supply available on  the Atmega328P board and I have connected the nRF board to that supply.

 

Thanks,

 

Ravi Upadhyaya

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you, Ralph. I understand  and to mellow that issue, I have added comments on each of the settings line. Guess it was not enough.. Sorry about that :(.

 

The data sheet of nRF and SPI seems to indicate that  CE pin is active HI and CSN pin is active LO - Not sure if those can be tied.

 

I can give a try on the LED for the IRQ option to check the IRQ being fired. One other option is probably to check the logic of the IRQ pin with a logic analyzer.

 

Thanks for the link - let me go through the discussions and see if I chance upon something.

 

UPDATE:

 

I have replaced the raw hex with the nRF register names. Hope that simplifies reading of the code.

 

 

Last Edited: Sat. Sep 27, 2014 - 09:08 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Update: I have replaced the raw hex values with its corresponding NRF register names.. Hope it improves the readability of the code. 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ravi.upadhyaya wrote:

The data sheet of nRF and SPI seems to indicate that  CE pin is active HI and CSN pin is active LO - Not sure if those can be tied.

 

Yes, so when the CE pin goes inactive, CSN goes active and vice-verse.  I've tested both CE tied high and CSN & CE tied together.

With CE tied high, you can poll the Rx fifo without dropping out of Rx mode(and possibly missing a packet).  With CE & CSN tied, you can switch between Tx & Rx mode quicker (~130uS) since you don't have to drop to power-down mode first.

If you use the Rx IRQ, then tied CE & CSN is probably the best option.

 

I have no special talents.  I am only passionately curious. - Albert Einstein

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you, Ralph. Yes - makes sense - as the number of CE transitions are by far less than those of CSN and keeping CE HI along with CSN does not alter the scenario much. My scenario is that one board transmits the packets continuously and the other tries to read the packets continuously - implying that the transmit board is in TX mode only and the receiver board is in RX mode . Am I doing it right? 

 

Ravi Upadhyaya

 

Last Edited: Sun. Sep 28, 2014 - 02:51 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ravi.upadhyaya wrote:

Am I doing it right? 

It's too much work to go through all your code to figure it out.  Since you're not using an existing & debugged library, every line needs to be verified.  However the first(and only) line I looked at appears to have a bug:

 writeRegister(CONFIG, 0x09);

This sets bit 0 (PRIM_RX) and bit 3 (EN_CRC), but not bit 1 (PWR_UP).  To receive it needs to be powered up.

If you used an existing lib, or at least the register definitions from an existing lib it would be a lot easier to read, "writeRegister(CONFIG, (1<<PRIM_RX) | (1<<EN_CRC))".  It would be easy to see that you forgot PWR_UP.

 

If I have time I'll whip up some Rx test code and post it for you.

 

I have no special talents.  I am only passionately curious. - Albert Einstein

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Ralph.

 

Going through your blog, I see that you use Mirf library. I have used Mirf library, RF24Master library, Davide Girone library, Elecfreaks Arduino nRF TX and RX code and nothing worked for me. I finally found this RAW nRF TX and RX code and altered it to my settings.

 

Jumping a few lines down from the CONFIG setting statement that sets it to 0x09, there is another CONFIG statement that sets it to 0x0B (0000-1011) where the power up bit gets set. However, I executed the code the code by setting the first CONFIG setting statement to 0x0B (enabling power up) - the results were the same. 

 

I have listed the TX and the RX code above. I am struggling to get the TX happen first and I have the issues mentioned above. I am currently not seeing any indication that the payload has been transmitted (TX_DS bit does not set indicating a successful transmission). I would like to have a piece of code that does a successful transmit first. If a Logic Analyzer trace is available (traces of SCK, MISO, MOSI, CSN and SS - (IRQ optional)) - it would be great. 

 

I connected the IRQ pin of the nRF to a logic analyzer to see if it goes LO when the transmit happens. It stays HI forever - indicating nothing was transmitted. The STATUS register and FIFO register indicate that in the first two cycles the FIFO Register has TX buffer space and from the third cycle the TX_FIFO buffer is full and this is reflected in the STATUS register as well.

 

Something is preventing the transmit from happening. 

 

Thanks again.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

There are several proven libraries.   I suggest that you choose one and then follow instructions meticulously.

 

If you have a problem:

1. download the original library into another directory.

2. 'diff' your files with the virgin distribution.

3. post a link to the original distribution.

4. post your 'diffs'

5. provide an explanation of your problems in English.

 

This approach applies to most things in life.     It is more likely that a reader chooses to build your project.   You are more likely to get help.

 

But most likely,   you will see where you made a foolish edit and correct it yourself.

 

Posting reams of 'your' code will not produce great response.    I am not going to 'diff' it myself.    Especially when I don't know where the original came from.     And I certainly don't want to read through hundreds of lines.

 

Yes,   I think that the Brennen tutorials and examples are well written.     I started from these.    From memory,   the examples are not written for AVR but are easy to port.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks David. As I mentioned I have tried a set of libraries and unfortunately that did not work. I got hold of this code from Sparkfun forum where a member pointed to his code - link below. It is a test code written for PIC C18 and I had to modify it for AVR. Modified the virgin code again today with minimal changes - majorly changed was the SPI setup routine and it's corresponding #defines (PIN references) as it was PIC dependent. 

 

http://www.leonheller.com/MiRF%20V2/MIR ... 520%29.zip

 

Brennen's has put in effort to make the program as flexible as possible and has lots and lots of code with generous comments. I want to test the set up with something a lot simpler and the test code at the link above seemed reasonable to start with.

 

The simplest to compile and run was the arduino code that was posted at http://www.elecfreaks.com/203.html. At the bottom of the article there is a download link - Download nRF24L01_Demo_For_Arduino_v1.1. that downloads a zip file with a TX and RX codes. All I had to change was the PIN references. Even that did not work. The TX board and RX board printed the STATUS register as 0E and that was it. Code walked and found that TX board was waiting for the TX_DS bit of the status register to be set to indicate completion of transmission and that was not happening. Since TX was not complete there was nothing to be received by the RX board.

 

I have 3 nRF boards and all the three behave exactly the same ...

 

Thanks,

 

 

 

 

 

Last Edited: Mon. Sep 29, 2014 - 01:07 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Solder smd 1uF and 10nF capacitor on nRF24l01 pin header and place a 10uF capacitor on breadboard.

 

Try compiling in debug mode

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The nRF board has a 10nF and a 470uF capacitor between the VCC and GND on the nRF board to smooth out any spikes. 

 

Isn't debug mode for code execution tracing and to see the status of the AVR registers, memory and stacks? I seem to be having problems with the nRF and debug may not help.

 

 

 

 

Last Edited: Mon. Sep 29, 2014 - 01:58 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include "mirf/mirf.h"
#include "mirf/nRF24L01.h"
#include <util/delay.h>

/* packet buffer */
//static uint8_t buf[mirf_PAYLOAD] = {0xde, 0xad, 0};
static uint8_t buf[mirf_PAYLOAD];


const uint8_t mirf_config_items[] = {
    EN_AA, 0,
    LAST_ITEM, 0
};

void main(void)
{
    mirf_init();

    // wait for mirf - is this necessary?
//    _delay_ms(50);

    mirf_config();

//    mirf_config_register(SETUP_RETR, 0 ); // no retransmit
    // disable enhanced shockburst
    mirf_config_register(EN_AA, 0 ); // no auto-ack
//    mirf_config_register(RF_SETUP, (1<<RF_DR_LOW) ); // low spd & power

    while (1){
        /* tie LED to CSN for diag */
        mirf_CSN_lo;
        _delay_ms(100);
        mirf_CSN_hi;

        // need time to come out of power down mode
        // s. 6.1.7, table 16
        // datasheet says 1.5ms max, tested as low as 600us
        mirf_config_register(CONFIG, mirf_CONFIG | (1<<PWR_UP) );
        _delay_ms(1);

        mirf_send(buf, mirf_PAYLOAD);
        // clear PWR_UP after CE high time
        // in practice, seems to work without it
        _delay_us(10);
        mirf_config_register(CONFIG, mirf_CONFIG );
        _delay_ms(1000);

        // Reset status register for further interaction
//        mirf_config_register(STATUS,(1<<TX_DS)|(1<<MAX_RT)); // Reset status r
egister
        mirf_config_register(STATUS,(1<<TX_DS)); // Reset status register
    }
}

This is my test transmit code.  It worked fine with a t88 piggybacked on a nrf module with CE tied high, powered by a CR2032.

I have no special talents.  I am only passionately curious. - Albert Einstein

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My God! Ralph. You took all the trouble. Thanks a million. 

 

Some of the points that I see that I have done differently (which I will correct and test)

 

1) The nRF powerup is done only once in the nRF init.

2) Delay after config register is written for power up - I am using a 50us delay.

3) Clearing POWER_UP after CE HI

 

Let me try this out.

 

By the way - what is the capacitor soldered on your board? I have a 470uF capacitor soldered - does that cause issues? Not much electronics knowledge :(

 

Thanks for your effort and time.

 

Ravi Upadhyaya

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This was something I had already done, so it was just a matter of digging up the code and posting it.

 

It's not necessary to power off between transmits.  I do this to reduce power so it will run on a cheap CR2032.  A good quality (i.e. Duracell or Panasonic) CR2032 can put out ~20mA sustained, but the cheap ones I have drop below 2V when the current gets much over 10mA.  With the 20uF cap there's no problem powering up for a transmit once per second.

 

I have no special talents.  I am only passionately curious. - Albert Einstein

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ralph:

 

What version of mirf library are you using? Erros pop up on the following functions that are referred in your code.

 

- mirf_config_register(register, value)

- mirf_send(buffer, payload)

 

The equivalents that I have are 

 

- mirf_write_register(register, value)

- mirf_write(buffer)

 

Thanks,

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is the mirf library I used:

http://www.tinkerer.eu/AVRLib/nR...

 

I have no special talents.  I am only passionately curious. - Albert Einstein

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Too low decoupling capacitance. 470uF is too big (= slow) and only one 10nF is too poor.

I solved with 4 modules adding SMD capacitors like said.

 

Debug mode disable optimizations of compiler that can cause subdole bug.

 

Please use strong power supply with ability to supply 100+ mA, not watch battery, to make system initially works.

 

My 2 cents

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok! Downloaded the tinkerer nRF library. Will give it a try. 

 

Thanks Ralph.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you, flz. You make some good points. Electronics not my strong point. I will replace the capacitor with a lower one and check. 

 

Yeah!! Debug mode disables the optimizations - will give that a try. There are some switches too that disable the optimizations - let me check on that too.

 

As regards to the power supply, I am using two AA eneloops charged (2000 mAH) - I guess that should be quite strong. 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not only lower values, smd MLCC or tantalium capacitor. Better if not Y5V dieletric.

NiMH battery are OK.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Ralph:

 

Changes that I made are marked in red.

 

/*
 * NRF_TINKER.c
 *
 * Created: 03-Oct-14 9:35:11 AM
 *  Author: Ravi Upadhyaya
 */ 



#ifndef F_CPU
#define F_CPU 16000000L
#endif

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#include "mirf.h"
#include "nrf24.h"
#include "spi.h"

/* packet buffer */
static uint8_t buf[mirf_PAYLOAD] = "abcdefghijklmnop";

int main(void)
{
	spi_init();
	mirf_init();

	// wait for mirf - is this necessary?
	//    _delay_ms(50);

	mirf_config();

	sei();
	
	//    mirf_config_register(SETUP_RETR, 0 ); // no retransmit
	// disable enhanced shockburst

	mirf_config_register(EN_AA, 0 ); // no auto-ack

	//    mirf_config_register(RF_SETUP, (1<<RF_DR_LOW) ); // low spd & power

	while (1)
	{
		/* tie LED to CSN for diag */
//		mirf_CSN_lo;
//		_delay_ms(100);
//		mirf_CSN_hi;

		// need time to come out of power down mode
		// s. 6.1.7, table 13
		// datasheet says 1.5ms max, tested as low as 600us

		mirf_config_register(CONFIG, mirf_CONFIG | (1<<PWR_UP) );
		_delay_ms(1);

		mirf_send(buf, mirf_PAYLOAD);
		// clear PWR_UP after CE high time
		// in practice, seems to work without it

		mirf_CSN_lo;		
		spi_fast_shift(R_REGISTER | (REGISTER_MASK & STATUS));	// Read Status
		mirf_CSN_hi;
		
		mirf_config_register(CONFIG, mirf_CONFIG );
		mirf_config_register(CONFIG, mirf_CONFIG | (0<<PWR_UP));
		
		_delay_ms(1000);

		// Reset status register for further interaction
		//        mirf_config_register(STATUS,(1<<TX_DS)|(1<<MAX_RT)); // Reset status register
		mirf_config_register(STATUS,(1<<TX_DS)); // Reset status register
	}
}

Does not work. The status register returns 0x0E => 0000-1110 => TX_DS is not set and TX_FIFO is not full. Please see the Logic Analyzer trace for info.

 

 

Channel 4 is CE and Channel 5 is IRQ (Constantly HI in the picture). Executed the program on a 328P board and a Atmega 8 board. Results are the same as regards to TX_DS (does not set).

 

I have replaced the 470 uF with 10uF Electrolytic capacitor (not SMD).

 

thanks,

 

Last Edited: Tue. Oct 7, 2014 - 02:24 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Capacitor should be near to the IC. View attached images with cap on pin header.

Status register 0x0E is default value, sure that module does not reset itself due to power spike? Again fix it with smd cap on pin header.

 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow! So close and so small.. That is delicate work!!!!!! I guess I have to get it done by some guy with a delicate hand! 

 

Your board looks a wee bit different. 

Attached an electrolytic 1uF capacitor between the GND and VCC on this board. As well as I got a power supply to deliver regulated 3.3V to the transceiver... No Luck!! The only option left is to try the SMD capacitors sad!!!

Thanks 

 

 

Update : The IRQ trace seems to have appeared - it seems to be pulsing with each payload transmit!! However the status register still reads 0x0E!! Exploring further...!

 

 

Last Edited: Thu. Oct 9, 2014 - 12:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hurrrraayyy!!!!! Transmitting!!!!!  

 

Thanks a lot to Ralph for your suggestions and code, David for your suggestions on How-to-ask-questions and Flz for your insight!! Flz, I will try remaining boards with an SMD. Electrolytic 1uF worked for now!!!!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeah!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The receiver too is working. However, after receiving the first packet, it stops receiving further packets. I am transmitting "ABCD" continuously from the transmitter.

Any tips as to why? 

Thanks in advance,

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ravi.upadhyaya wrote:

The receiver too is working. However, after receiving the first packet, it stops receiving further packets. I am transmitting "ABCD" continuously from the transmitter.

Any tips as to why? 

Thanks in advance,

 

Oh! Classic symptom:

 

You're transmitting the same message over and over, and shockburst CLAIMS to check a 4 bit id field to know it's not just retransmitted after a lost ack, but it does not. Change your transmitted message on each send, and your receiver will see them. I often just add a "Message Number" byte than increments each time I send the message.

 

274,207,281-1 The largest known Mersenne Prime

Measure twice, cry, go back to the hardware store

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Changed the content of the packet. First packet is "ABCD", second packet is "EFGH", third is "HIJK".. and so on and transmit each of the packet at 100 ms intervals. Auto ack is not enabled on the receiver or the transmitter - just blind send and receive.

 

Working!!!!!! 

 

Thanks a lot, everyone...

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Auto ack is a feature of Enanched Shockburst that is enabled by default on nrf24l01 and PID (packed id) is auto-incremented and is not related to payload.

To improve communication use 2 byte CRC and set an address with bit that change a lot. Remember to change from TX to standby or RX every 4ms (internal TX PLL is open-loop and need to "recalibrate") like the datasheet say.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Torby wrote:

 

ravi.upadhyaya wrote:

 

The receiver too is working. However, after receiving the first packet, it stops receiving further packets. I am transmitting "ABCD" continuously from the transmitter.

Any tips as to why? 

Thanks in advance,

 

 

 

Oh! Classic symptom:

 

You're transmitting the same message over and over, and shockburst CLAIMS to check a 4 bit id field to know it's not just retransmitted after a lost ack, but it does not. Change your transmitted message on each send, and your receiver will see them. I often just add a "Message Number" byte than increments each time I send the message.

 

 

Can you explain more?

Even with EN_AA = 0 (which means no 9-bit packet control field added), the receiving nRF will drop duplicate packets?

 

Do you know if the setting for ARC matters?  Section 7.9 of the datasheet says:

Set the register EN_AA = 0x00 and ARC = 0 to disable Enhanced ShockBurst™.

 

But since EN_AA is per-pipe, and ARC is global, is it possible to have enhanced shockburst on some pipes and not others, with ARC applying only to those pipes with EN_AA?

 

I have no special talents.  I am only passionately curious. - Albert Einstein

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Haven't messed with disabling shockburst, all I know... if you send the same packet over and over, you'll only receive it once. If you make something in the packet change, you'll receive it most of the time.

 

Of course, any packet can be lost at any time. You have to keep this in mind. But the thing works 'cause the vast majority of packets are received.

274,207,281-1 The largest known Mersenne Prime

Measure twice, cry, go back to the hardware store

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Ravi, I have the same problem with you. my nrf can't transmitting. in your case, the problem is the capacitor on vcc and ground or the code? I have tried not use auto ack, but still no luck. what capacitor do you use?

 

 

Last Edited: Mon. Jul 3, 2017 - 02:17 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Note that the last post from "Ravi" was going on for three years ago ... !

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

can anyone tell me what power source that suitable for NRF24L01?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Any 3V power (2 AA Duracell batteries) should work!! If your uC board has a 3v3 output even that can be used.

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry about the delayed response. I should be getting these posts a mails in my gmail - for some reason that did not happen and I missed this post. 
​The Capacitor is 1uF capacitor soldered on the NRF board itself - between the GND and the VCC pins. That should work!

Ravi Upadhyaya

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks ravi for your responses. Now i have problem with my receiver. It was working once and after i changed the data to be transmitted, my receiver only received three times. Could you send me your receiver code for my reference?
What kind of cap do you use? Elco, tantalum or SMD?

Last Edited: Tue. Sep 19, 2017 - 07:54 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks ravi for your responses. Now i have problem with my receiver. It was working once and after i changed the data to be transmitted, my receiver only received three times. Could you send me your receiver code for my reference?
What kind of cap do you use? Elco, tantalum or SMD?

Last Edited: Tue. Sep 19, 2017 - 07:56 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Joseph.Remond wrote:
Elco, tantalum or (sic) SMD?

Eh??

 

Both Elco & Tantalum are available as SMD!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thaks ravi for your responses. Now i have problem with my receiver. It was working once and after i changed the data to be transmitted, my receiver only received three times. Could you send me your receiver code for my reference?
What kind of cap do you use? Elco, tantalum or SMD?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why do you keep repeating exactly the same post: #41, #42, and now #44 ?!