---
# System prepended metadata

title: GPS LC29H in Python
tags: [NTURacing]

---

# GPS LC29H in Python

## Preparation:
```cmd=
pip install pyserial
```

## Code in your mainFIle
```python=
import serial
import time

PORT = '/dev/ttyUSB1'
BAUDRATE = 115200 

def parse_gga(gga):
    parts = gga.split(',')
    if len(parts) < 15:
        return "GGA數據格式不完整"
    
    result = []
    
    if parts[1]:
        time_str = parts[1]
        hour = int(time_str[0:2])
        minute = int(time_str[2:4])
        second = float(time_str[4:])
        result.append(f"UTC时间: {hour:02d}:{minute:02d}:{second:.2f}")
   
    if parts[2] and parts[4]:
        lat = float(parts[2][:2]) + float(parts[2][2:]) / 60
        lat_dir = parts[3] rts[4][:3]) + float(parts[4][3:]) / 60
        lon_dir = parts[5]  
        result.append(f"緯度: {lat:.6f}° {lat_dir}")
        result.append(f"經度: {lon:.6f}° {lon_dir}")
    
    
    if parts[6]:
        quality = int(parts[6])
        quality_desc = {
            0: "無定位",
            1: "GPS定位",
            2: "差分GPS定位",
            4: "RTK固定解",
            5: "RTK浮点解"
        }
        result.append(f"定位質量: {quality} ({quality_desc.get(quality, '未知')})")
    
    
    if parts[7]:
        satellites = int(parts[7])
        result.append(f"使用的衛星數量: {satellites}")
    
    
    if parts[8]:
        hdop = float(parts[8])
        result.append(f"HDOP(水平精度因子): {hdop}")
    
    
    if parts[9]:
        altitude = float(parts[9])
        altitude_unit = parts[10]  
        result.append(f"海拔: {altitude} {altitude_unit}")
    
    return "\n".join(result)

def parse_rmc(rmc):
    
    parts = rmc.split(',')
    if len(parts) < 12:
        return "RMC數據格式不完整"
    
    result = []
   
    status = parts[2]
    result.append(f"定位狀態: {'有效' if status == 'A' else '無效'}")
    
    if status != 'A':
        result.append("警告: 位置數據無效！")
        return "\n".join(result)
    
   
    if parts[1] and parts[9]:
        time_str = parts[1]
        date_str = parts[9]
        
        hour = int(time_str[0:2])
        minute = int(time_str[2:4])
        second = float(time_str[4:])
        
        day = int(date_str[0:2])
        month = int(date_str[2:4])
        year = 2000 + int(date_str[4:6])  # 假设是21世纪
        
        result.append(f"日期时间: {year}-{month:02d}-{day:02d} {hour:02d}:{minute:02d}:{second:.2f} UTC")
    

    if parts[3] and parts[5]:
        lat = float(parts[3][:2]) + float(parts[3][2:]) / 60
        lat_dir = parts[4]  # N或S
        lon = float(parts[5][:3]) + float(parts[5][3:]) / 60
        lon_dir = parts[6]  # E或W
        
        result.append(f"緯度: {lat:.6f}° {lat_dir}")
        result.append(f"經度: {lon:.6f}° {lon_dir}")
    
    # 速度
    if parts[7]:
        speed = float(parts[7]) * 1.852  # 从节转换为公里/小时
        result.append(f"速度: {speed:.2f} km/h")
    
    # 航向
    if parts[8]:
        course = float(parts[8])
        result.append(f"航向: {course:.2f}°")
    
    return "\n".join(result)

def parse_nmea(line):
    if not line.startswith('$'):
        return "非NMEA格式数据"
    
    nmea_type = line.split(',')[0][1:]
    
    if "GGA" in nmea_type:
        print("GGA")
        # print("\n" + "="*50)
        return parse_gga(line)
    elif "RMC" in nmea_type:
        # print("\n" + "="*50)
        print("RMC")
        return parse_rmc(line)
    else:
        # return f"收到 {nmea_type} 类型的NMEA语句: {line}"
        return "0"

def clean_nmea_data(raw_data):
    if raw_data.count('$') > 1:
        second_dollar = raw_data.find('$', 1)
        
        return raw_data[second_dollar:]
    return raw_data

def main():
    try:
        print(f"連接到GPS {PORT}，Port rate {BAUDRATE}...")
        ser = serial.Serial(PORT, BAUDRATE, timeout=1)
        print(f"成功連結，開始接收...")
        print("按 Ctrl+C 停止")
        
        while True:
            if ser.in_waiting > 0:
                line = ser.readline().decode('ascii', errors='replace').strip()
                if line.startswith('$'):
                    line = clean_nmea_data(line)
                    
                    if parse_nmea(line) != "0":
                        print(parse_nmea(line))
            time.sleep(0.1)
            
    except KeyboardInterrupt:
        print("\n程序已停止")
    except Exception as e:
        print(f"錯誤: {e}")
    finally:
        if 'ser' in locals() and ser.is_open:
            ser.close()
            print("串口已關閉")


if __name__ == "__main__":
    main()

```

## Method to execute

### In powershell

1. To check if your device has connected
```
usbipd list
```
2. Check your device number and bind it 

```
usbipd bind --busid= "your device number (such as 1-2)"
```
3. attch to your device
```
usbipd attach -b 1-2 -w
```

### In WSL
You can check your device with
```
lsusb
```