树莓派Zero中GPS模块与Xbee共用UART引脚的解决方案咨询
树莓派Zero:UART引脚被Xbee占用时GPS模块的解决办法
问题背景
使用树莓派Zero,GPS模块需要的UART引脚已被Xbee占用,尝试用GPIO模拟UART通信但无法正常获取GPS数据,代码如下:
from gpiozero import DigitalOutputDevice, DigitalInputDevice import time gps_tx_pin = 17 # GPIO pin connected to the TX pin of the GPS module gps_rx_pin = 26 # GPIO pin connected to the RX pin of the GPS module gps_tx = DigitalOutputDevice(gps_tx_pin) gps_rx = DigitalInputDevice(gps_rx_pin) def gps_write(data): for char in data: binary = bin(ord(char))[2:].zfill(8) # Convert character to binary string for bit in binary: gps_tx.value = int(bit) time.sleep(0.01) # Adjust the delay as per the requirements def gps_read(): data = "" while True: if gps_rx.value: data += "1" else: data += "0" time.sleep(0.01) # Adjust the delay as per the requirements if len(data) >= 8: # Adjust the number of bits received per character break return data while True: gps_write("AT\r\n") # Send command to GPS module response = gps_read() # Read response from GPS module response_char = chr(int(response, 2)) # Convert binary string to ASCII character if response_char.startswith("$GPGGA"): data_parts = response_char.split(",") if len(data_parts) >= 10: latitude = data_parts[2] longitude = data_parts[4] print("Latitude: {}".format(latitude)) print("Longitude: {}".format(longitude)) time.sleep(1) # Adjust the delay as per the requirements
可行解决方法
方法1:启用树莓派的辅助UART(Mini UART)
树莓派Zero自带两个UART接口:
- 主UART(
ttyAMA0):通常被Xbee占用 - 辅助UART(
ttyS0):默认未启用,可用于连接GPS
配置步骤:
- 编辑
/boot/config.txt文件:sudo nano /boot/config.txt - 在文件末尾添加对应内容:
- 若为树莓派Zero(无蓝牙):
enable_uart=1 dtoverlay=uart1,txd1_pin=32,rxd1_pin=33 - 若为树莓派Zero W(带蓝牙),先禁用蓝牙对主UART的占用,再启用辅助UART:
enable_uart=1 dtoverlay=pi3-disable-bt
- 若为树莓派Zero(无蓝牙):
- 保存并重启树莓派:
sudo reboot - 重启后将GPS模块的TX接GPIO15(RXD0)、RX接GPIO14(TXD0),之后可通过
minicom或pyserial库直接读取/dev/ttyS0或/dev/ttyAMA0的GPS数据。
方法2:改进软件模拟UART代码
你当前的模拟代码存在两个核心问题:
- 时序错误:
time.sleep(0.01)对应100波特率,而GPS模块默认波特率为9600,单bit延迟应为1/9600 ≈ 0.000104秒 - 未处理UART的起始位、停止位,仅读取8位数据,无法正确解析GPS的NMEA语句
改进方案:使用pigpio库实现高精度模拟UART(依赖硬件定时,比gpiozero更适合串口模拟):
- 安装pigpio:
sudo apt-get install pigpio python3-pigpio sudo systemctl start pigpiod sudo systemctl enable pigpiod - 替换代码为:
import pigpio import time # 配置模拟UART引脚 GPS_TX = 17 GPS_RX = 26 BAUD_RATE = 9600 pi = pigpio.pi() if not pi.connected: exit() # 初始化模拟UART pi.set_mode(GPS_TX, pigpio.OUTPUT) pi.set_mode(GPS_RX, pigpio.INPUT) pi.bb_serial_read_open(GPS_RX, BAUD_RATE) pi.bb_serial_write_open(GPS_TX, BAUD_RATE) try: while True: # 读取GPS数据 count, data = pi.bb_serial_read(GPS_RX) if count > 0: nmea_str = data.decode('ascii') for line in nmea_str.split('\n'): if line.startswith('$GPGGA'): parts = line.split(',') if len(parts) >= 10: lat = parts[2] lon = parts[4] print(f"纬度: {lat}, 经度: {lon}") time.sleep(0.1) finally: pi.bb_serial_read_close(GPS_RX) pi.bb_serial_write_close(GPS_TX) pi.stop()
方法3:使用USB转UART模块(最便捷)
无需占用GPIO引脚,直接将GPS模块通过USB转TTL模块连接到树莓派的USB口:
- 连接后,树莓派会识别出串口设备(通常为
/dev/ttyUSB0或/dev/ttyACM0) - 使用
pyserial库读取数据:pip install pyserialimport serial import time ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1) try: while True: line = ser.readline().decode('ascii').strip() if line.startswith('$GPGGA'): parts = line.split(',') if len(parts) >= 10: lat = parts[2] lon = parts[4] print(f"纬度: {lat}, 经度: {lon}") time.sleep(0.1) finally: ser.close()
内容的提问来源于stack exchange,提问作者Aysu Mammadli
相关产品推荐
相关产品推荐

