Library 17- nRF24L01+ for STM32F4

17th library is here. I will show how to basic communicate with 2 nRF24L01+ RF transceivers.

The Nordic nRF24L01+ is a highly integrated, ultra low power (ULP) 2Mbps RF transceiver IC for the 2.4GHz ISM (Industrial, Scientific and Medical) band. With peak RX/TX currents lower than 14mA, a sub μA power down mode, advanced power management, and a 1.9 to 3.6V supply range, the nRF24L01+ provides a true ULP solution enabling months to years of battery life from coin cell or AA/AAA batteries. The Enhanced ShockBurst™ hardware protocol accelerator offloads time critical protocol functions from the application microcontroller enabling the implementation of advanced and robust wireless connectivity with low cost 3rd-party microcontrollers.

The Nordic nRF24L01+ integrates a complete 2.4GHz RF transceiver, RF synthesizer, and baseband logic including the Enhanced ShockBurst™ hardware protocol accelerator supporting a high-speed SPI interface for the application controller. No external loop filter, resonators, or VCO varactor diodes are required, only a low cost ±60ppm crystal, matching circuitry, and antenna.

The nRF24L01+ is available in a compact 20-pin 4 x 4mm QFN package.

nRF24L01+ has 6 data pypes. This means, that can receive data simultaneously from 5 nRF24L01+. My library uses only 1 data pype, so 2 nRF24L01s can be connected together and communicate. Every of them has an unique 5bytes long address, which is software selectable.

For example below, i used nRF24L01+ modules from ebay (link), their pinout is belowNRF2L01+ pinout

Connect NRF24L01 to discovery board
NRF24L01+ Discovery board Description
GND GND Ground
VCC 3.3V 3.3V
CE PD8 RF activated pin
CSN PD7 SPI3 Pinspack 2 CSN pin
SCK PC10 SPI3 Pinspack 2 SCK pin
MOSI PC12 SPI3 Pinspack 2 MOSI pin
MISO PC11 SPI3 Pinspack 2 MISO pin
IRQ Not used Interrupt pin. Goes low when active

nRF24L01+ Library

Features

  • Support for nRF24L01+
  • Max 32bytes of payload size
  • User selectable Own and TX address
  • up to 15 auto retransmissions with auto ACK
  • Get transmission status (sent ok, message lost, still sending)
  • Channel selectable from 0 to 125 (2.4 to 2.525GHz)
  • Data rate selectable, 2Mbps, 1Mbps or 250kbps
  • Output power selectable, -18dBm, -12dBm, -6dBm or 0dBm
  • Interrupt pin activated on nRF24L01+

Future planing

In near future I’m planning to make a nRF24L01+ wireless network.

Library Dependencies

  • CMSIS
    • STM32F4xx
    • STM32F4xx RCC
    • STM32F4xx GPIO
    • STM32F4xx SPI
  • TM
    • TM SPI
    • TM GPIO
    • defines.h

Functions and enumerations

Example

In example, I used 2 nRF24L01+ modules to communicate. One was connected to my STM32F4 discovery, second to STM32F429.

In example below, “transmitter” sends 32bytes of data to receiver and starts counting time. If sent was successfully, data will be returned from receiver. Time needed for that is displayed on Terminal with USART.

Code has comments, so I think it will be understandable.

Bottom are use “transmitter” and “receiver”, but remember: nRF24L01+ can be both, transmitter and receiver!

Make sure, that addresses match each other. On one side “TX” address is on other side “My” address.

Transmitter code

NRF24L01+ transmitter result

NRF24L01+ transmitter result


Receiver code

Projects available on Github, download library below.

Icon
TM STM32F4 NRF24L01+ Library

nRF24L01+ 2.4GHz transceiver

On my Github you will also found examples with interrupts for send and receive data.

tilz0R

Owner of this site. Also electronic enthusiasts, web developer, 3D printer fan, handball player and more. Big fan of STM32F4 devices. In anticipation of the new Discovery board for STM32F7 lines.

You may also like...

Read before commenting!

Before you make a new comment, make sure you agree with things listed below:

  • - Read post to make sure if it is already posted what you are asking for,
  • - Make sure you have the latest version of libraries used in your project,
  • - Make a clean and grammatically correct written message,
  • - Report as many details as possible, including what have you done so far,
  • - Do NOT post any code here. Use Pastebin,
  • - Do NOT post any error codes here. Use Pastebin,
  • - Specify STM32Fxxx family and used Discovery/EVAL/Nucleo or custom made board,
  • - Make sure your clock is set correct for PLL,
  • - If you are using my HAL drivers, please check this post how to start.
