首页 文章

Arduino Serial.parseInt()数据读取太多Serial.print()?

提问于
浏览
-1

我正在做一个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 回答

  • 1

    答案结果证明是9600波特的字符限制 .

    在这种特殊情况下,PC正在以60Hz获得数据 . 在9600波特率下,串行线路每个周期只能处理16个字符 .

    尝试输出整个字符串超过了16字节限制:“Car Vel:59 55 255”

    实验表明,如果我将组合的发送/接收数据降低到<= 16字节,则它始终没有错误 .

相关问题