Hello friends, I hope you are doing well. In today's tutorial, I am going to share our RFM69HCW Proteus Library. With this library, we can place two RFM69HCW RF modules in one Proteus design, connect each module to an Arduino Uno and send messages from a node to a gateway at 433 MHz. The gateway answers every message with an acknowledgement, and both boards print the signal strength on their Virtual Terminals.

We will start with the basics of the module, install the library files and wire the circuit. After that, we will run the supplied two-Arduino simulation and study the control panel in detail, because its distance buttons let us test a link of up to 10 km. We will also understand both Arduino sketches and calculate the values shown on the terminals. The download includes the wired project, two compiled HEX files, both sketches and the Arduino driver.

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 node is on the left and the gateway is on the right. Eight messages have been sent and acknowledged, and the signal strength dropped from -65 dBm to -95 dBm when the distance was changed to 1 km.

Figure: The node on the left has sent eight messages and received an ACK for each one. Both terminals show -65 dBm at 100 m and -95 dBm after the distance was changed to 1 km.

What Is the RFM69HCW RF Module?

The RFM69HCW is a radio transceiver module from HopeRF for frequencies below 1 GHz. A transceiver can both transmit and receive, so we use the same module on each side of a wireless link. The microcontroller configures the module and exchanges data with it through SPI. The letters HCW mark the high-power version of the module. HopeRF describes it in the RFM69HCW datasheet.

Main Features of the RFM69HCW

  • It works in the 315, 433, 868 and 915 MHz bands.
  • Its output power is programmable up to +20 dBm, which is 100 mW.
  • Its sensitivity goes down to -120 dBm at 1.2 kbps.
  • It supports FSK bit rates up to 300 kbps.
  • It supports FSK, GFSK, MSK, GMSK and OOK modulation.
  • Its packet engine includes a 16-bit CRC, AES-128 encryption and a 66-byte FIFO, which is a first-in, first-out buffer.
  • Its supply range is 1.8 to 3.6 V.

Important Terms

  • Node ID: the address of one radio. In our example, the gateway is node 1 and the sender is node 2.
  • Network ID: a number shared by all radios that talk to each other. Our example uses network 100.
  • Gateway: the radio that collects the messages of the other nodes.
  • ACK: a short answer that confirms a message.
  • dBm: a unit of signal power. A value of 0 dBm is 1 mW, and negative values are weaker signals.
  • RSSI: the received signal strength indicator. It tells us how strong the signal was at the receiver.
  • Sensitivity: the weakest signal that the receiver can still decode.

Features of Our Proteus Model

  • The component is named RFM69TEP and has eight pins.
  • Every radio placed in the same design shares one virtual band, so no wire is needed between the two sides.
  • A control panel beside each module shows its live mode, settings, counters and the last packet.
  • Eight distance buttons, from 10 m to 10 km, set the distance to the other radios.
  • The panel decodes the header of the driver, so it shows the sender, the receiver and the ACK flags of every packet.
  • The Arduino communicates with the model through real SPI commands and registers.

Keep one distinction in mind. This is a functional model with a simple range calculation. It does not simulate antennas, buildings, reflections or interference. The distance buttons are useful for learning how power, bit rate and distance are related, but they do not predict the range of a real installation.

Download the RFM69HCW 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 of the simulation folder together.

Download RFM69HCW Proteus Library V1.0 and Arduino Simulation
Contents of the RFM69HCW Proteus package
Folder or fileContents and purpose
Proteus Library FilesTEPRFM69.LIB for the radio module, and the TEP Arduino UNO V3 LIB/IDX files.
Proteus Model FilesTEPRFM69.DLL, which provides the module's simulated behavior.
Proteus SimulationRFM69-ArduinoUnoV3.pdsprj, RFM69_Node.hex, RFM69_Gateway.hex and a local copy of the DLL.
Arduino CodeBoth sketches, the LowPowerLab RFM69 1.6.0 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 it its behavior. The RFM69 Arduino library gives our sketch the functions for talking to the radio. Installing the Arduino library alone will not make RFM69TEP appear in Proteus.

How to Install the RFM69HCW 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 TEPRFM69.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 TEPRFM69.DLL into your configured Proteus MODELS directory.
  5. Restart Proteus, open Pick Devices and search for RFM69TEP.
  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 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 has not been established.

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.

RFM69HCW Pinout and Arduino Uno Wiring

The TEP module has eight pins along its lower edge. From left to right, they are VCC, GND, SCK, MISO, MOSI, NSS, RST and DIO0. 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.
NSSArduino Uno D10Selects the module for an SPI command. It is active low.
RSTArduino Uno D9Reset input. It is active high.
DIO0Arduino Uno D2Interrupt output. It tells the Arduino that a packet has arrived.
Figure: The stopped circuit connects SCK, MISO, MOSI and NSS to D13, D12, D11 and D10, RST to D9 and DIO0 to D2 on both boards.

