To integrate an ERDILRF laser rangefinder module with ArduPilot, PX4, ROS 2 or Arduino, first identify which of two UART protocol families your model uses, wire TX to RX with a common ground at the right logic level, then use the open-source MIT-licensed driver repository. It has Python, Arduino and ROS 2 code, but no PX4 or ArduPilot driver.
This page is for developers and integrators. It describes what the public repository really contains, the protocol facts we publish for each family, wiring rules and the places where a manual leaves a question open. Where a manual is unclear we say so and point you to the datasheet, because a wrong baud rate or unit is a ten-fold error, not a rounding error. Related hubs: UAV gimbal laser rangefinder modules, laser rangefinder modules, model directory.
What the open-source repository contains
The repository is erdi-lrf-drivers on GitHub. We read it at commit 2175cd6 (“README: link Zenodo software archive DOI for v0.1.0”). Its licence is MIT, copyright ERDI Technology (Chengdu). The tree contains:
- Python package (
python/erdi_lrf):protocol_a.pyandprotocol_b.pycodecs as pure functions with no serial dependency, adevice.pyserial transport, amodels.pyper-model table,errors.py, and anerdi-lrfcommand-line tool (models,info,measure,stream). Tests are inpython/tests. - Arduino library (
arduino/ErdiLRF):ErdiLRF.h,ErdiLRF.cppand two examples,BasicMeasureandContinuousStream. The README says the library is also maintained in a standalone repository,yu911517778-a11y/ErdiLRF, for the Arduino Library Manager and the PlatformIO Registry. - ROS 2 package (
ros2/erdi_lrf_ros2): arange_node.pynode, a launch fileerdi_lrf.launch.py,package.xmlandsetup.py. - Protocol documents (
docs):protocol-A-55AA.md,protocol-B-5C.mdandmodels.md, each row quoting the manual sentence it came from. - Metadata:
README.md,LICENSEandCITATION.cff.
The README states that the drivers cover 22 models with a published protocol, in two families. It also lists limits plainly: the codecs are verified against frames printed in the manuals and against a scripted fake serial port, not against live hardware in that repository, and the ROS 2 package has been statically checked but not run in a ROS 2 environment there. Treat it as a well-documented starting point and bench-test it with your own module. There is no ArduPilot or PX4 driver in the repository, and no official flight-stack package; that integration path is described below.
Protocol family A: 8-byte 55 AA command and response
Family A covers the LR-series E2/E4 modules, LRF1200A1, LRF3000A1 and the SPD1200N0/N2/N4 modules. Facts below come from the KB product records for LRF3000A1 and LR1000E2 and from the repository’s docs/protocol-A-55AA.md.
- Frame header
55 AA, frame length 8 bytes, 8 data bits, default 115200 bps (LRF3000A1 also lists 9600 bps). - Layout:
55 AA Function D1 D2 D3 D4 Checksum. - Single-shot ranging request:
55 AA 88 FF FF FF FF 84. Continuous ranging, stop and angle requests are listed in the LRF3000A1 record as55 AA 89 FF FF FF FF 85,55 AA 8E FF FF FF FF 8Aand55 AA 8A FF FF FF FF 86. - Reply to single-shot:
55 AA 88 STA FF DIS_H DIS_L SUM.STA = 1means the measurement succeeded. - Scale: results are output as the real value × 10, so reported value = measured × 10, one count is 0.1 m for the models in the repository table (the LRF1200A1 manual does not state the base unit, so see its datasheet before decoding to metres). The distance is
DIS_H << 8 | DIS_L. - Checksums differ by direction: the manual says the verification content for sending and receiving may differ. The repository documents the transmit sum as the low 8 bits of Function + D1 to D4, and the reply sum as the low 8 bits of
0x55 + 0xAAplus the same bytes. Using the transmit rule on replies is the most common first-integration bug.
TX 55 AA 88 FF FF FF FF 84 single-shot request (source: LRF3000A1 KB record, LR1000E2 manual row)
RX 55 AA 88 STA FF DIS_H DIS_L SUM
distance_m = ((DIS_H << 8) | DIS_L) / 10
The Python snippet below is from the repository README:
from erdi_lrf import ErdiLRF
with ErdiLRF("/dev/ttyUSB0", model="LRF3000A1") as lrf:
m = lrf.measure()
print(f"{m.metres:.1f} m")
Protocol family B: free-running 5C frames
Family B covers the H-series (LRF50H, LRF100H, LRF200H, LRF300H, LRF600H, LRF1500H) and the VB series (LRF22VB, LRF50VB). From the repository’s docs/protocol-B-5C.md and the LRF50H, LRF300H and LRF1500H records:
- Data frame:
5C dist_lo dist_hi check, little-endian. LRF1500H is the one model with a five-byte frame and a three-byte distance. - Default baud 460800 (adjustable), 8 data bits, 1 stop bit, no parity.
- Checksum: start at the second byte, end at the second-last, sum and invert. Example frame
5C 02 11 EC:~(0x02 + 0x11) = 0xEC. - Units are per model, not per family. In the H-series manuals the example
5C 02 11 ECis 4354 cm, which is 43.54 m. In the VB-series manuals the same bytes are 4354 mm, which is 4.354 m. Select the model by name and never infer the unit from the family. - Configuration uses a separate
5Acommand frame; for example the LRF50H record gives read serial number as5A 0D 02 0D 0D D6.
Family B modules stream once powered, so there is no request to send for a reading. The repository’s stream() call reads them continuously.
Wiring: TX/RX, ground, logic level and baud
- Cross TX and RX. Module TX goes to host RX, and module RX goes to host TX. The H-series manuals label the pins from the host’s point of view (their “TX” wire is the host’s RX), so follow the pin table of your exact model.
- Join the grounds. Power ground and signal ground must meet at the host. The H-series pin tables list a separate port ground wire.
- Check the logic level separately from the supply. Supply range does not tell you the UART level. What the KB records show:
- LRF3000A1: UART TTL 3.3 V, stated in its manual pin table (TTL_TXD and TTL_RXD at 3.3 V level), supply DC 3.3–5 V.
- LR1000E2: 3.3 V TXD/RXD level, from an ERDI confirmation that is not printed in the manual; supply 3.3–5 V. Confirm in writing before relying on it.
- LR1200E2, LR2000E2, SPD1200N0, LRF50H, LRF200H, LRF600H, LRF300H and LRF1500H: the manual does not state the signal level. The H-series supply is 9–36 V DC, which says nothing about the TX/RX level. Ask us for written confirmation and use a level shifter or a scope until you have it.
- LRF1200A1: the record lists UART TTL 3.3 V, but the supply is one of the fields where the manual holds two values. See datasheet before you decide on a 5 V supply.
- Set the baud. Family A defaults to 115200 and family B to 460800 per the manuals. An AVR SoftwareSerial cannot reach 460800, so use a hardware UART or lower the module rate with the documented command.
- Check the enable pin. LRF3000A1 lists an enable pin that powers the module on at low level. Pin order and enable polarity differ by model and by connector viewing direction; read the pin table in the manual for your unit and verify the harness before applying power. Wire colours are only documented for some models. See pinout and wire colours and the UART/TTL integration guide.
ArduPilot
The repository contains no ArduPilot driver, and ArduPilot does not list an ERDI protocol natively at the time of the existing guide. The guide Connect a UART Laser Rangefinder to Pixhawk/ArduPilot describes two custom routes: a companion board that decodes the frame and sends a MAVLink distance message (RNGFND1_TYPE = 10), or a Lua scripting driver on the flight controller (RNGFND1_TYPE = 36), where the installed firmware supports them. See the ArduPilot rangefinder documentation and parameter list for your firmware. Either route needs a decoder for the exact model, bench validation and a plan for stale or invalid readings. It is not a tested flight setup.
PX4
There is no PX4 driver in the repository. PX4 lists the rangefinders it supports on its rangefinder page; check it for your release. The integration path we can describe is the same as for ArduPilot: read the module on a companion computer or microcontroller with the documented frame, and publish a MAVLink DISTANCE_SENSOR message to the flight controller. Validate units, minimum and maximum distance fields, and the behaviour when the module reports out of range.
ROS 2
The repository does include a ROS 2 package, erdi_lrf_ros2, with a node named range_node that publishes sensor_msgs/Range on range. It uses the Python package as its driver. The README gives these commands:
cp -r ros2/erdi_lrf_ros2 ~/ros2_ws/src/
cd ~/ros2_ws && colcon build --packages-select erdi_lrf_ros2
source install/setup.bash
ros2 run erdi_lrf_ros2 range_node --ros-args \
-p port:=/dev/ttyUSB0 -p model:=LRF3000A1 -p rate:=10.0 -p frame_id:=lrf_link
Parameters: port, model, baud (0 means the model default), rate, frame_id, field_of_view, continuous and acknowledge_protocol_hold. min_range and max_range come from the model’s ranging-range row, and field_of_view defaults to 0.0 because the protocol manuals carry no beam divergence; set it from your datasheet. The README states the package has not been run in a ROS 2 environment there, so run it against your module before you depend on it. See the ROS documentation for sensor_msgs/Range.
Arduino
The ErdiLRF library works with any Arduino Stream, hardware or software serial. From the repository README:
#include <ErdiLRF.h>
ErdiLRF lrf(Serial1, ERDI_LRF3000A1);
void setup() {
Serial.begin(115200);
Serial1.begin(erdiDefaultBaud(ERDI_LRF3000A1));
}
void loop() {
ErdiMeasurement m;
if (lrf.measure(&m) == ERDI_OK) Serial.println(m.metres, 3);
delay(500);
}
For a step-by-step walkthrough read Read a laser distance module with Arduino over UART. A 3.3 V board is the safe match for modules with a 3.3 V UART level; a 5 V board needs a level shifter on the module RX line unless the manual says otherwise.
I²C
Most modules here are UART first. The repository’s protocol document lists an I²C register map and default address 0x52 for the VB series, and an address for LRF200H, while several H models publish no address. The repository drivers implement the UART path only. See which modules support I²C.
Where the manuals disagree: check the manual
The knowledge base keeps a conflicts register and the drivers refuse to guess. Items you should check against the manual and with us before design-in:
- LRF1200A1 and LRF3000A1: send and receive verification content may differ, and continuous ranging is under a protocol hold because the request and reply function bytes differ in the manual. Single-shot ranging is not affected. The repository requires an explicit acknowledgement before streaming on these two models.
- LRF1500H: the printed example frame does not match its own checksum formula, and the out-of-range value is stated in two ways.
- LRF50VB: the printed checksum of the serial-number request does not verify against the manual’s function.
- SPD1200N2: the lower bound of the measurement frequency has two values in the manual.
Read the delivered unit’s manual for these items and use serial protocol, frames and checksums to debug a silent port. For other fields, see how to read the datasheet fields.
How to cite
Two records are archived on Zenodo: the technical note Reading 905 nm UART Laser Rangefinder Modules: Two Frame Families, Per-Model Units, and Manual Inconsistencies, DOI 10.5281/zenodo.23297197, and the software archive of release v0.1.0, DOI 10.5281/zenodo.23297253. The repository’s CITATION.cff names ERDI Technology (Chengdu) as author, MIT as licence, 2026 as year and the technical note as the preferred citation. If you use the drivers in published work, cite the technical note and, for reproducibility, the software archive DOI.
Downloads and next steps
Driver files and documentation are on /downloads/drivers/; datasheets and manuals are on /downloads/. For support, see support. To request samples or datasheets, use the contact form, WhatsApp +86 133 0819 5790 or tommy@erdimail.com. Lead time, minimum order and sample terms are confirmed in writing with the quotation.
Frequently asked questions
Is there an official ArduPilot or PX4 driver for ERDILRF modules?
No. The public repository has Python, Arduino and ROS 2 code but no ArduPilot or PX4 driver. The practical route is a companion board or script that decodes the module frame and sends a MAVLink distance message. See the Pixhawk/ArduPilot guide.
Is there a ROS 2 driver for the laser rangefinder?
Yes, as a package in the open-source repository: erdi_lrf_ros2 with a range_node that publishes sensor_msgs/Range. The README states it has been statically checked but not run in a ROS 2 environment there, so bench-test it with your module first.
What baud rate and logic level should I use?
Family A (55 AA) modules default to 115200 bps; family B (5C) modules to 460800 bps. The logic level is model specific and not always stated in the manual. LRF3000A1 states 3.3 V TTL. For other models, ask for written confirmation first.
Why are my distance readings ten times too large or small?
Units differ by model. Family A reports the real value × 10. In family B the H series counts centimetres and the VB series counts millimetres. The same frame 5C 02 11 EC is 43.54 m on an H model and 4.354 m on a VB model. Select the driver model by name.
Can I use the drivers commercially?
The repository is published under the MIT licence, which permits commercial use, modification and distribution provided the copyright and licence notice are kept. The software is provided as is, so validate it with your hardware. Read the LICENSE file for the exact terms.
How do I cite the drivers in a paper or report?
Cite the technical note, DOI 10.5281/zenodo.23297197, and for the exact code version the software archive, DOI 10.5281/zenodo.23297253. The repository’s CITATION.cff lists the preferred citation.