Модуль GPS выводит вопросительные знаки в последовательном окне

У меня есть GPS-модуль uBlox Neo 7N, и я настроил его так, что если нет входящих данных, он печатает нет местоположения, а если есть, то печатает широту и долготу. Однако он печатает ?,?.

Поэтому я предполагаю, что он подключен правильно, поскольку я получаю вывод, однако, возможно, мой код не позволяет ему вывести два длинных числа, поэтому вместо этого преобразует их в ?.

  char buf[128];   
  if (gps.location.isValid()) {
    snprintf(buf, sizeof(buf), "%lf,%lf", gps.location.lat(), gps.location.lng());
    Serial.println(buf);
  }

EDIT Я знаю, что получаю чтение, так как я установил две переменные типа double lat и long равными gps.location.lat() и gps.location.lng() соответственно, и я получаю число. Как мне исправить эту строку snprintf, чтобы она печаталась правильно?

, 👍2

Обсуждение

Когда платы Arduino использовали atmega8, памяти было так мало, что они решили убрать поддержку плавающей точки для s(n)printf. Вместо того, чтобы позволить пользователям решать, использовать sprintf или нет, они просто убрали ее. Это вызвало массу проблем. В 2018 году ее все еще нет, что возмутительно. Извините, что вы столкнулись с этой проблемой. Вам нужно сделать обходной путь. Его можно привести к unsigned long или использовать функцию dstrtof, а сам Serial.println поддерживает переменные с плавающей точкой. Uno не поддерживает 64-битные double, только 32-битные переменные с плавающей точкой., @Jot

Ого, ну это имеет смысл. Спасибо за ответ, попробую вашу рекомендацию!, @Explorex

Упс, это «dtostrf»., @Jot

Я бы попробовал настроить скорость передачи данных, на которой ваш arduino или MCU считывает поток данных GPS. Я предполагаю, что поток неправильно интерпретируется., @j0h


1 ответ


Лучший ответ:

3

Для sprintf нет плавающей точки, выводится «?».

Функции sprintf, sscanf и подобные функции (snprintf и другие) не поддерживают операции с плавающей точкой для микроконтроллеров AVR.

История

Одна из первых плат Arduino использовала микроконтроллер Atmega8 с всего лишь 8k flash и 1k sram. Важно было обеспечить высокую эффективность памяти.
Компилятор gcc не включил автоматически библиотеки поддержки плавающей точки для функций sprintf, однако их было легко включить. Arduino решила не включать эти дополнительные библиотеки, поскольку они используют дополнительную память.

Arduino имеет препроцессор, компилятор и компоновщик, который пытается использовать только тот код, который действительно используется. sprintf не знает во время компиляции, будет ли использоваться плавающая точка, поэтому ему пришлось бы включить эти дополнительные библиотеки поддержки плавающей точки, независимо от того, использовались они или нет.

Сейчас 2018 год, а он, к сожалению, все еще не включен.

Временное решение

  • Функции Serial.println могут печатать переменные с плавающей точкой. Однако они не могут печатать вывод в экспоненциальном формате. Они округляют выводимое значение до ближайшего числа.
  • dtostrf() и dtostre() преобразуют переменную float в текст. dtostre() предназначен для научной записи.
  • Переменная типа float может быть приведена к целому числу.
  • Строковый объект Arduino может обрабатывать число с плавающей точкой.

Только float для микроконтроллеров AVR, нет double.

Микроконтроллеры avr — это 8-битные микроконтроллеры. Для 64-битных переменных double нет библиотеки с плавающей точкой, есть только библиотека для 32-битных переменных float.
Эта библиотека соответствует стандарту IEEE, она чрезвычайно быстра и оптимизирована.

,