0

我正在研究两个 MCU 特别小的(类似于 Arduino)之间的串行通信,以生成假 GPS 数据。我已经能够很好地写入 GPS 数据并从其他 MCU 读取,但如果你仔细观察,打印的数据有些模糊。最后一个值以某种方式更改,我不明白为什么这是因为 sprintf 命令或将浮点数转换为字符串或什么?

一些帮助将不胜感激。

以下是串行终端的工作代码和片段。

谢谢

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);
}

结果

4

1 回答 1

0

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

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

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

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

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

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

然后打印很容易:

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

但是,如果需要数学运算——加法、减法等——这不会削减它;找到像Nick Gammon 的任意大数库

最后,请注意:在您的代码中str1太小 - 没有考虑 sprintf 附加的空终止符,因此您很幸运您的程序没有崩溃。

于 2019-05-31T13:46:03.787 回答