如何修复我的代码从serial1接收数据并按下一个值并将其发送到serial0,同时运行步进电机 &



我有一个大代码的以下部分,它发送一个十六进制代码到一个扭矩传感器认为serial1,并收到一个响应,然后它将十六进制值转换为十进制,将十进制转换为浮点数,然后将其发送到serial0 (pc)。

这应该在步进电机使用Accelstepper库运行时发生。

电机在没有MeasureTorque()函数的情况下运行快速平稳,但在使用MeasureTorque()函数时,步进速度很慢。

据我所知,Serial1。Readbytes在步骤之间阻塞了我的代码,那么在不阻塞代码的情况下做同样的事情的另一种方法是什么?

我使用arduino mega2560,如果这很重要。

下面是代码的相关部分:

void MeasureTorque(){
Serial1.write(getvalue, sizeof(getvalue));

Serial1.readBytes(response, sizeof(response));
decvalue = (response[3]<<24) | (response[4]<<16) | (response[5]<<8) | response[6];
if(decvalue>>9999){
decvalue = -(4294967296-decvalue);
fltvalue = (float)decvalue/100.0;
}
else{
fltvalue = (float)decvalue/100.0;
}
Serial.println(fltvalue);

memset(response, 0, sizeof(response));
decvalue=0;
fltvalue=0;

}
void loop() {
CheckButtons();
Motor.run();
CheckQueuedTest();
MeasureTorque();
}

我试图使代码在一个循环周期内一次接收一个字节,但它没有工作,似乎我不明白应该怎么做。

当使用MeasureTorque()函数时,步进器太慢了

这是因为您没有把握在MeasureTorque()中花费的时间间隔. 在loop()中包含一个新例程影响Motor.run(),这可能与问题直接相关。

Serial1.write ()需要时间来执行,就像Serial1.readBytes()以(). I/O在源代码中看起来微不足道,但是可以/将会消耗CPU周期(或者如果内核支持的话会导致任务挂起)。

但是最重要的时间杀手可能是调用Serial1.readBytes()时等待响应所导致的未知长度的隐藏时间延迟。. 在等待传感器处理请求并生成/发送其响应时,您的处理循环已死在水中。

保留简单循环以执行所有"任务"的解决方案;涉及分解MeasureTorque()到"tasklets"快速执行loop()的迭代以合理的速度发生。每次调用MeasureTorque()循环()被修改为只执行一个微线程。以便只消耗合理的执行时间。这个解决方案将使用一个简单的状态机来选择哪个微线程;在每次调用时执行的度量扭矩().

状态机由变量mt_state控制。mt_state的值决定了MeasureTorque()将在调用时执行。但是在之前,MeasureTorque()返回,mt_state被更新,使不同的微线程"可在下次通话时执行


void MeasureTorque()
{
static int mt_state = 0;
static unsigned char getvalue = { ... };
static int decvalue;
static float fltvalue;
static unsigned char response;
switch (mt_state) {
default:
/* report invalid state */
...
mt_state = 0; /* try to recover */
/* fall through */
case 0:
memset(response, 0, sizeof(response));
decvalue = 0;
fltvalue = 0;
++mt_state;
break;
case 1:
Serial1.write(getvalue, sizeof(getvalue));
++mt_state;
break;
case 2:  /* optimization for slow responses */
if (response_is_available())
++mt_state;
/* else repeat this state */
break;
case 3:
Serial1.readBytes(response, sizeof(response));
++mt_state;
break;
case 4:
/* perform calculations on response */
...
++mt_state;
break;
case 5:
Serial.println(fltvalue);
mt_state = 0; /* restart state machine */
break;
}
return;
}

相关内容

  • 没有找到相关文章

最新更新