SX1278 LoRa Library for Proteus V1.1: two Arduino UNOs with black Ra-02 boards, the SX1278 Advance pop-up with its Radio page and the TEP Serial Monitor in its Simple interface

SX1278 LoRa Library for Proteus V1.1 (Ra-02 433 MHz + Arduino)

2.5K Views
40
700
60
25
60
PCBWay

Hello friends, I hope you all are doing great. Today, I am going to share the new SX1278 LoRa Library for Proteus V1.1. The SX1278 is Semtech's long-range LoRa radio chip, and the Ai-Thinker Ra-02 board with its silver shield can and spring antenna is the most popular way to use it at 433 MHz. With this SX1278 LoRa Library for Proteus, two Ra-02 modules in one design talk over a simulated 433 MHz air, even 10 km apart, and your Arduino drives them over SPI with the same arduino-LoRa library you use on real hardware.

Version 1.1 replaces the earlier version of this post. You now get two devices: SX1278 Simple, with its control panel on the schematic, and SX1278 Advance, with a pop-up window and four measured LoRa test tools. The new SX1278 Arduino Proteus demo has two Arduino UNOs that send packets, PING each other and switch the spreading factor from our TEP Serial Monitor. Have you read the earlier version? Then jump to "What's New" below.

NOTICE: This library is very special to our team. Our SX1278 model has the chip's LoRa registers and FIFO, works out the signal level and the SNR at every distance and measures the real LoRa time on air. It took our team a lot of hard work, many test runs and many design changes. Your feedback is the fuel that keeps us going, so please tell us what you think in the comments below or in the SX1278 Library board of our forum. And if our free libraries help you, you can buy us a coffee. So, let's get started with the SX1278 LoRa Library for Proteus:

SX1278 LoRa Library for Proteus V1.1: two Arduino UNOs with black Ra-02 boards, the SX1278 Advance pop-up with its Radio page and the TEP Serial Monitor in its Simple interface
Figure: The SX1278 demo in Proteus 8.5: NODE 1 (Simple) sends, NODE 2 (Advance) receives at -68 dBm, the Radio page and Serial Monitor U4 in the Simple interface.

What is the SX1278 LoRa Module (Ra-02)?

The SX1278 is a radio transceiver (it sends and receives) made by Semtech. Its LoRa modem, short for "Long Range", tunes from 137 to 525 MHz and trades speed for distance: it sends slowly, but over kilometres, so it is popular for weather stations, farm sensors and trackers. The Arduino talks to it over SPI, a 4-wire bus (clock, data in, data out and chip select), plus a reset pin and the DIO0 interrupt pin.

Most Arduino projects use the Ai-Thinker Ra-02 module: a 17 x 16 mm board for 410 - 525 MHz with the SX1278 under a silver shield can and an IPEX socket for the antenna. The print on the can says it all: Ra-02, Ai-Thinker, ISM: 410-525MHz, PA: +18dBm, LoRa/FSK/OOK.

The SX1278 and the Ra-02 at a Glance

SX1278 and Ra-02 in numbers
FeatureValue
ChipSemtech SX1278, from the SX1276/77/78/79 family (RegVersion 0x12)
FrequencyChip 137 - 525 MHz; the Ra-02 module 410 - 525 MHz, normally used at 433 MHz
ModulationLoRa (chirp spread spectrum); the chip also has an FSK / OOK modem
Spreading factorSF6 - SF12 (the demo sketches accept 7 - 12)
Bandwidth7.8 - 500 kHz (the demo: 125 kHz)
Coding rate4/5 - 4/8 (the demo: 4/5)
TX powerUp to +20 dBm on PA_BOOST (the Ra-02 is printed PA: +18dBm); the demo uses +17 dBm, arduino-LoRa's default
Sensitivity (our model, 125 kHz)-125 dBm at SF7 down to -137 dBm at SF12
BufferA 256-byte FIFO; packets up to 255 bytes
Supply3.3 V (Ra-02: 2.5 - 3.7 V); the pins are NOT 5 V tolerant
InterfaceSPI plus RST and DIO0 (RxDone / TxDone)

SX1278, RFM95W, SX1262 or Another Radio: Which Library Do You Need?

Our RF libraries for Proteus
Your moduleWhat it doesOur library
SX1278 / Ra-02 (black square board, spring antenna)433 MHz LoRa, long range at low data rates, SPIThis article
RFM95W (HopeRF, SX1276)868 / 915 MHz LoRa, SPI, the same arduino-LoRa libraryRFM95W LoRa Library for Proteus
SX1262 (Ebyte E22)The newer LoRa chip, up to +22 dBm, RadioLib on an Arduino Mega 2560SX1262 LoRa Library for Proteus
CC1101315 / 433 / 868 / 915 MHz FSK and OOK, SPICC1101 Library for Proteus
RFM69HCW315 / 433 / 868 / 915 MHz FSK with ACKs, SPIRFM69HCW Library for Proteus
nRF24L012.4 GHz, SPI, short rangenRF24L01 Library for Proteus
HC-12433 MHz wireless serial module (UART)HC-12 Library for Proteus

All of them are compared in our RF Module Libraries for Proteus roundup. Ra-02, RFM95W and SX1262 modules can even talk to each other in one design, because the three LoRa libraries share one model.

LoRa Terms You Will See in This Article

