Hello friends, I hope you are doing well. In today's tutorial, I am going to share our nRF24L01 Proteus Library. With this library, we can place two nRF24L01 RF modules in one Proteus design, connect each module to an Arduino Uno and send messages from one board to the other. The transmitter reports whether every message was acknowledged, and the receiver prints each message on its own Virtual Terminal.

We will start with the basics of the module, download and install the library files, and wire the SPI pins. After that, we will run the supplied two-Arduino simulation, test a broken link with the range switch, and understand both Arduino sketches. The download includes the wired project, two compiled HEX files, both sketches and the Arduino radio driver, so you can run the first experiment before compiling anything yourself.

This tutorial uses our V1.0 package, the TEP Arduino UNO V3 and a 16 MHz clock. The package notes record a test of the supplied project in Proteus 8.5 SP0. In the running screenshot below, the transmitter is on the left and the receiver is on the right. Eight messages have been sent, acknowledged and received.

Figure: The transmitter on the left has sent eight messages and received an ACK for each one. The receiver on the right shows the same eight messages and RX - LISTENING on its panel.

What Is the nRF24L01 RF Module?

The nRF24L01 is a 2.4 GHz radio transceiver from Nordic Semiconductor. A transceiver can both transmit and receive, so we use the same module on each side of a wireless link. The microcontroller configures the chip and exchanges data with it through SPI. The improved version of this chip is the nRF24L01+, and that is the version our library models. Nordic's nRF24L01+ Product Specification describes the registers, commands and timing of the chip.

Main Features of the nRF24L01+

nRF24L01+ features described in the manufacturer's specification
FeatureValue
Operating band2.4 GHz, with 126 RF channels from 2400 to 2525 MHz
Air data rates250 kbps, 1 Mbps and 2 Mbps
Supply range1.9 to 3.6 V, with 5 V tolerant inputs
Host interfaceFour-pin SPI, up to 10 Mbps
Payload lengthUp to 32 bytes in each packet
Data buffersThree-level transmit and receive FIFOs, which are first-in, first-out buffers
Receive addressesSix data pipes for one receiver

How Enhanced ShockBurst Works

The chip contains a packet protocol called Enhanced ShockBurst. Our Arduino code does not handle individual radio bits. The exchange follows these steps:

  1. We give the chip a payload of up to 32 bytes.
  2. The chip builds the packet, adds an error-checking code called a CRC and transmits it.
  3. The receiving chip checks the address and the CRC.
  4. The receiving chip sends back a short acknowledgement, which we call an ACK.
  5. If no ACK arrives, the transmitter repeats the packet automatically.

Important Terms

  • Channel: the radio frequency of the link. Both radios must use the same channel.
  • Address: a number of up to five bytes that is sent with every packet.
  • Data pipe: one receive address of a receiver. A receiver can listen for up to six addresses at the same time.
  • ACK: the short answer of the receiver, which confirms a packet.
  • CE and CSN: two control pins. CSN selects the chip for an SPI command, and CE starts a transmission or enables listening.

Features of Our Proteus Model

  • The component is named NRF24L01TEP and has eight pins.
  • Every radio placed in the same design shares one virtual 2.4 GHz band, so two modules exchange packets without any wire between them.
  • A control panel beside each module shows its live mode, settings, addresses and counters.
  • A range switch on every panel cuts that radio off the air.
  • The Arduino communicates with the model through real SPI commands and registers.

If you want more background on the hardware, read our Introduction to NRF24L01 and NRF24L01 Arduino Interfacing tutorials.

Keep one distinction in mind from the start. This is a functional model of the chip's digital behavior. It does not simulate antennas, distance, walls or interference. A packet is delivered when the radio settings match and both radios are marked as in range.

Download the nRF24L01 Library for Proteus

First of all, download the V1.0 package using the button below. Extract the complete ZIP into a normal folder before opening the project, and keep the files inside the simulation folder together.

