Can't read STATUS from NRF24L01

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

Hello!

 

Thanks to the advice in this tread I bought a number of NRF24L01 and tried to make it work with them. However, I'm stuck at the very beginning.

 

I'm trying to follow this tutorial, but I failed when trying to even read STATUS register from the NRF.

 

I'm using Atmega328p at the moment. Apart from the power I have 3 LEDs connected: Yellow to PD7, green to PB0 and red to PC3. NRF is connected as in tutorial:

-Power supply to 3.3V, and I also soldered additional 10uF capacitor between GND and VCC of the module,

-CE to PB1,

-CSN to PB2

-SCK to PB5

-MO to PB3,

-MI to PB4

-IRQ not connected or connected to PD2.

 

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

#include "nRF24L01.h"

void SPI_MasterInit(void)
{
    PORTB |= (1<<PB2);    //CSN high
    PORTB &= ~(1<<PB1);    //CE low
    /* Enable SPI, Master, set clock rate fck/16*/
    SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR0);

}

uint8_t WRByteSPI(uint8_t cData)
{
    // Start transmission
    SPDR = cData;

    PORTD |= (1<<PD7);    //diagnostic Yellow LED ON
    // Wait for transmission complete
    while(!(SPSR & (1<<SPIF)));
    PORTD &= ~(1<<PD7); //diagnostic Yellow LED OFF
    //return received transmission
    return SPDR;
}

uint8_t GetReg(uint8_t reg)
{
    _delay_us(10);
    PORTB &= ~(1<<PB2); //CSN low - nRF starts to listen

    _delay_us(10);
    WRByteSPI(R_REGISTER + reg);        //set nRF in reading mode

    _delay_us(10);
    reg=WRByteSPI(NOP);    //Send dummy byte to receive byte from reg

    _delay_us(10);
    PORTB |= (1<<PB2);    //CSN high - nRF goes back to doing nothing

    _delay_ms(300);
    return reg;
}

int main(void)
{
    //IOPort init
    DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3) | (1<<PB5);
    DDRC |= (1<<PC3);
    DDRD |= (1<<PD7);
    //set SS, MOSI, SCK, PB1 (CE in NRF), PB0 (Green LED), PC3 (Red LED) and PD7 (Yellow LED) as outputs.

    //LED TEST
    PORTD |= (1<<PD7);    //Yellow
    PORTC |= (1<<PC3);    //Red
    PORTB |= (1<<PB0);    //Green
    _delay_ms(300);

    void SPI_MasterInit(void);

    _delay_ms(300);
    PORTC &= ~(1<<PC3);
    PORTB &= ~(1<<PB0);
    PORTD &= ~(1<<PD7);
    //LEDs are ok, SPI init completed
    _delay_ms(300);

    while (1)
    {

        if (GetReg(0x07)!=0x0E)
        {
            PORTC ^= (1<<PC3);    /*Switch Red LED if incorrect value has been read*/
        }else
        {
            PORTB ^= (1<<PB0);/*Switch Green LED if correct value has been read*/
        }
        _delay_ms(200);
    }
}

 

With this code all LEDs light up and turn off as expected and then yellow LED lights up again and stays on forever. It confirms that the program hangs on:

while(!(SPSR & (1<<SPIF)));

 

I know that a common reason for this is SS being set as input and not kept high but in my case SS is set as output. I've also tried with multiple NRFs, but to no avail.

 

What I expect to happen is to green LED blink every 0.2s.

 

Can anyone help with this? Does anyone have a similar code that I could use to test my setup?

 

This topic has a solution.

"Better" is the enemy of "good".

Last Edited: Fri. Jun 14, 2019 - 09:29 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What is the AVR Vcc Voltage? 

Do you have AVcc connected?

Do you have Bypass Caps on the AVR? 

What is the CPU frequency of the AVR? 

Do you have the DIV8 fuse programmed or unprogrammed?

 

Did you do the Hokey Pokey, and then shake it all about?

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

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

I was going to ask for a schematic, but not sure that would help.

The SPI h/w just works, you write data and 8 clocks later the flag is set, assuming the SS pin is an output! 

I'll try loading the code and see what happens.....

 

Jim

 

 

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274

 

 

 

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

Where are you controlling the /SS pin?  That is not controlled by the SPI engine.  Unless the 2401 does not use it?

 

East Coast Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Irrehaare wrote:
void SPI_MasterInit(void);

This line is a function definition, and not a function call!  So the init never happens!

 

change this:

void SPI_MasterInit(void);

to this:

 SPI_MasterInit();

 

Found the problem by single stepping in the simulator!

Noticed the init was never called.

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274

 

 

 

Last Edited: Fri. Jun 14, 2019 - 07:56 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh. My. God. I was stuck for months, looking for the problem in the connections and that did it. It is working flawlessly. I feel like an idiot now. Again :P Anyway, should you ever be near Crocow please let me know, I owe you A LOT of bear.

 

@jgmdesign

-AVR 5V, AVcc connected, both have bypass caps. NRF gets 3.3v, since more would fry it.

-16MHz with external oscillator (again with ceramic caps),

-DIV8 ummm youi got me, no idea. I don't remember changing it, I was using separate software to set fuses and it's working ok in all solutions.

-a lot of Hokey Pokeying was involved.

 

"Better" is the enemy of "good".