This guide provides a fully working, no-extra-documentation-needed solution to integrate:
LD30-S1R → Companion Computer (Raspberry Pi / Jetson / Android) → MAVLink → Pixhawk
It includes wiring diagrams, data parsing flow, ready-to-run Python code, Pixhawk parameter setup, and ground control station verification.
Follow this guide step-by-step and the system will work immediately.
1. Wiring Connections (LD30 ↔ Companion Computer ↔ Flight Controller)
1.1 LD30-S1R ↔ Companion Computer (UART)
Companion computers pode be:
Raspberry Pi / Jetson Nano / Industrial PC / Android device with USB–UART
| LD30-S1R | Companion Computer (UART) |
|---|
| VCC (3.3–4.0V) | 3.3V or external regulator |
| GND | GND |
| TXD (open-drain) | RX |
| RXD | TX |
| PWREN | Pull HIGH (3.3V) or GPIO |
| nRST | Not connected |
Note: LD30 uses 3.3V TTL UART. Do not connect to 5V TTL UART.
TX is open-drain; internal pull-ups on Raspberry Pi and Jetson work fine.
1.2 Companion Computer ↔ Pixhawk (MAVLink UART)
Utilização TELEM1 / TELEM2 port.
| Companion Computer | Pixhawk (TELEM Port) |
|---|
| TX | RX |
| RX | TX |
| GND | GND |
- Baud rate: 115200
- Protocol: MAVLink2
2. Reading LD30-S1R Data on the Companion Computer
LD30 communicates using a binary command protocol.
The companion computer handles:
- Open UART port
- Send “continuous measurement” command
- Parse frames beginning with 0xAA
- Extract distance (mm)
- Convert to meters
- Pack into MAVLink DISTANCE_SENSOR
- Send to Pixhawk
2.1 Continuous Measurement Command
From LD30 User Manual (section 14.12):
AA 00 00 20 00 01 00 04 25
2.2 Data Frame Format
Returned data includes:
- Distance: 4 bytes (mm)
- Signal quality: 2 bytes
- Frame header: 0xAA
3. Complete Python Script (Ready to Run)
This script:
✔ Reads LD30
✔ Parses distance
✔ Converts mm → m
✔ Sends MAVLink DISTANCE_SENSOR
✔ Streams data to Pixhawk in real time
Save as ld30_to_mavlink.py
Run with:
python3 ld30_to_mavlink.py
import serial
from pymavlink import mavutil
import struct
# --- LD30 Serial Port ---
ld30 = serial.Serial('/dev/ttyUSB0', 115200, timeout=0.1)
# Continuous measurement command (from manual 14.12)
CONT_MEASURE = bytes([0xAA,0x00,0x00,0x20,0x00,0x01,0x00,0x04,0x25])
ld30.write(CONT_MEASURE)
# --- MAVLink connection to Pixhawk ---
mav = mavutil.mavlink_connection('/dev/ttyAMA0', baud=115200)
def send_distance_to_fc(distance_m):
mav.mav.distance_sensor_send(
0, # time_boot_ms
3, # min_distance (cm)
3000, # max_distance (cm)
int(distance_m * 100), # current distance (cm)
0, # type
0, # id
0, # orientation
0 # covariance
)
buffer = bytearray()
while True:
data = ld30.read()
if not data:
continue
buffer += data
# Minimum frame length = 12 bytes
if len(buffer) >= 12:
# Look for header 0xAA
if buffer[0] != 0xAA:
buffer.pop(0)
continue
# Parse fixed-length frame
if len(buffer) >= 12:
# Distance is bytes 6~9 (big-endian)
dist_bytes = buffer[6:10]
distance_mm = struct.unpack(">I", dist_bytes)[0]
distance_m = distance_mm / 1000.0
print("LD30 Distance:", distance_m, "m")
send_distance_to_fc(distance_m)
buffer = bytearray() # Clear buffer
4. Pixhawk Parameter Configuration (Mission Planner)
Go to:
Config → Full Parameter List
Set the following:
| Parâmetro | Valor |
|---|
| RNGFND1_TYPE | 10 (MAVLink) |
| RNGFND1_MIN_CM | 3 |
| RNGFND1_MAX_CM | 3000 |
| RNGFND1_ORIENT | 0 (Forward) or 25 (Downward) |
| RNGFND1_RMETRIC | 1 |
| SERIAL1_PROTOCOL | 2 (MAVLink2) |
| SERIAL1_BAUD | 115 |
If using TELEM2, use SERIAL2_*
If using TELEM3, use SERIAL3_*
5. Monitoring LD30 Data in Mission Planner / QGroundControl
5.1 Mission Planner
Navigate to:
Flight Data → Status → sonar_range / rngfnd1_dist
or:
Ctrl + F → MAVLink Inspector → DISTANCE_SENSOR
You will see:
- Real-time distance
- Update frequency
- MAVLink stream ID
5.2 QGroundControl
Navigate:
Widgets → Analyze Tools → MAVLink Inspector → DISTANCE_SENSOR
6. Overall System Workflow
LD30-S1R
│
TTL UART 3.3V
│
┌────Companion Computer────┐
│ LD30 parsing logic │
│ MAVLink packaging │
└─────────┬──────────┘
MAVLink UART
│
Pixhawk Flight Controller
│
Mission Planner / QGroundControl