Download nRF24L01 Proteus Library V1.0 and Arduino Simulation
Contents of the nRF24L01 Proteus package
Folder or fileContents and purpose
Proteus Library FilesTEPNRF24L01.LIB for the radio module, and the TEP Arduino UNO V3 LIB/IDX files.
Proteus Model FilesTEPNRF24L01.DLL, which provides the module's simulated behavior.
Proteus SimulationNRF24L01-ArduinoUnoV3.pdsprj, NRF24_Transmitter.hex, NRF24_Receiver.hex and a local copy of the DLL.
Arduino CodeBoth sketches, the RF24 1.6.2 driver, the AVR core archive and a firmware rebuild script.
Model SourceThe chip model, SPI transport, shared radio band and Proteus adapter.
DocumentationModel notes, third-party notices and a preview of the board artwork.
README.txt and SHA256SUMS.txtQuick-start instructions and checksums of the packaged files.

The Proteus library and the Arduino library have different jobs. The LIB file defines the component that we place on the schematic, and the DLL gives that component its behavior. The RF24 Arduino library gives our sketch the functions for talking to the radio. Installing RF24 in Arduino IDE alone will not make NRF24L01TEP appear in Proteus.

How to Install the nRF24L01 Proteus Library

Copy the Library and Model Files

Save your work and close Proteus before copying the files. Then follow these steps:

  1. Open the extracted Proteus Library Files folder.
  2. Copy TEPNRF24L01.LIB into the library directory configured for your Proteus installation.
  3. Copy ArduinoV3TEP.LIB and ArduinoV3TEP.IDX from the same folder if our TEP Arduino UNO V3 library is not installed already.
  4. Open Proteus Model Files and copy TEPNRF24L01.DLL into your configured Proteus MODELS directory.
  5. Restart Proteus, open Pick Devices and search for NRF24L01TEP.
  6. Place the module on the schematic, or open the supplied project to use the completed circuit.

Points to Remember

  • Use the library and model folders that your installation actually searches. Their locations differ between installations.
  • The radio module is supplied as a LIB file without a separate IDX. The included IDX belongs to the Arduino board.
  • Keep the extra DLL beside the project in the Proteus Simulation folder.
  • The two HEX files are programs for the two Arduino boards. The radio module does not need a HEX file.
  • Compatibility with Proteus 7 and other releases has not been established, and your installation needs AVR simulation support.

The Arduino board in this project comes from our Arduino Library for Proteus V3.0. Start with the supplied project, so that the boards, wiring and firmware match the demonstration.

nRF24L01 Pinout and Arduino Uno Wiring

The TEP module has eight pins in a single row along its lower edge. From left to right, they are VCC, GND, SCK, MISO, MOSI, CSN, CE and IRQ. Start each wire at the exposed pin endpoint below the board artwork.

Connections used on both Arduino boards
Module pinConnectionPurpose
VCCPositive supply terminalPowers the digital model.
GNDGroundProvides the shared reference.
SCKArduino Uno D13SPI clock from the Arduino.
MISOArduino Uno D12Data from the module to the Arduino.
MOSIArduino Uno D11Data from the Arduino to the module.
CSNArduino Uno D10Selects the module for an SPI command. It is active low.
CEArduino Uno D9Starts a transmission or enables listening.
IRQUnconnectedActive-low interrupt output. The supplied sketches do not use it.
Figure: The stopped circuit connects SCK, MISO, MOSI, CSN and CE to D13, D12, D11, D10 and D9 on both boards. Each panel shows the chip's reset values before the simulation starts.

Both boards use the same wiring. The Arduino named ARD1 works with module U1 as the transmitter, and ARD2 works with U2 as the receiver. There is no wire between the two halves of the circuit. The only link between them is the simulated radio band.

Virtual Terminal Connections

  • Connect Arduino D1/TX to RXD on the Virtual Terminal of each board.
  • Set both terminals to 9600 baud, eight data bits, no parity and one stop bit.
  • The return connection to D0/RX is shown in the circuit, but these sketches do not read typed commands.

Notes for Physical Hardware

  • Power a real nRF24L01 module from 3.3 V. The chip's supply range is 1.9 to 3.6 V, so connecting VCC to 5 V can damage it.
  • Its signal inputs are 5 V tolerant, which is why an Uno can drive the SPI pins directly.
  • The model treats the module as unpowered when VCC is low or GND is high. It does not check the supply voltage, so a working simulation does not prove that your hardware supply is correct.
  • The pin order of our Proteus board is different from the physical module. The common hardware module has a two-row header arranged as GND, VCC, CE, CSN, SCK, MOSI, MISO and IRQ. Always follow the printed labels.