Both boards use the same wiring. The Arduino named ARD1 works with module U1 as node 2, and ARD2 works with U2 as the gateway. Two connections need special attention:

  • DIO0 must go to D2. The driver receives packets through the interrupt of this pin. Without this wire, the gateway prints nothing.
  • RST is active high. The module runs when the pin is low or open, and it stays in reset while the pin is high. Both sketches give the pin a short high pulse before they start the radio.

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 terminal windows are narrow. Drag them apart and make them wider to see the complete lines.

Notes for Physical Hardware

  • The real RFM69HCW is a 3.3 V part with a supply range of 1.8 to 3.6 V.
  • According to the package notes, its pins are not 5 V tolerant. Use a 3.3 V supply and level shifting with a 5 V Arduino.
  • The model does not check the supply voltage, so a working simulation does not prove that your hardware supply is correct.
  • The header order of hardware breakout boards varies. Follow the labels printed on your board.
  • A real module needs an antenna for its frequency. Use only the frequencies and power levels that are permitted in your country.

Run the Two-Arduino Simulation

Start the Simulation

  1. Open Proteus Simulation/RFM69-ArduinoUnoV3.pdsprj from the extracted package.
  2. Keep both HEX files and TEPRFM69.DLL in that folder.
  3. Double-click ARD1 and confirm that its Program File is RFM69_Node.hex.
  4. Double-click ARD2 and confirm that its Program File is RFM69_Gateway.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 node prints its heading and then Node 2, network 100, 433 MHz - sending to the gateway (node 1).
  • Every two seconds, the node prints a line such as Sending "Hello #0" ... ACK received, RSSI -65 dBm.
  • The gateway prints Gateway (node 1), network 100, 433 MHz - listening.
  • For every message, the gateway prints a line such as [2] Hello #0 RSSI -65 dBm - ACK sent. The number in brackets is the node ID of the sender.

In the running screenshot at the top, messages 0 to 2 show -65 dBm on both terminals. These are the values for the default distance of 100 m. Before message 3, the distance on the node's panel was changed to 1 km, and the following messages show -95 dBm. The node prints the signal strength of the ACK, and the gateway prints the signal strength of the message. Both radios send with the same power, so the two values are equal.

Understand the RFM69HCW Control Panel

The control panel is the most interesting part of this library. It shows what the radio is doing at every moment, and its distance buttons let us test the link without changing the code. The following picture shows the module and its panel before the simulation starts.

Figure: The RFM69TEP component with its control panel. The panel shows the mode, the radio settings, the counters, the last packet and the eight distance buttons.

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
SLEEPBlueThe radio is in its power-saving mode.
STANDBYBlueThe radio is on, but it is neither sending nor listening.
SYNTHESIZERBlueThe frequency synthesizer is running, and the radio is ready to change to sending or listening.
RX - LISTENINGGreenThe radio is listening for packets.
TX - SENDINGOrangeA packet is being sent.
NO POWER - CHECK VCC / GNDRedThe module is not powered.
IN RESET - RST PIN HIGHRedThe RST pin is high, so the module is held in reset.
OUT OF BAND, with the frequencyRedThe selected frequency is outside the bands of the module. Nothing is sent or received.
  • The gateway's banner is green and shows RX - LISTENING, because it waits for messages all the time.
  • The node's banner is blue and shows STANDBY. Sending a message and receiving its ACK takes a few milliseconds, and the sketch then waits for two seconds.
  • If the banner stays red with IN RESET, check the RST wire and the reset pulse in the sketch.

The Two Settings Lines

The next two lines show the radio settings. They are read from the registers of the chip, so they show what the sketch has really written.

Values on the two settings lines
Value in our exampleMeaningSet by
433.920 MHzCarrier frequencyThe band in initialize(), or setFrequency()
FSKModulation, FSK or OOKThe driver's default
55.6 kbpsBit rateThe driver's default
NETWORK 100Network IDThe network in initialize(), or setNetwork()
CRC ONCRC setting, ON or OFFThe driver's default
AES OFFEncryption, ON or OFFencrypt()
+20 dBm PA_BOOSTOutput power and the amplifier in usesetHighPower() and setPowerLevel()

The amplifier name needs an explanation. The chip has three power amplifiers, and the panel shows which of them is active:

  • PA_BOOST means that the two high-power amplifiers are on. This is the correct setting for the RFM69HCW at higher power levels.
  • PA1 means that one high-power amplifier is on. The driver uses it for the lower power levels.
  • PA0 - NOT WIRED means that the low-power amplifier is selected. On the RFM69HCW, this amplifier is not connected to the antenna. It appears when a sketch does not call setHighPower().

