我正在做一个Arduino项目,根据iRacing中的车速进行风扇旋转 . 这是我的第一个arduino项目,所以请耐心等待 . 我对PC / Arduino串口通讯的一些奇怪行为感到困惑,我希望有人可以帮忙解释一下发生的事情......
基本上,PC上有一个C程序可以从iRacing SDK获取车辆速度的数据,并通过串行线路将数据发送到Arduino . Arduino进行一些简单的处理并驱动电机控制器来运行风扇 .
我试图理解的现象是,如果我使用Serial.print()语句让Arduino对串行编写过多,它会破坏使用Serial.parseInt()读取的值 .
我只是没有将"too much"写入串行线,但是有一段时间它表现不正常 - 即使iRacing值稳定,风扇速度也会上升和下降 . 我在我的arduino sketch和serial.readSerial中添加了额外的Serial.print内容,试图在PC端看到这些值发生了什么,事实证明这让事情变得更糟 .
把我的头发拉了一下之后,我从头开始在arduino草图上使用了所有相同的逻辑,但是将Serial.print命令注释掉了!所以我系统地将它们添加回去,发现存在一些阈值,如果我在串行线上打印太多,它就会出现故障 .
这是PC上工作时看到的输出 . PC正在向Arduiono发送59作为int . Arduino正在接收Serial.parseInt(),将constrain()做为55,然后将其映射到40-255范围 . 最小的Serial.print()语句将该数据发送回PC并在其中进行读取和打印 . 一切都很好 .
59 55 255
59 55 255
59 55 255
59 55 255
59 55 255
59 55 255
59 55 255
59 55 255
如果我添加更多的Serial.print()语句来描述数据,那么我从具有Serial.parseInt()的PC读取的值开始受到干扰 . 此输出显示了我发现的情况 . 数据看起来搞砸了,确实风扇速度变得混乱 . 这与上面的情况相同,应该稳定在59:
Car Vel: 59 55 255
Car Vel: 59 55 255
Car Vel: 9 9 71
Car Vel: 47 47 223
Car Vel: 59 55 255
Car Vel: 59 55 255
Car Vel: 9 9 71
Car Vel: 47 47 223
Car Vel: 59 55 255
Car Vel: 71 55 255
Car Vel: 47 47 223
Car Vel: 59 55 255
Car Vel: 59 55 255
这里是一直简化的Arduino草图,所以它只是从PC读取int,约束它,将它映射到一个范围并打印值 . 如下所示,它会发生故障并产生输出(如上面的第二个清单) . 如果我注释掉“Car Vel:”打印,那么它可以工作并且数据是稳定的(就像上面的第一个列表一样) .
#define MIN 40
#define MAX 255
#define TOPSPEED 55
void setup() {
Serial.begin(9600);
}
void loop() {
uint8_t v;
uint8_t s;
if (Serial.available() > 0) {
v = Serial.parseInt();
Serial.print("Car Vel: "); //UNCOMMENT ANY OF THESE TO SEE THE FAIL
Serial.print(v);
Serial.print("\t");
v = constrain(v,0,TOPSPEED);
// Serial.print("Clamped Vel: "); //UNCOMMENT ANY OF THESE TO SEE THE FAIL
Serial.print(v);
Serial.print("\t");
s = map(v,1,TOPSPEED,MIN,MAX);
// Serial.print("Fan Speed: "); //UNCOMMENT ANY OF THESE TO SEE THE FAIL
Serial.println(s);
}
}
在PC端,我使用iRacing SDK中的irsdk_ir2ad C代码,只修改了run()例程,如下所示:
void run()
{
// wait up to 16 ms for start of session or new data
if(irsdkClient::instance().waitForData(16))
{
// and grab the data
int v = g_carVelX.getInt();
serial.writeSerialPrintf("%d\n", v);
}
// check for data coming back from Arduino
if (serial.serialHasData())
{
static char buffer[256];
serial.readSerial(buffer, 256);
printf("%s", buffer);
}
monitorConnectionStatus();
}
我有信心取消注释Serial.print行确实会出现问题,但我没有真正好的解释原因 . 有人可以帮忙吗?是某种超出的发送长度(似乎是一个非常少量的文本)?或者当Arduino正在编写自己的数据时,从PC上写入的数据太多了?或者某种时间选择,它只是额外的时间而不是与写入的数据量有什么关系?
1 回答
答案结果证明是9600波特的字符限制 .
在这种特殊情况下,PC正在以60Hz获得数据 . 在9600波特率下,串行线路每个周期只能处理16个字符 .
尝试输出整个字符串超过了16字节限制:“Car Vel:59 55 255”
实验表明,如果我将组合的发送/接收数据降低到<= 16字节,则它始终没有错误 .