Run the Two-Arduino Simulation

Start the Simulation

  1. Open Proteus Simulation/NRF24L01-ArduinoUnoV3.pdsprj from the extracted package.
  2. Keep both HEX files and TEPNRF24L01.DLL in that folder.
  3. Double-click ARD1 and confirm that its Program File is NRF24_Transmitter.hex.
  4. Double-click ARD2 and confirm that its Program File is NRF24_Receiver.hex.
  5. Confirm the 16 MHz clock on both boards and 9600 baud on both terminals.
  6. Press Run. If the two terminal windows open on top of each other, drag them apart.

Read the Terminal Output

  • The transmitter prints its heading and then Radio ready: channel 76, 1 Mbps, address 00001.
  • After that, the transmitter prints one line every second, such as Sent: Hello TEP #1 -> ACK received.
  • The receiver prints Listening: channel 76, 1 Mbps, address 00001.
  • For every message, the receiver prints a line such as Received #1: Hello TEP #1.

In the running screenshot at the top of this tutorial, both terminals have reached message 8. The transmitter panel reports SENT 8 and FAILED 0. The receiver panel reports RECEIVED 8, and its last packet is "Hello TEP #8" with a length of 32 bytes. We will see later why a twelve-character message occupies 32 bytes.

Understand the nRF24L01 Control Panel

The control panel is the most interesting part of this library. It shows what the radio is doing at every moment, without any debug code in the sketch. Let us go through the panel from top to bottom.

The Mode Banner and Its Colors

Modes shown on the banner of the control panel
Banner textColorMeaning
NO POWER - CHECK VCC / GNDRedThe module is not powered.
POWER DOWNBlueThe chip is switched off by its configuration. The registers keep their values.
STANDBY-IBlueThe chip is on and waits with CE low.
STANDBY-IIBlueThe chip is a transmitter with CE high, but its transmit buffer is empty.
RX - SETTLINGBlueThe receiver has been started and is not ready yet.
RX - LISTENINGGreenThe receiver is ready and waits for packets.
TX - SENDINGOrangeA packet is being sent, including its repetitions.
  • The receiver stays in RX - LISTENING, because it waits for packets all the time.
  • The transmitter shows STANDBY-I in the screenshot, although it is sending messages. One successful transmission takes less than a millisecond and the sketch then waits for one second, so the radio is idle almost all the time.
  • The text (MAX_RT) after the mode means that the retry limit has been reached and the flag has not been cleared yet. The driver clears it at once, so you will rarely see it.

The Settings Line

The line below the banner reads CH 76 = 2476 MHz, 1 MBPS, CRC 16-BIT in our example. It shows three settings:

Values on the settings line
ValueMeaningDriver function
CH 76 = 2476 MHzChannel number and its frequencysetChannel()
1 MBPSAir data rate: 250 KBPS, 1 MBPS or 2 MBPSsetDataRate()
CRC 16-BITCRC length: 8-BIT or 16-BITsetCRCLength()

The stopped circuit in the wiring section shows channel 2 at 2402 MHz, 2 Mbps and an 8-bit CRC. These are the chip's reset values. When the simulation starts, the RF24 driver writes its own settings, and the panel changes to channel 76, 1 Mbps and a 16-bit CRC.

The Address Lines

  • TX ADDR is the address to which this radio sends its packets.
  • RX ADDR is the address on which this radio receives.
  • An address is shown as text when all of its bytes are printable characters. Otherwise it is shown as hexadecimal bytes.

In the running screenshot, the transmitter shows 00001 for both addresses. The receiver shows RX ADDR 00001, but its TX ADDR is E7 E7 E7 E7 E7. That value is the chip's reset address. The receiver sketch never opens a writing pipe, so its transmit address is never changed.

The Counters

  • SENT counts the packets that were acknowledged.
  • FAILED counts the packets that reached the retry limit without an ACK.
  • RECEIVED counts the packets that this radio has received.