LoRa terms
TermMeaning
LoRaSemtech's long-range modulation: every symbol is sent as a chirp
ChirpA tone that sweeps across the whole bandwidth; where the sweep starts carries the data
Spreading factor (SF)SF7 - SF12: how long each chirp is; one step up doubles it and reaches further
Bandwidth (BW)How wide the sweep is: 125 kHz in the demo
Coding rate (CR)Extra bits for error correction: 4/5 sends 5 bits for every 4 data bits
dBmPower compared to 1 mW: 0 dBm = 1 mW, +17 dBm = 50 mW, -120 dBm is a very weak signal
RSSIReceived Signal Strength Indicator: the level of a packet in dBm
SNRSignal-to-noise ratio: how far the signal is above the noise (below it, if negative)
Noise floorThe noise in the receiver's bandwidth: -117 dBm at 125 kHz in our model
SensitivityThe weakest signal the receiver can still decode at its SF and bandwidth
Sync wordOne byte (0x12 in the demo) that keeps networks apart: a receiver ignores other sync words
Explicit headerA short header that tells the receiver the length, coding rate and CRC setting
Time on airHow long one packet keeps the channel busy
Duty cycleThe share of time a transmitter is on the air; the EU allows 10 % in its 433 MHz band
LDROLow data rate optimisation: switched on when a symbol lasts more than 16 ms
RX singleThe receiver listens for one packet and stops after a timeout; arduino-LoRa's parsePacket() uses it

How LoRa Works: Chirps, Spreading Factor and Range

Simple radios, such as the CC1101, send a 1 or a 0 by moving the frequency a little up or down. LoRa sends every symbol as a chirp: a tone that sweeps steadily up across the whole bandwidth, and the data sits in where the sweep starts. At spreading factor 7 there are 2 to the power of 7 = 128 starting points, so one chirp carries 7 bits. The receiver adds up the energy of the whole sweep, so it finds a chirp even in noise stronger than the signal.

A packet starts with a preamble of plain chirps (8 in the demo), then come the sync word, the header, the data and, if switched on, a CRC; arduino-LoRa leaves the CRC off unless you call LoRa.enableCrc().

Spreading Factor, Bandwidth and Coding Rate

  • Spreading factor (SF): 7 to 12 in the demo. Each step up makes every chirp twice as long and lets the receiver decode a signal 2.5 dB weaker.
  • Bandwidth (BW): 7.8 to 500 kHz, 125 kHz in the demo. Half the bandwidth lets in 3 dB less noise, but every chirp lasts twice as long.
  • Coding rate (CR): 4/5 to 4/8. 4/5 sends 5 bits for every 4 data bits; more extra bits repair more errors.

One chirp lasts 2 to the power of SF, divided by the bandwidth: 128 / 125,000 = 1.024 ms at SF7 and 125 kHz (the "1.024 ms / symbol" on the Radio page), but 32.768 ms at SF12.

RSSI and SNR: Why LoRa Hears Below the Noise

The RSSI is the level of a packet in dBm. The SNR says how far that level is above the noise in the receiver's bandwidth, which our model puts at -174 dBm/Hz + 10 log(BW) + 6 dB: -117 dBm at 125 kHz. LoRa can decode below the noise: each SF has its own lowest SNR, and the sensitivity is the noise floor plus that limit:

SNR limits of the SX1278 data sheet, as used by our model (times measured by the Time on air tool)
SFLowest SNRSensitivity at 125 kHzTime on air (12 bytes)
SF7-7.5 dB-125 dBm41.2 ms
SF8-10 dB-127 dBm72.2 ms
SF9-12.5 dB-130 dBm144.4 ms
SF10-15 dB-132 dBm288.8 ms
SF11-17.5 dB-135 dBm577.5 ms
SF12-20 dB-137 dBm991.2 ms

So at 5 km, the demo's packets arrive at -119 dBm, an SNR of -2.1 dB, and SF7 still decodes them. Close up, the SNR is capped at +10 dB, as on real modules: 100 m prints 10.00 dB, although the signal is about 49 dB above the noise.

Why a Higher SF Reaches Further

The level at the receiver is the TX power minus the path loss. Our model uses free-space loss for the first metre (25.2 dB at 433 MHz), then a path-loss exponent of 3.0, typical of a built-up area: 30 dB more for every ten times the distance. With the demo's +17 dBm:

  • 100 m: 85.2 dB of loss, so -68 dBm; SF7 needs -125 dBm: OK, with +56.4 dB to spare.
  • 10 km: 145.2 dB of loss, so -128 dBm, an SNR of -11.1 dB: too weak for SF7 (-7.5 dB) and SF8 (-10 dB), but OK for SF9 (-12.5 dB).

A chirp twice as long carries twice the energy, so every SF step digs 2.5 dB deeper into the noise: "HIGHER SF REACHES FURTHER", as our panels say. The price is time on air.

Time on Air: The Price of Range

The time on air is how long one packet keeps the channel busy. Our model uses Semtech's formula (application note AN1200.13). For a 12-byte packet such as "hello TEP 10" at SF7, 125 kHz, CR 4/5, explicit header and no CRC:

  1. One symbol lasts 1.024 ms; the preamble takes 8 + 4.25 = 12.25 symbols.
  2. The payload takes 8 + ceil((8 x 12 - 4 x 7 + 28) / (4 x 7)) x 5 = 8 + 4 x 5 = 28 symbols (the 5 comes from CR 4/5).
  3. Together: 40.25 symbols x 1.024 ms = 41.2 ms, exactly what the Time on air tool measures.

At SF12, a symbol lasts 32.768 ms, more than 16 ms, so arduino-LoRa switches on the low data rate optimisation (LDRO): 30.25 symbols, 991.2 ms, almost a second.

Duty Cycle: How Often May You Send?

In the EU band 433.05 - 434.79 MHz, a transmitter may be on the air at most 10 % of the time, at 10 mW: 360 s per hour. With 41.2 ms packets, that is at most 8734 packets per hour, with a pause of at least 0.37 s after each. The demo's packet every 2 s uses about 2 % at SF7; at SF12 it would be on the air half of the time.

Sync Word and the Settings Both Radios Must Share

A receiver accepts only packets with its own sync word: 0x12 for private networks such as the demo (LoRaWAN uses 0x34). Two radios form a link only when the frequency (within a quarter of the bandwidth), SF, bandwidth, sync word, IQ setting and header mode match; the coding rate and CRC may differ, because the explicit header announces them. And there is no ACK: a LoRa radio never answers "got it" by itself, so the demo's PING and PONG show how a sketch adds a reply.

What's New in SX1278 LoRa Library for Proteus V1.1