The power on this line is the power of the last packet sent. The driver switches the +20 dBm registers on only during a transmission. Before a radio has sent its first packet, the panel can therefore show +17 dBm.

The Counters

  • SENT counts the packets that have left this radio. An ACK is a packet too.
  • RECEIVED counts the packets that this radio has received with a correct CRC.
  • TOO WEAK counts the packets that matched the settings of this radio but were weaker than its sensitivity.
  • CRC ERR appears at the end of the line after the first packet with a CRC error.

In the running screenshot, both panels show SENT 8 and RECEIVED 8. The node has sent eight messages and received eight ACKs. The gateway has received eight messages and sent eight ACKs.

The counters count packets, and the terminal counts messages. When a message gets no ACK, the driver sends it three times. The node's SENT counter then increases by three, although the terminal prints only one line.

How to read the counters while the node's SENT counter increases
Gateway panelMeaning
RECEIVED and SENT increase.The link works in both directions.
TOO WEAK increases.The settings match, but the distance is too large for the power and the bit rate.
CRC ERR appears.The signal is at the edge of the sensitivity.
No counter changes.The frequency, the bit rate or the network ID is different, or the gateway is not listening.
RECEIVED increases, but the terminal prints nothing.The encryption keys are different, so the message cannot be read.

The Last Packet Lines

Before the first packet arrives, the panel shows LAST PACKET RECEIVED with a dash below it. After that, the first line shows the RSSI of the latest packet. The second line shows the packet with its decoded header:

  • 2 -> 1: "Hello #7" ACK REQ on the gateway means a packet from node 2 to node 1 with the text Hello #7, and the sender has requested an ACK.
  • 1 -> 2: "" ACK on the node means a packet from node 1 to node 2 without any text. It is the ACK of the gateway.
  • A packet that is not readable text is shown as hexadecimal bytes with its length.

The Distance Buttons and the Prediction Line

Below the heading DISTANCE TO THE OTHER RADIOS, there are eight buttons: 10 m, 100 m, 500 m, 1 km, 2 km, 3 km, 5 km and 10 km. The selected button is blue, and the default is 100 m. Click a button while the simulation runs.

The line below the buttons is a prediction. In the picture above, it reads AT 100 m: -65 dBm, 55.6 kbps NEEDS -103 dBm -> OK. It has three parts:

  1. AT 100 m: -65 dBm is the signal strength that a packet from this radio has at the selected distance.
  2. 55.6 kbps NEEDS -103 dBm is the sensitivity at the present bit rate.
  3. OK or TOO WEAK is the result of comparing the two values.

The prediction uses the settings of its own panel only. The Simulation Log records every distance change, the first packet sent and received, and the first packet that was too weak.

Panel Combinations: Distance, Bit Rate and Power

Now comes the exciting part. The result of a transmission depends on several settings together. We will take the combinations one by one. The values for 100 m and 1 km agree with the screenshots of this tutorial, and the package notes record the results for 500 m and 3 km. The other values are calculated with the formulas of the model, which we will work through after the code.

Combination 1: The Distances on the Two Panels

Each radio has its own distance buttons. For a packet between two radios, the model uses the larger of the two selected distances.

Link distance for different selections at +20 dBm and 55.6 kbps
Node panelGateway panelLink distanceRSSIResult
100 m100 m100 m-65 dBmReceived
1 km100 m1 km-95 dBmReceived
100 m500 m500 m-86 dBmReceived
10 m3 km3 km-110 dBmToo weak
3 km10 m3 km-110 dBmToo weak

The second row is the running screenshot at the top of this tutorial. The node is set to 1 km and the gateway to 100 m, and the messages arrive with -95 dBm. This rule has three consequences:

  • To move the radios apart, one click on either panel is enough.
  • To bring them together again, both panels must show a short distance.
  • The prediction line of one panel can show OK while the packets are too weak, because the other panel has a larger distance. The LAST PACKET line always shows the real value.

Try the Distance Buttons

  1. Let the simulation run at 100 m and note the RSSI on both terminals.
  2. Click 1 km on one panel and wait for the next message.
  3. Click 3 km. The gateway stops printing, and its TOO WEAK counter increases. The node prints no ACK.
  4. Click 500 m to restore the link. The messages arrive with -86 dBm.

While the link is broken, the node tries every message three times. Its SENT counter and the gateway's TOO WEAK counter therefore increase by three for every message.

Combination 2: Distance and Bit Rate

The hint on the panel says that a lower kbps value reaches further. A slower bit rate has a better sensitivity, so the same signal can be decoded at a larger distance.

