从字符串中提取信息

Extracting info from a string

我一直在尝试用游戏中的汽车速度来驱动 Arduino 伺服系统 "Assetto Corsa"。我已经设法使用共享内存从游戏中提取实时数据,并试图通过串行端口将其发送到 Arduino。

我还没有设法在伺服上代表汽车的实际速度,我想知道为什么。我很确定问题出在 Arduino 代码上,我可以提取汽车的速度,但我不确定如何正确使用它。也许你能帮忙?

这是 Arduino 代码摘录:

char inData[8];    
char inChar; // Where to store the character read
byte index = 0; // Index into array; where to store the character
int angle = 0;
int newAngle = 0;
int MaxChars = sizeof(inData);
char ch;


      while (Serial.available())
      {
        char ch = Serial.read();
        Serial.write(ch);
        if (index < MaxChars && isDigit(ch))
        {
          inData[index++] = ch;
        }
        else
        {
          inData[index] = 0;
          newAngle = atoi(inData);
          Serial.write(newAngle);
          if (newAngle > 0 && newAngle < 180)
          {
            if (newAngle < angle)
              for (; angle > newAngle; angle -= 1)
              {
                myServo.write(angle);
              }
            else
              for (; angle < newAngle; angle += 1)
              {
                myServo.write(angle);
              }
          }
          index = 0;
          angle = newAngle;
          delay(1000);
        }
      }

这是我用来从游戏中提取信息并将其发送到 Arduino 的代码:

while (true)
{

    snprintf(Data, sizeof(Data)-1, "%3.3f", pf->speedKmh);

    SP->WriteData(Data, sizeof(Data));              

    std::this_thread::sleep_for(std::chrono::milliseconds(1000));

    int readResult = SP->ReadData(inData, sizeof(inData));

       printf("\t Bytes read:  %i\n",readResult);

       for (int i = 0; i < sizeof(inData); i++)
       {
           printf("%i", inData[i]);
           inData[i] = 0;
       }
}

Output screenshot:

这是来自

的回声截图
Serial.write(NewAngle);

我用黄色勾勒出了汽车的速度。我的问题是:如何从接收到的数据中提取这个速度以与 Arduino Servo 一起使用?

非常感谢!

------------更新----------

有效!非常感谢,这是我改变的:

snprintf(Data, sizeof(Data)-1, "%3.3f", (int)(pf->speedKmh)*1.0);

将速度转换为 int 并乘以 1.0。这似乎已经成功了!这是 "Don't know why it doesn't work, change something, don't know why it works!"

的另一种情况

主要问题是这些短 "messages"(只是一个数字)没有任何框架。延迟或睡眠不算作帧,因为两个系统的时间不同步。

我建议在数字之间加一个换行符,这样您就可以知道一个数字在哪里结束,下一个数字从哪里开始。并注意两个系统上 '\n' 的差异...您可以显式发送 (char)10(char)13 并在接收器中观察相同的字节。如果字符丢失,框架将允许您重新同步到消息边界。这也可以让您消除 Arduino 端的 delay,这是一件非常好的事情。

这里有一个潜在的问题:

if (index < MaxChars&& isDigit(ch))
{
  inData[index++] = ch;
}
else
{
  inData[index] = 0;

测试应该是 index < MaxChars-1 因为你为 NUL 终止添加了一个字符。

当在 xbox 上打印接收到的字节时,您应该在数组元素之间放置一个分隔符:printf("%i,",inData[i])您正在查看的数字可能是 2 和 3,或 23,或 238 .

我建议进行微小的更改:您正在发送一个浮点值,但随后您将接收到的字符串(在非数字处停止后)转换为具有 atoi 的整数。下一次循环时,你会得到你还没有读过的任何字符。您也可以将值作为整数发送:(int)(speed*100.0)。这也避免了另外两个问题:当速度 < 100.0 时,%f3.3 将用空格填充(Arduino 不寻找这些);和速度的小数部分被截断。