If you used the earlier version of this post (v1.0 and its 29 Sep model update), here is what has changed:

  • Two devices in TEPSX1278.LIB: SX1278 Simple (SX1278TEP, the v1.0 device, so old designs keep working) and SX1278 Advance (SX1278ADVTEP) with a pop-up window.
  • A redrawn board: black and square like the real Ra-02, with its shield can and a spring antenna (v1.0: a navy board); the 8 pins stay where they were.
  • A live antenna and three LEDs: the spring glows orange while sending and green while receiving. PWR, TX and RX are a TEP addition: the real Ra-02 has no LEDs.
  • Close and reopen: a red X and a PANEL button on the Simple, OPEN PANEL on the Advance.
  • Four measured test tools (Advance): Link test, Time on air, Range and Registers.
  • Model: every radio now records its packets and SPI accesses for the tools; the link budget (100 m: -68 dBm, SNR 10 dB) and the 29 Sep update (one model for our three LoRa libraries) are unchanged.
  • A two-UNO demo with the TEP Serial Monitor instead of Virtual Terminals: every v1.0 output line plus commands (SEND, PING, STATUS, SF, BW, PWR, HELP; AUTO on node 1) and a link line every 10 s.
  • Lighter package: about 1.5 MB, without the C++ source code (before: about 7.4 MB).

A v1.0 design keeps its old symbol: the new model, but no new board, LEDs or red X. Before a sketch starts the radio, its panel shows the chip's reset values:

A v1.0 SX1278 design after the update to v1.1: the old navy Ra-02 board and the v1.0 SX1278 LoRa CONTROLS panel showing FSK/OOK MODE - NOT MODELLED
Figure: A v1.0 design after the update: the old navy board and the v1.0 panel; re-pick the part for the new one (PC render).

SX1278 LoRa Library for Proteus: Simple vs Advance

Both devices run the same model; only the panel differs:

SX1278 Simple vs Advance
FeatureSimpleAdvance
Full SX1278 LoRa model (SPI, registers, 256-byte FIFO, modes, IRQ flags, DIO0, RSSI / SNR, real time on air)✔✔
Black Ra-02 board, glowing spring antenna and PWR / TX / RX LEDs✔✔
DISTANCE buttons 10 m - 20 km and the link-budget verdict✔✔
Control panel on the schematic (mode, settings, counters, last packet)✔✘
Pop-up window you can move, resize and minimise✘✔
Radio page: what the sketch set, traffic, distance and reach✘✔
Link test, Time on air, Range and Registers✘✔
TEP Dark / Light theme, text size, Help page with Copy diagnostics✘✔
Same device name as v1.0 (old designs keep working)✔✘

Choose Simple to keep the radio's state beside your circuit, and Advance for hard numbers about your link. The demo has one of each.

Download SX1278 LoRa Library for Proteus

Click the button below to download SX1278-LoRa-Library-for-Proteus-v1.1.zip (about 1.5 MB, without the C++ source code):

SX1278 LoRa Library for Proteus V1.1
  • README.txt: a guide to the files, the wiring, the model, the tools and real hardware.
  • Proteus Library Files: TEPSX1278.LIB (both devices), TEPSERIALMON.LIB and our Arduino UNO library ArduinoV3TEP.LIB / ArduinoV3TEP.IDX.
  • Proteus Model Files: TEPSX1278.DLL and TEPSERIALMON.DLL. Our RFM95W and SX1262 libraries ship the identical TEPSX1278.DLL, so installing all three is safe.
  • Proteus Simulation: SX1278-ArduinoUnoV3.pdsprj, LoRa_Sender.hex, LoRa_Receiver.hex and copies of both DLLs.
  • Arduino Code: LoRa_Sender.ino, LoRa_Receiver.ino and the arduino-LoRa library 0.8.0 (Sandeep Mistry), unmodified, with its examples and its LICENSE file, under the MIT License.

No Proteus yet? Read How to Download and Install Proteus 7 and 8. New to libraries? Follow How to Install a New Library in Proteus.

How to Install SX1278 LoRa Library for Proteus

  1. Close Proteus and extract the whole zip file.
  2. Copy the four files from Proteus Library Files into the LIBRARY folder, usually C:\Program Files (x86)\Labcenter Electronics\Proteus 8 Professional\LIBRARY (on some PCs C:\ProgramData\Labcenter Electronics\Proteus 8 Professional\LIBRARY).
  3. Copy TEPSX1278.DLL and TEPSERIALMON.DLL into the MODELS folder.
  4. Start Proteus, press P and search for SX1278. You get the Simple and the Advance device (category Peripherals > Wireless).

Updating from v1.0? Replace TEPSX1278.LIB and TEPSX1278.DLL, and delete TEPSX1278.IDX if there is one in LIBRARY. A v1.0 design keeps its v1.0 symbol and runs with the new model; re-pick the part to get the v1.1 board. Tested in Proteus 8.5; Proteus 7 is not supported.

The Ra-02 Board in Proteus

We designed the module as a clean TEP board after the real Ai-Thinker Ra-02: a square black board, the silver shield can with its notch and the real engraving and Ai logo, gold half-hole pads and the IPEX socket with a copper spring antenna. Below the can: the board button, three LEDs, a SIMPLE or ADVANCE badge and the pins. One honest note: the real Ra-02 has its IPEX socket next to pin 1; we draw it top-right, so the antenna stays clear of your wiring. Here is U1, the Simple device, with its panel while it sends:

SX1278 LoRa Library for Proteus: SX1278 Simple Ra-02 board sending with an orange spring antenna and waves, PWR and TX LEDs lit, PANEL: SHOWN, and the SX1278 LoRa CONTROLS panel at 100 m with the last packet PONG
Figure: U1 (Simple) sends: orange spring and waves, PWR and TX lit; its panel at 100 m.

The spring and its waves glow orange; PWR and TX are lit, RX stays dark. On U2, the Advance device, they glow green when a packet arrives:

SX1278 Advance Ra-02 board in Proteus receiving a packet: green spring antenna and waves, PWR and RX LEDs lit, OPEN PANEL button and ADVANCE badge
Figure: U2 (Advance) receives: green spring and waves, PWR and RX lit.

Pinout

The eight Proteus pins keep the v1.0 order. A real Ra-02 has more pads (DIO1 to DIO5, extra grounds) in another order, so wire a real module by the pin names in its data sheet:

SX1278 pins in Proteus (VCC GND SCK MISO MOSI NSS RST DIO0)
PinFunctionDemo connection
VCCPower (3.3 V on a real module)Supply terminal
GNDGroundGND
SCKSPI clock from the ArduinoArduino D13
MISOSPI data from the radioArduino D12
MOSISPI data to the radioArduino D11
NSSSPI chip select, active LOWArduino D10
RSTReset, active LOW; LoRa.begin() pulses itArduino D9
DIO0Interrupt output: RxDone or TxDoneArduino D2

Spring, LEDs and Waves

Board animations (the same on both devices)
IndicatorWhat it shows
PWR LED (red)Lit while VCC and GND are connected
TX LED (orange)Blinks for every packet sent (held 0.3 s)
RX LED (green)Blinks for every packet received (held 0.4 s)
Spring antennaCopper at rest, orange while sending, green while receiving
Waves above the springGrey at rest; they ripple out while sending and in while receiving
PANEL / OPEN PANEL, SIMPLE / ADVANCEThe panel button and the device badge

There are no properties to edit: your sketch sets the radio over SPI, as on the real chip, and you choose the DISTANCE on the panel (100 m at every Run).

SX1278 Simple: The Control Panel on the Sheet

Beside the Simple board, the SX1278 LoRa CONTROLS panel shows what the radio is doing, without one debug line in your sketch. You saw it in the first board image, at the default 100 m. From top to bottom:

The SX1278 Simple panel
PartWhat it shows
Header, red XSX1278 LoRa CONTROLS; the X closes the panel
Mode bannerFor example RX SINGLE or RX CONTINUOUS (green), TX - SENDING (orange), STANDBY, SLEEP or CAD (blue), NO POWER - CHECK VCC / GND or OUT OF BAND (red); FSK/OOK MODE - NOT MODELLED before a sketch switches the chip to LoRa
Settings line 1433.000 MHz SF7 BW 125 kHz CR 4/5: what the sketch wrote
Settings line 2SYNC 0x12 CRC OFF EXPLICIT +17 dBm
CountersSENT, RECEIVED, TOO WEAK (CRC ERR appears after the first CRC error)
LAST PACKETRSSI and SNR of the last packet received, then its text and length
DISTANCE TO THE OTHER RADIOS10 m, 100 m, 1 km, 2 km, 5 km, 10 km, 15 km, 20 km
VerdictAT 100 m: -68 dBm, SF7 NEEDS -125 dBm -> OK
Hint and footerCLICK A DISTANCE - HIGHER SF REACHES FURTHER; LoRa 433 MHz Ai-Thinker Ra-02

Why the Sender Says RX SINGLE

U1 is the sender, yet its banner says RX SINGLE. That is correct: the v1.1 sender calls parsePacket() in every loop, which keeps the radio listening in windows of 100 symbols (about 102 ms at SF7), so node 2 can PING it; its last packet is the PONG from my PING test. A 41.2 ms hello every 2 s is rarely caught as TX - SENDING, but the TX LED and the orange spring show every one. A sketch that must not miss a packet listens continuously with LoRa.onReceive() and LoRa.receive() (DIO0 on D2).

DISTANCE: 100 m Works, 10 km Is TOO WEAK

Now click 10 km on the panel of U1. The verdict turns to -128 dBm, TOO WEAK, because SF7 needs -125 dBm:

SX1278 Simple panel in Proteus with 10 km clicked: AT 10 km: -128 dBm, SF7 NEEDS -125 dBm, TOO WEAK
Figure: 10 km at SF7: -128 dBm, TOO WEAK.

From now on, U4 prints only "Link (10 s): 0 received, 0 sent", while U3 keeps printing "Sending packet: n": without an ACK, the sender never notices. U2 counts the weak packets (6 in my run). The link uses the larger of the two DISTANCE settings, so bringing the radios back needs a short distance on both.

Higher SF Reaches Further: SF 9 at 10 km

The hint on the panel says it: a higher SF reaches further. Leave 10 km and type SF 9 in the send box of BOTH Serial Monitors (one node alone would break the link). The panel of U1 shows SF9, and the verdict says OK again:

SX1278 Simple panel in Proteus at 10 km and SF9: AT 10 km: -128 dBm, SF9 NEEDS -130 dBm, OK
Figure: SF 9 on both nodes: at 10 km, -128 dBm is enough, because SF9 needs only -130 dBm.

On U4, the packets come back:

SX1278 receiver output in the TEP Serial Monitor Simple interface: SF 9 typed, Spreading factor SF9, then hello TEP 26 and 27 received at RSSI -128 dBm, SNR -11.25 dB
Figure: U4: SF 9, then packets at 10 km with -128 dBm and an SNR of -11.25 dB.
Received packet 'hello TEP 12' with RSSI -68 dBm, SNR 10.00 dB
Link (10 s): 3 received, RSSI -68 dBm avg, SNR 10.0 dB avg, 0 sent
Link (10 s): 0 received, 0 sent
Link (10 s): 0 received, 0 sent
SF 9
Spreading factor SF9 - set node 1 to the same SF
Received packet 'hello TEP 26' with RSSI -128 dBm, SNR -11.25 dB
Received packet 'hello TEP 27' with RSSI -128 dBm, SNR -11.25 dB

Packets 13 to 25 were sent while the link was too weak or the two nodes used different SFs, and never arrived. From 26 on, every packet arrives at -128 dBm with an SNR of -11.25 dB (the chip counts in steps of 0.25 dB): 11 dB below the noise, yet SF9 decodes down to -12.5 dB. The price: 144.4 ms on air instead of 41.2 ms. To go back, click 100 m and type SF 7 on both monitors.