On the transmitter, SENT plus FAILED is the number of messages that the sketch has tried to send. We can use the counters of both panels to find the reason for a problem.

How to read the counters of both panels
Transmitter panelReceiver panelMeaning
SENT increases.RECEIVED increases.The link works.
FAILED increases.RECEIVED does not change.The packets do not reach the receiver. Check the range switches and compare the settings.
No counter changes.No counter changes.The transmitter sketch is not sending. Check the terminal for an error message.

The Last Packet Line

Before the first packet arrives, the panel shows a dash. After that, it shows the payload in quotation marks, followed by its length. The panel shows the text up to the first zero byte. A payload that is not readable text is shown as hexadecimal bytes.

The Range Switch

The large button near the bottom is the range switch. It is green and shows IN RANGE at the start. A click changes it to a red OUT OF RANGE, and another click changes it back. The line below the button tells you what the next click will do.

Panel Combinations: Range, Settings and Retries

Now comes the exciting part. The result of a transmission depends on the settings of both radios together. We will take the combinations one by one. The first combination is shown in the screenshots of this tutorial. The results and values of the other combinations follow from the rules and timing of the model.

Combination 1: The Two Range Switches

Each radio has its own switch. A radio that is out of range neither sends packets to other radios nor receives packets from them. A packet therefore needs both radios in range.

Results for the four switch positions
Transmitter switchReceiver switchTransmitter terminalReceiver terminal
IN RANGEIN RANGEACK receivedPrints the message
OUT OF RANGEIN RANGEFAILED, no ACKPrints nothing
IN RANGEOUT OF RANGEFAILED, no ACKPrints nothing
OUT OF RANGEOUT OF RANGEFAILED, no ACKPrints nothing

Try the Range Switch

  1. Let the simulation run and watch a few acknowledged messages.
  2. Click the green IN RANGE button on the transmitter's panel.
  3. Watch the next messages on the transmitter's terminal.
  4. Click the button again to bring the radio back in range.
Figure: With the transmitter moved out of range, messages 42 to 47 fail after the retry limit. The receiver's last packet remains Hello TEP #41.

In this screenshot, messages 37 to 41 were acknowledged. The transmitter was then moved out of range, and messages 42 to 47 each ended with FAILED, no ACK. The transmitter panel shows SENT 41 and FAILED 6, which accounts for all 47 messages. The receiver panel still shows RECEIVED 41, and its last packet remains "Hello TEP #41".

According to the package's test notes, the link is restored at once when the radio is back in range. The Simulation Log records these events too. It reports when each module is powered, the first packet received, the first failed transmission and every range change.

There is one more detail to watch after the link returns. The number inside the message comes from the transmitter's counter, which increases on every attempt. The number after "Received" comes from the receiver's own counter, which increases only when a packet arrives. After six lost messages, the two numbers on a receiver line will differ by six.

Combination 2: Different Settings on the Two Radios

Both radios can be in range and the link can still fail. The receiver accepts a packet only when the settings of both radios agree. The panels show most of these settings, so put them side by side and compare them.

Settings that must agree, and where to find them
SettingWhere it is shownResult of a difference
ChannelSettings line of both panelsEvery message fails.
Data rateSettings line of both panelsEvery message fails.
CRC lengthSettings line of both panelsEvery message fails.
AddressTX ADDR of the transmitter and RX ADDR of the receiverThe receiver ignores the packets.
Payload sizeNot shown on the panelThe receiver ignores the packets.
Receiver modeBanner of the receiverNothing is received unless the banner shows RX - LISTENING.

There is one more condition on the transmitter's own panel. Its TX ADDR and RX ADDR must be the same, because the ACK comes back on the transmit address. The driver takes care of this when we open the writing pipe.

Combination 3: Retry Delay and Retry Count

When no ACK arrives, the chip repeats the packet. The driver function setRetries(delay, count) sets the waiting time and the number of repetitions. The delay value is a step number, and the waiting time is (delay + 1) × 250 microseconds. The supplied sketches use the driver's default of setRetries(5, 15).

