树莓派通过串口终端访问hidraw设备失败,寻求技术帮助
与USB逆变器(/dev/hidraw0)通信的问题
- 设备通过USB连接,识别为
/dev/hidraw0 - 使用hidapi库无法建立通信,仅能通过GTKterm配置
/dev/hidraw0实现读写 - 尝试用pyserial编写串口终端程序,连接
/dev/hidraw0时提示语法错误 - 已尝试通过Udev修改设备读写权限并加入plugdev组,问题仍未解决
附上尝试的代码:
import tkinter as tk import serial import binascii def send_data(): data = input_entry.get().strip() if data: hex_data = data.replace(" ", "").strip() byte_data = binascii.unhexlify(hex_data) serial_port.write(byte_data) display_sent_data(hex_data) def display_sent_data(data): sent_data_text.insert(tk.END, data + "\n") def read_data(): data = serial_port.read_all() if data: hex_data = binascii.hexlify(data).decode() display_received_data(hex_data) def display_received_data(data): received_data_text.insert(tk.END, data + "\n") # Scroll to the end of the received data text received_data_text.see(tk.END) # Serial port configuration serial_port = serial.Serial('/dev/ttyUSB1', baudrate=38400, timeout=0.1) # Replace with your actual serial port configuration # GUI setup window = tk.Tk() window.title("Serial Terminal") window.geometry("400x300") # Input entry and send button input_entry = tk.Entry(window, width=30) input_entry.pack(pady=10) send_button = tk.Button(window, text="Send", command=send_data) send_button.pack() # Sent data display sent_data_text = tk.Text(window, height=8, width=40) sent_data_text.pack(pady=10) # Received data display received_data_text = tk.Text(window, height=8, width=40) received_data_text.pack() # Read data from serial port def read_serial(): read_data() window.after(100, read_serial) read_serial() window.mainloop()
问题分析与解决方法
核心问题
pyserial是为串口设备(如ttyUSB、ttyACM)设计的,/dev/hidraw0属于HID类设备的原始字符设备,不属于串口范畴,直接用serial.Serial()打开必然报错。
解决方案1:改用hidapi-python库实现通信
GTKterm能正常操作说明设备HID通信逻辑正常,之前hidapi使用失败大概率是参数或调用方式错误。
- 先安装依赖:
pip install hidapi
- 修改后的适配代码:
import tkinter as tk import hid import binascii # 替换为你的设备VID和PID(用lsusb命令可查看) VID = 0xXXXX PID = 0xYYYY def open_hid_device(): try: dev = hid.device() dev.open(VID, PID) dev.set_nonblocking(True) return dev except Exception as e: print(f"设备打开失败: {e}") return None hid_device = open_hid_device() def send_data(): data = input_entry.get().strip() if data and hid_device: hex_data = data.replace(" ", "").strip() # 多数HID设备需要前缀报告ID(通常为0x00,需根据设备调整) byte_data = b'\x00' + binascii.unhexlify(hex_data) try: hid_device.write(byte_data) display_sent_data(hex_data) except Exception as e: print(f"发送失败: {e}") def read_data(): if hid_device: try: # 读取64字节(HID默认报告长度,按需调整) data = hid_device.read(64) if data: # 去掉前缀的报告ID(如果设备返回的数据包包含) hex_data = binascii.hexlify(data[1:]).decode() if len(data) >1 else binascii.hexlify(data).decode() display_received_data(hex_data) except Exception as e: print(f"读取失败: {e}") # 以下GUI部分与原代码一致,省略重复内容 window = tk.Tk() window.title("HID Terminal") window.geometry("400x300") input_entry = tk.Entry(window, width=30) input_entry.pack(pady=10) send_button = tk.Button(window, text="Send", command=send_data) send_button.pack() sent_data_text = tk.Text(window, height=8, width=40) sent_data_text.pack(pady=10) received_data_text = tk.Text(window, height=8, width=40) received_data_text.pack() def read_loop(): read_data() window.after(100, read_loop) read_loop() window.mainloop()
解决方案2:直接通过文件操作读写hidraw
如果不想用hidapi库,可以模拟GTKterm的原生文件操作方式:
修改原代码的串口配置与读写函数:
# 打开hidraw设备 hidraw_fd = open('/dev/hidraw0', 'rb+') def send_data(): data = input_entry.get().strip() if data: hex_data = data.replace(" ", "").strip() byte_data = binascii.unhexlify(hex_data) hidraw_fd.write(byte_data) hidraw_fd.flush() display_sent_data(hex_data) def read_data(): data = hidraw_fd.read(64) if data: hex_data = binascii.hexlify(data).decode() display_received_data(hex_data)
额外排查步骤
- 用
lsusb确认设备的VID/PID,确保hidapi调用参数正确 - 用
cat /dev/hidraw0和echo -n -e '\xXX\xYY' > /dev/hidraw0测试原生读写,验证设备是否响应 - 查看GTKterm的配置细节,确认是否使用了特定报告ID或数据格式,同步到代码中
内容的提问来源于stack exchange,提问作者Trynabal
相关产品推荐
相关产品推荐

