LoRa Protocol
The charger acts as a MQTT ↔ LoRa bridge. It translates all MQTT JSON commands into binary LoRa packets and vice versa.
Hardware
| Property |
Value |
| Module |
EBYTE E32/E22 series |
| Frequency |
433 MHz |
| UART |
UART1 (TX=GPIO17, RX=GPIO18) |
| Mode pins |
M0=GPIO12, M1=GPIO46 |
Operating Modes
| M0 |
M1 |
Mode |
| 0 |
0 |
Normal/transparent (data) |
| 1 |
1 |
Configuration (AT-commands) |
┌──────┬──────┬──────┬──────┬───────┬─────────────┬──────────┬──────┬──────┐
│ 0x02 │ 0x02 │ ADDR │ ADDR │ LEN+1 │ PAYLOAD... │ XOR CSUM │ 0x03 │ 0x03 │
│ Start│ Start│ High │ Low │ │ │ │ End │ End │
└──────┴──────┴──────┴──────┴───────┴─────────────┴──────────┴──────┴──────┘
| Offset |
Size |
Value |
Description |
| 0-1 |
2 |
0x02, 0x02 |
Start bytes |
| 2-3 |
2 |
Address |
0x00, 0x03 (TX to mower) / 0x00, 0x01 (RX from mower) |
| 4 |
1 |
len+1 |
Payload length + 1 |
| 5..5+n |
n |
varies |
Payload (command byte + data) |
| 5+n |
1 |
XOR |
XOR checksum over all payload bytes |
| 6+n, 7+n |
2 |
0x03, 0x03 |
End bytes |
Addresses
| Address |
Device |
0x00, 0x03 |
Charger (sender) |
0x00, 0x01 |
Mower (receiver) |
Command Categories
The first byte of the payload identifies the command category:
| Byte |
Category |
Description |
0x30 ('0') |
CHARGER |
Charger hardware (Hall sensor ACK, IRQ ACK) |
0x31 ('1') |
RTK_RELAY |
RTK GPS NMEA data relay to mower |
0x32 ('2') |
CONFIG |
Configuration commands |
0x33 ('3') |
GPS |
GPS position data (lat/lon/alt, 16 bytes) |
0x34 ('4') |
REPORT |
Status reports (heartbeat poll + mower data) |
0x35 ('5') |
ORDER |
Mowing commands (start/pause/stop/go_pile) |
0x36 ('6') |
SCAN_CHANNEL |
LoRa channel scan |
See LoRa Packets for detailed packet structures.
See LoRa Command Mapping for MQTT ↔ LoRa translation table.
Communication Flow
sequenceDiagram
participant App
participant Charger as Charger (MQTT + LoRa)
participant Mower as Mower (LoRa)
Note over Charger,Mower: Heartbeat (every ~1.5s)
Charger->>Mower: LoRa [0x34, 0x01] (poll)
Mower-->>Charger: LoRa [0x34, 0x02, status...] (19 bytes)
Charger->>App: MQTT: up_status_info (includes mower data)
Note over App,Mower: Command relay
App->>Charger: MQTT: start_run
Charger->>Charger: Translate to LoRa
Charger->>Mower: LoRa [0x35, 0x01, mapName, area, height]
Note over Charger: Wait max 3s for ACK
Mower-->>Charger: LoRa ACK
Charger->>App: MQTT: start_run_respond
Note over Charger,Mower: RTK GPS relay
Charger->>Charger: UM960 GNGGA NMEA
Charger->>Mower: LoRa [0x31, NMEA_data...]
Note over Mower: cm-accurate positioning
Query: [0xC0, 0xC1, 0xC2, 0xC3, 0x00, 0x01]
Response: [0xC1, 0x00, 0x01, <RSSI byte>]
- RSSI < 146 (0x92) = good signal
- Channel scan: tries all channels from
lc to hc, sorts by RSSI (bubble sort), picks best