Time until a failed message is reported at 1 Mbps with a 32-byte payload
SettingWaiting timeTransmissionsTime until FAILED
setRetries(5, 15)1500 microseconds1629.4 ms
setRetries(5, 5)1500 microseconds611.1 ms
setRetries(5, 0)1500 microseconds12.0 ms
setRetries(1, 15)500 microseconds1613.4 ms
setRetries(15, 15)4000 microseconds1669.4 ms
  • More repetitions give a packet more chances in a real environment with interference.
  • Fewer repetitions let the sketch react faster when the receiver is missing.
  • In the model, a packet that fails once fails on every repetition, because the conditions do not change within a few milliseconds.

Combination 4: Data Rate and Timing

The data rate changes the time that a packet spends on the air. Use the same data rate in both sketches.

Timing of a 32-byte message for the three data rates in the model
Data rateAir time of the packetTime for a successful messageTime until FAILED
250 kbps1316 microseconds1.9 ms45.2 ms
1 Mbps329 microseconds0.7 ms29.4 ms
2 Mbps169 microseconds0.5 ms26.8 ms

The last column uses the default retry settings. In real hardware, the lowest data rate gives the best sensitivity and the longest range, and the highest data rate gives the shortest air time. The model does not simulate range, so the data rate changes only the timing.

Combination 5: Channel and Frequency

The channel number sets the frequency with frequency in MHz = 2400 + channel number. The panel shows both values.

  • Channel 2 is 2402 MHz. This is the reset value that the stopped circuit shows.
  • Channel 76 is 2476 MHz. This is the driver's default and the value of our example.
  • Channel 125 is 2525 MHz, which is the highest channel.

To change the channel, add radio.setChannel(90); after radio.begin() in both sketches. Both panels then show CH 90 = 2490 MHz.

Arduino Code for the nRF24L01 Transmitter

The following is the exact transmitter sketch included in the download. It uses the bundled RF24 library, version 1.6.2. Use the supplied copy for your first build, so that your firmware matches the packaged HEX file.

// TEP nRF24L01 Transmitter Demo v1.0
// The Engineering Projects - www.TheEngineeringProjects.com
//
// Sends "Hello TEP #n" once a second to address "00001" and reports whether the
// receiver acknowledged it. Pair it with NRF24_Receiver on a second Arduino.
//
// Wiring (Arduino UNO): VCC -> 3.3V, GND -> GND, SCK -> D13, MISO -> D12,
//                       MOSI -> D11, CSN -> D10, CE -> D9, IRQ -> not used
// Library: RF24 by TMRh20 / nRF24 (Arduino Library Manager: "RF24")

#include <SPI.h>
#include <RF24.h>

RF24 radio(9, 10);                    // CE, CSN
const byte address[6] = "00001";
unsigned long counter = 0;

void setup() {
  Serial.begin(9600);
  Serial.println(F("TEP nRF24L01 Transmitter Demo v1.0"));
  if (!radio.begin()) {
    Serial.println(F("nRF24L01 not responding - check the SPI wiring and power"));
    while (true) {}
  }
  radio.setPALevel(RF24_PA_LOW);
  radio.openWritingPipe(address);
  radio.stopListening();              // transmitter mode
  Serial.println(F("Radio ready: channel 76, 1 Mbps, address 00001"));
}

void loop() {
  char message[32] = "";
  snprintf(message, sizeof message, "Hello TEP #%lu", ++counter);
  bool ok = radio.write(message, sizeof message);
  Serial.print(F("Sent: "));
  Serial.print(message);
  if (ok) Serial.println(F("  -> ACK received"));
  else Serial.println(F("  -> FAILED, no ACK"));
  delay(1000);
}

Create the Radio Object and Address

  • RF24 radio(9, 10) tells the driver that CE is on D9 and CSN is on D10.
  • The SPI pins D11, D12 and D13 are fixed by the Arduino Uno hardware, so the sketch does not name them.
  • The address is the text 00001. The array has six elements, because a C string ends with a hidden zero byte. The radio uses the first five bytes as its address.
  • Both sketches must use the same address. Otherwise the receiver ignores the packets.

Initialize the Radio

The call radio.begin() starts SPI, configures the radio and checks that the chip answers correctly. If it fails, the sketch prints nRF24L01 not responding and stops. The channel and data rate printed by the sketch are not set by our code. They are the defaults written by this version of the driver.

