Arduino Mega2560串口阻塞致步进电机卡顿,求非阻塞解决方案
非阻塞式扭矩传感器串口通信方案(解决步进电机卡顿)
问题根源
原代码中Serial1.readBytes()是阻塞式调用,会一直等待指定字节数的响应接收完成才继续执行后续代码,导致Motor.run()无法被高频调用,步进电机因此卡顿。
非阻塞实现方案
通过状态机管理串口通信的全流程,拆分发送指令、接收响应、处理数据三个阶段,确保每一步都不会阻塞主循环:
1. 定义全局状态与缓冲区
// 串口通信状态枚举 enum SerialState { STATE_IDLE, // 空闲,准备发送指令 STATE_SENT_CMD, // 已发送指令,等待接收响应 STATE_RECEIVING // 已接收完整响应,准备处理数据 }; SerialState currentState = STATE_IDLE; byte responseBuffer[7]; // 匹配原代码中response数组的长度 int responseIndex = 0; unsigned long lastSendTime = 0; const long sendInterval = 100; // 指令发送间隔(毫秒),可根据传感器调整 float fltvalue = 0.0;
2. 非阻塞式传感器处理函数
void handleTorqueSensor() { switch(currentState) { case STATE_IDLE: // 定时发送指令,避免频繁通信占用资源 if(millis() - lastSendTime >= sendInterval) { Serial1.write(getvalue, sizeof(getvalue)); lastSendTime = millis(); currentState = STATE_SENT_CMD; responseIndex = 0; // 重置缓冲区索引 } break; case STATE_SENT_CMD: // 逐字节读取串口数据,不阻塞 while(Serial1.available() > 0) { byte incomingByte = Serial1.read(); responseBuffer[responseIndex++] = incomingByte; // 检查是否接收完所有响应字节 if(responseIndex >= sizeof(responseBuffer)) { currentState = STATE_RECEIVING; break; } } break; case STATE_RECEIVING: // 转换十六进制响应为浮点扭矩值 unsigned long decvalue = (responseBuffer[3] << 24) | (responseBuffer[4] << 16) | (responseBuffer[5] << 8) | responseBuffer[6]; // 修正原代码的负数判断逻辑:通过32位最高位识别补码负数 if(decvalue & 0x80000000) { decvalue = -(0x100000000UL - decvalue); } fltvalue = (float)decvalue / 100.0; // 输出到PC串口 Serial.println(fltvalue); // 重置状态,准备下一次通信 currentState = STATE_IDLE; memset(responseBuffer, 0, sizeof(responseBuffer)); responseIndex = 0; break; } }
3. 修改主循环
将原MeasureTorque()替换为非阻塞的handleTorqueSensor(),确保Motor.run()能被持续高频调用:
void loop() { CheckButtons(); Motor.run(); // 高频调用保证步进电机流畅运行 CheckQueuedTest(); handleTorqueSensor(); // 非阻塞,不占用主循环时间 }
关键优化点
- 状态机拆分:将串口通信拆分为独立阶段,每个阶段仅处理当前任务,避免阻塞
- 定时发送:用
millis()实现无阻塞定时,控制指令发送频率,平衡数据更新与资源占用 - 修正负数判断:原代码
decvalue>>9999是错误的位运算,改为通过32位整数最高位(0x80000000)识别补码负数 - 逐字节接收:通过
Serial1.available()检查数据是否就绪,仅在有数据时读取,不等待
内容的提问来源于stack exchange,提问作者Elias Taalab
相关产品推荐
相关产品推荐