Closing the Panel

Need room on the sheet? Click the red X. The board button says PANEL: CLOSED with a grey dot, while the radio and the sketch keep running. Click PANEL to bring it back.

SX1278 Simple Ra-02 board in Proteus with the control panel closed: PANEL: CLOSED, the red PWR LED lit and the copper spring antenna between packets
Figure: The panel closed: PANEL: CLOSED, PWR lit, the spring copper between packets.

SX1278 Advance: The Pop-Up Window

The Advance device keeps only the board on the schematic. At Run, the "TEP SX1278 Advance" pop-up opens with the look of our Serial Monitor and no Windows title bar: move it by its header, resize or minimise it, and reopen it with OPEN PANEL. The header shows the state (U2 · RX), the Radio and Test tabs and the theme, Settings and Help icons.

The Radio Page

SX1278 Advance Radio page in Proteus: RX SINGLE, 433.000 MHz, +17 dBm, sync word 0x12, SF7 BW 125 kHz CR 4/5, 31 packets received, At 100 m: -68 dBm, SF7 needs -125 dBm, OK (+56.4 dB), reach about 7.6 km
Figure: The Radio page: 31 packets received at -68 dBm, OK at 100 m (+56.4 dB), reach about 7.6 km.
  • RADIO - WHAT THE SKETCH SET: 433.000 MHz, +17 dBm, sync word 0x12 (private), 8 preamble symbols of 1.024 ms, SF7 / BW 125 kHz / CR 4/5, sensitivity -125 dBm, explicit header, CRC off, LDRO off, IQ normal.
  • TRAFFIC: 31 packets received and 1 sent (the 4-byte PONG, 31.0 ms on air), 6 too weak from my 10 km test; the last, "hello TEP 43", at -68 dBm and 10.0 dB.
  • DISTANCE: "At 100 m: -68 dBm, SF7 needs -125 dBm -> OK (+56.4 dB)" and my favourite line, "These settings reach about 7.6 km; SF12 would reach 19.7 km".

The Test Page: Four Measured LoRa Test Tools

Every number on the Test tab is measured on the running model, and each tool ends with a "Good for:" line.

1. Link Test: How Far Does Your Link Reach?

Choose 10, 20 or 50 packets and click Run test. The tool records the next real packets this radio sends or hears (decoded, CRC error, too weak or nobody heard it) with their RSSI, SNR and time on air. The DISTANCE buttons sit on the tool, so you can move the radios mid-test. 10 packets at 100 m:

SX1278 LoRa link test in Proteus: 10 of 10 packets decoded at -68 dBm and 10.0 dB SNR, 41.2 ms on air, and the link budget from 10 m to 20 km with the lowest SF that works
Figure: Link test at 100 m: 10 / 10 decoded, -68 dBm, 10.0 dB, 41.2 ms on air.

U2 decoded all 10 packets from U1 at -68 dBm and 10.0 dB, 41.2 ms each, every green bar above the dashed "SF7 needs -125 dBm" line; click 10 km during a test, and the bars turn red. Below, the link budget for every distance and the lowest SF that works there:

Link budget at SF7, BW 125 kHz, +17 dBm, 433 MHz (from the Link test)
DistanceRSSISNRAt your SF (SF7)Lowest SF, time on air
10 m-38 dBm10.0 dBOK +86 dBSF7, 41.2 ms
100 m-68 dBm10.0 dBOK +56 dBSF7, 41.2 ms
1 km-98 dBm10.0 dBOK +26 dBSF7, 41.2 ms
2 km-107 dBm9.8 dBOK +17 dBSF7, 41.2 ms
5 km-119 dBm-2.1 dBOK +5 dBSF7, 41.2 ms
10 km-128 dBm-11.1 dBTOO WEAK -4 dBSF9, 144.4 ms
15 km-133 dBm-16.4 dBTOO WEAK -9 dBSF11, 577.5 ms
20 km-137 dBm-20.2 dBTOO WEAK -13 dBnone (even SF12 is too weak)

From 5 km on, the SNR is negative, yet SF7 still decodes. 10 km needs SF9, 15 km SF11, and at 20 km even SF12 is too weak at +17 dBm. Good for: seeing how far your link reaches and how strongly each packet arrives.

2. Time on Air: How Long Is One Packet?

This tool does not use your sketch: two model radios in a private test air, which your design never hears, send one packet for every SF from 7 to 12 at 125, 250 and 500 kHz, with 12, 32, 64 or 255 bytes, and measure TX start to TxDone. 12 bytes:

SX1278 time on air test in Proteus: 12-byte packets measured from SF7 41.2 ms to SF12 991.2 ms at 125, 250 and 500 kHz, and the EU 433 MHz duty-cycle card
Figure: Time on air, 12 bytes: SF7 41.2 ms to SF12 991.2 ms, and the duty-cycle card for 433.000 MHz.
Measured time on air, 12 bytes, CR 4/5, CRC off, explicit header
SFBW 125 kHzBW 250 kHzBW 500 kHz
SF741.2 ms20.6 ms10.3 ms
SF872.2 ms36.1 ms18.0 ms
SF9144.4 ms72.2 ms36.1 ms
SF10288.8 ms144.4 ms72.2 ms
SF11577.5 ms (LDRO)247.8 ms123.9 ms
SF12991.2 ms (LDRO)495.6 ms (LDRO)247.8 ms

Your setting measured 41.22 ms, exactly Semtech's formula. Each SF step roughly doubles the time; each doubling of the bandwidth halves it.

The duty-cycle card warns: "just BELOW the EU 433.05-434.79 MHz band: use e.g. 433.92 MHz on real hardware (10 %, 10 mW)", and "SF7 / 125 kHz, 12 bytes: 41.2 ms on air -> wait at least 0.37 s between packets, at most 8734 packets per hour". Good for: choosing the SF and bandwidth for your message size and the legal duty cycle.

