串行通讯打印问题

时间:2019-05-31 08:37:51

标签: serial-port printf serial-communication teensy

我正在研究两个MCU(尤其是Arduino)之间的串行通信,以生成伪造的GPS数据。我已经能够写入GPS数据并可以从其他MCU读取数据,但是如果您仔细观察,则打印出的数据有一些歧义。最后的值以某种方式更改,我不明白为什么这是因为sprintf命令或将float转换为字符串还是什么?

一些帮助将不胜感激。

下面是串行终端的工作代码和摘要。

谢谢

float lat = 37.4980608;
char str1[21];

void setup()
{
  Serial3.begin(115200);
  Serial.begin(115200); // Config serial port (USB)

  while(!Serial);
  while(!Serial3);

  Serial.println("Sending gps data");
}

void loop()
{
  sprintf(str1, "%.7f%.7f", lon, lat);
  Serial.println(str1);
  Serial3.write(str1);
  Serial3.flush();
  delay(500);
}

Result

1 个答案:

答案 0 :(得分:0)

您看到的是编译器对float的近似值,因为它们的值超出了float可能达到的精度(4字节)。除非您的MCU支持8字节的双精度字,否则使用双精度字将无济于事。我还没用过,但是我非常怀疑它是否支持8字节的双打。

这不是一个聪明的解决方案,但是它应该使您指向正确的方向。

定义一个可以表示大实数值的结构

typedef struct {
    int whole;
    unsigned long fraction;
} BigNumber;

您可以声明/初始化纬度和经度

BigNumber latitude { 126, 9653503 };
BigNumber longitude { 37, 4980608 };

然后打印很容易:

sprintf(strbuf, "%i.%lu %i.%lu", 
    latitude.whole, latitude.fraction, 
    longitude.whole, longitude.fraction
  ); 

但是,如果必须进行数学运算-加,减等-这不会减少;找到一个像Nick Gammon's

这样的任意大数字库

最后,请当心:您的代码中 str1 太小了-sprintf附加的空终止符没有说明,因此您很幸运,程序没有崩溃。 / p>