Reception at 433.92 MHz and +20 dBm for five bit rates
DistanceRSSI1.2 kbps4.8 kbps38.4 kbps55.6 kbps250 kbps
10 m-35 dBmReceivedReceivedReceivedReceivedReceived
100 m-65 dBmReceivedReceivedReceivedReceivedReceived
500 m-86 dBmReceivedReceivedReceivedReceivedReceived
1 km-95 dBmReceivedReceivedReceivedReceivedReceived
2 km-104 dBmReceivedReceivedCRC errorToo weakToo weak
3 km-110 dBmReceivedReceivedToo weakToo weakToo weak
5 km-116 dBmReceivedToo weakToo weakToo weakToo weak
10 km-125 dBmToo weakToo weakToo weakToo weakToo weak

The price of a larger range is time. The same message stays on the air much longer at a low bit rate.

Sensitivity in the model, range and air time of the message "Hello #0"
Bit rateSensitivityLargest distanceAir time of the messageAir time of the ACK
1.2 kbps-118 dBm5 km126.7 ms73.3 ms
4.8 kbps-114 dBm3 km31.7 ms18.3 ms
38.4 kbps-105 dBm1 km4.0 ms2.3 ms
55.6 kbps-103.4 dBm1 km2.7 ms1.6 ms
250 kbps-97 dBm1 km0.6 ms0.4 ms

The driver has no single function for the bit rate, so we write the two bit rate registers. Add this line at the top of both sketches:

#include <RFM69registers.h>

Then add these two lines after radio.initialize() in both sketches:

radio.writeReg(REG_BITRATEMSB, RF_BITRATEMSB_4800);

radio.writeReg(REG_BITRATELSB, RF_BITRATELSB_4800);

  • Use the same bit rate in both sketches. The model accepts a difference of up to 10 percent.
  • After the change, the first settings line shows 4.8 kbps, and the prediction line shows the new sensitivity.
  • The model uses -118 dBm at 1.2 kbps. This is a little more careful than the best value of -120 dBm in the datasheet.
  • The node waits only 30 ms for an ACK. At 1.2 kbps, the ACK alone needs 73 ms, so give sendWithRetry() a longer waiting time, as we will see in the code section.
  • In real hardware, a different bit rate also needs a suitable receiver bandwidth and frequency deviation. The model does not check these two settings against the bit rate.

Combination 3: Distance and Power Level

The driver function setPowerLevel() accepts the levels 0 to 23 for the RFM69HCW. The output power moves every RSSI value up or down by the same amount.

Power levels of the driver at 433.92 MHz and 55.6 kbps
Power levelOutput powerAmplifier on the panelRSSI at 100 mLargest distance with reception
23+20 dBmPA_BOOST-65 dBm1 km
20+17 dBmPA_BOOST-68 dBm1 km
19+15 dBmPA_BOOST-70 dBm1 km
16+12 dBmPA_BOOST-73 dBm500 m
15+13 dBmPA1-72 dBm500 m
10+8 dBmPA1-77 dBm500 m
5+3 dBmPA1-82 dBm100 m
0-2 dBmPA1-87 dBm100 m
  • To change the power, add radio.setPowerLevel(10); after radio.setHighPower().
  • The levels of the two amplifier ranges overlap. Level 15 gives +13 dBm, and level 16 gives +12 dBm.
  • For a packet, only the power of the sending radio matters. If you reduce the power of the node only, its messages become weaker, but the ACKs of the gateway keep their strength.

Combination 4: A Sketch Without setHighPower()

This is the most common mistake with the high-power modules. Without setHighPower(), the driver uses the low-power amplifier, which the RFM69HCW does not connect to the antenna. The model reduces the signal by 40 dB in this case.

  • The panel shows -27 dBm PA0 - NOT WIRED.
  • At 100 m, the RSSI is -27 - 85.2 = -112.2 dBm, which is too weak.
  • At 10 m, the RSSI is -27 - 55.2 = -82.2 dBm, so the link works only at the shortest distance.
  • The Simulation Log reports that the radio is sending with PA0 and asks for setHighPower().

Combination 5: The CRC Error Zone

Between a good packet and a packet that is too weak, there is a small zone. When the signal is less than 1.5 dB above the sensitivity, the model gives the packet a CRC error. The driver lets the chip remove such packets, so the gateway prints nothing and the node gets no ACK. CRC ERR appears on the panel of the receiver.

We can reach this zone with power level 5 at 500 m. The output power is +3 dBm, so the RSSI is 3 - 106.2 = -103.2 dBm. The sensitivity is -103.4 dBm, and the signal is only 0.2 dB above the limit.

Combination 6: Network, Frequency and Encryption