3. Range: Which SF Do You Need?

Run test sends one 12-byte packet per SF at each of the 8 DISTANCE steps between two model radios: green = decoded, red = too weak:

SX1278 range test in Proteus: one packet per spreading factor at 8 distances, green decoded and red too weak, link budget SF7 7.6 km to SF12 19.7 km
Figure: Range at +17 dBm: SF7 decodes up to 5 km, SF12 up to 15 km.
Range at BW 125 kHz, +17 dBm, 433 MHz (measured)
SFLink budgetDecoded up toToo weak from
SF77.6 km5 km10 km
SF89.2 km5 km10 km
SF911.1 km10 km15 km
SF1013.4 km10 km15 km
SF1116.3 km15 km20 km
SF1219.7 km15 km20 km

SF8's 9.2 km budget falls between the 5 and 10 km steps, so it ends where SF7 does. The second card compares our LoRa modules at full power: Ra-02 (+20 dBm) 9.5 to 24.8 km, RFM95W (868 MHz) 6.0 to 15.6 km, SX1262 (+22 dBm) 7.0 to 18.2 km. Good for: picking the spreading factor that reaches the distance you need.

4. Registers: What Did Your Sketch Write?

This tool reads the registers live, as an SPI read would, decodes them and lists the Arduino's last SPI accesses:

