Roni Bandini β Buenos Aires, Argentina β November 2025
LoRa RYLR999 is a small collection of examples for experimenting with long-range communication using REYAX RYLR999 LoRa + BLE modules.
The repository contains three examples:
- π€ ESP32-C6 sender β sends
Hola mundoevery five seconds. - π₯ ESP32-C6 receiver β receives LoRa packets and can turn its onboard LED on or off from remote messages.
- π₯οΈ UNIHIKER M10 receiver β receives packets and displays timestamp, sender address and message on its screen.
The examples communicate with the RYLR999 through its LoRa UART using simple AT commands.
- π‘ REYAX RYLR999 LoRa communication
- π°οΈ Addressed point-to-point messages
- π§© Simple UART + AT-command interface
- βΎοΈ ESP32-C6 Arduino examples
- π Python receiver for UNIHIKER M10
- π₯οΈ Incoming messages displayed on UNIHIKER
- π Timestamped messages
- π·οΈ Sender-address extraction
- π‘ Remote LED
on/offexample - πΆ RSSI and SNR available in received packets
- π΅ / π’ NeoPixel status feedback on UNIHIKER
- π‘ RYLR999 BLE functionality available for further expansion
flowchart LR
ESP1["ESP32-C6<br/>Address 1"]
TX["RYLR999<br/>Sender"]
LORA["π‘ LoRa"]
RX["RYLR999<br/>Address 7"]
ESP2["ESP32-C6<br/>Receiver"]
UNI["UNIHIKER M10<br/>Receiver"]
LED["π‘ LED"]
GUI["π₯οΈ GUI"]
ESP1 -->|"UART / AT+SEND"| TX
TX --> LORA
LORA --> RX
RX -->|"UART"| ESP2
RX -->|"UART"| UNI
ESP2 --> LED
UNI --> GUI
The examples use:
Sender address: 1
Receiver address: 7
Network ID: 18
The RYLR999 combines two independent wireless systems:
868 / 915 MHz LoRa
+
2.4 GHz Bluetooth Low Energy
Each is exposed through a separate UART.
Official specifications include:
| Feature | Specification |
|---|---|
| LoRa frequency range | 820β960 MHz |
| Typical LoRa bands | 868 / 915 MHz |
| Maximum LoRa RF output | 30 dBm |
| LoRa sensitivity | down to -133 dBm |
| BLE RF output | up to 20 dBm |
| LoRa maximum payload | 240 bytes |
| UART default | 115200 8N1 |
| Supply | 4.75β5.25 V |
| Digital I/O | 3.3 V |
| Dimensions | 25 Γ 22 Γ 3 mm |
Official resources:
π RYLR999 Product Page
π RYLR999 Datasheet
π RYLR999 AT Command Manual
The module does not require an Arduino LoRa library.
Communication is handled through text commands terminated with:
\r\n
Typical setup:
AT+ADDRESS=1
AT+NETWORKID=18
The receiver uses:
AT+ADDRESS=7
AT+NETWORKID=18
Modules must share compatible:
NETWORKID- RF frequency
- spreading factor
- bandwidth
- coding rate
- preamble settings
REYAX recommends configuring the address and network before transmitting.
RYLR999 uses:
AT+SEND=<Address>,<Length>,<Data>
Example:
AT+SEND=7,10,Hola mundo
The sender sketch builds the command dynamically:
String mensaje = "Hola mundo";
int largo = mensaje.length();
String comando =
"AT+SEND=7," +
String(largo) +
"," +
mensaje;
sendATCommand(comando);Main firmware:
π sender.ino
The message is transmitted every:
5000milliseconds.
After each transmission the FireBeetle onboard LED on:
int led = 15;blinks for 200 ms.
RYLR999 automatically reports incoming messages as:
+RCV=<Address>,<Length>,<Data>,<RSSI>,<SNR>
For example:
+RCV=1,10,Hola mundo,-91,12
where:
| Field | Meaning |
|---|---|
1 |
Sender address |
10 |
Payload length |
Hola mundo |
Data |
-91 |
RSSI |
12 |
SNR |
The official AT-command manual specifies this same response format.
The sender uses a DFRobot FireBeetle 2 ESP32-C6.
UART:
HardwareSerial LoRaSerial(2);
LoRaSerial.begin(
57600,
SERIAL_8N1,
4,
5
);Meaning:
ESP32 GPIO4 β RX
ESP32 GPIO5 β TX
Connect crosswise:
| RYLR999 LoRa UART | FireBeetle |
|---|---|
| RX | GPIO 5 / TX |
| TX | GPIO 4 / RX |
| GND | GND |
The sketch configures:
sendATCommand("AT+ADDRESS=1");
sendATCommand("AT+NETWORKID=18");and then sends to:
Address 7
every five seconds.
Receiver firmware:
π receiver.ino
It uses the same UART pins:
LoRaSerial.begin(
57600,
SERIAL_8N1,
4,
5
);but configures the module as:
AT+ADDRESS=7
AT+NETWORKID=18The program waits for asynchronous:
+RCV=
messages.
The ESP32 receiver extracts the data field from:
+RCV=<sender>,<length>,<data>,<RSSI>,<SNR>
using:
if (msg.startsWith("+RCV=")) {
int dataStart =
msg.indexOf(',') + 1;
dataStart =
msg.indexOf(',', dataStart) + 1;
int dataEnd =
msg.indexOf(',', dataStart);
if (dataEnd > 0) {
data =
msg.substring(
dataStart,
dataEnd
);
}
}So:
+RCV=1,2,on,-87,10
becomes:
on
The receiver also demonstrates a simple remote-control application.
If the payload contains:
on
the FireBeetle onboard LED is enabled:
if (data.indexOf("on") >= 0) {
digitalWrite(led, HIGH);
}For:
off
it is disabled:
else if (
data.indexOf("off") >= 0
) {
digitalWrite(led, LOW);
}To test this functionality, change the sender payload from:
String mensaje = "Hola mundo";to:
String mensaje = "on";or:
String mensaje = "off";The third example replaces the receiving ESP32 with a UNIHIKER M10.
Python application:
π lorareceiver.py
Initialization:
Board("UNIHIKER").begin()
gui = GUI()
uart = UART(bus_num=0)
uart.init(
baud_rate=115200,
bits=8,
parity=0,
stop=1
)Unlike the ESP32 sketches, this version communicates at the RYLR999's factory-default:
115200 baud
UNIHIKER hardware UART 1 uses:
P0 β RX
P3 β TX
Therefore:
| RYLR999 LoRa UART | UNIHIKER |
|---|---|
| TX | P0 / RX |
| RX | P3 / TX |
| GND | GND |
Official reference:
π UNIHIKER UART / PinPong Documentation
The current RYLR999 datasheet specifies 4.75β5.25 V for VDD, while its UART digital I/O operates at 3.3 V logic levels.
Use the current REYAX datasheet as the reference for module power.
At startup, the UNIHIKER displays:
LORA Receiver
Roni Bandini
and configures:
send_at("AT+ADDRESS=7")
send_at("AT+NETWORKID=18")When a packet arrives, Python separates its fields:
parts = msg.split(',')
sender = parts[0].split('=')[1]
data = parts[2]A timestamp is generated with:
timestamp = datetime.now().strftime(
"%H:%M:%S"
)and displayed as:
14:32:18 (1) Hola mundo
This makes the UNIHIKER version useful as a simple LoRa message monitor.
The application uses three external NeoPixels:
np1 = NeoPixel(
Pin(Pin.P13),
3
)At startup they briefly turn blue:
np1.range_color(
0,
2,
0x0000FF
)When a valid +RCV message arrives they turn green:
np1.range_color(
0,
2,
0x00FF00
)and switch off again after two seconds.
sequenceDiagram
participant E as ESP32 Sender
participant T as RYLR999 #1
participant R as RYLR999 #7
participant U as Receiver
E->>T: AT+SEND=7,10,Hola mundo
T-->>E: +OK
T->>R: LoRa packet
R->>U: +RCV=1,10,Hola mundo,RSSI,SNR
U->>U: Parse sender + payload
U->>U: Display message
This repository contains two UART configurations:
57600 baud
115200 baud
The RYLR999 factory default is 115200 baud.
To use the ESP32 sketches exactly as provided, configure each module once:
AT+IPR=57600
The setting is stored in module flash.
Alternatively, change:
LoRaSerial.begin(
57600,
SERIAL_8N1,
4,
5
);to:
LoRaSerial.begin(
115200,
SERIAL_8N1,
4,
5
);to use factory-default modules.
The example sketches explicitly configure only:
ADDRESS
NETWORKID
RYLR999 also supports:
AT+BAND
AT+PARAMETER
AT+CRFOP
AT+CPIN
Factory defaults include:
Band: 915 MHz
Spreading Factor: 9
Bandwidth: 125 kHz
Coding Rate: 1
Preamble: 12
Network ID: 18
RF power: 30 dBm
UART: 115200
Both communicating modules need compatible RF parameters.
Example:
AT+BAND=915000000
AT+PARAMETER=9,7,1,12
The RYLR999 also supports 868 MHz configurations through AT+BAND.
The module supports:
AT+CPIN=<password>
with an eight-character hexadecimal password.
For example:
AT+CPIN=EEDCAA90
Modules using the same password can recognize each other's data.
This feature is not used in the repository examples.
RYLR999 contains a second independent UART for Bluetooth Low Energy.
REYAX documents a hardware configuration in which the BLE and LoRa UARTs are interconnected, allowing a phone or BLE device to pass commands/data into the LoRa link.
Conceptually:
flowchart LR
PHONE["π± Smartphone"]
BLE["BLE<br/>RYLR999 #1"]
LORA1["LoRa<br/>RYLR999 #1"]
AIR["π‘ Long Range"]
LORA2["RYLR999 #2"]
MCU["MCU / Computer"]
PHONE --> BLE
BLE --> LORA1
LORA1 --> AIR
AIR --> LORA2
LORA2 --> MCU
Official application note:
π RYLR999 BLE-to-LoRa Converter Application
For the examples in this repository:
| Component | Quantity |
|---|---|
| REYAX RYLR999 | 2 |
| DFRobot FireBeetle 2 ESP32-C6 | 1β2 |
| UNIHIKER M10 | Optional |
| LoRa antennas | 2 |
| Jumper wires | Several |
| USB cables / suitable power | As required |
You can test:
ESP32 β ESP32
or:
ESP32 β UNIHIKER
with the same RYLR999 radio modules.
π Arduino IDE
Follow the FireBeetle guide:
π FireBeetle 2 ESP32-C6 Getting Started
git clone \
https://github.com/ronibandini/LORARYLR999.git
cd LORARYLR999Repository:
π github.com/ronibandini/LORARYLR999
Open:
π sender.ino
Open:
π receiver.ino
Both use Serial Monitor at:
115200 baud
Copy:
π lorareceiver.py
to the UNIHIKER and run:
python3 lorareceiver.pyThe program uses the standard:
unihikerpinpong
libraries supplied with the UNIHIKER environment.
Official documentation:
π UNIHIKER M10 Documentation
π PinPong UART API
LORARYLR999/
β
βββ sender.ino
βββ receiver.ino
βββ lorareceiver.py
βββ README.md
βββ LICENSE
- π€
sender.inoβ ESP32 LoRa transmitter - π₯
receiver.inoβ ESP32 LoRa receiver + LED example - π₯οΈ
lorareceiver.pyβ UNIHIKER graphical receiver - βοΈ
LICENSEβ MIT License
Official product information:
π REYAX RYLR999
Datasheet:
π RYLR999 Datasheet
AT commands:
BLE-to-LoRa:
π RYLR999 BLE-to-LoRa Application Note
π FireBeetle 2 ESP32-C6 Wiki
π FireBeetle 2 ESP32-C6 Product Page
π UNIHIKER M10 Documentation
π UNIHIKER UART Documentation
Indoor pet-location prototype using FireBeetle ESP32 and BLE beacons.
π github.com/ronibandini/bleIndoorLocation
Human-presence detector using ESP32 and mmWave radar with remote notifications.
π github.com/ronibandini/mmWaveAlarm
UNIHIKER + ESP32-C6 project for displaying mmWave heart and respiration data.
π github.com/ronibandini/heartRespirationMonitor
Physical UNIHIKER interface for n8n workflows.
π github.com/ronibandini/n8nTerminal
Contracultura Maker is a book by Roni Bandini about maker culture, experimental electronics, AI, physical computing and technological autonomy.
π Contracultura Maker β GitHub repository
π Download Contracultura Maker PDF
Roni Bandini Maker Β· AI Developer Β· Writer Buenos Aires, Argentina
- π GitHub β @ronibandini
- π Medium β @ronibandini
- π X / Twitter β @RoniBandini
- πΈ Instagram β @ronibandini
βΆοΈ YouTube β @RoniBandini- πΌ LinkedIn β Roni Bandini
Built with π‘ + LoRa + ESP32-C6 + UNIHIKER.