Results of different settings on the two radios
DifferenceWhat the panels showResult
Network IDDifferent NETWORK valuesNothing is received, and no counter of the gateway changes.
Frequency bandDifferent frequenciesNothing is received, and no counter of the gateway changes.
Bit rateDifferent kbps valuesNothing is received, and no counter of the gateway changes.
Encryption key, or AES on one side onlyAES ON or AES OFFThe gateway's RECEIVED counter increases, but its last packet is not readable and the terminal prints nothing.

To try the encryption, remove the two slashes before ENCRYPTKEY in both sketches and rebuild them. Both panels then show AES ON. The key must have exactly 16 characters and must be the same on every node.

Combination 7: Frequency Band

A higher frequency has a higher path loss. The band is selected in initialize() with RF69_315MHZ, RF69_433MHZ, RF69_868MHZ or RF69_915MHZ.

Frequency bands at +20 dBm and 55.6 kbps
FrequencyLoss of the first metreRSSI at 100 mRSSI at 1 kmLargest distance
315 MHz22.4 dB-62 dBm-92 dBm2 km
433.92 MHz25.2 dB-65 dBm-95 dBm1 km
868 MHz31.2 dB-71 dBm-101 dBm1 km
915 MHz31.7 dB-72 dBm-102 dBm1 km

Use the same band in both sketches. The model accepts the bands of the module and shows OUT OF BAND for other frequencies.

Arduino Code for the RFM69HCW Node

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

// TEP RFM69HCW Node Demo v1.0
// The Engineering Projects - www.TheEngineeringProjects.com
//
// Sends "Hello #n" to the gateway (node 1) every 2 seconds with sendWithRetry(), which
// asks for an ACK and retries up to 2 times. Prints whether the ACK came back and its RSSI.
// Pair it with RFM69_Gateway. Settings follow the LowPowerLab examples: 433 MHz band,
// network 100, 55.5 kbps FSK, RFM69HCW high power (+20 dBm).
//
// Wiring (Arduino UNO): VCC -> 3.3V, GND -> GND, SCK -> D13, MISO -> D12, MOSI -> D11,
//                       NSS -> D10, RST -> D9, DIO0 -> D2
// Library: RFM69 by LowPowerLab (Arduino Library Manager: "RFM69_LowPowerLab")

#include <RFM69.h>

#define NODEID      2              // unique for each node on the same network
#define GATEWAYID   1
#define NETWORKID   100            // identical on all nodes that talk to each other
#define FREQUENCY   RF69_433MHZ
//#define ENCRYPTKEY  "sampleEncryptKey"   // exactly 16 characters, the same on every node
#define RFM69_RST   9

RFM69 radio;                       // NSS on D10 (SS), DIO0 on D2 (INT0)
unsigned int counter = 0;

void setup() {
  Serial.begin(9600);
  Serial.println(F("TEP RFM69HCW Node Demo v1.0"));
  pinMode(RFM69_RST, OUTPUT);      // RST is active HIGH: pulse it for a clean start
  digitalWrite(RFM69_RST, HIGH);
  delay(10);
  digitalWrite(RFM69_RST, LOW);
  delay(10);
  if (!radio.initialize(FREQUENCY, NODEID, NETWORKID)) {
    Serial.println(F("RFM69 not responding - check the SPI wiring, RST and power"));
    while (true) {}
  }
  radio.setHighPower();            // RFM69HCW / RFM69HW only: PA_BOOST, up to +20 dBm
#ifdef ENCRYPTKEY
  radio.encrypt(ENCRYPTKEY);
#endif
  Serial.println(F("Node 2, network 100, 433 MHz - sending to the gateway (node 1)"));
}

void loop() {
  char message[20];
  sprintf(message, "Hello #%u", counter++);
  Serial.print(F("Sending \""));
  Serial.print(message);
  Serial.print(F("\" ... "));
  if (radio.sendWithRetry(GATEWAYID, message, strlen(message))) {
    Serial.print(F("ACK received, RSSI "));
    Serial.print(radio.RSSI);
    Serial.println(F(" dBm"));
  } else {
    Serial.println(F("no ACK"));
  }
  delay(2000);
}

Set the Identifiers

  • NODEID is 2. Every node of a network needs its own number.
  • GATEWAYID is 1. It is the address to which this node sends.
  • NETWORKID is 100. It must be the same on all nodes that talk to each other.
  • FREQUENCY selects the 433 MHz band.
  • ENCRYPTKEY is switched off by the two slashes at the start of its line.
  • The line RFM69 radio; uses the default pins of the driver, which are D10 for NSS and D2 for DIO0 on the Arduino Uno.

