{"id":6336,"date":"2025-11-26T16:57:02","date_gmt":"2025-11-26T08:57:02","guid":{"rendered":"https:\/\/meskernel.net\/?p=6336"},"modified":"2025-11-26T16:57:05","modified_gmt":"2025-11-26T08:57:05","slug":"companion-computer","status":"publish","type":"post","link":"https:\/\/meskernel.net\/pl\/companion-computer\/","title":{"rendered":"Laser Rangefinder LD30-S1R(LDL-T) \u2192 Companion Computer \u2192 Pixhawk Flight Controller"},"content":{"rendered":"<p>This guide provides a fully working, no-extra-documentation-needed solution to integrate:<\/p>\n\n\n\n<p>LD30-S1R \u2192 Companion Computer (Raspberry Pi \/ Jetson \/ Android) \u2192 MAVLink \u2192 <a href=\"https:\/\/meskernel.net\/pl\/pixhawk-ldl-t-laser-distance-sensor-integration\/\">Pixhawk<\/a><\/p>\n\n\n\n<p>It includes wiring diagrams, data parsing flow, ready-to-run Python code, Pixhawk parameter setup, and ground control station verification.<\/p>\n\n\n\n<p>Follow this guide step-by-step and the system will work immediately.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>1. Wiring Connections (LD30 \u2194 Companion Computer \u2194 Flight Controller)<\/strong><\/h1>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>1.1 LD30-S1R \u2194 Companion Computer (UART)<\/strong><\/h2>\n\n\n\n<p>Companion computers can be:<br><strong>Raspberry Pi \/ Jetson Nano \/ Industrial PC \/ Android device with USB\u2013UART<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>LD30-S1R<\/th><th>Companion Computer (<a href=\"https:\/\/meskernel.net\/pl\/usart-vs-uart\/\">UART<\/a>)<\/th><\/tr><\/thead><tbody><tr><td><strong>VCC (3.3\u20134.0V)<\/strong><\/td><td>3.3V or external regulator<\/td><\/tr><tr><td><strong>GND<\/strong><\/td><td>GND<\/td><\/tr><tr><td><strong>TXD (open-drain)<\/strong><\/td><td>RX<\/td><\/tr><tr><td><strong>RXD<\/strong><\/td><td>TX<\/td><\/tr><tr><td><strong>PWREN<\/strong><\/td><td>Pull HIGH (3.3V) or GPIO<\/td><\/tr><tr><td><strong>nRST<\/strong><\/td><td>Not connected<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Note:<\/strong> LD30 uses 3.3V TTL UART. <strong>Do not<\/strong> connect to 5V TTL UART.<br>TX is open-drain; internal pull-ups on Raspberry Pi and Jetson work fine.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>1.2 Companion Computer \u2194 Pixhawk (MAVLink UART)<\/strong><\/h2>\n\n\n\n<p>U\u017cycie <strong>TELEM1 \/ TELEM2<\/strong> port.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Companion Computer<\/th><th>Pixhawk (TELEM Port)<\/th><\/tr><\/thead><tbody><tr><td><strong>TX<\/strong><\/td><td>RX<\/td><\/tr><tr><td><strong>RX<\/strong><\/td><td>TX<\/td><\/tr><tr><td><strong>GND<\/strong><\/td><td>GND<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Baud rate: <strong>115200<\/strong><\/li>\n\n\n\n<li>Protocol: <strong>MAVLink2<\/strong><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>2. Reading LD30-S1R Data on the Companion Computer<\/strong><\/h1>\n\n\n\n<p>LD30 communicates using a binary command protocol.<br>The companion computer handles:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open UART port<\/li>\n\n\n\n<li>Send \u201ccontinuous measurement\u201d command<\/li>\n\n\n\n<li>Parse frames beginning with <strong>0xAA<\/strong><\/li>\n\n\n\n<li>Extract distance (mm)<\/li>\n\n\n\n<li>Convert to meters<\/li>\n\n\n\n<li>Pack into MAVLink <strong>DISTANCE_SENSOR<\/strong><\/li>\n\n\n\n<li>Send to Pixhawk<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>2.1 Continuous Measurement Command<\/strong><\/h2>\n\n\n\n<p>From LD30 User Manual (section 14.12):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>AA 00 00 20 00 01 00 04 25\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>2.2 Data Frame Format<\/strong><\/h2>\n\n\n\n<p>Returned data includes:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Distance:<\/strong> 4 bytes (mm)<\/li>\n\n\n\n<li><strong>Signal quality:<\/strong> 2 bytes<\/li>\n\n\n\n<li>Frame header: <strong>0xAA<\/strong><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>3. Complete Python Script (Ready to Run)<\/strong><\/h1>\n\n\n\n<p>This script:<\/p>\n\n\n\n<p>\u2714 Reads LD30<br>\u2714 Parses distance<br>\u2714 Converts mm \u2192 m<br>\u2714 Sends MAVLink <code>DISTANCE_SENSOR<\/code><br>\u2714 Streams data to Pixhawk in real time<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Save as <code>ld30_to_mavlink.py<\/code><br>Run with:<br><code>python3 ld30_to_mavlink.py<\/code><\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>import serial\nfrom pymavlink import mavutil\nimport struct\n\n# --- LD30 Serial Port ---\nld30 = serial.Serial('\/dev\/ttyUSB0', 115200, timeout=0.1)\n\n# Continuous measurement command (from manual 14.12)\nCONT_MEASURE = bytes(&#91;0xAA,0x00,0x00,0x20,0x00,0x01,0x00,0x04,0x25])\nld30.write(CONT_MEASURE)\n\n# --- MAVLink connection to Pixhawk ---\nmav = mavutil.mavlink_connection('\/dev\/ttyAMA0', baud=115200)\n\ndef send_distance_to_fc(distance_m):\n    mav.mav.distance_sensor_send(\n        0,       # time_boot_ms\n        3,       # min_distance (cm)\n        3000,    # max_distance (cm)\n        int(distance_m * 100),  # current distance (cm)\n        0,       # type\n        0,       # id\n        0,       # orientation\n        0        # covariance\n    )\n\nbuffer = bytearray()\n\nwhile True:\n    data = ld30.read()\n    if not data:\n        continue\n\n    buffer += data\n\n    # Minimum frame length = 12 bytes\n    if len(buffer) >= 12:\n        # Look for header 0xAA\n        if buffer&#91;0] != 0xAA:\n            buffer.pop(0)\n            continue\n\n        # Parse fixed-length frame\n        if len(buffer) >= 12:\n            # Distance is bytes 6~9 (big-endian)\n            dist_bytes = buffer&#91;6:10]\n            distance_mm = struct.unpack(\">I\", dist_bytes)&#91;0]\n            distance_m = distance_mm \/ 1000.0\n\n            print(\"LD30 Distance:\", distance_m, \"m\")\n            send_distance_to_fc(distance_m)\n\n            buffer = bytearray()  # Clear buffer\n<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>4. Pixhawk Parameter Configuration (Mission Planner)<\/strong><\/h1>\n\n\n\n<p>Go to:<br><strong>Config \u2192 Full Parameter List<\/strong><\/p>\n\n\n\n<p>Set the following:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Parametr<\/th><th>Warto\u015b\u0107<\/th><\/tr><\/thead><tbody><tr><td><strong>RNGFND1_TYPE<\/strong><\/td><td>10 (MAVLink)<\/td><\/tr><tr><td><strong>RNGFND1_MIN_CM<\/strong><\/td><td>3<\/td><\/tr><tr><td><strong>RNGFND1_MAX_CM<\/strong><\/td><td>3000<\/td><\/tr><tr><td><strong>RNGFND1_ORIENT<\/strong><\/td><td>0 (Forward) or <strong>25 (Downward)<\/strong><\/td><\/tr><tr><td><strong>RNGFND1_RMETRIC<\/strong><\/td><td>1<\/td><\/tr><tr><td><strong>SERIAL1_PROTOCOL<\/strong><\/td><td>2 (MAVLink2)<\/td><\/tr><tr><td><strong>SERIAL1_BAUD<\/strong><\/td><td>115<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>If using TELEM2, use SERIAL2_*<br>If using TELEM3, use SERIAL3_*<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>5. Monitoring LD30 Data in Mission Planner \/ QGroundControl<\/strong><\/h1>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>5.1 Mission Planner<\/strong><\/h2>\n\n\n\n<p>Navigate to:<\/p>\n\n\n\n<p><strong>Flight Data \u2192 Status \u2192 sonar_range \/ rngfnd1_dist<\/strong><\/p>\n\n\n\n<p>or:<\/p>\n\n\n\n<p><strong>Ctrl + F \u2192 MAVLink Inspector \u2192 DISTANCE_SENSOR<\/strong><\/p>\n\n\n\n<p>You will see:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Real-time distance<\/li>\n\n\n\n<li>Update frequency<\/li>\n\n\n\n<li>MAVLink stream ID<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>5.2 QGroundControl<\/strong><\/h2>\n\n\n\n<p>Navigate:<\/p>\n\n\n\n<p><strong>Widgets \u2192 Analyze Tools \u2192 MAVLink Inspector \u2192 DISTANCE_SENSOR<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>6. Overall System Workflow<\/strong><\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>            LD30-S1R\n                \u2502\n           TTL UART 3.3V\n                \u2502\n        \u250c\u2500\u2500\u2500\u2500Companion Computer\u2500\u2500\u2500\u2500\u2510\n        \u2502   LD30 parsing logic     \u2502\n        \u2502   MAVLink packaging      \u2502\n        \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                  MAVLink UART\n                       \u2502\n                 Pixhawk Flight Controller\n                       \u2502\n        Mission Planner \/ QGroundControl\n<\/code><\/pre>\n\n\n\n<p><\/p>","protected":false},"excerpt":{"rendered":"<p>This guide provides a fully working, no-extra-documentation-needed solution to integrate: LD30-S1R \u2192 Companion Computer (Raspberry Pi \/ Jetson \/ Android) [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":6339,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[49],"tags":[],"class_list":["post-6336","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-solution"],"_links":{"self":[{"href":"https:\/\/meskernel.net\/pl\/wp-json\/wp\/v2\/posts\/6336","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/meskernel.net\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/meskernel.net\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/meskernel.net\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/meskernel.net\/pl\/wp-json\/wp\/v2\/comments?post=6336"}],"version-history":[{"count":0,"href":"https:\/\/meskernel.net\/pl\/wp-json\/wp\/v2\/posts\/6336\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/meskernel.net\/pl\/wp-json\/wp\/v2\/media\/6339"}],"wp:attachment":[{"href":"https:\/\/meskernel.net\/pl\/wp-json\/wp\/v2\/media?parent=6336"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/meskernel.net\/pl\/wp-json\/wp\/v2\/categories?post=6336"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/meskernel.net\/pl\/wp-json\/wp\/v2\/tags?post=6336"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}