Adafruit Grand Central M4 Metro:Processing与CircuitPython串口连接故障排查
我用搭载CircuitPython的Adafruit Grand Central M4 Metro控制3个电机,引脚分别对应D5/D6、D14/D15、D52/D53。现有两个CircuitPython文件:一个负责电机初始化与动作定义,另一个通过busio.UART(波特率9600)接收串口指令调用电机动作。
我用Processing编写了带可视化按钮的程序,按下按钮发送'L'/'R'指令,但电机无任何反应;但手动在CircuitPython代码中调用动作函数时,电机可正常运转,因此判断问题出在串口连接环节,恳请排查故障原因。
CircuitPython 代码
import time import board from motor import * import busio uart = busio.UART(board.TX, board.RX, baudrate=9600) def vorwärts(): while True: motor1_R1(30) motor2_R2(30) def rückwärts(): while True: motor1_R2(30) motor2_R1(30) def drehung_rechts(): while True: motor1_R2(30) motor2_R2(30) motor3_R2(30) def drehung_links(): while True: motor1_R1(30) motor2_R1(30) motor3_R1(30) while True: data = uart.readline() if data is not None: received_data = data.decode().strip() if received_data == 'L': drehung_links() elif received_data == 'R': drehung_rechts()
Processing 代码
import processing.serial.*; Serial myPort; void setup() { size(400, 400); // 设置窗口大小 String portName = "COM3"; myPort = new Serial(this, portName, 9600); } if (mouseX > 50 && mouseX < 150 && mouseY > 50 && mouseY < 150) { // 点击左侧按钮 // 通过串口发送信号 myPort.write('L'); println("左侧按钮被点击"); } if (mouseX > 250 && mouseX < 350 && mouseY > 50 && mouseY < 150) { // 点击右侧按钮 // 通过串口发送信号 myPort.write('R'); println("右侧按钮被点击"); }
故障原因分析及解决步骤
1. Processing 点击逻辑位置错误
你的Processing代码中,按钮点击判断代码未放入事件处理函数,只会在程序启动时执行一次,完全无法响应鼠标点击动作。必须将判断逻辑放到mousePressed()(单次点击触发)或draw()(持续检测)函数中:
// 示例:用mousePressed()处理单次点击 void mousePressed() { if (mouseX > 50 && mouseX < 150 && mouseY > 50 && mouseY < 150) { myPort.write('L'); println("左侧按钮被点击"); } if (mouseX > 250 && mouseX < 350 && mouseY > 50 && mouseY < 150) { myPort.write('R'); println("右侧按钮被点击"); } }
2. 串口数据格式不匹配
CircuitPython中uart.readline()需要等待换行符(\n)才会返回完整数据,但Processing仅发送单个字符'L'/'R',无换行符,导致串口一直无法读取到有效数据。两种解决方式:
- 方式一:Processing发送时添加换行
myPort.write('L' + '\n'); - 方式二:CircuitPython改用
uart.read(1)读取单个字符while True: data = uart.read(1) if data is not None: received_data = data.decode().strip() if received_data == 'L': drehung_links() elif received_data == 'R': drehung_rechts()
3. 串口端口号可能错误
不要硬写"COM3",先确认Grand Central M4在电脑上的实际COM口。可以在Processing中打印所有可用端口:
void setup() { size(400, 400); println(Serial.list()); // 打印所有可用串口 String portName = Serial.list()[0]; // 根据实际输出选择对应端口 myPort = new Serial(this, portName, 9600); }
4. UART引脚连接或配置问题
Grand Central M4的board.TX是发送引脚,board.RX是接收引脚,若使用外接USB转串口模块,需交叉接线(TX接电脑RX,RX接电脑TX);若使用板载USB串口,需确认CircuitPython是否正确映射了板载串口的引脚。
5. 动作函数死循环卡住主逻辑
drehung_links()和drehung_rechts()函数内的while True死循环,会导致调用后直接卡住主程序的串口读取逻辑。建议改成无死循环的状态驱动模式:
current_action = None def drehung_links(): motor1_R1(30) motor2_R1(30) motor3_R1(30) def drehung_rechts(): motor1_R2(30) motor2_R2(30) motor3_R2(30) while True: data = uart.read(1) if data is not None: current_action = data.decode().strip() # 根据当前状态执行动作 if current_action == 'L': drehung_links() elif current_action == 'R': drehung_rechts() time.sleep(0.01) // 避免占用过多资源
内容的提问来源于stack exchange,提问作者Zahlensuppe

