Last active
March 13, 2023 10:29
-
-
Save okalachev/7704b15c7d0752acad72e50a35a460b1 to your computer and use it in GitHub Desktop.
Read and parse USB data from KingKong/LDARC Tiny X8 2.4G 8CH/16CH Radio Transmitter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# Read and parse USB data from KingKong/LDARC Tiny X8 2.4G 8CH Radio Transmitter | |
# Usage: ./tiny_rc.py <device_path> | |
# Example: ./tiny_rc.py /dev/tty.usbserial-210 | |
# Author: Oleg Kalachev <okalachev@gmail.com> | |
# https://github.com/okalachev | |
import sys | |
import serial | |
PACKET_SIZE = 103 | |
HEADER = bytes([0x4C, 0x44, 0x41, 0x54, 0x58, 0x31, 0x30]) | |
DEVICE = sys.argv[1] if len(sys.argv) > 1 else '/dev/tty.usbserial-210' | |
# Packet structure (https://github.com/kingkong-rc/TINY-TX-X8/blob/0fcbf/FRSKY-D8/IAR-STM8-210/U3.c#L14): | |
# Start header (7 Byte data fixed): 0x4C, 0x44, 0x41, 0x54, 0x58, 0x31, 0x30 | |
# Remote control type (1 Byte 0x45 / 0x44) | |
# Remote control software version number (3 Byte year-month-day) | |
# Wireless protocol version number (1 Byte) | |
# American hand/Japanese hand mode selection (1 Byte) | |
# The unique ID number of the remote control (4 Byte) | |
# 16 channel data (2 Byte per channel = 16*2 Byte = 32 Byte) | |
# Channel reverse flag (1 Byte) | |
# All buttons + 8-bit DIP switch GPIO value (2 Byte) | |
# Battery voltage value (2 Byte battery voltage is magnified by 100 times) | |
# Reference voltage 431 + high frequency module + neutral calibration is successful flag bit (1 Byte) | |
# All channels AD sampling original value (2 Byte per channel = 6*2 Byte = 12 Byte) | |
# LED status (1 Byte) 1 means on, 0 means off | |
# Alarm status (1 Byte) | |
# The number of timer crashes (1 Byte) | |
# Four joystick offset value (4 Byte) | |
# The maximum AD value of the four rockers (4*2 Byte = 8 Byte) | |
# The median AD value of the four joysticks (4*2 Byte = 8 Byte) | |
# The minimum AD value of the four rockers (4*2 Byte = 8 Byte) | |
# Packet checksum (2 Byte) | |
device = serial.Serial(DEVICE, 115200, timeout=1) | |
buf = bytes() | |
while True: | |
# wait for the magic header | |
buf += device.read(1) | |
if len(buf) < len(HEADER): | |
if HEADER.startswith(buf): | |
continue | |
if not HEADER.startswith(buf): | |
buf = bytes() | |
continue | |
# skip uninteresting data | |
device.read(10) | |
# grab channels data | |
data = device.read(32) | |
# parse and print channel values | |
channels = [] | |
for ch in range(16): | |
channels.append(data[ch * 2] << 8 | (data[ch * 2 + 1])) | |
print(f'Channel {ch + 1}: {channels[-1]}') | |
# continue looking for the header... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment