Серийный выпуск печати - PullRequest
0 голосов
/ 31 мая 2019

Я работаю над последовательной связью между двумя MCU, особенно подростковыми (похожими на Arduino) для генерации поддельных данных GPS.Я был в состоянии записать данные GPS и прочитать с другого MCU хорошо, но если вы посмотрите внимательно, данные, которые печатаются, имеют некоторую неоднозначность.Последние значения как-то меняются, и я не понимаю, почему это из-за команды sprintf или преобразования float в string или как?

Будет полезна некоторая помощь.

Ниже приведены рабочий код и фрагмент последовательного терминала.

Спасибо

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 голосов
/ 31 мая 2019

То, что вы видите, является приближением компилятора ваших значений с плавающей точкой, потому что их значения превышают точность, возможную с помощью числа с плавающей точкой (4 байта). Использование двойного не поможет, если ваш MCU не поддерживает 8-байтовые двойные числа; Я не использовал тинси, но я сильно сомневаюсь, что он поддерживает 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
  ); 

Однако , если необходимы математические операции - сложение, вычитание и т. Д. - это не обрезает; найти произвольную библиотеку больших чисел, такую ​​как Ника Гаммона

Наконец, будьте осторожны: в вашем коде str1 слишком маленький - нет никакого учета нулевого терминатора, добавляемого sprintf, так что вам просто повезло, что ваша программа не дает сбоя.

...