Python host driver
Host-side UART driver for ERDI 905 nm laser rangefinder modules — the LR1000E2 protocol family.
Zero core dependencies — framing and decoding are pure standard library, so the whole driver
runs and is testable on any machine, including one with no hardware attached. pyserial is optional
and only needed to actually open a port.
pip install -e . # from this directory (python/)
pip install -e python/ # from the repository root — same thing
pip install pyserial # only needed to open a real port
Command line
Every command below runs with no hardware and no serial port except the last three:
erdilrf frames # print the whole command table
erdilrf decode "55 AA 88 01 FF 27 10 BE" # decode a captured frame
erdilrf ports
erdilrf measure --port COM3 --count 5
erdilrf stream --port COM3
erdilrf selftest --port COM3 # run immediately after power-on
Library
from erdilrf_lrf import Rangefinder, SerialTransport
with Rangefinder(SerialTransport("COM3")) as rf:
print(rf.single_shot()) # 123.4 metres, or None if the shot failed
for distance in rf.stream(count=10): # 3-10 Hz adaptive continuous ranging
print(distance)
Protocol in one table
Fixed 8-byte frames. The checksum is the low byte of a sum — and the two directions use different ranges, which is the single most common integration mistake.
offset 0 1 2 3 4 5 6 7
0x55 0xAA FUNC D1 D2 D3 D4 SUM
host -> module SUM = (FUNC + D1 + D2 + D3 + D4) & 0xFF
module -> host SUM = (0x55 + 0xAA + FUNC + D1 + D2 + D3 + D4) & 0xFF
| Command | Transmit | Response |
|---|---|---|
| Single-shot ranging | 55 AA 88 FF FF FF FF 84 |
55 AA 88 STA FF DIS_H DIS_L SUM |
| Continuous ranging | 55 AA 89 FF FF FF FF 85 |
55 AA 89 STA FF DIS_H DIS_L SUM |
| Stop ranging | 55 AA 8E FF FF FF FF 8A |
55 AA 8E STA FF FF FF SUM |
| Angle measurement † | 55 AA 8A FF FF FF FF 86 |
55 AA 8A STA FF ANG_H ANG_L SUM |
| LD constant-on on / off | 55 AA 86 FF FF FF 01 84 / … 00 83 |
see known gap below |
| Set baud rate | 55 AA TYPE FF FF FF FF SUM |
55 AA TYPE STA FF FF FF SUM |
Distance and angle are both scaled by 10 — the 16-bit register holds tenths, so
((DIS_H << 8) | DIS_L) / 10 gives metres.
† Angle measurement is available only on modules fitted with an angle sensor.
Default link: 115200 bps, 8 data bits, 8-byte frame. The manufacturer documents 115200 and 8 data
bits; it is silent on parity and stop bits, so this driver assumes 8N1 and says so. If a module
stays silent, try --parity E or --parity O before assuming a wiring fault.
Tests
50 tests, no hardware and no serial port required — serial I/O is injected as a two-method transport, so the whole driver runs against a scripted fake link.
python -m pytest -q
The suite has already caught real defects in this repository: a FrameReader that validated
transmitted frames with the response checksum rule, and a pre-command flush that silently ate
the answer to the command it had just sent (a wrong distance with no error — the worst failure this
driver can produce).
Golden vectors assert that all six transmit frames printed in the manufacturer's manual are reproduced byte for byte, and that each printed checksum is reproducible from the stated rule.
What the tests do not cover
No test in this repository has ever run against a real module. The framing is verified against the manual and against itself, not against silicon. A capture from real hardware outranks every table above — if your module disagrees, open an issue with the raw bytes.
Known gaps we did not paper over
- The LD constant-on response frame is incomplete in the published manual — section 8 prints
only
55for that row. This driver sends the command and does not validate a reply. It does not guess the missing bytes. - Cable wire colours are not documented. The manual gives pin numbers only: 1 GND, 2 VCC, 3 I/O (reserved), 4 TXD, 5 RXD, 6 SW-SHOT.
- SW-SHOT polarity is configuration-dependent. The manual says "function enable (active high)" and in the same row "compatible with active-low control requirements". Confirm per unit.
- UART logic-level tolerance is not specified. Only the 3.3–5 V supply figure is given.
About this file
This is the PyPI long description for the erdilrf-lrf distribution. The packaging toolchain
cannot read a file outside the project directory, so this file lives here rather than reusing the
repository root README.md. It mirrors the Python-relevant sections of that root README; the root
README remains authoritative for the repository as a whole (protocol reference, Arduino driver,
wiring notes).
Installable package name: erdilrf-lrf · import name: erdilrf_lrf · CLI: erdilrf.
Note that the package name differs from the import name and from the CLI name — see
pyproject.toml for the single source of truth.
Part of erdilrf/erdilrf-drivers · MIT · modules documented at erdilrf.com
Metadata
Release files for erdilrf-lrf 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| erdilrf_lrf-0.2.0.tar.gz | 25.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| erdilrf_lrf-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 43.0 kB
Release files / erdilrf_lrf-0.2.0.tar.gz
| Download URL | erdilrf_lrf-0.2.0.tar.gz |
|---|---|
| Size | 25.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
456ec4b5bd4fd5a434f4f5f5d0ceb70b8698ab8bac77c2df36de5968ec71c5d7
|
|
BLAKE2b-256 checksum How to use checksums |
70373cd4795f3bfd73fca73f25caf9cdd9d78788a42fb50077c5978a91025fe9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / erdilrf_lrf-0.2.0-py3-none-any.whl
| Download URL | erdilrf_lrf-0.2.0-py3-none-any.whl |
|---|---|
| Size | 17.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6901704dbec5672a6fd66272df990d386b767a827e1cdabf817a168d847c5171
|
|
BLAKE2b-256 checksum How to use checksums |
07017d84f052620c4ec532436ed9deff69ef0f420d1501d087c36bb19403f935
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|