Reset and Initialize the Radio

  1. The sketch sets RST high for 10 ms and then low for 10 ms. This gives the module a clean start.
  2. radio.initialize() checks that the chip answers and writes the driver's settings. If it fails, the sketch prints RFM69 not responding and stops.
  3. radio.setHighPower() selects the high-power amplifiers of the RFM69HCW.
  4. radio.encrypt() is called only when ENCRYPTKEY is defined.
Radio settings written by the driver during initialize()
SettingValue
Frequency433.92 MHz for the 433 MHz band
ModulationFSK in packet mode
Bit rate55.6 kbps
Receiver bandwidth125 kHz
Sync wordTwo bytes. The second byte is the network ID.
Packet formatVariable length with CRC
EncryptionOff

Send a Message with Retries

Inside loop, sprintf writes the text and the counter into a buffer. The counter is increased after it is used, so the first message is number 0. The call radio.sendWithRetry(GATEWAYID, message, strlen(message)) does the following work:

  1. It sends the message with a request for an ACK.
  2. It waits up to 30 ms for the ACK of the gateway.
  3. If no ACK arrives, it sends the message again. With the default settings, it makes three attempts.
  4. It returns true as soon as an ACK arrives, and false after the last attempt.

After a success, radio.RSSI holds the signal strength of the ACK. The function has two more parameters for the number of retries and the waiting time in milliseconds. For a low bit rate, we can write radio.sendWithRetry(GATEWAYID, message, strlen(message), 2, 150) to wait 150 ms for every ACK.

Arduino Code for the RFM69HCW Gateway

The setup part of the gateway is the same as in the node, except for its node ID of 1. Here is the exact sketch from the package:

// TEP RFM69HCW Gateway Demo v1.0
// The Engineering Projects - www.TheEngineeringProjects.com
//
// Listens as node 1 on network 100 and prints every packet: sender, text and RSSI.
// When the sender asks for an ACK (sendWithRetry() on the node), the ACK goes out at
// once - the node waits only 30 ms for it - and the line is printed afterwards.
// Pair it with RFM69_Node.
//
// Wiring (Arduino UNO): VCC -> 3.3V, GND -> GND, SCK -> D13, MISO -> D12, MOSI -> D11,
//                       NSS -> D10, RST -> D9, DIO0 -> D2
// Library: RFM69 by LowPowerLab (Arduino Library Manager: "RFM69_LowPowerLab")

#include <RFM69.h>

#define NODEID      1              // the gateway
#define NETWORKID   100            // identical on all nodes that talk to each other
#define FREQUENCY   RF69_433MHZ
//#define ENCRYPTKEY  "sampleEncryptKey"   // exactly 16 characters, the same on every node
#define RFM69_RST   9

RFM69 radio;                       // NSS on D10 (SS), DIO0 on D2 (INT0)

void setup() {
  Serial.begin(9600);
  Serial.println(F("TEP RFM69HCW Gateway Demo v1.0"));
  pinMode(RFM69_RST, OUTPUT);      // RST is active HIGH: pulse it for a clean start
  digitalWrite(RFM69_RST, HIGH);
  delay(10);
  digitalWrite(RFM69_RST, LOW);
  delay(10);
  if (!radio.initialize(FREQUENCY, NODEID, NETWORKID)) {
    Serial.println(F("RFM69 not responding - check the SPI wiring, RST and power"));
    while (true) {}
  }
  radio.setHighPower();            // RFM69HCW / RFM69HW only: PA_BOOST, up to +20 dBm
#ifdef ENCRYPTKEY
  radio.encrypt(ENCRYPTKEY);
#endif
  Serial.println(F("Gateway (node 1), network 100, 433 MHz - listening"));
}

void loop() {
  if (radio.receiveDone()) {
    char text[RF69_MAX_DATA_LEN + 1];
    byte length = radio.DATALEN;
    memcpy(text, (const void *)radio.DATA, length);
    text[length] = '\0';
    uint16_t sender = radio.SENDERID;
    int16_t rssi = radio.RSSI;
    bool ack = radio.ACKRequested();
    if (ack) radio.sendACK();      // reply first, print afterwards
    Serial.print('[');
    Serial.print(sender);
    Serial.print(F("] "));
    Serial.print(text);
    Serial.print(F("   RSSI "));
    Serial.print(rssi);
    Serial.print(F(" dBm"));
    if (ack) Serial.print(F("   - ACK sent"));
    Serial.println();
  }
}

Receive a Packet

The function radio.receiveDone() puts the radio into receive mode and returns true when a packet has arrived. The driver then offers the packet in these variables:

  • radio.DATA holds the payload, and radio.DATALEN holds its length.
  • radio.SENDERID holds the node ID of the sender.
  • radio.RSSI holds the signal strength of the packet.

