从字符串中提取信息

时间:2016-04-15 11:50:41

标签: c++ arduino game-physics serial-communication

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

我还没有设法代表赛车的实际速度,我想知道为什么。我很确定问题来自Arduino Code,我可以提取汽车的速度,但我不确定如何正确使用它。也许你可以帮忙吗?

这是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 screenshot1

这是来自

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

我用黄色概述了汽车的速度。我的问题是:如何从我收到的数据中提取此速度以将其与Arduino伺服一起使用?

非常感谢!

---------- ---------- UPDATE

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

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

将速度转换为int并乘以1.0。这似乎已经成功了!这是另一个案例&#34;不知道为什么它不起作用,改变一些东西,不知道它为什么起作用!&#34;

1 个答案:

答案 0 :(得分:2)

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

我建议在数字之间加一个换行符,这样你就可以知道一个数字的结束位置和下一个数字的开始位置。并注意&#39; \ n&#39;在两个系统上......您可以明确发送(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)。这也避免了另外两个问题:当速度<1时,%f3.3将填充空格。 100.0(Arduino不会寻找这些);速度的小数部分被截断。