Radio settings written by RF24 1.6.2 during begin()
SettingValue
RF channel76
Air data rate1 Mbps
CRC length16 bits
Address width5 bytes
Payload size32 bytes, fixed length
Automatic acknowledgementEnabled on all pipes
RetransmissionDelay setting 5 and a limit of 15 retransmissions

The remaining calls of setup do the following work:

  1. setPALevel(RF24_PA_LOW) selects a low transmitter power. The model stores this setting, but output power has no effect on the simulated link.
  2. openWritingPipe(address) writes the address to both the transmit address and receive pipe 0. This is why the transmitter's panel shows 00001 twice.
  3. stopListening() puts the radio in transmitter mode.

Send a Message and Check the Acknowledgement

  1. The sketch creates a 32-byte buffer filled with zeros.
  2. The function snprintf writes the text and the counter value into it. The counter is increased before it is printed, so the first message is number 1.
  3. The call radio.write(message, sizeof message) sends all 32 bytes and waits for the result.
  4. The function returns true when the ACK arrives. It returns false when the chip has used all of its retransmissions without an ACK.
  5. The sketch prints the matching text and then waits for one second.

Arduino Code for the nRF24L01 Receiver

The receiver sketch is shorter, because the chip handles the acknowledgement by itself. Here is the exact sketch from the package:

// TEP nRF24L01 Receiver Demo v1.0
// The Engineering Projects - www.TheEngineeringProjects.com
//
// Listens on address "00001" and prints every message it receives.
// Pair it with NRF24_Transmitter on a second Arduino.
//
// Wiring (Arduino UNO): VCC -> 3.3V, GND -> GND, SCK -> D13, MISO -> D12,
//                       MOSI -> D11, CSN -> D10, CE -> D9, IRQ -> not used
// Library: RF24 by TMRh20 / nRF24 (Arduino Library Manager: "RF24")

#include <SPI.h>
#include <RF24.h>

RF24 radio(9, 10);                    // CE, CSN
const byte address[6] = "00001";
unsigned long counter = 0;

void setup() {
  Serial.begin(9600);
  Serial.println(F("TEP nRF24L01 Receiver Demo v1.0"));
  if (!radio.begin()) {
    Serial.println(F("nRF24L01 not responding - check the SPI wiring and power"));
    while (true) {}
  }
  radio.setPALevel(RF24_PA_LOW);
  radio.openReadingPipe(0, address);
  radio.startListening();             // receiver mode
  Serial.println(F("Listening: channel 76, 1 Mbps, address 00001"));
}

void loop() {
  if (radio.available()) {
    char message[32] = "";
    radio.read(message, sizeof message);
    Serial.print(F("Received #"));
    Serial.print(++counter);
    Serial.print(F(": "));
    Serial.println(message);
  }
}

Open the Reading Pipe and Listen

  • The first part of setup is the same as in the transmitter.
  • openReadingPipe(0, address) tells the driver to receive packets sent to 00001 on pipe 0.
  • startListening() selects receiver mode and sets CE high. After a short settling time, the panel shows RX - LISTENING.

Read a Payload

  • radio.available() checks whether the receive FIFO holds a payload.
  • radio.read() copies 32 bytes into the buffer.
  • The sketch prints its own counter and then the message text.

The receiver does not call any function to send the ACK. With automatic acknowledgement enabled, the chip transmits the ACK as soon as it accepts a packet. This loop also has no delay, so the sketch checks for new data continuously.

How the Simulated Radio Link Works

Let us look at what happens inside the model. When the transmitter's packet is complete, the model examines every other radio in the design. A radio accepts the packet only when all of these conditions are true:

  • The radio is powered, in receiver mode with CE high, and its settling time has passed.
  • Both radios use the same channel, data rate, address width and CRC length.
  • An enabled receive pipe has an address that matches the transmit address.
  • The payload length matches the size configured for that pipe.
  • The receive FIFO has a free slot.
  • Both radios are in range.

If a receiver accepts the packet and acknowledgement is enabled, the ACK is scheduled. The transmitter counts the packet as sent when the ACK arrives. Otherwise, the transmitter waits for its retransmit delay and sends the packet again. When the retry limit is reached, the chip sets its MAX_RT flag and the panel's FAILED counter increases.

