GPS-симулятор Arduino: проблемы с программным обеспечением

Для моего проекта мне нужен Arduino Uno для имитации GPS. Для этого мне нужно:

  • Генерировать импульс 5 В раз в секунду (нет проблем)
  • Отправить предложение $GPRMC NMEA с текущим временем через RS-232 (у меня есть экран RS-232)

Сообщение GPRMC, которое мне нужно отправить, выглядит следующим образом:

$GPRMC,075832.293,A,4042.695,N,07400.796,W,,,080120,000.0,W*63

Где первая часть — это время, и ее нужно изменить. Я в основном реализовал это как:

// Настройка
String prefix = "$GPRMC,";
String gprmc  = "075832.293";
String suffix = ",A,4042.695,N,07400.796,W,,,080120,000.0,W*63";
String all = prefix + gprmc + suffix;
char* buff = (char*) malloc(sizeof(char)*all.length()+1);

Затем в коде цикла я обновляю время и хочу отправить сообщение:

//...внутри условия, которое выполняется раз в секунду
gprmc = String(gprmc.toFloat()+1);
all = prefix+gprmc+suffix;
all.toCharArray(buff, all.length()+1);
mySerial.write(buff);

Я использую экран RS-232, который показывает мне, когда сообщение отправляется, миганием светодиода. Однако, похоже, это работает только в том случае, если я сокращаю всю строку, то есть: Работает:

all = prefix+gprmc;

Не работает:

all = prefix+gprmc+suffix;

Возможно ли, что сообщение слишком длинное для отправки? Есть ли способ исправить это? Потому что очень важно отправить сообщение целиком.

Примечание. В настоящее время я работаю над Arduino Uno, но сегодня перехожу на Arduino Leonardo. В настоящее время у меня мало доступной памяти (используется 77%). может ли это усугубить проблему?

Большое спасибо за помощь! :)

, 👍0

Обсуждение

Что вы имеете ввиду под "не работает"? Чего вы ожидали и что происходит на самом деле?, @chrisl

На RS-232 Shield светодиод мигает при отправке сообщения. Под «не работает» я подразумеваю, что сообщение не отправляется (светодиод не мигает), @MarayJay


1 ответ


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

2

Во-первых, несколько комментариев о вашем коде:

  • Никогда не используйте String, если это абсолютно неизбежно
  • Если у вас нет free() для балансировки вашего malloc(), вам почти сразу не хватит памяти
  • Никогда не нужно объединять строки для отправки через последовательный порт таким образом.

Вместо того, что вы делаете сейчас, просто полностью откажитесь от использования String и вашей переменной buf. Нет необходимости объединять вещи вместе — последовательный интерфейс отправляет данные по одному символу за раз, так что вы ничего не получите от объединения и только создадите себе дополнительные проблемы.

Как вы должны это делать:

// Изменяющееся значение как число с плавающей запятой
float gprmc=75832.293;
// Печатаем префикс
mySerial.print(F("$GPRMC,"));
// Дополняем значение нулями
if (gprmc < 10) mySerial.print(F("0"));
if (gprmc < 100) mySerial.print(F("0"));
if (gprmc < 1000) mySerial.print(F("0"));
if (gprmc < 10000) mySerial.print(F("0"));
if (gprmc < 100000) mySerial.print(F("0"));
// Печатаем значение с 3 знаками после запятой
mySerial.print(gprmc, 3);
// Наконец, напечатайте суффикс
mySerial.println(F(",A,4042.695,N,07400.796,W,,,080120,000.0,W*63"));

Обратите внимание на использование макроса F() для дальнейшего сокращения использования оперативной памяти за счет сохранения строковых констант во флэш-памяти.

,

Спасибо! Есть ли разница в том, как сообщение будет передано с помощью mySerial.print(...) или mySerial.write(...)? каким-то образом [пример](http://wiki.seeedstudio.com/RS232_Shield/) использует команду .write(), которая привела к моим проблемам., @MarayJay

Нет. print просто вызывает write, но принимает больше типов параметров., @Majenko