Comment will be deleted on breaking these rules without notification!
  • Arif Ahmet Balık

    You’re doing a great job. Thanks for library. I’m waiting for more about IoT library.

    • Thanks.
      I’m waiting new modules to arrive from ebay. They are connected to internet via wifi.

  • Victor

    Thanks for such great library. How can I set a transmitter to broadcast data to other 6 receivers (I’ve already set up all receivers with the same address)? By disabling ACKs? If so, how should I proceed? Thanks!

    • Currently only one to one communication can be activated.

      • Victor

        Thanks for the quick reply. I’ve just managed how to handle the broadcast comm by taking a look at the nrf24L01 datasheet. Just to inform here, I did it by deactivating the Enhanced Shockburst Mode (setting EN_AA=0x00 and ARC = 0). The bandwith reduces as well. Keep up with the good, TM!

  • Ricardo

    Hi, Thank you very much for sharing this great work.
    A quick question. If we want to send data longer than 32 bytes we have breake the data in packets right?
    Thanks

    • Hi.

      Yes, because nrf supports only 32bytes at a time.

  • Tyler

    Hey Majerle, thanks for the open source code. I’m currently using it for a school project to produce a wireless audio streamer. I’m running into a bit of a problem when receiving the data. I have the transceivers set at 2Mbps and I’ve got a payload size of 6 bytes. The problem is that it’s taking the receiver 500us to receiver the data. I need it to be much quicker in order to maintain the audio quality. Is there a setting that I might be overlooking ?

    • Hi.

      If I understand you right, from sending data to receiving them is 500us?
      Well you cannot expect much quicker. Use more payload (up to 32bytes) to transfer.

      • Tyler

        Shouldn’t I be able to decrease the time or increase the amount of data? if I’m only sending 32bytes at 500us then wouldn’t that only be 512kbps ? (32bytes * 1/500us)*8

        • OK, transfer with SPI from MCU to NRF takes sime time. If you have default SPI settings, then you use SPI prescaler 32, which gives you frequency of (SYSTEMCLOCK / 2) / 32. In case of F429 this is 2.8MHz.

          If you send 32bytes of data, then you have to send “payload write” command, then 32 bytes data and send command. This is 34bytes *8 bits = 272 clock cycles. One cycle is 1/2.8MHz = 357ns * 272 = 97us. The same has to be done on the receiver side and also, communication by air is not ideal. There is delay for sure. And as you can see, it’s a big delay.

          First, you can increase SPI clock. Open defines.h file and add line:
          //Increase SPI3 frequency
          #define TM_SPI3_PRESCALER SPI_BaudRatePrescaler_16

          NRF24L01+ max frequency = 10MHz

          • Tyler

            I actually noticed the prescaler in your code before I asked you the first question. That changed the delay from 1ms to around 500 us. Thanks for your quick response, and your open source code. I really appreciate you trying to help me.

  • Dima Bulkin

    Hi,
    I have implemented your code for F4, works fine,
    but after I am moved it to L1, and can’t find mistake. I am always in loop where TM_NRF24L01_GetTransmissionStatus. Please, help with idea what it can be?

    • Hello,

      From here, I can now just say that you need to implement pins for CE and CSN and SPI communication.
      Make sure that your clock is correct for peripheral, for example. On f4 gpios are on ahb1 bus, verify on which bus are on l1 version.

      • Dima Bulkin

        Thank you Majerle
        CE & CSN are fine too. I will check SCK time to doublecheck clocks and compare answers for SPI exchange while initialization. Will report later.

      • Dima Bulkin

        Works fine Just changed SCK and MISO Thank you!

        • Dima Bulkin

          Ok,
          now Transmitter is off, I just do TM_NRF24L01_GetData(). It constantly reports that there is new data.
          I am checked buffer. It is full ”.

  • nguyen phonghoa

    Hello Majerle Tilen,
    Could you please post whole project here?

    • nguyen phonghoa

      I only use KeilC Version 4 and lib Version 1.0.0 so when I creat and build project, it have an error : #35 “error directive” “Please select first target STM32F4xx…” . If you can , please post whole project.

      • You have project on Github provided.
        This error you get, because STD peripheral drivers does not know for which target your project is.

  • nguyen phonghoa

    Hello Majerle Tilen,

    If I want to send only a character and check it again in receiver, what should I do?

    In trans file:

    sprintf((char *)dataOut, “U”);

    /* Transmit data, goes automatically to TX mode */

    TM_NRF24L01_Transmit(dataOut);

    In receiver file:

    if (TM_NRF24L01_DataReady()) {

    /* Get data from NRF24L01+ */

    TM_NRF24L01_GetData(dataIn);

    if ( dataIn[0] == 0x55) // ASSCII
    {

    //do something
    }
    Is it TRUE?

    • If U is the same as 0x55 then yes.

      • nguyen phonghoa

        Thank you so much. I have another question

        In line 318 file system_stm32..
        #define PLL_M 8

        Do I need add HSE_VALUE=8000000 in Build for target , C/C++?

        and modify Xtal in Target is 25 as usual?

        • If you have discovery board, then set HSE_VALUE to 8000000 and PLL_M to 8 yes.

          Then, you should have proper clock for your device.

          • nguyen phonghoa

            Thank you for information. I have two discovery boards 407VGT. In your project, Transceiver or Receiver connect with STM32F4 discovery?
            Thank you so much.

          • Correct.

    • Việt Anh Nguyễn

      Hello nguyen phonghoa, Can I have your contact?
      my email: anh.nguyen@ntq-solution.com.vn
      See you soon!

  • nguyen phonghoa

    Hello Majerle Tilen,

    I see that in “tm_stm32f4_nrf24l01.h” the pin “IRQ Not used Interrupt pin. Goes low when active”. I have read datasheet but I don’t know how to make an interrupt when data was received. Could you please help me solve this problem or show me how to do it.

    Thank you in advance!

    • I have now reupload new version, which activates interrupts in NRF.

      You have to manually make an interrupt pin on STM, pin is your choice and also how will you do it (you can use my EXTI library for that).

      In this interrupt handler (falling edge) you have to first read Status register from nrf and then according to the bits you get, mask out which interrupt has occured.

      After that, you have to clear all of these interrupts which are set by writing corresponding bit to that location in status register or by calling NRF24L01_CLEAR_INTERRUPTS; somewhere in your handler.

      • nguyen phonghoa

        Thank you for your information

      • nguyen phonghoa

        Hello Majerle Tilen,

        I have used your library for external interrupt then I read data from register. But It was failed.

        Could you please help me ?

        Here is code:

        void Configure_PD0(void) {

        /* Set variables used */

        GPIO_InitTypeDef GPIO_InitStruct;

        EXTI_InitTypeDef EXTI_InitStruct;

        NVIC_InitTypeDef NVIC_InitStruct;

        /* Enable clock for GPIOD */

        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

        /* Enable clock for SYSCFG */

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

        /* Set pin as input */

        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;

        GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;

        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;

        GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;

        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;

        GPIO_Init(GPIOD, &GPIO_InitStruct);

        /* Tell system that you will use PD0 for EXTI_Line0 */

        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource0);

        /* PD0 is connected to EXTI_Line0 */

        EXTI_InitStruct.EXTI_Line = EXTI_Line0;

        /* Enable interrupt */

        EXTI_InitStruct.EXTI_LineCmd = ENABLE;

        /* Interrupt mode */

        EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;

        /* Triggers on falling edge */

        EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;

        /* Add to EXTI */

        EXTI_Init(&EXTI_InitStruct);

        /* Add IRQ vector to NVIC */

        /* PD0 is connected to EXTI_Line0, which has EXTI0_IRQn vector */

        NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;

        /* Set priority */

        NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;

        /* Set sub priority */

        NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;

        /* Enable interrupt */

        NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

        /* Add to NVIC */

        NVIC_Init(&NVIC_InitStruct);

        }

        /* Set interrupt handlers */

        /* Handle PD0 interrupt */

        void EXTI0_IRQHandler(void) {

        /* Make sure that interrupt flag is set */

        if (EXTI_GetITStatus(EXTI_Line0) != RESET) {

        /* Do your stuff when PD0 is changed */

        /* If data is ready on NRF24L01+ */

        if (TM_NRF24L01_DataReady())
        {

        /* Get data from NRF24L01+ */

        TM_NRF24L01_GetData(dataIn);

        Motor_Control();
        //Clear interrupts

        NRF24L01_CLEAR_INTERRUPTS;
        }

        /* Clear interrupt flag */

        EXTI_ClearITPendingBit(EXTI_Line0);

        }

        }

        • Let’s make some tests now.
          Put LED or something to IRQ pin and test, if IRQ happen
          If it will happen LED should stop blink if you connect it IRQ — A — K — Resistor — GND.

          PS: Do not read data in interrupt. In interrupt just set some flag, let’s say “nrf_interrupt_happen=1” and then somewhere in your application call status function and check which interrupt happen. According to the bit you get then do the stuff.

          I think here is problem because NRF is not trigger an interrupt.

          • nguyen phonghoa

            Thank you so much. I will try it again

          • nguyen phonghoa

            Hello Majerle Tilen,
            I have tried tried again but some thing was wrong.
            It can not make an interrupt when receive data.
            when I don’t use interrupt, your library is ok.

          • nguyen phonghoa

            Thank you so much Tilen, I have fixed it. Now, I can use interrupt for nRF24L01.

  • Erkan Karakaş

    Hi,
    How can use this library on NRF24L01 (not +)?

    • Hi.
      I’ve never test lib with not + version.
      I think it will not work but you can try and report.

      • Erkan Karakaş

        I tried but didnt work.I found a lot of difference in registers plus one version with not + version. I will set registers and try again.

  • Mihai Ignat

    Hello. I want to try to adapt your library to a STM32F103RBT6 and I want to use the NRF24L01+ with a WiFi device. Have you tried to use your examples in a WiFi network? Thank you.

    • You mean to go on the web with nrf? No go.
      Use ESP8266 instead.

      • Mihai Ignat

        Thank you for your answer. Have a nice day 🙂

  • Артем Тихонович

    Hi! Thank you for yours work. Do you have a example with connection test nrf to board? Usually this test print config registers from nrf. Ping test is a next step. -)

    • Ok, try to read Status register from NRF.
      If you will read something else rather than 0x00 or 0xFF, then communication works with SPI 😀

      • Артем Тихонович

        Thank you-). In arduino libs this function is really usefull. Sometimes nrf modules need a capacitor on power pins. On linux board i suppouse nrf module work normal i see in registers real data if unplug ce pin the data changed.

  • Sweetol

    Hi! I’m a student, i need your code to work on a project. I’m using f3 discovery and i’m trying to change the code to work with my board, but i failed. A lot of library seems to be missing. I tryed to download the missing libraries from Github, but i failed again. Too much error about missing definitions, undefined variables, ecc. Can you help me giving to me a full working project? I’m using IAR compiler…thankss..

  • Việt Anh Nguyễn

    Hi, every one. I need help.
    I used function TM_NRF24L01_DataReady() to check but I always recievered data even when don’t have transmission.

  • Oleksandr Korkh

    Hi, every one. I need help.
    On what parameters function

    SystemInit()
    TM_DELAY_Init();

    sets up microcontroller?

    • SystemInit() enables PLL and other stuff for MCU.
      TM_DELAY_Init() enables 1ms Systick interrupts and enables delay functions.

      • Oleksandr Korkh

        please take interrupt and delay function, I used other platform

        • ? Please be more clear here.

          • Oleksandr Korkh

            I am sorry, please lay out interrupt function systick and delay function,

          • It looks like I’m jork but I don’t understand what you want to do.
            You can copy/paste example and remove what you don’t need.

          • Oleksandr Korkh

            thanks, question it isn’t actual, I understood that not so

  • Kaustubh Mundhada

    Please Tell me what are the possible reasons for getting
    “NRF24L01_MESSAGE_LOST” as transmission status

    • 1. NRF modules too long away (not in range)
      2. Invalid addresses for both. They must have address each set. Look at examples how they are set.
      3. Message is lost because of other interferences.

      My choice here:
      1 or 2

      • Kaustubh Mundhada

        Thank you for the response.

        In TM_NRF24L01_SetMyAddress
        we are writing the register after making CE low
        But in
        TM_NRF24L01_SetTxAddress

        we are not doing CE low prior to writing the register.

        Can you please tell me the reason for this.

        • You can modify TX address function with CE LOW and CE HIGH functions if you need and test. It may be a bug but I don’t see it.

          • Kaustubh Mundhada

            There is a bug in the function

            TM_NRF24LO1_Init.

            In this function for changing channel we are using “TM_NRF24L01_SetChannel()” function and passing the “TM_NRF24L01_Struct.Channel” value to it.

            But in the function “TM_NRF24L01_SetChannel()” we are checking the following condition.

            if(channel <= 125 && channel != TM_NRF24L01_Struct.Channel)

            and hence it will never assign the specified channel and the module always work on channel 2 which is the by default channel.

            Thank you.

          • After this fix, everything works like expected?
            I will fix it now.

            Edit: FIXED.

          • Kaustubh Mundhada

            After this the channel is changing properly.

          • As far I know you had some problems with message lost. Does this work now?

          • Kaustubh Mundhada

            It is working now…

            Thank you for the support… 🙂

  • Ankit Lohani

    I have two STM32F4s and two nrf modules. I want to program one as a receiver and other as a transmitter. I simply want one to send 1,2,3,4 and other to receive these 4 digits with the four LEDs on the discovery board to toggle. Eg, 1 is received LED_GREEN is toggled and so on. The red led in the transmitter side is glowing all the time means

    /**********************receiver side code *******************************************/

    #include “stm32f4xx.h”
    #include “defines.h”
    #include “tm_stm32f4_nrf24l01.h”
    #include “tm_stm32f4_nrf24l01.c”
    #include “tm_stm32f4_disco.h”
    #include “tm_stm32f4_disco.c”
    #include “tm_stm32f4_delay.h”
    #include “tm_stm32f4_delay.c”
    #include “tm_stm32f4_spi.h”
    #include “tm_stm32f4_spi.c”
    #include “stm32f4xx_syscfg.h”
    #include “stm32f4xx_exti.h”
    #include “misc.h”
    int count = 0;
    uint8_t TxAddress[] = {
    0xE7,0xE7,0xE7,0xE7,0xE7
    };
    uint8_t MyAddress[] = {
    0x7E,0x7E,0x7E,0x7E,0x7E
    };
    uint8_t dataIn;
    int main(void) {
    TM_NRF24L01_Transmit_Status_t transmissionStatus;
    SystemInit();
    TM_DELAY_Init();
    TM_DISCO_LedInit();
    TM_NRF24L01_Init(15,1);
    TM_NRF24L01_SetRF(TM_NRF24L01_DataRate_2M, TM_NRF24L01_OutputPower_M18dBm);
    TM_NRF24L01_SetMyAddress(MyAddress);
    TM_NRF24L01_SetTxAddress(TxAddress);
    while (1) {
    if (TM_NRF24L01_DataReady()) {
    TM_NRF24L01_GetData(&dataIn);
    if (&dataIn==1) {
    TM_DISCO_LedOn(LED_BLUE);
    TM_DISCO_LedOff(LED_GREEN);
    TM_DISCO_LedOff(LED_ORANGE);
    TM_DISCO_LedOff(LED_RED);
    }
    else if (&dataIn==2) {
    TM_DISCO_LedOff(LED_ORANGE);
    TM_DISCO_LedOn(LED_RED);
    TM_DISCO_LedOff(LED_GREEN);
    TM_DISCO_LedOff(LED_BLUE);
    }
    else if (dataIn==3) {
    TM_DISCO_LedOff(LED_ORANGE);
    TM_DISCO_LedOff(LED_RED);
    TM_DISCO_LedOn(LED_GREEN);
    TM_DISCO_LedOff(LED_BLUE);
    }
    else if (dataIn==4) {
    TM_DISCO_LedOn(LED_ORANGE);
    TM_DISCO_LedOff(LED_RED);
    TM_DISCO_LedOff(LED_GREEN);
    TM_DISCO_LedOff(LED_BLUE);
    }
    else {
    TM_DISCO_LedOff(LED_ORANGE);
    TM_DISCO_LedOff(LED_RED);
    TM_DISCO_LedOff(LED_GREEN);
    TM_DISCO_LedOff(LED_BLUE);
    }
    TM_NRF24L01_PowerUpRx();
    }}}

    /****************************Transmitter side code************************************/
    #include “stm32f4xx.h”
    #include “defines.h”
    #include “tm_stm32f4_nrf24l01.h”
    #include “tm_stm32f4_nrf24l01.c”
    #include “tm_stm32f4_disco.h”
    #include “tm_stm32f4_disco.c”
    #include “tm_stm32f4_delay.h”
    #include “tm_stm32f4_delay.c”
    #include “tm_stm32f4_spi.h”
    #include “tm_stm32f4_spi.c”
    #include
    uint8_t MyAddress[] = {
    0xE7,0xE7,0xE7,0xE7,0xE7
    };
    uint8_t TxAddress[] = {
    0x7E,0x7E,0x7E,0x7E,0x7E
    };
    uint8_t dataOut = 0;
    int main(void) {
    TM_NRF24L01_Transmit_Status_t transmissionStatus;
    SystemInit();
    TM_DELAY_Init();
    TM_DISCO_LedInit();
    TM_DELAY_Init();
    TM_NRF24L01_Init(15,1);
    TM_NRF24L01_SetRF(TM_NRF24L01_DataRate_2M, TM_NRF24L01_OutputPower_M18dBm);
    TM_NRF24L01_SetMyAddress(MyAddress);
    TM_NRF24L01_SetTxAddress(TxAddress);
    while (1) {
    dataOut = dataOut + 1;
    TM_NRF24L01_Transmit(&dataOut);
    do {
    transmissionStatus = TM_NRF24L01_GetTransmissionStatus();
    } while (transmissionStatus == TM_NRF24L01_Transmit_Status_Sending);
    TM_DISCO_LedOn(LED_GREEN);
    /* Check transmit status */
    if (transmissionStatus == TM_NRF24L01_Transmit_Status_Ok) {
    TM_DISCO_LedOn(LED_BLUE);
    TM_DISCO_LedOff(LED_GREEN);
    TM_DISCO_LedOff(LED_RED);
    TM_DISCO_LedOff(LED_ORANGE);
    /* Transmit went OK */
    } else if (transmissionStatus == TM_NRF24L01_Transmit_Status_Lost) {
    TM_DISCO_LedOn(LED_RED);
    TM_DISCO_LedOff(LED_GREEN);
    TM_DISCO_LedOff(LED_BLUE);
    TM_DISCO_LedOff(LED_ORANGE);
    }
    /* Message was LOST */
    else {
    TM_DISCO_LedOn(LED_ORANGE);
    TM_DISCO_LedOff(LED_GREEN);
    TM_DISCO_LedOff(LED_RED);
    TM_DISCO_LedOff(LED_BLUE);
    }
    TM_DELAY_SetTime(0);
    while(TM_DELAY_Time()<50000);
    if(dataOut4)
    {
    dataOut=0;
    }}}

  • Ankit Lohani

    I have two STM32F4s and two nrf modules. I want to program one as a receiver and other as a transmitter. I simply want one to send 1,2,3,4 and other to receive these 4 digits with the four LEDs on the discovery board to toggle. Eg, 1 is received LED_GREEN is toggled and so on. The red led in the transmitter side is glowing all the time means all data lost. Plz check any other error in my code
    /**********************receiver side code *******************************************/
    #include “stm32f4xx.h”
    #include “defines.h”
    #include “tm_stm32f4_nrf24l01.h”
    #include “tm_stm32f4_nrf24l01.c”
    #include “tm_stm32f4_disco.h”
    #include “tm_stm32f4_disco.c”
    #include “tm_stm32f4_delay.h”
    #include “tm_stm32f4_delay.c”
    #include “tm_stm32f4_spi.h”
    #include “tm_stm32f4_spi.c”
    #include “stm32f4xx_syscfg.h”
    #include “stm32f4xx_exti.h”
    #include “misc.h”
    int count = 0;
    uint8_t TxAddress[] = {
    0xE7,0xE7,0xE7,0xE7,0xE7
    };
    uint8_t MyAddress[] = {
    0x7E,0x7E,0x7E,0x7E,0x7E
    };
    uint8_t dataIn;
    int main(void) {
    TM_NRF24L01_Transmit_Status_t transmissionStatus;
    SystemInit();
    TM_DELAY_Init();
    TM_DISCO_LedInit();
    TM_NRF24L01_Init(15,1);
    TM_NRF24L01_SetRF(TM_NRF24L01_DataRate_2M, M_NRF24L01_OutputPower_M18dBm);
    TM_NRF24L01_SetMyAddress(MyAddress);
    TM_NRF24L01_SetTxAddress(TxAddress);
    while (1) {
    if (TM_NRF24L01_DataReady()) {
    TM_NRF24L01_GetData(&dataIn);
    if (&dataIn==1) {
    TM_DISCO_LedOn(LED_BLUE);
    TM_DISCO_LedOff(LED_GREEN);
    TM_DISCO_LedOff(LED_ORANGE);
    TM_DISCO_LedOff(LED_RED);
    }
    else if (&dataIn==2) {
    TM_DISCO_LedOff(LED_ORANGE);
    TM_DISCO_LedOn(LED_RED);
    TM_DISCO_LedOff(LED_GREEN);
    TM_DISCO_LedOff(LED_BLUE);
    }
    else if (&dataIn==3) {
    TM_DISCO_LedOff(LED_ORANGE);
    TM_DISCO_LedOff(LED_RED);
    TM_DISCO_LedOn(LED_GREEN);
    TM_DISCO_LedOff(LED_BLUE);
    }
    else if (&dataIn==4) {
    TM_DISCO_LedOn(LED_ORANGE);
    TM_DISCO_LedOff(LED_RED);
    TM_DISCO_LedOff(LED_GREEN);
    TM_DISCO_LedOff(LED_BLUE);
    }
    else {
    TM_DISCO_LedOff(LED_ORANGE);
    TM_DISCO_LedOff(LED_RED);
    TM_DISCO_LedOff(LED_GREEN);
    TM_DISCO_LedOff(LED_BLUE);
    }
    TM_NRF24L01_PowerUpRx();
    }}}
    /****************************Transmitter side code************************************/
    #include “stm32f4xx.h”
    #include “defines.h”
    #include “tm_stm32f4_nrf24l01.h”
    #include “tm_stm32f4_nrf24l01.c”
    #include “tm_stm32f4_disco.h”
    #include “tm_stm32f4_disco.c”
    #include “tm_stm32f4_delay.h”
    #include “tm_stm32f4_delay.c”
    #include “tm_stm32f4_spi.h”
    #include “tm_stm32f4_spi.c”
    #include
    uint8_t MyAddress[] = {
    0xE7,0xE7,0xE7,0xE7,0xE7
    };
    uint8_t TxAddress[] = {
    0x7E,0x7E,0x7E,0x7E,0x7E
    };
    uint8_t dataOut = 0;
    int main(void) {
    TM_NRF24L01_Transmit_Status_t transmissionStatus;
    SystemInit();
    TM_DELAY_Init();
    TM_DISCO_LedInit();
    TM_DELAY_Init();
    TM_NRF24L01_Init(15,1);
    TM_NRF24L01_SetRF(TM_NRF24L01_DataRate_2M, TM_NRF24L01_OutputPower_M18dBm);
    TM_NRF24L01_SetMyAddress(MyAddress);
    TM_NRF24L01_SetTxAddress(TxAddress);
    while (1) {
    dataOut = dataOut + 1;
    TM_NRF24L01_Transmit(&dataOut);
    do {
    transmissionStatus = TM_NRF24L01_GetTransmissionStatus();
    } while (transmissionStatus == TM_NRF24L01_Transmit_Status_Sending);
    TM_DISCO_LedOn(LED_GREEN);
    /* Check transmit status */
    if (transmissionStatus == TM_NRF24L01_Transmit_Status_Ok) {
    TM_DISCO_LedOn(LED_BLUE);
    TM_DISCO_LedOff(LED_GREEN);
    TM_DISCO_LedOff(LED_RED);
    TM_DISCO_LedOff(LED_ORANGE);
    * Transmit went OK */
    } else if (transmissionStatus == TM_NRF24L01_Transmit_Status_Lost) {
    TM_DISCO_LedOn(LED_RED);
    TM_DISCO_LedOff(LED_GREEN);
    TM_DISCO_LedOff(LED_BLUE);
    TM_DISCO_LedOff(LED_ORANGE);
    }
    /* Message was LOST */
    else {
    TM_DISCO_LedOn(LED_ORANGE);
    TM_DISCO_LedOff(LED_GREEN);
    TM_DISCO_LedOff(LED_RED);
    TM_DISCO_LedOff(LED_BLUE);
    }
    TM_DELAY_SetTime(0);
    while(TM_DELAY_Time()<50000);
    if(dataOut4)
    {
    dataOut=0;
    }}}

    • As I told a lot of times, use pastebin for code, or I won’t make a response to it.
      I really don’t see nothing from this code!

      • soumaré

        hi majerle Tilen i would like to use your code to send data comming from a flamme sensor with the connecting the NRF24L01 + to an ST32F4discovery bord can you please help me

        her you gonna see my code to get data from two flamme sensor, I want to send it to another NRF24 monted on stm32f100rb

        her is the my code

        #include “stm32f4_discovery.h”

        #include “stm32f4xx.h”

        #include “stm32f4xx_rcc.h”

        #include “stm32f4xx_gpio.h”

        #include “stm32f4xx_adc.h”

        int ConvertedValue = 0;

        /**************************************************************************************/

        void RCC_Configuration(void)

        {

        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);

        }

        /**************************************************************************************/

        void GPIO_Configuration(void)

        {

        GPIO_InitTypeDef GPIO_InitStructure;

        /* ADC Channel 11 -> PC1 */

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

        GPIO_Init(GPIOC, &GPIO_InitStructure);

        }

        void inicialitzLED(void)

        {

        GPIO_InitTypeDef initValues;

        initValues.GPIO_Pin = GPIO_Pin_12;

        initValues.GPIO_Mode = GPIO_Mode_OUT;

        initValues.GPIO_OType = GPIO_OType_PP;

        initValues.GPIO_PuPd = GPIO_PuPd_NOPULL;

        initValues.GPIO_Speed = GPIO_Speed_2MHz;

        GPIO_Init(GPIOD, &initValues);

        }

        /**************************************************************************************/

        void ADC_Configuration(void)

        {

        ADC_CommonInitTypeDef ADC_CommonInitStructure;

        ADC_InitTypeDef ADC_InitStructure;

        // ADC structure configuration

        ADC_DeInit(); // Reset all parameters to their default values

        ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; // Input voltage is converted into a 12-bit number whose maximum value is 4095

        ADC_InitStructure.ADC_ScanConvMode = ENABLE; // No scan (only one channel)

        ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // the conversion is continuous (periodic)

        ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; // no external trigger for conversion

        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; // TRGO o CC1 (channel 1 capture/compare)

        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // converted data will be shifted to the right

        ADC_InitStructure.ADC_NbrOfConversion = 1; // Number of used ADC channels

        ADC_Init(ADC1, &ADC_InitStructure);

        // ADC common structure configuration

        ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; // independent mode

        ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; // f(ADC3)=84/4=48MHz

        ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; // disable DMA_MODE

        ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; // there are 5 clock cycles between 2 samplings

        ADC_CommonInit(&ADC_CommonInitStructure);

        /* ADC1 regular channel 11 configuration */

        ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_144Cycles); // PC1 is a sample time configured to 144 cycles
        /* Enable ADC1 */
        ADC_Cmd(ADC1, ENABLE);
        }
        int adc_convert(){

        ADC_SoftwareStartConv(ADC1);//Start the conversion

        while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//Processing the conversion

        return ADC_GetConversionValue(ADC1); //Return the converted data

        }

        void capteur_DC(void)

        {

        STM_EVAL_LEDInit(LED5);

        STM_EVAL_PBInit(BUTTON_USER,BUTTON_MODE_GPIO);

        STM_EVAL_LEDOff(LED5);

        if(!STM_EVAL_PBGetState(BUTTON_USER))

        STM_EVAL_LEDOn(LED5);

        }

        void capteur_AN(void)

        {

        ConvertedValue = adc_convert();

        if(ConvertedValueBSRRH= GPIO_Pin_12;

        }

        else if(ConvertedValue>3000)

        {

        GPIOD->BSRRL = GPIO_Pin_12;

        }

        }

        int main(void)

        {

        while(1) // Don’t want to exit

        {

        RCC_Configuration();

        GPIO_Configuration();

        inicialitzLED();

        ADC_Configuration();

        capteur_AN();

        capteur_DC();

        }

        }

        #ifdef USE_FULL_ASSERT

        /**

        * @brief Reports the name of the source file and the source line number

        * where the assert_param error has occurred.

        * @param file: pointer to the source file name

        * @param line: assert_param error line source number

        * @retval None

        */

        void assert_failed(uint8_t* file, uint32_t line)

        {

        /* User can add his own implementation to report the file name and line number,

        ex: printf(“Wrong parameters value: file %s on line %drn”, file, line) */

        /* Infinite loop */

        while (1)

        {

        }

        }

        #endif

        /**

        * @}

        */

        /**

        * @}

        */

        /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

  • Pingback: STM32F4 and nRF24LO1+ interfacing [on hold] | Question and Answer()

  • Tôn Quyền Ngô

    Hi Tilen,
    Can I use 2 NRF24L01+ in 1 board, with 1 will be transmitter, connect to UART1 and 1 will be receiver, connect to UART2?

    • Why on one board?
      Nrf works with spi.

      • Tôn Quyền Ngô

        Right now i have only one STM32F4 Disco board, so I wonder can I use SPI1 to transmit and SPI2 to receive the data (of course through the nRF module). when SPI2 receive data, it may blink the led or do something. Thanks.

        • Library does not support more than one NRF at a time.
          So, no, you can’t use like that.

  • Danh Ngọc Phương

    Dear Majerle Tilen,

    I used 2 SMT32F429 discovery board, 2 module Nrf24L01++ and your library to receive and transfer data between 2 module. I use logic analazer to capture data in the receiver module and I dont see any data received in MISO PIn and CE, CSN pin alway stay in level high. I read your library with tm_stm32f4_nrf24l01.h file. I thinks you were be wrong in the lines:

    /* Pins configuration */

    #define NRF24L01_CE_LOW TM_GPIO_SetPinHigh(NRF24L01_CE_PORT, NRF24L01_CE_PIN)

    #define NRF24L01_CE_HIGH TM_GPIO_SetPinHigh(NRF24L01_CE_PORT, NRF24L01_CE_PIN)

    #define NRF24L01_CSN_LOW TM_GPIO_SetPinHigh(NRF24L01_CSN_PORT, NRF24L01_CSN_PIN)

    #define NRF24L01_CSN_HIGH TM_GPIO_SetPinHigh(NRF24L01_CSN_PORT, NRF24L01_CSN_PIN)

    I thinks we should repair:

    #define NRF24L01_CE_LOW TM_GPIO_SetPinLow(NRF24L01_CE_PORT, NRF24L01_CE_PIN)

    #define NRF24L01_CE_HIGH TM_GPIO_SetPinHigh(NRF24L01_CE_PORT, NRF24L01_CE_PIN)

    #define NRF24L01_CSN_LOW TM_GPIO_SetPinLow(NRF24L01_CSN_PORT, NRF24L01_CSN_PIN)

    #define NRF24L01_CSN_HIGH TM_GPIO_SetPinHigh(NRF24L01_CSN_PORT, NRF24L01_CSN_PIN)

    Can you please tell me the reason for this.

    • Reason: I failed 😉
      Thanks for reporting this.

      • Danh Ngọc Phương

        Dear Majerle Tilen,

        Could you update new code to your library. I need this driver for my project.I am looking forward to hearing from you..

        Best regards.

        • I already did. But you can do it yourself also 😉

          • Danh Ngọc Phương

            Dear Majerle Tilen,
            I used two method:

            Method 1: Repaired state of CE and CSN pin on your library.
            Method 2:. I used new firmware of Library 17.

            With method 1 and 2, I didn’t see any data on receiver module. On Hyper Terminate printed: pinging: 100 ms: LOST.

            I thinks have some problem with this library. Could you test again this firmware on hardware with two module smt32f4 and nrf24l01++.?.

            Best regards.

          • When you told that first time with CE problems, I’ve checking this again using 2 STM32F4-Discovery boards.
            So, here are .hex files included below on link so you can test it yourself again. Pinout is the same as mentioned in this post.

            USART for debug is on PB6, 115200 bauds.

            http://stm32f4-discovery.com/wp-content/uploads/nrf24l01_working_code.rar

          • Anıl

            Hello Tilen,

            Firstly thank you for your work.

            I tried your work, but it is not working at all, and this HEX file is working like “Pressed reset button on tranceiver, led blinks once immediately on receiver board.” But as i understand from your code it must be working differently. I used 2 STM32F429 board. What should be the possible mistakes? Thank you!

          • “Pressed reset button on tranceiver” what does this mean?

          • Anıl

            When i press reset button on tranceiver, led on receiver blinks one. After that nothing is happening

          • This hex files works ok, user before confirmed that. Are you sure, everything is setup correct?
            Also, use debug output for USART.

          • Anıl

            Yes, i checked several times. I used debug now, tranceiver and receiver both stucked at SENDING at the same time.

          • Anıl

            It is working now, after “full erase chip”. Now trying to figure out using this module with GUI libraries 🙂

          • Anıl

            Hey Majerle, i am working with these modules again, and here is my problem, everything is fine with your codes, i am modifying your transceiver code, just changing dataout with something else, and receiver starts not receiving any data from transceiver, i added some leds, it is always waiting for dataready status, but everything is same, just coming data is different, what should be the problem? Do you have an idea? Thank you for your work!

  • Marcin Filipek

    Hi Majerle Tilen,
    In function TM_NRF24L01_SetTxAddress() you set RX_ADDR_P0 and TX_ADDR. Set RX_ADDR_P0 is nedded? If I set only TX_ADDR in this function, RX_ADDR_P0 in TM_NRF24L01_SetRxAddress() transmission work? I think good ?

    • In current lib configuration, it works just OK, so I think there is no problems with that.

      • Marcin Filipek

        In manual is “The RX address for data pipe 0 (RX_ADDR_P0) must be equal to the TX address (TX_ADDR) in the PTX device” in Enhanced ShockBurst™. I don’t understand, because NRF can connect with 6 device, so if set ADDR_P0 same TX_ADDR I lost one device. In MultiCeive is otherwise ?

        • When you have 6 devices, then you can’t use hardware CRC and other features if you don’t specify direct TX and RX address first to both devices for send and receive as far I know. Maybe I’m wrong.

          Well, you have working lib, if you need modifications, you can do it as well.

          • Marcin Filipek

            “One of the quirks of the device when using Enhanced ShockBurst is that pipe 0 must have the same address as the transmit register so to accomplish this and still be able to have 6 channels as receivers I swap out the pipe 0 register with the required address on transmit and then replace the pipe 0 address as needed when the device is put in receive mode.”
            Thanks 😉

  • Shagas Heizenberg

    Hello, Tilen.
    I’ve been trying to get your library to work for past 3 days now . Here is my setup:
    I’m trying to get my nrf on the stm32discovery to talk to my nrf on an Arduino nano and for some reason it’s not working. 2 arduino talk with each other no problem but the stm32 nrf does not talk to the nrf on the arduino.
    I set both nrf on 1Mbaud and channel 76 and I’ve confirmed on the oscilloscope by using a current shunt that the stm32f4 nrf IS transmitting! , but the nrf on the arduino is NOT receiving any packets. Can you please advise on what could be the problem? I’ve exhausted all my debugging ideas. Can the problem be in the CRC? I’ve tried various settings on the arduino including disabling , 8bit and 16 bit but none are working. What is the CRC of your library? I tried to find it but it is unclear to me. Also , is there anything special that I have to define in the define.h file or anywhere else? Im using default SPI pins and the rest of the stuff so I didn’t edit anything.
    Thanks in advance for the help!

    • Nrf can work in different modes, in my case it works with hardware crc and exactly specific address, but maybe arduino lib has other configuration that can receive data from everywhere technically.

      You can port my lib to arduino for example, or arduino code to stm. For me, only gpio and spi settings must be added/changed.

      • Shagas Heizenberg

        But with how many bits CRC is your library set at? 8 or 16? The arduino library has a variable where you enter only 1 address pipe (so I enter 0x7E7E7E7E7E). Porting it would take a long time and I’m already planning on porting the arduino mpu6050 DMP library to STM using your libraries , but once I’m finished with this project.
        Do you have any advice on what I can try perhaps to make your library work with the arduino one?
        I’m using the RF24 library. I feel that there is just a very small mistake/inconsistency somewhere and that it would work fine if I found it.

        • I have no idea right now crc is used. Default as far i know. I cant check right now that. But, checking initialization lib is pretty straightforward, so you can do it yrself in my lib :))

  • Name

    Hello Tilen!

    I try to use your library, but on the receiver side I always get values, not just in every two seconds. I don’t understand why. I tried other channels but the results are the same. Why is tha Dataready() always true?

    • Sounds like NRF does not clear status register for data ready.

      • Name

        I cheched it again Its not always high, its changing, just very fast. like i dont send information in every two seconds but in every two ms. But the transmitter is blinking in every two secs regularly,

        • Show me your examples. Use pastebin.

          • Name

            I am using yours without any modification.

          • Below in comments, you will found two examples. Check it for start. If atill doesnt work, then there is hardware problem.

          • Name

            I forgot to mention, that I changed the SPI pinouts for the communication. I added to the defines.h this:
            #define NRF24L01_SPI SPI4
            #define NRF24L01_SPI_PINS TM_SPI_PinsPack_2

            It’s because with the default pinout nothing worked, neither the transmitter, nor the receiver, i think because the audio DAC uses the C10, C12 pins. With this modification the transmitter works, but the receiver not, I checked with bots stm32 discovery boards, and with bots transcievers, but the receiver side is the same. What is the problem? Do i have to modificate with the spi pinspack the CSN Pin? I can’t find out whats the problem 🙁

          • You didn’t answer if .hex files worked for you. I don’t know how to help if you are not answering questions.

            CSN pin is itself and is not related to SPI.

          • Name

            I’m sorry. With the hex files works nothing 🙁 also nothing works with the PC10,11,12 SPI pinspack. With other pinspack the transmitter is working but the receiver don’t.. I tried every combination, more discovery boards, more nrf transmitters but everything is the same.
            I forgot to mention that I have NRF24L01+PA+LNA
            Can that be a problem?

          • Hex files are for f4 discovery board. If default pinout as set in this post does not work for you, then you have hardware problems.

          • Name

            I use f4 discovery. I’m not sure I flashed the hex files on the stm32, how do I have to flash them exactly?

          • Omg..use ST-Link utility.

          • Name

            sorry things are better now. the transmitter sends the data, but the receiver receives only the first data . when i reset the receiver stm32 then receives the first data again and then the green led remains on, and the serial writes: pinging 1ms : OK pinging 100ms LOST …

          • So, as mentioned earlier. If data ready bit is not clear (should be clear by hardware) then maybe you can try another chip.

  • Qasim

    hello i cannot find attributes.h can any one help me with this please? i m trying to use the library for tm_stm32f4_nrf24l01

    • This library does not need this file.
      Open post about a library which includes “attributes.h” file in your project and download from there.

      • Qasim

        thanks

      • Pradeep Chl

        Did you use Keil for compiling your code or GCC-ARM-Embedded toolchain in Linux? Is the file attributes.h available in Keil, ? I use Linux. Can you point to attributes.h file if possible?

        • Not sure why you need that in this library.
          Probably library where this file needs to be has also dependencies on its post available to download.

          Please check which library is a problem here.

  • Christian Julius

    Is 32 bytes (8 x 32 bit uint’s) really the maximum payload size? No chance to transmit a steady data stream with this modules? Have still 10 of them but dont know if they are usefull.

  • Christian Julius

    Hint:

    In tm_stm32f4_nrf24l01.c

    /* NRF structure */
    static TM_NRF24L01_t TM_NRF24L01_Struct;

    must be replaced by

    volatile TM_NRF24L01_t TM_NRF24L01_Struct;

    otherwise GCC removes it with -Os (Optimized for size) parameter. and some routines wont work.

    • Looks like GCC fail 😉

      • Christian Julius

        No…. every unused global variable can be optimized when not being used. Therefore volatile must be used in case of using them in Interrupts and can be used with other globals. I rewrote the lib using RX_DR Ints to fetch data from RF module.

        • I dont see a reason for that in library. Structure is used in some places so it shouldnt be a problem at all.

          You are “not allowed” to modify library. If you do, take care of that variables.

          With not allowed, I mean that all additions you make should be done out library. Ststic declaration is for reason so variable is not visible outside.

          Make irq handler in main file or irq file foryour project.

          Btw..im still surprised, that you use allll libs from this site in your project. Must be something else 😉

          • Christian Julius

            Well … at the moment I try to write my own functions based on StdPeriphLibs because it is better for understanding, e.g. the complex I2C Interface or DMA. I wrote my own API for 16 bit adressed devices. Using libs is nice but you dont learn something about the hardware. And I need this for my big project: the drone controller pixhawk with 20.000 files in project folder, ChiBiOS as platform

            Your “competitor” is also very active 🙂

            http://mikrocontroller.bplaced.net/wordpress/?page_id=744

          • Wow, nice site.

            Let me ask you…20000 files?
            What has nrf to do with adc, dma, i2c, 16bit eeprom?

            Btw.. I saw your eeprom code you linked here.

            Can you now stop blame the code all the time to make you great developer? Just asking.. Again, volatile/static has nothing to do with lib and i2c eeprom.

          • Christian Julius

            I dont know your problem. If i find something strange, I report it to discus it. But if you prefer it, I take everything as it is.
            20.000 files with all: CMSIS, ChiBiOS Real Time OS and every combination of hardware for a copter. But not compatible with any IDE, pure shell command line.
            And all the stuff: nrf, eeprom, adc, dma etc are combined in this little project to get familiar with this great controller.

          • Well, I don’t have a problem, looks like you have it when you always hate this web and all the libraries you are using. Feel free to make your own and documented. Then publish it 😉

            Btw..nice board. Think about FSMC, 8080 16-bit LCD display.
            http://www.buydisplay.com/default/tft-display/5-inch?interface=390

          • Christian Julius

            I am wondring if it is possible to use one SPI for more than 1 device (Display, 7-Segment diplay on one SPI port but with different CS Pins). I gues that I have to initilize them before every access, so that Init_ILI9343 must be called before every acess,

          • Init should be done only one time.

          • Christian Julius

            But SPI are normally designed to communicate with several slaves. I connected NRF24L01 (3.3V) and a MAXIM7219 (5V TTL) at the same SPI, but too tired to test it today.

          • Christian Julius

            Is there any chance to check, if the NRF24L01 is adressed and working? I read out the status and it is always 0x14. Not nice to test a system, if both modules must work to be tested. Arduino = I hope… STM32 = I am not sure….

          • Christian Julius

            There is really something strange. The volatile doesnt change the problem.
            This simple code runs without problems, when compiling with no optimization.
            http://pastebin.com/kXBpUNib
            But with any kind of optimzation the led LED flashes because the loop never ends.
            But normally the loop must end, because there is no endless lop in your code.

            Very strange…..

          • So my lib is not a problem. Btw..i dont see how you call this function, because in this function led cant blink!

          • Christian Julius

            Ok,
            void __attribute__((optimize(0))) TM_NRF24L01_Transmit(uint8_t *data) {
            did the trick. When nothing is transmitted, no answer can be read.

            No idea why, but GCC seems to be strange sometimes…

  • Pradeep Chl

    I am getting below error while compiling with GCC-ARM-Embedded compiler in Linux:

    inc/tm_stm32f4_spi.h:568:9: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘void’
    __weak void TM_SPI_InitCustomPinsCallback(SPI_TypeDef* SPIx);

    Looks like the compiler has a problem with ‘__weak’, and when I removed it , it gives below error:
    src/tm_stm32f4_spi.c:463: undefined reference to `TM_SPI_InitCustomPinsCallback’

    How to get around this one ?

    Thanks,
    Pradeep.

    • Compiler is smart. It says you which file is a problem, in your case it is tm_stm32f4_spi.h

      So find TM SPI library on this site for standard peripheral drivers (link to that post is also in tm_stm32f4_spi.h file) and download what you need.

      Really don’t know what has this to do with NRF library!

      • Pradeep Chl

        The library has tm_stm32f4_spi.c and tm_stm32f4_spi.h right?

  • Pradeep Chl

    Hii TM, what is the name of the RFID standard that is been implemented in nRF24L01+ code?

    • What?

      • Pradeep Chl

        You must be knowing that there are different RFID standards, which one you are using? I hope I am clear

        • Haha 🙂 I know that there are different standards.
          But you must be knowing that nRF24L01+ is NOT RFID chip.

          • Pradeep Chl

            Okey, Did you happen to use data frame packet in nRF24L01+ driver ? The data frame packet i mean it will include CRC, Preamble, Payload, Header etc . I find only Payload of 32 bytes used in the code.

          • I don’t know how familiar are you with this cip, but anyway.

            Payload means data which will be sent to another chip.
            CRC is done on hardware together with other info. Data you wanna sent to another NRF are max of 32-bytes at once (payload).

            If you want add CRC in your packet, add it inside payload.

            I’m not sure what you wanna do here.

          • Pradeep Chl

            I assume you have used a standard protocol, Is it possible to make it encrypted to make it specific to a proprietary protocol.? Can you briefly explain about CIP?

          • In communication, everything you must take care is what you sent and address where to sent.

            CRC and other stuffs are done on chip level to make sure everything is set correctly.
            What you will send is up to you. You can make CRC of your payload in software part and send it together inside payload data.

            PS: Is there more than standard protocol?

          • Pradeep Chl

            you mean I can use some bytes of the payload for an encryption algorithm. Can you suggest an encryption scheme ! I am sorry if I am being repetative

          • No, I can’t suggest because I never used this.

  • Christian Julius

    Hi,

    do you know if these the lib is compatible? The sender must be a single-chip arduino in my app, because of ultra low power operation. In the middle of the text, a format is mentioned for the transmission:
    —–
    Packet Format

    All messages sent and received by this NRF24 library must conform to this packet format, as specified by the nRF24L01 product specificaiton:

    1 octets PREAMBLE
    4 octets ADDRESS
    9 bits packet control field
    0 to 32 octets PAYLOAD
    2 octets CRC
    —–

    The lib also used ACK. No need to inspect to source code, the description is very good.

    http://www.airspayce.com/mikem/arduino/NRF24/

    I only want to get pure raw 32 byte data out of the module.

    • Arduino for ultra-low? Nice try.

      Btw..you can test if it is compatible, I won’t 🙂

      • Christian Julius

        >>Arduino for ultra-low? Nice try.

        Only the Single Attiny84 Chip @ 1 Mhz and the sleep modes! 1 wake up per minute. Nothing else, no regulator, no extra hardware.

  • Pradeep Chl

    I have read in the SPI main.c file that I would need a 1.4.0 or greater version of standard peripheral drivers required. I have version 1.0.0. Do you know where will I find the recent version of std peripheral drivers ?

  • Christian Julius

    Tileeeeen?

    Is there really everything ok with the NRFL2401 lib? I have such a strange behaviour …..

    This is the first transmission 32 Bytes…. it looks good, the module responds with it status, it sends “something”

    • Christian Julius

      Now the seconds transmission….. nothing is good. The module do not respond and the SPI keeps on working till timeout……

      I am so fed up with this f**** device ….3 days now without sucess!

      • Christian Julius

        Code is easy…..

        uint8_t tls_RFSendWork(Work_t *Data)
        {
        mydata_t tx;
        [….]
        TM_NRF24L01_Transmit((uint8_t*)&tx);
        if (NRF24L01_WaitForTransmission()!=SUCCESS)
        return ERROR;

        return SUCCESS;
        }

        // NRF24L01: Warte auf das Ende der Übertragung
        static uint8_t NRF24L01_WaitForTransmission()
        {
        TM_NRF24L01_Transmit_Status_t transmissionStatus;
        uint32_t timeout = 20000;
        do {
        transmissionStatus = TM_NRF24L01_GetTransmissionStatus();
        if (–timeout == 0) {
        GPIO_SetPin(GPIOD,LED_ORANGE);
        return ERROR;
        }
        } while (transmissionStatus == TM_NRF24L01_Transmit_Status_Sending);
        if (transmissionStatus == TM_NRF24L01_Transmit_Status_Lost)
        return ERROR;

        return SUCCESS;
        }

        • Christian Julius

          Five transmissions with 1s between…. there is something strange with the polarity of the signals between the transmissions……. but the pins are not used for anything else.

          • Christian Julius

            Init ok, First transm. ok, second not, others are rubbish

          • Christian Julius

            Ok…. 5 o’clock now …… need no answer…… I found the problem….. ARRRRGHHHHH!
            The Disco Board CPU was defective! Maybe due to ESD. Really, The CE or CSN Pin has gone. I have first detected this problem with another board, that some pins really die fast, when grabbing the board often with fingers. They “flickered”. I replaced the board now with a brand new one and every thing is fine !!!!!

          • So after all, my library works ok?

          • Christian Julius

            Yeah! Ping….pong….ping….pong……But I have to disable all GCC optimizations, otherwise it stucks somehwhre in an endless loop. This and the SPI are the only librarys where I have to partly disable Optimization.

            Unfortunately the Arduino mirf lib is not compatible, dont know why.

          • Nice to hear it works.

            Let me know where it stucks. It is funny because it shouldn’t anywhere.

            You have probably half an hour to port my lib to arduino. Porting arduino lib to STM32 would probably be harder since I assume it uses C++ there.

          • Christian Julius

            this loop never ends, wenn O1, O2, O3 (speed) or Os (size) is activated in GCC. I really miss a professional debugging equipment, where I can read out the last traced instructions. fixed this with #pragma __optimize__ ((0)) at the top of the module but thats only a work around. Sometimes better more “volatiles” than less ones.

            /* Wait for data to be sent */
            loop = 0;
            do {
            transmissionStatus = TM_NRF24L01_GetTransmissionStatus();
            } while (transmissionStatus == TM_NRF24L01_Transmit_Status_Sending);

          • Does not like lib problem.

            Next time, use pastebin or I will delete comment. Second time today. Rules are rules and apply to all.

          • Christian Julius

            Delete what you want…. bye!

          • Christian Julius

            The Arduino problem is simple: Find out what configuation for the RF is used and fix it. The RFL24L01 is not very complex. I will check this in the next days, first I travel to Russia this weekend, Kiew and Chernobyl 🙂

  • Pradeep Chl

    Hi TM, For communication between two transmitters and one receiver(mulitceiver), how should the addressing should be. Can you show it by assigning different addresses to each one if possible. You have said that ‘Own’ address of one device should be same as Tx address of other device, please elaborate on that .

  • Łukasz

    Hi, in documentation is bit: NRF24L01_MAX_RT and description: Write 1 to clear bit. If MAX_RT asserted it must cleared to enable futher communication. I can’t see this operation in your library. So I consider to add this functionality. What do you think about this ?

    • You must clear interrupt flags what I do in library when going to TX or RX mode.

      • Łukasz

        I see, thx

  • Arul Prasath K

    hi, i’m getting an error like “#error “tm_stm32f4_disco.h: Please select your board. Open tm_stm32f4_disco.h and follow instructions!!”” this, i’m using 2 STM32F4-Discovery and 2 nRF24L01 to communicate, but the code that you have uploaded is not working… can you help me to solve this prob…

    Thank You,
    With Regards.

    • You dont you do what error says? Why you dont wanna open file and follow instructions how to setup your board?

      • Arul Prasath K

        Thanks for your response, yes i can understand, but i’m using two “STM32F407VG”, but in “lib” file you have defined like this “#elif defined(STM32F407VG) || defined(STM32F401VC)// || defined(STM32F40_41xxx)” but i want to communicate two STM32F407VG, for example,in Tx side, one STM32F407VG is connected to nRF24L01 via SPI interface and similarly for Rx side..
        now how to modifies your library to communicate..so i don’t have any ideal how to solve this…

        Thank you,
        With Regards,

        • Make define for board on which your software is running.

          • Arul Prasath K

            ok i have modified this two lines
            “#elif defined(STM32F407VG) || defined(STM32F407VG)// || defined(STM32F40_41xxx)” and

            “/* STM32F4 & STM32F401 Discovery */
            #elif defined(TM_DISCO_STM32F4_DISCOVERY) || defined(TM_DISCO_STM32F4_DISCOVERY) ”
            but still i’m getting same error..

            Thank you,
            With Regards,

          • Thats because you didnt read content of a file with explanation.

          • Arul Prasath K

            ok but how can i do this modification ?

            Thank you,

          • I gave you a link!

  • a

    hello Tilen
    I used two stm32f407 discovery to connect nrf
    can i used your library without any changes?

  • Mircheil Nitchell

    Hello Tilen, can you show me what I need to change so that the STM32F4 can communicate with a Raspberry pi using 2 modules nrf24l01+ ? Here is the picture on Raspberry pi’s side:

  • Devan

    Hey Tilen, how would one make use of the interrupt on these devices and your libraries?

  • Linh Bui

    Hi Tilen,
    I am doing graduation thesis. My topic is sending photos via nRF24L01 with stm32f4 board. although I have set baudrate is 2Mps but really it has not been 1Mps. Can you tell me why is it?
    Thank you very much!

  • D Nesvera

    Hello Tilen,
    I wrote a library based on yours and RF24 using the new libraries of STM32CUBEMX. I mentioned this page there.
    https://github.com/GEPSE/STM32_NRF24
    Thanks for the help!

  • GoBen

    Hey Tjlen, everything is fine with me except it can’t transmit data, I simply copied your transmit example into my project. It compiled and uploaded OK but the green led is always ON (it means that it could not transmit data, right?) Can you show me any solution?

    • Who is the receiver?

      • GoBen

        Another stm32f4 disc board using receiver example, I think my nrf24l01 module might have problem, am I right?

        • GoBen

          Any idea tilen?

          • Um, actually I don’t have idea right now. Can you verify that data are really not received?

          • GoBen

            I opened up Terminal and I didn’t receive any thing on Terminal screen. I used a USB-UART module to connect to my stm32f4 disc board and I chose the exact port on the Terminal.
            Moreover, the green led on the transmitter unit always lightning up, it means that it couldn’t transmit the data (according to your code, if the data is transmitted successfully, the green LED must be turned off, right?)
            But, still struggling, I hope you can help me

  • GoBen

    Dear TIlen, can your program communicate with many STM32F4 boards using nrf24l01+ modules? Or it just a pair-to-pair communication between two STM32F4 boards?
    If I want to transmit/receive data with many other STM32F4 boards like a network, what should I do?

    • Rewrite lib to support that feature.

      • GoBen

        Thanks for your reply, but can you develop your program to have that feature because my code ability is limited. It would be so great for all of us. Thank you again

        • RIght now, I’m too busy to do that.

          • GoBen

            Um, so take your time. But I hope you could do such thing in near future, it would be a great, great help!