The Arduino does not read the panel or any hidden variable. It communicates with the module through SPI commands and registers, as it would with the physical chip. The package notes state that the model was driven by the unmodified RF24 library during its tests. A wrong CSN or CE connection therefore prevents the radio from working here as well.

Calculate the Packet Timing

Calculate the Air Time of One Message

An Enhanced ShockBurst packet contains more than our payload. The table shows the fields for the settings used by our example.

Packet length for the supplied example
Packet fieldSize in this exampleBits
Preamble1 byte8
Address5 bytes40
Packet control field9 bits9
Payload32 bytes256
CRC2 bytes16
Total329

The air time is number of bits / data rate. At 1 Mbps, each bit lasts one microsecond, so our packet needs 329 microseconds. The ACK has no payload, so it contains 8 + 40 + 9 + 16 = 73 bits and needs 73 microseconds.

Calculate the Time for a Successful Message

The radio needs a settling time of 130 microseconds before it transmits. The same time applies when the radios change direction for the ACK. In the model, the time from the start of transmission to the confirmed ACK is:

130 + 329 + 130 + 73 = 662 microseconds

This is about two thirds of a millisecond. It explains why the transmitter panel almost never shows TX - SENDING. The panel is refreshed every millisecond of simulation time, and the whole exchange is already complete within that period.

Calculate the Time Before FAILED Appears

  1. The driver's delay setting of 5 gives a retransmit delay of (5 + 1) × 250 = 1500 microseconds.
  2. The limit of 15 means the packet is sent once and then repeated up to fifteen times, which is sixteen transmissions in total.
  3. The first transmission ends after 130 + 329 = 459 microseconds.
  4. Each retransmission adds the delay and another air time, which is 1500 + 329 = 1829 microseconds.
  5. After the last attempt, the chip waits one more delay before it reports the failure.

459 + (15 × 1829) + 1500 = 29,394 microseconds

This is about 29.4 ms, which agrees with the figure of about 29 ms in the package notes. A failed message therefore takes longer than a successful one, but the difference is small compared with the one-second delay in the sketch.

Check the Payload Size

The text "Hello TEP #8" contains 12 characters. The payload is fixed at 32 bytes, so the remaining 20 bytes are zeros. The panel shows the text up to the first zero and reports the full length of 32 bytes.

Will a large counter value overflow the buffer? The text "Hello TEP #" has 11 characters. The largest value of an unsigned long on the Uno is 4,294,967,295, which has 10 digits. The longest message is 21 characters, and the 32-byte buffer has room for 31 characters and the ending zero. The message always fits.

Experiments to Try in Proteus

Once the basic example works, change one thing at a time and predict the result before you press Run. The following results follow from the model's acceptance rules. The supplied project and the range switch were tested in Proteus. The package notes list the mismatch cases as tests of the model on a PC, so check them in your own simulation.

Suggested experiments and their expected results
ChangeExpected result
Move either radio out of range.Every message fails until the radio is back in range.
Add radio.setChannel(90) to one sketch only.The panels show different channels and every message fails.
Add the same channel setting to both sketches.The link works and both panels show channel 90 at 2490 MHz.
Change the address in one sketch only.The receiver ignores the packets and the transmitter reports failures.
Select RF24_2MBPS with setDataRate in one sketch only.The data rates differ and no packet is accepted.
Add radio.setRetries(5, 0) to the transmitter and move it out of range.Each message fails after a single transmission.
Change delay(1000) to delay(200) in the transmitter.About five messages are sent each second.

After each experiment, compare both panels before reading the code again. Keep each modified project in its own folder with its matching HEX files.

Compile and Load Your Own Arduino Changes

  1. Open Arduino Code/NRF24_Transmitter/NRF24_Transmitter.ino or the receiver sketch in Arduino IDE.
  2. Install the RF24 library. For the same version as the example, copy Arduino Code/libraries/RF24 into your sketchbook's libraries folder.
  3. Select Arduino Uno as the board.
  4. Compile the sketch and use the Export Compiled Binary command.
  5. Select the new application HEX in the Program File property of the correct Arduino.
  6. Restart the simulation.

