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%). может ли это усугубить проблему?
Большое спасибо за помощь! :)
@MarayJay, 👍0
Обсуждение1 ответ
Лучший ответ:
Во-первых, несколько комментариев о вашем коде:
- Никогда не используйте
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
- Ардуино для чтения с преобразователя RS232 в последовательный модуль TTL
- Как читать и записывать на устройство rs232 с/на Arduino
- последовательная передача данных на GPS-экране duinopeak
- GSM и GPS-модуль не работают вместе
- как заставить щит GPRS/GSM SIM900 работать с модулем gps neo-6M с помощью платы Arduino UNO
- vk2828u7g5lf GPS модуль над SoftwareSerial
- Использование Arduino для чтения и записи данных на устройство RS232
- Искаженный серийный номер устройства GPS
Что вы имеете ввиду под "не работает"? Чего вы ожидали и что происходит на самом деле?, @chrisl
На RS-232 Shield светодиод мигает при отправке сообщения. Под «не работает» я подразумеваю, что сообщение не отправляется (светодиод не мигает), @MarayJay