The sketch copies these values into its own variables at once. It also adds a zero after the last character, so that the text can be printed.

Send the ACK Before Printing

The order of the next steps is important. The sketch first asks radio.ACKRequested() and calls radio.sendACK(). Only after that, it prints the line. A line of about 40 characters needs about 40 ms at 9600 baud, which is longer than the 30 ms that the node waits for its ACK. The sketch therefore answers first, so that the ACK never depends on the serial port.

This also explains why the sketch copies the values first. Sending the ACK uses the radio again, so the variables of the driver can change.

Calculate the Link Budget

A link budget tells us whether the signal at the receiver is strong enough. The model uses three steps, and we can repeat them with a calculator.

Step 1: Calculate the Path Loss

The model uses the free-space loss for the first metre, and then a loss that grows with 30 dB for every ten-fold increase in distance:

Path loss in dB = 20 × log10(4 × pi × f / c) + 30 × log10(distance in metres)

Here, f is the frequency in Hz and c is the speed of light. At 433.92 MHz, the first part is 25.2 dB. For 100 m, the second part is 30 × 2 = 60 dB. The path loss at 100 m is therefore 85.2 dB.

Step 2: Calculate the RSSI

RSSI = output power - path loss

  • 100 m: +20 - 85.2 = -65.2 dBm, which is displayed as -65 dBm.
  • 500 m: the path loss is 25.2 + 81.0 = 106.2 dB, so the RSSI is -86.2 dBm.
  • 1 km: the path loss is 25.2 + 90 = 115.2 dB, so the RSSI is -95.2 dBm.
  • 2 km: the path loss is 25.2 + 99.0 = 124.2 dB, so the RSSI is -104.2 dBm.

Step 3: Compare with the Sensitivity

The model uses four sensitivity values and interpolates between them. For the driver's bit rate of 55.6 kbps, the result is -103.4 dBm, which the panel shows as -103 dBm.

  • At 1 km, -95.2 dBm is 8.2 dB stronger than the sensitivity. The packet is received.
  • At 2 km, -104.2 dBm is weaker than the sensitivity. The packet is counted as too weak.
  • For OOK modulation, the model uses values that are 2 dB worse.

Calculate the Output Power

The output power depends on the active amplifiers and on a number from 0 to 31, which the datasheet calls OutputPower.

Output power formulas of the chip
AmplifiersFormulaRange
One amplifier, PA0 or PA1-18 + OutputPower-18 to +13 dBm
PA1 and PA2-14 + OutputPowerUp to +17 dBm
PA1 and PA2 with the high-power setting-11 + OutputPowerUp to +20 dBm

The driver's default power level is the highest one. It selects PA1 and PA2 with an OutputPower of 31 and the high-power setting, which gives -11 + 31 = +20 dBm.

Calculate the Bit Rate and the Frequency Step

  • The chip uses a 32 MHz crystal. The bit rate is 32 MHz / register value. The driver writes the value 576, which gives 32,000,000 / 576 = 55,556 bits per second.
  • One frequency step is 32 MHz / 524,288 = 61 Hz. For 433.92 MHz, the frequency registers hold the number 7,109,345.

Calculate the Air Time of One Message

At 55.6 kbps, one bit lasts 18 microseconds. The message "Hello #0" has 8 characters, and the driver adds a header of three bytes for the receiver, the sender and the control flags.

Packet length of the message "Hello #0"
Packet fieldSizeBits
Preamble3 bytes24
Sync word2 bytes16
Length byte1 byte8
Header of the driver3 bytes24
Payload8 bytes64
CRC2 bytes16
Total19 bytes152

The message needs 152 × 18 = 2736 microseconds, which is about 2.7 ms. The ACK has no payload, so it has 88 bits and needs about 1.6 ms. According to the package notes, the complete exchange of a message and its ACK takes about 5.4 ms.

Calculate the Time of a Failed Message

When the gateway cannot be reached, the node makes three attempts. Each attempt consists of the message and the waiting time of 30 ms. The three attempts together take about 100 ms, and the node then prints no ACK. This is short compared with the delay of two seconds in the sketch.

Experiments to Try in Proteus

Change one thing at a time and predict the result before you press Run. The results below follow from the model's rules. The supplied project and the distance buttons were tested in Proteus. The package notes list the other cases as tests of the model on a PC, so check them in your own simulation.

