{"id":4257,"date":"2020-05-13T20:00:56","date_gmt":"2020-05-13T18:00:56","guid":{"rendered":"https:\/\/msalamon.pl\/?p=4257"},"modified":"2025-12-27T17:27:46","modified_gmt":"2025-12-27T16:27:46","slug":"radio-communication-using-nrf24l01-modules-part-1","status":"publish","type":"post","link":"https:\/\/msalamon.pl\/en\/radio-communication-using-nrf24l01-modules-part-1\/","title":{"rendered":"Radio Communication Using nRF24L01+ Modules, Part 1"},"content":{"rendered":"\n<p>The topic of <a href=\"https:\/\/sklep.msalamon.pl\/?s=nrf24&amp;post_type=product&amp;utm_source=blog&amp;utm_medium=article&amp;utm_campaign=nrf24&amp;utm_content=Text\">nRF24L01+<\/a> had been sitting on my \u201cto-do\u201d list basically since this blog was created. This chip is one of the most popular radio ICs. Modules from China cost proverbial pennies, and the capabilities offered by these nRFs are out of this world. So why did it take me so long?<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>The problem was that a few years ago, when I was still coding only on AVR, I had a huge problem with these modules. I couldn\u2019t get them to work with interrupts. Now, with much more experience, it worked almost right away. Once I got unstuck, I decided to strike while the iron was hot and write this mini-series about these great modules.<\/p>\n\n\n\n<p>The entire series about <a href=\"https:\/\/sklep.msalamon.pl\/?s=nrf24&amp;post_type=product&amp;utm_source=blog&amp;utm_medium=article&amp;utm_campaign=nrf24&amp;utm_content=Text\">nRF24L01+<\/a>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"http:\/\/msalamon.pl\/komunikacja-radiowa-z-uzyciem-modulow-nrf24l01-cz-1\/\">Part 1<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/msalamon.pl\/komunikacja-radiowa-z-uzyciem-modulow-nrf24l01-cz-2\/\">Part 2<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/msalamon.pl\/komunikacja-radiowa-z-uzyciem-modulow-nrf24l01-cz-3\/\">Part 3<\/a><\/li>\n<\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">nRF24L01+ chip<\/h1>\n\n\n\n<p><a href=\"http:\/\/msalamon.pl\/download\/1099\/\">nRF24L01+ datasheet<\/a><\/p>\n\n\n\n<p>This chip supports radio communication at 2.4 GHz. It has 126 programmable channels on which it can transmit. The best part is that these <strong>channels do not overlap<\/strong> like, for example, WiFi channels.<\/p>\n\n\n\n<p>You can also set the data rate and transmitter power. This is useful for reducing power consumption. Power Down mode is also useful for that.<\/p>\n\n\n\n<p>Now the best part. The <a href=\"https:\/\/sklep.msalamon.pl\/?s=nrf24&amp;post_type=product&amp;utm_source=blog&amp;utm_medium=article&amp;utm_campaign=nrf24&amp;utm_content=Text\">nRF24L01+<\/a> chips support the&nbsp;<strong>Enchanced ShockBurst\u2122<\/strong> technology. Sounds like some weird advertising slogan. What does it give us? The most important things are:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Automatic handling of radio packets.<\/strong> You don\u2019t have to think about whether you need to send start bits, stop bits, preambles, and other such things over the air. You only load into the <a href=\"https:\/\/sklep.msalamon.pl\/?s=nrf24&amp;post_type=product&amp;utm_source=blog&amp;utm_medium=article&amp;utm_campaign=nrf24&amp;utm_content=Text\">nRF<\/a> what you actually want to send, and it wraps it into packets by itself. On reception, it will also decode it by itself, returning your data, i.e. the so-called payload.<\/li>\n\n\n\n<li><strong>The payload is dynamic.<\/strong> What does that mean? You can transmit messages of size 1\u201332 bytes, and the modules will tell each other how much data came through in the payload.<\/li>\n\n\n\n<li><strong>Automatic acknowledgment of packet reception.<\/strong> You don\u2019t need to send any \u201cokays\u201d back. The ACK is hardware-based and if you received the payload, both sides will know about it.<\/li>\n\n\n\n<li><strong>Automatic CRC checking.<\/strong> You don\u2019t have to calculate and verify it yourself. The chip does it for you! If a packet arrives corrupted, the <a href=\"https:\/\/sklep.msalamon.pl\/?s=nrf24&amp;post_type=product&amp;utm_source=blog&amp;utm_medium=article&amp;utm_campaign=nrf24&amp;utm_content=Text\">nRF<\/a> will reject it and won\u2019t send an acknowledgment, for example forcing retransmission by the transmitting chip.<\/li>\n\n\n\n<li><strong>Reception from multiple transmitters.<\/strong> Up to six. This helps connect chips in a mesh, star, and other topologies.<\/li>\n<\/ol>\n\n\n\n<p>The chips are <strong>addressed with 3\u20135 bytes<\/strong>. The \u201ctunnel\u201d address of Pipe 0 and 1 is basically arbitrary. The remaining Pipes 2\u20135 have the same most significant part of the address as Pipe 1. They differ only in the least significant byte. This is explained by this figure from the <a href=\"http:\/\/msalamon.pl\/download\/1099\/\">documentation<\/a>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_addressing.png\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"204\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_addressing-300x204.png\" alt=\"\" class=\"wp-image-1520\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_addressing-300x204.png 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_addressing-24x16.png 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_addressing-36x24.png 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_addressing-118x80.png 118w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_addressing.png 542w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Modules with nRF24L01+<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>I mentioned at the beginning that the chip\u2019s popularity is due, among other things, to cheap and easily available modules from China. The basic module has pins on classic 2.54\u2033 headers and costs a few z\u0142oty.<\/p>\n\n\n\n<p>There is also a \u201cMINI\u201d version that is slightly smaller and allows SMD mounting.<\/p>\n\n\n\n<p>Those who care about good range will like modules with a large external antenna and an RF amplifier. You can get pretty good ranges with these modules.<\/p>\n\n\n\n<p><strong><a href=\"https:\/\/sklep.msalamon.pl\/?s=nrf24&amp;post_type=product\/&amp;utm_source=blog&amp;utm_medium=article&amp;utm_campaign=nrf24&amp;utm_content=Text\">You can buy all these modules in my shop.<\/a><\/strong><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/sklep.msalamon.pl\/?s=nrf24&amp;post_type=product\/&amp;utm_source=blog&amp;utm_medium=banner&amp;utm_campaign=nrf24&amp;utm_content=nrf24\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"400\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nRF24L01-baner.jpg\" alt=\"\" class=\"wp-image-1528\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nRF24L01-baner.jpg 1200w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nRF24L01-baner-300x100.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nRF24L01-baner-1024x341.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nRF24L01-baner-768x256.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nRF24L01-baner-24x8.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nRF24L01-baner-36x12.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nRF24L01-baner-160x53.jpg 160w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>Unfortunately, it\u2019s not all that beautiful. I need to warn you a bit. In China, as China goes, copying is popular. The <strong><a href=\"https:\/\/sklep.msalamon.pl\/?s=nrf24&amp;post_type=product&amp;utm_source=blog&amp;utm_medium=article&amp;utm_campaign=nrf24&amp;utm_content=Text\">nRF24L01+<\/a> chip was copied and released under the name Si24R1<\/strong>. They work \u201cthe same,\u201d but you know how that can be. I\u2019d approach them with a bit of distance.<\/p>\n\n\n\n<p><strong>In my shop I clearly mark which chip is placed on the module.<\/strong> But you know\u2014anything can be written on an IC, so in reality nobody knows what\u2019s inside. On my side, I do what I can.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wiring diagram to Nucleo<\/h2>\n\n\n\n<p>I\u2019ll use the classic 2.54\u2033 pin modules. The wiring for the transmitter and receiver is identical. Below you have the pinout of the module itself. Unfortunately it is not labeled on the PCB, so wiring takes a moment.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24l01_pinout.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"367\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24l01_pinout.jpg\" alt=\"\" class=\"wp-image-1521\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24l01_pinout.jpg 800w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24l01_pinout-300x138.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24l01_pinout-768x352.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24l01_pinout-24x11.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24l01_pinout-36x17.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24l01_pinout-160x73.jpg 160w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/figure>\n<\/div>\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_schematic.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1300\" height=\"650\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_schematic.png\" alt=\"\" class=\"wp-image-1522\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_schematic.png 1300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_schematic-300x150.png 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_schematic-1024x512.png 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_schematic-768x384.png 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_schematic-24x12.png 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_schematic-36x18.png 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_schematic-160x80.png 160w\" sizes=\"auto, (max-width: 1300px) 100vw, 1300px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>What\u2019s important is that the <a href=\"https:\/\/sklep.msalamon.pl\/?s=nrf24&amp;post_type=product&amp;utm_source=blog&amp;utm_medium=article&amp;utm_campaign=nrf24&amp;utm_content=Text\"> nRF24L01+<\/a> chip is powered from 3V3. <strong>If for some reason it doesn\u2019t want to work properly, it\u2019s worth adding an electrolytic capacitor as close as possible to the power pins, e.g. 1 uF.<\/strong> It can help a lot.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Configuration in CubeIDE<\/h2>\n\n\n\n<p>For tests I used two almost identical Nucleo boards \u2013 <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/nucleo-f401re\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=nrf24&amp;utm_content=Text\">F401RE<\/a> and F410RB. Thanks to this, the transmitter and receiver projects are almost the same \ud83d\ude42<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/sklep.msalamon.pl\/kategoria-produktu\/dev-boardy\/stm32-nucleo\/?utm_source=blog&amp;utm_medium=banner&amp;utm_campaign=nrf24&amp;utm_content=nucleo\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"400\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner.jpg\" alt=\"\" class=\"wp-image-1593\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner.jpg 1200w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner-300x100.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner-1024x341.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner-768x256.jpg 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>Software versions I use:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>STM32CubeIDE v1.3.0<\/li>\n\n\n\n<li>STM32CubeMX v5.6.0 built into the IDE\u00a0<\/li>\n\n\n\n<li>HAL library for F4 v1.25.0<\/li>\n<\/ul>\n\n\n\n<p>I created the project with the default peripheral settings for Nucleo \u2013 UART and Serial Debug are already taken care of \ud83d\ude42<\/p>\n\n\n\n<p>To communicate with the microcontroller, the module requires an SPI interface. It supports up to 10 MHz, so standard as befits SPI chips. You can probably overclock it if you really want \ud83d\ude42<\/p>\n\n\n\n<p>I like using Arduino pins because I have easy access to them with a logic analyzer as well. SPI1 is on those pins, so that\u2019s what I\u2019ll use.<\/p>\n\n\n\n<p>Set it to Full-Duplex Master mode. If you did it like I did with the default settings, then HCLK is set to 84 MHz, and therefore SPI is clocked with 42 MHz. I set the SPI prescaler to 16, so effectively on the SPI clock I\u2019ll get around 2.63 MHz. Perfect for viewing on a low-performance logic analyzer.<\/p>\n\n\n\n<p>My configuration is in the screenshot.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_spi_settings.png\"><img loading=\"lazy\" decoding=\"async\" width=\"714\" height=\"606\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_spi_settings.png\" alt=\"\" class=\"wp-image-1523\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_spi_settings.png 714w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_spi_settings-300x255.png 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_spi_settings-24x20.png 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_spi_settings-36x31.png 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_spi_settings-94x80.png 94w\" sizes=\"auto, (max-width: 714px) 100vw, 714px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>The <a href=\"https:\/\/sklep.msalamon.pl\/?s=nrf24&amp;post_type=product&amp;utm_source=blog&amp;utm_medium=article&amp;utm_campaign=nrf24&amp;utm_content=Text\">nRF24<\/a> modules also have a few other pins: CE, CSN, IRQ. The first two are inputs, so you need to set the MCU pins as GPIO Output.<\/p>\n\n\n\n<p>IRQ is an interrupt, so set GPIO_EXTI.<\/p>\n\n\n\n<p>I used PA9, PB6, and PC7, which are next to the SPI pins. Everything is close together.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_gpios.png\"><img loading=\"lazy\" decoding=\"async\" width=\"786\" height=\"112\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_gpios.png\" alt=\"\" class=\"wp-image-1524\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_gpios.png 786w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_gpios-300x43.png 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_gpios-768x109.png 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_gpios-24x3.png 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_gpios-36x5.png 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_gpios-160x23.png 160w\" sizes=\"auto, (max-width: 786px) 100vw, 786px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>For now we won\u2019t use interrupts, but it\u2019s worth having the GPIO already configured \ud83d\ude42<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Code<\/h2>\n\n\n\n<p>As I mentioned at the beginning of this post, I had the library partially prepared from a few years ago. From what I recall, I based it on the popular and fairly well-working RF24 library from Arduino. Back then it didn\u2019t have good interrupt support, and my attempts ended in a temporary failure.<\/p>\n\n\n\n<p>I\u2019m coming back stronger and I\u2019ve already got working interrupts, but those will be in the next part of the <a href=\"https:\/\/sklep.msalamon.pl\/?s=nrf24&amp;post_type=product&amp;utm_source=blog&amp;utm_medium=article&amp;utm_campaign=nrf24&amp;utm_content=Text\">nRF24<\/a> series. Today I\u2019ll show you the chip configuration and the basic mode of operation, i.e. polling.<\/p>\n\n\n\n<p>I\u2019ll start with initialization.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void nRF24_Init(SPI_HandleTypeDef *hspi)\n{\n\thspi_nrf = hspi;\n\n\tNRF24_CE_LOW;\n\tNRF24_CSN_HIGH;\n\n\tnRF24_Delay(5); \/\/ Wait for radio power up\n\n\tnRF24_SetPALevel(NRF24_PA_PWR_0dBM); \/\/ Radio power\n\tnRF24_SetDataRate(NRF24_RF_DR_250KBPS); \/\/ Data Rate\n\tnRF24_EnableCRC(1); \/\/ Enable CRC\n\tnRF24_SetCRCLength(NRF24_CRC_WIDTH_1B); \/\/ CRC Length 1 byte\n\tnRF24_SetRetries(0x04, 0x07); \/\/ 1000us, 7 times\n\tnRF24_WriteRegister(NRF24_DYNPD, 0); \/\/ Disable dynamic payloads for all pipes\n\tnRF24_SetRFChannel(10); \/\/ Set RF channel for transmission\n\tnRF24_SetPayloadSize(0, NRF24_PAYLOAD_SIZE); \/\/ Set 32 bytes payload for pipe 0\n\tnRF24_EnablePipe(0, 1); \/\/ Enable pipe 0\n\tnRF24_AutoACK(0, 1); \/\/ Enable auto ACK for pipe 0\n\tnRF24_SetAddressWidth(NRF24_ADDR_SIZE); \/\/ Set address size\n\n\tnRF24_Delay(20);\n\n\tnRF24_EnableRXDataReadyIRQ(0);\n\tnRF24_EnableTXDataSentIRQ(0);\n\tnRF24_EnableMaxRetransmitIRQ(0);\n\n\tnRF24_Delay(20);\n\n\tnRF24_ClearInterrupts();\n}<\/pre>\n\n\n\n<p>As usual in my libraries, you need to provide a pointer to the SPI handler you want to use.<\/p>\n\n\n\n<p>You may have noticed earlier, but we have a pin called <strong>CE. This is not the SPI CS pin.<\/strong> This pin <strong>is used to select transmit and receive modes<\/strong>. The library handles it fully \ud83d\ude42<\/p>\n\n\n\n<p>Initialization includes, among other things:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Setting transmitter power<\/li>\n\n\n\n<li>Setting data rate<\/li>\n\n\n\n<li>Enabling CRC and retransmissions<\/li>\n\n\n\n<li>Setting the RF channel<\/li>\n\n\n\n<li>Payload size<\/li>\n\n\n\n<li>Address size<\/li>\n<\/ul>\n\n\n\n<p>At the end there are interrupt settings. For now I disabled them all, but you still need to clear them. Only the reflection on the IRQ pin will be disabled. The registers behave as if those interrupts existed, and we will use them to find out whether something arrived.<\/p>\n\n\n\n<p>All these settings, especially transmit power, speed, and channel, you can freely set according to your preferences. Whether you change it in initialization or later\u2014that\u2019s up to you.<\/p>\n\n\n\n<p>There are also two constants that you set in the nRF24_Defs.h file.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#define NRF24_PAYLOAD_SIZE 1\n\n#define NRF24_ADDR_SIZE\t3<\/pre>\n\n\n\n<p>They correspond to the payload size (1\u201332) and the addressing length (3\u20135).<\/p>\n\n\n\n<p>Now you need to set addresses. In RX you set the address at which you want to receive. In TX \u2013 which one you transmit to. Finally, I enable the appropriate mode.<\/p>\n\n\n\n<p>For the transmitter it will look like this.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">  nRF24_SetRXAddress(0, \"Tx\");\n  nRF24_SetTXAddress(\"Rx\");\n  nRF24_TX_Mode();<\/pre>\n\n\n\n<p>Receiver:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">  nRF24_SetRXAddress(0, \"Rx\");\n  nRF24_SetTXAddress(\"Tx\");\n  nRF24_RX_Mode();<\/pre>\n\n\n\n<p>And now you can transmit\/receive. In the example I have the payload length set to one character, so I\u2019ll transmit digits 0\u20139.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\t  for(i=0; i&amp;lt;10; i++)\n\t  {\n\t\t  MessageLength = sprintf(Message, \"%d\", i );\n\t\t  nRF24_WriteTXPayload(Message);\n\t\t  HAL_Delay(1);\n\t\t  nRF24_WaitTX();\n\t\t  HAL_Delay(1000);\n\t  }<\/pre>\n\n\n\n<p>In this simple code I prepare a number as an ASCII character, write it to the TX payload, and wait for transmission. And so every second. How to receive it?<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\t  if(nRF24_RXAvailible())\n\t  {\n\t\t  nRF24_ReadRXPaylaod(Nrf24_Message);\n\t\t  MessageLength = sprintf(Message, \"%c\\n\\r\", Nrf24_Message[0]);\n\t\t  HAL_UART_Transmit(&amp;amp;huart2, Message, MessageLength, 1000);\n\t  }<\/pre>\n\n\n\n<p>The nRF24_RXAvailible() function checks the RX_DR bit in the status register. It tells us that something arrived and is waiting in the FIFO of the <a href=\"https:\/\/sklep.msalamon.pl\/?s=nrf24&amp;post_type=product&amp;utm_source=blog&amp;utm_medium=article&amp;utm_campaign=nrf24&amp;utm_content=Text\">nRF<\/a>. If we have something, we need to read it with nRF24_ReadRXPaylaod().<\/p>\n\n\n\n<p>Later I restore the number and push it to UART. Result.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_receive_simple.png\"><img loading=\"lazy\" decoding=\"async\" width=\"735\" height=\"396\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_receive_simple.png\" alt=\"\" class=\"wp-image-1525\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_receive_simple.png 735w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_receive_simple-300x162.png 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_receive_simple-24x13.png 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_receive_simple-36x19.png 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/05\/nrf24_receive_simple-148x80.png 148w\" sizes=\"auto, (max-width: 735px) 100vw, 735px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>This is what the simplest handling looks like, i.e. blocking polling. I also haven\u2019t used dynamic payload yet. The <a href=\"https:\/\/sklep.msalamon.pl\/?s=nrf24&amp;post_type=product&amp;utm_source=blog&amp;utm_medium=article&amp;utm_campaign=nrf24&amp;utm_content=Text\">nRF24L01+<\/a> chip can tell us how much data arrived and how much data is to be sent. Then we don\u2019t have to limit ourselves to a fixed message length. It will definitely be useful.<\/p>\n\n\n\n<p>I\u2019ll deal with that in the next post. Same with interrupt-based handling, which is definitely better than polling the chip.<\/p>\n\n\n\n<p><strong>If you liked the article, you can support me by buying something from me \ud83d\ude42 <a href=\"https:\/\/sklep.msalamon.pl\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=nrf24&amp;utm_content=Text\">https:\/\/sklep.msalamon.pl\/<\/a><\/strong><\/p>\n\n\n\n<p>The entire series:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"http:\/\/msalamon.pl\/komunikacja-radiowa-z-uzyciem-modulow-nrf24l01-cz-1\/\">Part 1<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/msalamon.pl\/komunikacja-radiowa-z-uzyciem-modulow-nrf24l01-cz-2\/\">Part 2<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/msalamon.pl\/komunikacja-radiowa-z-uzyciem-modulow-nrf24l01-cz-3\/\">Part 3<\/a><\/li>\n<\/ul>\n\n\n\n<p>You can find the full project with the library, as usual, on my GitHub: <a href=\"https:\/\/github.com\/lamik\/nRF24L01_Transmitter\/tree\/Simple\" target=\"_blank\" rel=\"noopener\">TRANSMITTER<\/a>, <a href=\"https:\/\/github.com\/lamik\/nRF24L01_Receiver\/tree\/Simple\" target=\"_blank\" rel=\"noopener\">RECEIVER<\/a><\/p>\n\n\n\n<p><span>If you noticed a mistake, disagree with something, would like to add something important, or simply feel like discussing this topic, write a comment. Remember that the discussion should be polite and follow the rules of the Polish language.<\/span><\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;4257&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;0&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;0&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;0&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;0\\\/5 - (0 votes)&quot;,&quot;size&quot;:&quot;24&quot;,&quot;title&quot;:&quot;Radio Communication Using nRF24L01+ Modules, Part 1&quot;,&quot;width&quot;:&quot;0&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} - ({count} {votes})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 0px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 19.2px;\">\n            <span class=\"kksr-muted\"><\/span>\n    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>The topic of nRF24L01+ had been sitting on my \u201cto-do\u201d list basically since this blog was created. This chip is one of the most popular radio ICs. Modules from China cost proverbial pennies, and the capabilities offered by these nRFs are out of this world. So why did it take [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3443,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[160],"tags":[175,176,174],"class_list":["post-4257","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-stm32","tag-electronics","tag-programming","tag-stm32"],"_links":{"self":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4257","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/comments?post=4257"}],"version-history":[{"count":3,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4257\/revisions"}],"predecessor-version":[{"id":4371,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4257\/revisions\/4371"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/media\/3443"}],"wp:attachment":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/media?parent=4257"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/categories?post=4257"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/tags?post=4257"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}