c++ - 从字符串中提取信息

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

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

我还没有设法在 Servo 上表示汽车的实际速度,我想知道为什么。我很确定问题出在 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 : 1

这是来自的回声截图

Serial.write(NewAngle);

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

非常感谢!

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

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

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

将速度转换为 int 并乘以 1.0。这似乎已经成功了!又是“不知道为什么不行,换个东西,不知道为什么行!”的又一例。

最佳答案

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

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

这里有一个潜在的问题:

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 不寻找这些);速度的小数部分被截断。

关于c++ - 从字符串中提取信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36646395/

相关文章:

c++ - 指向成员的指针选择

c - Arduino Serial.print() 优化

html - 如何使用 HTML5 Canvas 为轨道上的物体制作动画?

c++ - C++ 中的新增功能

c++ - 在DOS上作图用什么?

c++ - gdb : examining whatis to intelligently print values

Arduino无需屏蔽即可上网

c - pgm_read_ 和 PROGMEM - 意外行为

c++ - 一群士兵一起在网格 map 上移动

ios - Spritekit物理: One ball hit another ball