Remember that the project has two programs. If you change a radio setting such as the channel or address, rebuild both sketches and load each HEX into its own board. The package also contains a rebuild script and the AVR core source archive. Its README explains the compiler folders required for that route.

Common Problems and Their Solutions

Troubleshooting the nRF24L01 Proteus simulation
ProblemWhat to check
NRF24L01TEP is missing from Pick Devices.Check that TEPNRF24L01.LIB is in the active library folder and restart Proteus.
The module is placed, but its model cannot load.Check TEPNRF24L01.DLL in MODELS and beside the project.
The terminal prints nRF24L01 not responding.Check SCK, MISO, MOSI, CSN and CE, then VCC and GND.
The panel shows NO POWER.Check that VCC goes to the supply terminal and GND to ground.
Every message shows FAILED, no ACK.Check that ARD2 runs NRF24_Receiver.hex, the receiver shows RX - LISTENING, both panels are in range and their channel and address match.
A terminal is blank or unreadable.Check the Program File, the 16 MHz clock, D1/TX to RXD and 9600 baud.
Only one terminal window is visible.The windows may overlap. Drag the top window aside.
Code changes have no effect.Compile a new HEX and select it in the correct Arduino before restarting.

If a problem remains, return to the unmodified project and change one thing at a time. When you ask for help, include your Proteus version, both terminal windows and a screenshot of both control panels.

Practical Review and Model Limitations

This library is useful for learning how an nRF24L01 link is configured and how a program should react to a missing acknowledgement. The two panels show the settings of both radios side by side, which makes a mismatch easy to find. The range switch gives us a repeatable way to test failure handling.

What the Model Supports

  • The nRF24L01+ register map and its SPI commands.
  • The three-level transmit and receive FIFOs and six receive pipes.
  • Automatic acknowledgement and retransmission with the retry limit.
  • Dynamic payloads and ACK payloads. The supplied sketches use only the basic fixed-length exchange.
  • Settling times and the air time at all three data rates.

What the Model Does Not Simulate

  • Real radio propagation, distance and output power. The range switch is an on/off control.
  • Collisions between transmitters that send at the same moment.
  • Duplicate-packet detection.
  • SPI timing violations and the supply voltage.

Range, antenna placement, power supply noise and interference must be evaluated with real hardware.

More Proteus Libraries of This Series

This library belongs to a series of wireless and RFID libraries for Proteus. Every library has its own control panel and its own tutorial:

Frequently Asked Questions

Do I Need Two Arduino Boards in the Simulation?

Yes, for a complete link. One board runs the transmitter sketch and the other runs the receiver sketch. With only a transmitter in the design, no radio can acknowledge its packets, so every message fails.

Why Is VCC Not Connected to 3.3 V in the Simulation?

The model treats VCC as a digital signal and does not measure its voltage. The supply terminal in the project is sufficient for the simulation. A physical module must be powered from 3.3 V.

Do I Need to Connect the IRQ Pin?

No. The supplied sketches check the radio through SPI. The IRQ output is available for interrupt-based sketches, which need additional wiring and code.

Can I Place More Than Two Radios?

Yes. Every NRF24L01TEP in the design shares the same band. For example, one receiver can listen on several pipes for different transmitters. The supplied project demonstrates two radios, and the model does not simulate collisions between simultaneous transmissions.

Does the Range Switch Simulate Distance?

No. It is an on/off control. A radio is either connected to the shared band or cut off from it. Signal strength and gradual packet loss are not simulated.

Can I Use a Different Arduino Library for the Radio?

The model implements the chip's commands and registers, so it does not depend on one driver. However, the package was tested with RF24 1.6.2 only. Start with that version and check any other driver separately.

Do I Need Arduino IDE to Run the Supplied Circuit?

No. Both compiled HEX files are included. You need Arduino IDE, or the documented build tools, only when you change a sketch.

That completes our nRF24L01 Proteus Library tutorial. Start with the supplied project, watch both panels and then break the link with the range switch. Once the results make sense, change the channel or the message and build your own wireless project. Share your questions and simulation results in the comments below.