需要使用游戏手柄来控制平衡小车,由于游戏手柄和平衡小车不能连接,所以使用电脑作为中介实现两者通信。
需要实现以下功能
Python扩展程序包的二进制文件下载网址为:
https://www.lfd.uci.edu/~gohlke/pythonlibs/
pygame
是一个可以读取手柄和键盘模块,我的python环境为3.7版本所以我下载的的是pygame‑2.0.1‑cp37‑cp37m‑win_amd64.whl
。
pyserial
是一个串口通信模块,我下载的为pyserial‑3.5‑py3‑none‑any.whl
。
下载完成后以管理员的身份打开命令提示符使用 pip 指令安装:
# 跳转到文件下载的目录 C:\WINDOWS\system32> cd C:\Users\Administrator\Downloads # 使用 pip 安装 文件 C:\Users\Administrator\Downloads> pip install pygame‑2.0.1‑cp37‑cp37m‑win_amd64.whl
pyserial
的啊安装也是一样的。
注意:如果是使用pycharm
编写的程序,会提示找不到模块,因为pycharm
运行环境的扩展库只扫描当前项目下的,因此我是使用VScode 编写。
定义通信规则:为了方便起见每次只发送一个字符,直行发送 ‘q’,加速发送 ‘s’,减速发送 ‘e’,左转发送 ‘l’,右转发送 ‘r’。
第一次调试可以打开print(message)
查看系统获取的信息
import pygame import time import serial import serial.tools.list_ports # 串口通信端口号 portx = '' # 串口通信 波特率 Baud = 115200 # 程序状态 state = True # 消息 message = dict() # 串口对象 ser = serial.Serial() # 检查并选择端口 def set_port(): global portx print("正在检查可用端口。。") port_list = list(serial.tools.list_ports.comports()) if len(port_list) == 0: print("无可用串口!") return 0 else: print('序号\t名称') for i in range(0, len(port_list)): print(i + 1, '\t', port_list[i]) n = 1 if len(port_list) != 1: n = int(input('输入端口序号:')) portx = str(port_list[n - 1].device) print('已选择端口:', portx) return 1 def open_port(): global portx try: ser.baudrate = Baud ser.port = portx ser.open() # 打开串口 except Exception as e: ser.close() # 关闭端口 print('端口打开失败,尝试更换端口:', e) return 0 return 1 def send_joystick(): print('连接成功!') global state pygame.init() pygame.joystick.init() while state: time.sleep(0.2) message.clear() for event in pygame.event.get(): if event.type == pygame.QUIT: done = True if event.type == pygame.JOYBUTTONDOWN: message['JOYBUTTONDOWN'] = event.button if event.type == pygame.JOYBUTTONUP: message['JOYBUTTONUP'] = event.button joystick_count = pygame.joystick.get_count() for nums in range(joystick_count): joystick = pygame.joystick.Joystick(nums) joystick.init() axes = joystick.get_numaxes() for i in range(axes): axis = joystick.get_axis(i) message['axes' + str(i)] = int(axis * 10) # print(message) #打印获取的信息 if message == {}: # 未连接 state = False print('没有找到手柄') break if message.get('JOYBUTTONDOWN') == 0: # 直行 ser.write(b'z') print('直行') if message.get('JOYBUTTONDOWN') == 1: # 停车 ser.write(b'q') print('停车') if message.get('axes5') >= 0: # 加速 ser.write(b's') print('加速') if message.get('axes2') >= 0: # 减速 ser.write(b'e') print('减速') if message.get('axes0') <= -5: # 左转 ser.write(b'l') print('左转') if message.get('axes0') >= 5: # 右转 ser.write(b'r') print('右转') if message.get('JOYBUTTONDOWN') == 7: # 退出 state = False print('退出') if ser.in_waiting: print(ser.read(ser.in_waiting).decode("gbk"), end='') if set_port() == 1: if open_port() == 1: send_joystick() ser.close() # 关闭端口 input("按任意键退出!")