
RFM69HCW Proteus Library | RFM69 Arduino Simulation

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.
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| Folder or file | Contents and purpose |
|---|---|
| Proteus Library Files | TEPRFM69.LIB for the radio module, and the TEP Arduino UNO V3 LIB/IDX files. |
| Proteus Model Files | TEPRFM69.DLL, which provides the module's simulated behavior. |
| Proteus Simulation | RFM69-ArduinoUnoV3.pdsprj, RFM69_Node.hex, RFM69_Gateway.hex and a local copy of the DLL. |
| Arduino Code | Both sketches, the LowPowerLab RFM69 1.6.0 driver, the AVR core archive and a firmware rebuild script. |
| Model Source | The chip model, SPI transport, shared radio band and Proteus adapter. |
| Documentation | Model notes, third-party notices and a preview of the board artwork. |
| README.txt and SHA256SUMS.txt | Quick-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:
- Open the extracted Proteus Library Files folder.
- Copy
TEPRFM69.LIBinto the library directory configured for your Proteus installation. - Copy
ArduinoV3TEP.LIBandArduinoV3TEP.IDXfrom the same folder if our TEP Arduino UNO V3 library is not installed already. - Open Proteus Model Files and copy
TEPRFM69.DLLinto your configured ProteusMODELSdirectory. - Restart Proteus, open Pick Devices and search for RFM69TEP.
- 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.
| Module pin | Connection | Purpose |
|---|---|---|
| VCC | Positive supply terminal | Powers the digital model. |
| GND | Ground | Provides the shared reference. |
| SCK | Arduino Uno D13 | SPI clock from the Arduino. |
| MISO | Arduino Uno D12 | Data from the module to the Arduino. |
| MOSI | Arduino Uno D11 | Data from the Arduino to the module. |
| NSS | Arduino Uno D10 | Selects the module for an SPI command. It is active low. |
| RST | Arduino Uno D9 | Reset input. It is active high. |
| DIO0 | Arduino Uno D2 | Interrupt output. It tells the Arduino that a packet has arrived. |
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
- Open
Proteus Simulation/RFM69-ArduinoUnoV3.pdsprjfrom the extracted package. - Keep both HEX files and
TEPRFM69.DLLin that folder. - Double-click ARD1 and confirm that its Program File is
RFM69_Node.hex. - Double-click ARD2 and confirm that its Program File is
RFM69_Gateway.hex. - Confirm the 16 MHz clock on both boards and 9600 baud on both terminals.
- 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.
Let us go through the panel from top to bottom.
The Mode Banner and Its Colors
| Banner text | Color | Meaning |
|---|---|---|
| SLEEP | Blue | The radio is in its power-saving mode. |
| STANDBY | Blue | The radio is on, but it is neither sending nor listening. |
| SYNTHESIZER | Blue | The frequency synthesizer is running, and the radio is ready to change to sending or listening. |
| RX - LISTENING | Green | The radio is listening for packets. |
| TX - SENDING | Orange | A packet is being sent. |
| NO POWER - CHECK VCC / GND | Red | The module is not powered. |
| IN RESET - RST PIN HIGH | Red | The RST pin is high, so the module is held in reset. |
| OUT OF BAND, with the frequency | Red | The 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.
| Value in our example | Meaning | Set by |
|---|---|---|
| 433.920 MHz | Carrier frequency | The band in initialize(), or setFrequency() |
| FSK | Modulation, FSK or OOK | The driver's default |
| 55.6 kbps | Bit rate | The driver's default |
| NETWORK 100 | Network ID | The network in initialize(), or setNetwork() |
| CRC ON | CRC setting, ON or OFF | The driver's default |
| AES OFF | Encryption, ON or OFF | encrypt() |
| +20 dBm PA_BOOST | Output power and the amplifier in use | setHighPower() 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.
| Gateway panel | Meaning |
|---|---|
| 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:
- AT 100 m: -65 dBm is the signal strength that a packet from this radio has at the selected distance.
- 55.6 kbps NEEDS -103 dBm is the sensitivity at the present bit rate.
- 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.
| Node panel | Gateway panel | Link distance | RSSI | Result |
|---|---|---|---|---|
| 100 m | 100 m | 100 m | -65 dBm | Received |
| 1 km | 100 m | 1 km | -95 dBm | Received |
| 100 m | 500 m | 500 m | -86 dBm | Received |
| 10 m | 3 km | 3 km | -110 dBm | Too weak |
| 3 km | 10 m | 3 km | -110 dBm | Too 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
- Let the simulation run at 100 m and note the RSSI on both terminals.
- Click 1 km on one panel and wait for the next message.
- Click 3 km. The gateway stops printing, and its TOO WEAK counter increases. The node prints
no ACK. - 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.
| Distance | RSSI | 1.2 kbps | 4.8 kbps | 38.4 kbps | 55.6 kbps | 250 kbps |
|---|---|---|---|---|---|---|
| 10 m | -35 dBm | Received | Received | Received | Received | Received |
| 100 m | -65 dBm | Received | Received | Received | Received | Received |
| 500 m | -86 dBm | Received | Received | Received | Received | Received |
| 1 km | -95 dBm | Received | Received | Received | Received | Received |
| 2 km | -104 dBm | Received | Received | CRC error | Too weak | Too weak |
| 3 km | -110 dBm | Received | Received | Too weak | Too weak | Too weak |
| 5 km | -116 dBm | Received | Too weak | Too weak | Too weak | Too weak |
| 10 km | -125 dBm | Too weak | Too weak | Too weak | Too weak | Too weak |
The price of a larger range is time. The same message stays on the air much longer at a low bit rate.
| Bit rate | Sensitivity | Largest distance | Air time of the message | Air time of the ACK |
|---|---|---|---|---|
| 1.2 kbps | -118 dBm | 5 km | 126.7 ms | 73.3 ms |
| 4.8 kbps | -114 dBm | 3 km | 31.7 ms | 18.3 ms |
| 38.4 kbps | -105 dBm | 1 km | 4.0 ms | 2.3 ms |
| 55.6 kbps | -103.4 dBm | 1 km | 2.7 ms | 1.6 ms |
| 250 kbps | -97 dBm | 1 km | 0.6 ms | 0.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 level | Output power | Amplifier on the panel | RSSI at 100 m | Largest distance with reception |
|---|---|---|---|---|
| 23 | +20 dBm | PA_BOOST | -65 dBm | 1 km |
| 20 | +17 dBm | PA_BOOST | -68 dBm | 1 km |
| 19 | +15 dBm | PA_BOOST | -70 dBm | 1 km |
| 16 | +12 dBm | PA_BOOST | -73 dBm | 500 m |
| 15 | +13 dBm | PA1 | -72 dBm | 500 m |
| 10 | +8 dBm | PA1 | -77 dBm | 500 m |
| 5 | +3 dBm | PA1 | -82 dBm | 100 m |
| 0 | -2 dBm | PA1 | -87 dBm | 100 m |
- To change the power, add
radio.setPowerLevel(10);afterradio.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
| Difference | What the panels show | Result |
|---|---|---|
| Network ID | Different NETWORK values | Nothing is received, and no counter of the gateway changes. |
| Frequency band | Different frequencies | Nothing is received, and no counter of the gateway changes. |
| Bit rate | Different kbps values | Nothing is received, and no counter of the gateway changes. |
| Encryption key, or AES on one side only | AES ON or AES OFF | The 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 | Loss of the first metre | RSSI at 100 m | RSSI at 1 km | Largest distance |
|---|---|---|---|---|
| 315 MHz | 22.4 dB | -62 dBm | -92 dBm | 2 km |
| 433.92 MHz | 25.2 dB | -65 dBm | -95 dBm | 1 km |
| 868 MHz | 31.2 dB | -71 dBm | -101 dBm | 1 km |
| 915 MHz | 31.7 dB | -72 dBm | -102 dBm | 1 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
NODEIDis 2. Every node of a network needs its own number.GATEWAYIDis 1. It is the address to which this node sends.NETWORKIDis 100. It must be the same on all nodes that talk to each other.FREQUENCYselects the 433 MHz band.ENCRYPTKEYis 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
- The sketch sets RST high for 10 ms and then low for 10 ms. This gives the module a clean start.
radio.initialize()checks that the chip answers and writes the driver's settings. If it fails, the sketch prints RFM69 not responding and stops.radio.setHighPower()selects the high-power amplifiers of the RFM69HCW.radio.encrypt()is called only when ENCRYPTKEY is defined.
| Setting | Value |
|---|---|
| Frequency | 433.92 MHz for the 433 MHz band |
| Modulation | FSK in packet mode |
| Bit rate | 55.6 kbps |
| Receiver bandwidth | 125 kHz |
| Sync word | Two bytes. The second byte is the network ID. |
| Packet format | Variable length with CRC |
| Encryption | Off |
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:
- It sends the message with a request for an ACK.
- It waits up to 30 ms for the ACK of the gateway.
- If no ACK arrives, it sends the message again. With the default settings, it makes three attempts.
- 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.DATAholds the payload, andradio.DATALENholds its length.radio.SENDERIDholds the node ID of the sender.radio.RSSIholds 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.
| Amplifiers | Formula | Range |
|---|---|---|
| One amplifier, PA0 or PA1 | -18 + OutputPower | -18 to +13 dBm |
| PA1 and PA2 | -14 + OutputPower | Up to +17 dBm |
| PA1 and PA2 with the high-power setting | -11 + OutputPower | Up 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 field | Size | Bits |
|---|---|---|
| Preamble | 3 bytes | 24 |
| Sync word | 2 bytes | 16 |
| Length byte | 1 byte | 8 |
| Header of the driver | 3 bytes | 24 |
| Payload | 8 bytes | 64 |
| CRC | 2 bytes | 16 |
| Total | 19 bytes | 152 |
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.
| Change | Expected 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
- Open
Arduino Code/RFM69_Node/RFM69_Node.inoor the gateway sketch in Arduino IDE. - Install the RFM69_LowPowerLab library. For the same version as the example, copy
Arduino Code/libraries/RFM69_LowPowerLabinto your sketchbook's libraries folder. - Select Arduino Uno as the board.
- Compile the sketch and use the Export Compiled Binary command.
- Select the new application HEX in the Program File property of the correct Arduino.
- 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
| Problem | What 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:
- CC1101 Proteus Library: a link at 433.92 MHz with signal strength and distance buttons.
- nRF24L01 Proteus Library: a 2.4 GHz link between two Arduino Uno boards with the RF24 library.
- nRF24L01 PA LNA Proteus Library: the long-range 2.4 GHz module with a power amplifier and distance buttons up to 2 km.
- SX1278 LoRa Proteus Library: a LoRa link at 433 MHz with the Ra-02 module.
- RFM95W LoRa Proteus Library: a LoRa link at 868 MHz with RSSI, SNR and spreading factor.
- SX1262 LoRa Proteus Library: a LoRa link with up to +22 dBm, the Arduino Mega 2560 and RadioLib.
- MFRC522 RFID Proteus Library: a 13.56 MHz RFID reader with virtual MIFARE cards.
- EM-18 RFID Proteus Library: a 125 kHz RFID reader with serial output.
- PN532 NFC Proteus Library: an NFC reader for I2C and SPI with MIFARE Classic and NTAG213 cards.
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.
























Comments
0