我有一个大代码的以下部分,它发送一个十六进制代码到一个扭矩传感器认为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;
}