Suggested experiments and their expected results
ChangeExpected result
Click 3 km on either panel.The gateway prints nothing, and the node prints no ACK.
Remove radio.setHighPower() from the node.The node's panel shows PA0 - NOT WIRED, and the link works only at 10 m.
Add radio.setPowerLevel(0) to the node.The gateway shows -87 dBm at 100 m, and the node still shows -65 dBm for the ACK.
Change NETWORKID to 101 in one sketch only.Nothing is received, and the panels show different network numbers.
Enable ENCRYPTKEY in one sketch only.The gateway's RECEIVED counter increases, but its terminal prints nothing.
Remove the DIO0 wire of the gateway.The gateway prints nothing, although its panel counts the received packets.
Hold the RST pin of one module high.Its banner shows IN RESET, and the sketch reports that the radio does not respond.

After each experiment, compare both panels before reading the code again. A difference in frequency, bit rate, network or encryption is visible there.

Compile and Load Your Own Arduino Changes

  1. Open Arduino Code/RFM69_Node/RFM69_Node.ino or the gateway sketch in Arduino IDE.
  2. Install the RFM69_LowPowerLab library. For the same version as the example, copy Arduino Code/libraries/RFM69_LowPowerLab 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, rebuild both sketches and load each HEX into its own board. The package also contains a rebuild script and the AVR core source archive.

Common Problems and Their Solutions

Troubleshooting the RFM69HCW Proteus simulation
ProblemWhat to check
RFM69TEP is missing from Pick Devices.Check that TEPRFM69.LIB is in the active library folder and restart Proteus.
The module is placed, but its model cannot load.Check TEPRFM69.DLL in MODELS and beside the project.
The terminal prints RFM69 not responding.Check SCK, MISO, MOSI and NSS, then VCC and GND. Check that RST is low after the reset pulse.
The node prints no ACK for every message.Check that both sketches call setHighPower(), that the band, the network and the key are the same, and that the distance is not too large.
The gateway prints nothing at all.Check the DIO0 wire to D2 and that the gateway's banner shows RX - LISTENING.
The TOO WEAK counter increases.Select a shorter distance on both panels, raise the power or lower the bit rate.
A terminal line is cut off.Make the terminal window wider.
A terminal is blank or unreadable.Check the Program File, the 16 MHz clock, D1/TX to RXD and 9600 baud.

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

Practical Review and Model Limitations

This library is useful for learning how a network of RFM69 nodes is configured and how acknowledgements and retries work. The two panels show the settings of both radios side by side, and the distance buttons turn the link budget into an experiment that we can repeat.

What the Model Supports

  • The operating modes of the chip with their wake-up times.
  • Packet mode with FSK and OOK, the bit rate, the carrier frequency and the receiver bandwidth.
  • The three power amplifiers and the +20 dBm high-power setting.
  • The packet engine with preamble, sync word, variable length, CRC and address filtering.
  • The 66-byte FIFO and AES with key matching.
  • The DIO0 interrupt, the RSSI register, the RST pin and the temperature reading.

What the Model Does Not Simulate

  • Real antennas, terrain, reflections and interference.
  • Collisions between transmitters that send at the same moment.
  • Listen mode and continuous mode.
  • The pins DIO1 to DIO5, which are not available on the component.
  • Packets that are longer than the FIFO.
  • The frequency deviation and the automatic frequency correction.
  • The supply voltage and the current of the module.

Treat the range values as teaching examples. The range of real hardware depends on the antenna, its height, the surroundings and the local rules for the frequency band, so it must be measured with the actual devices.

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

What Is the Difference Between RFM69HCW and RFM69CW?

The RFM69HCW is the high-power version with an output power of up to +20 dBm. For this version, the sketch must call setHighPower(). Our model represents the RFM69HCW.

Why Do Both Terminals Show the Same RSSI?

The gateway prints the strength of the message, and the node prints the strength of the ACK. Both radios send with +20 dBm over the same distance, so both values are equal. They become different when the two radios use different power levels.

Can I Add More Nodes?

Yes. Every RFM69TEP in the design shares the same band. Give every node its own NODEID and the same NETWORKID. The gateway prints the node ID of each sender in brackets. The model does not simulate collisions between nodes that send at the same moment.

Why Does the Panel Show +17 dBm at the Start?

The driver switches the +20 dBm setting on only during a transmission. Before the first packet of a radio, the panel shows the power without this setting. After the first packet, it shows +20 dBm.

Do I Need to Connect the RST Pin?

The module runs when RST is low or open. The supplied sketches use the pin for a clean start, so keep the wire to D9 when you use them.

Is the Message Encrypted in the Supplied Example?

No. The panels show AES OFF. To use encryption, enable ENCRYPTKEY with the same 16 characters in both sketches and rebuild them.

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 RFM69HCW Proteus Library tutorial. Start with the supplied project, watch both panels and then change the distance step by step. Once the RSSI values make sense, change the power level or the bit rate and compare the results with your own calculation. Share your questions and simulation results in the comments below.