SX1278 registers read live in Proteus: RegOpMode 86 LoRa RX SINGLE, RegFrf 6C4000 433.000 MHz, RegPaConfig 8F PA_BOOST +17 dBm, the last SPI accesses and U1 as PARTNER (LISTENING)
Figure: Registers: what the receiver sketch wrote, its last SPI accesses, and U1 as PARTNER.
  • RegOpMode 86: LoRa, RX SINGLE. RegFrf 6C4000: 7,094,272 steps of about 61 Hz (32 MHz / 524,288) = 433.000 MHz.
  • RegPaConfig 8F: PA_BOOST, +17 dBm. RegModemConfig1 / 2 / 3 = 72 / 70 / 04: 125 kHz, CR 4/5, explicit; SF7, CRC off; LDRO off, AGC on.
  • RegPktRssi / Snr 60 28: 0x60 = 96, and 96 - 164 = -68 dBm; 0x28 = 40 x 0.25 = 10.0 dB (arduino-LoRa's formulas). RegRssiValue 2F: -117 dBm, the noise between packets.

Read the SPI log from the bottom up to watch parsePacket(): read and write RegModemConfig1, clear RegIrqFlags, read RegOpMode and RegIrqFlags, 9.8 us each, over and over: 46,614 SPI transactions per second. At the bottom, U1 is the PARTNER (LISTENING); a mismatch would be red. Good for: checking what your sketch really wrote into the radio.

Settings and Help

The gear opens Settings: theme (TEP Dark or Light), text size, open the panel at Run and window size, saved for your Windows user.

Settings page of the SX1278 Advance pop-up: theme TEP Dark or Light, text size, open the panel at Run and window size
Figure: Settings, saved under HKCU\Software\TheEngineeringProjects\TEP SX1278 Advance.

The ? icon opens Help & Support: eight cards and Copy diagnostics for a bug report. Report a bug and Suggest a feature open the SX1278 board of our forum, three cards open this article, and the others the donate page, our website and the forum; a links.ini next to the DLL can change the links.

Help and Support page of the SX1278 Advance: eight cards with their links to the SX1278 forum board, this article, the donate page, the website and the forum, and the Copy diagnostics button
Figure: Help & Support: every card shows its link; TEP SX1278 Advance v1.1, build 2026-10-06, TEPSX1278.DLL.

SX1278 LoRa Link with Arduino in Proteus

Open SX1278-ArduinoUnoV3.pdsprj from the Proteus Simulation folder, with the .hex files and the DLLs beside it. It has two Arduino UNOs from our Arduino Library for Proteus V3.0 (the first image shows the whole circuit):

  • NODE 1 - SENDER: UNO 1 (ARD1) with LoRa_Sender.hex, the SX1278 Simple (U1) and Serial Monitor U3.
  • NODE 2 - RECEIVER: UNO 2 (ARD2) with LoRa_Receiver.hex, the SX1278 Advance (U2) and Serial Monitor U4.

Wiring

Demo wiring (the same on both UNOs, as in the v1.0 demo)
FromToWhy
Ra-02 VCC / GNDSupply / groundPower (+5 V in the simulation; a real Ra-02 needs 3.3 V)
Ra-02 SCKArduino D13SPI clock
Ra-02 MISOArduino D12Data from the radio
Ra-02 MOSIArduino D11Data to the radio
Ra-02 NSSArduino D10Chip select
Ra-02 RSTArduino D9Reset
Ra-02 DIO0Arduino D2RxDone / TxDone interrupt (the demo sketches poll over SPI instead)
Serial Monitor RXD / TXD / GNDArduino D1 / D0 / groundShows what the Arduino prints, sends what you type

These are arduino-LoRa's default pins; D11, D12 and D13 are the UNO's hardware SPI pins (see our Introduction to Arduino UNO). To move NSS, RST or DIO0, call LoRa.setPins(ss, reset, dio0) before LoRa.begin(). No wire joins the two nodes: they share one simulated air.

The Arduino Code

Both sketches use the unmodified arduino-LoRa library by Sandeep Mistry (its object is LoRa). The settings live in variables, so the SF, BW and PWR commands can change them:

const long frequency = 433E6;
int spreadingFactor = 7, txPower = 17;
long bandwidth = 125E3;

LoRa.begin() resets the module over RST, checks RegVersion (0x12) and sets the frequency and +17 dBm; SF7, 125 kHz, CR 4/5 and sync word 0x12 are the chip's reset values. If the chip does not answer, the sketch stops:

  if (!LoRa.begin(frequency)) {
    Serial.println(F("LoRa module not responding - check the SPI wiring and power"));
    while (true) {}
  }

The sender keeps the v1.0 packet and output line. While AUTO is ON, it sends one every 2 s:

void sendHello() {                    // the v1.0 output line and packet
  Serial.print(F("Sending packet: "));
  Serial.println(counter);
  LoRa.beginPacket();
  LoRa.print("hello TEP ");
  LoRa.print(counter);
  LoRa.endPacket();
  counter++;
  ++sent; ++linkSent;
}
  if (autoSend && millis() - lastSend >= 2000) {
    lastSend = millis();
    sendHello();
  }

endPacket() waits until the chip reports TxDone, so the commands measure the time on air around it:

unsigned long transmit(const char* text) {
  LoRa.beginPacket();
  LoRa.print(text);
  unsigned long start = micros();
  LoRa.endPacket();
  unsigned long us = micros() - start;
  ++sent; ++linkSent;
  return us;
}

Both sketches read packets the same way. parsePacket() returns 0 while nothing has arrived and keeps the radio in RX single mode, so the sender listens between its own packets, too:

bool readPacket(char* text, byte size) {
  int packetSize = LoRa.parsePacket();
  if (!packetSize) return false;
  byte n = 0;
  while (LoRa.available()) {
    char c = (char)LoRa.read();
    if (n < size - 1) text[n++] = c;
  }
  text[n] = 0;
  lastRssi = LoRa.packetRssi();
  lastSnr = LoRa.packetSnr();

A PING is answered before anything is printed, so the round trip measures the radios, not the 9600-baud Serial port:

  bool ping = strcmp(text, "PING") == 0;
  if (ping) transmit("PONG");           // answer first (the round trip), print afterwards

Then the receiver prints the v1.0 line:

  Serial.print(F("Received packet '"));  // the v1.0 output line
  Serial.print(text);
  Serial.print(F("' with RSSI "));
  Serial.print(lastRssi);
  Serial.print(F(" dBm, SNR "));
  Serial.print(lastSnr);
  Serial.println(F(" dB"));

PING waits for the PONG for 500 ms plus three times its own time on air, so it still works at SF12:

  unsigned long start = micros();
  unsigned long air = transmit("PING");
  unsigned long waitMs = 500 + 3 * (air / 1000);   // the PONG takes about as long as the PING on air

The SF command checks its number and hands it to the library; BW and PWR use LoRa.setSignalBandwidth() and LoRa.setTxPower():

  } else if (strcmp(text, "SF") == 0) {
    int sf = atoi(arg);
    if (sf < 7 || sf > 12) { Serial.println(F("SF needs 7 - 12, e.g. SF 9")); return; }
    spreadingFactor = sf;
    LoRa.setSpreadingFactor(sf);

To change a sketch, install "LoRa" by Sandeep Mistry (or copy Arduino Code\libraries\LoRa into your sketchbook), export the compiled binary and load the new HEX file into its UNO; see How to get the HEX file from Arduino. New to Arduino? Start with our Arduino Tutorial for Beginners.

Serial Monitor Commands

Commands of the demo sketches (monitor quick buttons: PING, STATUS, SEND Hello from node 1 / 2, HELP)
CommandWhat it does
HELPThe command list
STATUSFrequency, SF, bandwidth, coding rate, sync word, power, counters and the last packet's RSSI / SNR
SEND <text>A message to the other node now (up to 42 characters)
PINGThe other node answers PONG; prints the round trip time
SF <7-12>For example SF 9: the spreading factor (type it on both monitors)
BW <kHz>7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250 or 500 (both monitors)
PWR <2-20>The transmit power in dBm
AUTO <ON|OFF>Node 1 only: the hello TEP packet every 2 s

How to Run the Demo

  1. Press Run. Both Serial Monitors (9600 baud) and the pop-up of U2 open.
  2. Type PING and STATUS on U3.
  3. Click 10 km on the panel of U1, then type SF 9 on both monitors. Back: 100 m and SF 7 on both.
  4. Close the panel of U1 with its red X, open it with PANEL.
  5. Run the four tools on the Test tab of U2.

SX1278 Proteus Simulation Results

The Serial Monitor in Its Simple Interface

Both monitors run in the Simple interface of our TEP Serial Monitor, as in every monitor screenshot here: only the log, the send box and one slim toolbar row (baud rate, follow, pause, search and clear) stay visible, so the window stays small next to your schematic.

  • Switch to it: right-click the log and choose Simple interface, or press Ctrl+Shift+U.
  • Back to the full view: click the corner button (the expand arrows at the top right), press Esc or Ctrl+Shift+U, or right-click and choose Full interface.
  • Your choice is remembered.

Type commands such as PING or SF 9 in the send box and press Enter; the quick buttons come back with the full view. RXD2, the monitor's second input, is not used: the Ra-02 talks SPI and has no serial line to watch. Read all about the monitor in TEP Serial Monitor Advance for Proteus.

Start-Up: hello TEP Arrives

After Run, both monitors print their banners, and U3 prints the v1.0 line "Sending packet: n" every 2 s. The first lines of U4 in my run:

SX1278 LoRa receiver output in the TEP Serial Monitor Simple interface: the Receiver Demo v1.1 banner and hello TEP 0 to 3 received with RSSI -68 dBm, SNR 10.00 dB
Figure: U4 after Run: the banner, then hello TEP 0 to 3 at -68 dBm, SNR 10.00 dB.
TEP SX1278 LoRa Receiver Demo v1.1
Listening: 433 MHz, SF7, 125 kHz, CR 4/5, sync 0x12
Type HELP in the Serial Monitor for the commands
Received packet 'hello TEP 0' with RSSI -68 dBm, SNR 10.00 dB
Received packet 'hello TEP 1' with RSSI -68 dBm, SNR 10.00 dB
Received packet 'hello TEP 2' with RSSI -68 dBm, SNR 10.00 dB
Received packet 'hello TEP 3' with RSSI -68 dBm, SNR 10.00 dB

Every packet arrives at -68 dBm and 10.00 dB, the 100 m numbers. Every 10 s, U4 adds a link line such as "Link (10 s): 5 received, RSSI -68 dBm avg, SNR 10.0 dB avg, 0 sent".

Typing Commands: PING, PONG and STATUS

Now U3, the sender. I typed PING, pressed Enter, then STATUS. Lines you send carry a blue TX tag, the Arduino's lines a green RX tag:

TEP Serial Monitor Simple interface in Proteus: PING typed, PING: PONG from node 2 after 63.6 ms at RSSI -68 dBm SNR 10.00 dB, and the STATUS lines of the SX1278 sender
Figure: U3: PING answered after 63.6 ms, and the STATUS lines.
Sending packet: 3
PING
PING: PONG from node 2 after 63.6 ms (RSSI -68 dBm, SNR 10.00 dB)
Sending packet: 4
STATUS
Status: 433.000 MHz, SF7, BW 125 kHz, CR 4/5, sync 0x12, +17 dBm
  sent 6, received 1, auto-send ON (every 2 s)
  last packet: RSSI -68 dBm, SNR 10.00 dB
Sending packet: 5

PONG came back after 63.6 ms: two 4-byte packets of 31.0 ms on air at SF7, plus a little time on both UNOs. STATUS prints the sketch's settings and counters: 6 sent (hello 0 to 4 plus the PING) and 1 received, the PONG. On U4, the PING arrives like any message:

SX1278 receiver output in the TEP Serial Monitor Simple interface: Received packet PING at RSSI -68 dBm and PONG sent back between the hello TEP packets
Figure: U4: the PING arrives, and node 2 answers with PONG.
Received packet 'hello TEP 3' with RSSI -68 dBm, SNR 10.00 dB
Received packet 'PING' with RSSI -68 dBm, SNR 10.00 dB
  -> PONG sent back
Received packet 'hello TEP 4' with RSSI -68 dBm, SNR 10.00 dB
Link (10 s): 6 received, RSSI -68 dBm avg, SNR 10.0 dB avg, 1 sent

Try the other direction, too: type SEND Hello on U4, and U3 prints it as "Received from node 2:" with its RSSI and SNR.

Troubleshooting

  • "LoRa module not responding - check the SPI wiring and power": check SCK D13, MISO D12, MOSI D11, NSS D10, RST D9 and VCC / GND, and TEPSX1278.DLL in MODELS and beside the project.
  • Nothing received, or "PING: no PONG": both radios need the same frequency, SF, bandwidth and sync word (the Registers tool lists what does not match), and the DISTANCE must suit the SF (watch the "-> TOO WEAK" line).
  • No monitor window or no pop-up: a DLL is missing; click OPEN MONITOR on the monitor part or OPEN PANEL on the board, or turn "Open the panel at Run" back on.
  • No red X / the old navy board: replace the LIB, delete TEPSX1278.IDX and re-pick the part.
  • Your own sketch: hardware SPI works in Proteus 8.5; only SoftwareSerial cannot receive there (no pin-change interrupts), which this demo does not need.

Things to Know Before Using a Real Ra-02

The demo sketches use only arduino-LoRa, so they run on two real UNOs and Ra-02 modules, too. Keep in mind:

  • 3.3 V only: feed VCC from 3.3 V, never from 5 V (in the simulation, VCC goes to +5 V, because the model only checks that it is powered). A 10 uF capacitor at VCC helps at +17 dBm.
  • Level shifting: the Ra-02's pins are NOT 5 V tolerant, so a 5 V UNO must not drive them directly. Use a level shifter (or a 3.3 V board) for SCK, MOSI, NSS and RST.
  • Antenna first: fit the antenna before you transmit; sending into a missing antenna can destroy the power amplifier.
  • Frequency: the demo's 433.000 MHz lies just below the EU 433.05 - 434.79 MHz band. Use e.g. 433.92 MHz on real hardware: change 433E6 to 433.92E6 in both sketches.
  • Power and duty cycle: use what your country allows. In that EU band: 10 % duty cycle and 10 mW e.r.p.; +17 dBm is 50 mW, so lower the power with PWR or LoRa.setTxPower().
  • One band: the Ra-02 is a 433 MHz module. For 868 / 915 MHz you need an RFM95W or another SX1276 module.

Limitations of the Simulation

  • Not modelled: the FSK / OOK modem, DIO1 to DIO5, frequency hopping, collisions (each packet is judged on its own), frequency error, fading and terrain, and the supply voltage. The RFO output counts 20 dB weaker, because the Ra-02 only connects PA_BOOST.
  • The range is a teaching model (exponent 3.0); real range depends on your antennas and surroundings.
  • The model is our own implementation, written from Semtech's SX1276/77/78/79 data sheet and AN1200.13; it contains no arduino-LoRa code.
  • Tested in Proteus 8.5 SP0 on 6 and 7 Oct 2026 (the demo, PING, 10 km and SF 9, the four tools and every Proteus screenshot here) and with 1,293 automatic PC checks of the SX1278 and RFM95W side, all passed, 48 of them with the unmodified arduino-LoRa 0.8.0 and 56 with the real v1.1 sketches. The "PC render" was drawn by the model's own code. Proteus 7 is not supported.

For 868 / 915 MHz, see our RFM95W LoRa Library for Proteus, and for the newer SX1262, our SX1262 LoRa Library for Proteus. For other radios, try our CC1101 Library for Proteus, RFM69HCW Library for Proteus, HC-12 Library for Proteus or nRF24L01 Library for Proteus.

So, that was all about the SX1278 LoRa Library for Proteus V1.1. I hope the DISTANCE buttons, the glowing spring, the four test tools and the SF 9 experiment at 10 km make LoRa much easier to understand, so your long-range project works the first time you wire two real Ra-02 modules. If you use the SX1278 LoRa Library for Proteus in a project, please share your feedback in the comments or in our forum, and if you have any questions, ask in the comments and I will help you out. Till the next tutorial, take care and have fun!


Comments

0

Join the conversation