ArduinoJson читает `null` из последовательного порта
У меня есть установка, которая считывает данные из последовательного порта, когда я чувствую, что есть что-то, что нужно прочитать (и всегда предполагаю, что то, что отправляется на Arduino, является действительным json):
void setup(){
Serial.begin(9600);
while (!Serial) continue;
}
void loop() {
if(Serial.available()){
StaticJsonDocument<256> doc;
deserializeJson(doc, Serial);
serializeJson(doc, Serial);
Serial.println();
}
}
Учитывая следующий ввод от последовательного монитора ArduinoIDE (установите настройку newline
, 9600
бод):
{"hello": "world"}
Это приводит к следующему:
{"hello": "world"}
null
У меня два вопроса:
- Правильна ли эта настройка/как мне следует ждать и получать JSON из последовательного порта?
- Зачем нужен дополнительный ввод
null
? Похоже, что-то еще осталось в последовательном буфере даже после первой итерации? Как обнаружить второй случай, когда результирующий документ повторно сериализуется какРазобрался с этим, узнал оnull
? Сравнение с0
,NULL
иnullptr
, кажется, не работаетDeserializationError
При использовании DeserializationError
похоже, что при синтаксическом анализе null
произошла ошибка EmptyInput
@Snappawapa, 👍1
Обсуждение1 ответ
Как видно в настройках последовательной консоли
, здесь упоминаются как новая строка, так и 9600 бод. Давайте разберемся:
Проблема с последовательным соединением
Частичная полезная нагрузка. В настоящее время вы предполагаете, что когда
Serial.available()
возвращаетtrue
, вся полезная нагрузка JSON была полученный. Однако из-за особенностей последовательной связи (особенно при скорости 9600 бод) данные могут поступать фрагментированными частями. ВызовdeserializeJson()
для части полезных данных JSON может привести к неполным или поврежденным данным.Неоднозначность конца сообщения. Отсутствие четкого маркера конца сообщения затрудняет определение момента получения полной полезной нагрузки JSON. Например, при отправке
{"hello": "world"
с последовательного монитора Arduino IDE он автоматически добавляет новую строку (или возврат каретки в зависимости от вашей конфигурации). Эта новая строка затем ошибочно интерпретируется как другая полезная нагрузка JSON, что приводит к нежелательному выводуnull
.
Как это решить:
Использовать разделитель. Выберите определенный символ или последовательность, которая будет использоваться в качестве разделителя конца сообщения. Символ новой строки (
\n
) является типичным выбором, особенно если данные передаются исключительно с последовательного монитора Arduino IDE. Тем не менее, если вы ожидаете появления новых строк в своих данных JSON, вы можете использовать другой отдельный символ, например#
.Читать до разделителя: настройте свой код так, чтобы он непрерывно считывал символы из последовательного порта до тех пор, пока не встретится выбранный разделитель. После получения всего сообщения его можно проанализировать.
Пример кода
Вот пример кода, в котором в качестве разделителя используется символ новой строки:
const int maxBuffer = 256;
char serialBuffer[maxBuffer];
int bufferPos = 0;
void setup() {
Serial.begin(9600);
while (!Serial) continue;
}
void loop() {
if (Serial.available()) {
char inChar = Serial.read();
if (inChar == '\n') { // EOM
serialBuffer[bufferPos] = '\0';
processMessage(serialBuffer);
bufferPos = 0; // Сброс позиции буфера
} else if (bufferPos < maxBuffer - 1) { // Избегаем переполнения буфера
serialBuffer[bufferPos++] = inChar;
}
}
}
void processMessage(char* message) {
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, message);
if (error) {
Serial.println("Failed to parse JSON");
} else {
serializeJson(doc, Serial);
Serial.println();
}
}
Таким образом, вы гарантируете, что сообщение будет проанализировано и получено целиком и, следовательно, избежите нежелательных выводов null
.
Надеюсь, это поможет ^_^
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Ошибка "'Serial' does not name a type"
- Построение графика на Python с использованием Tkinter Canvas
- Команда strtok() с Serial связью
- Как отправить целое число через pyserial с Python на Arduino и получить тот же результат?
- Сделать плату Arduino одновременно и USB-накопителем, и клавиатурой?
- Ошибка 'Serial' was not declared in this scope
- Как изменить переменную при нажатии кнопки, подключенной к контакту 2
что отправляет данные? ... каковы фактические данные, которые отправляются?, @jsotola
Последовательная консоль Arduino IDE, @Snappawapa
тогда данные ручного ввода.... каковы настройки последовательной консоли? ... существует более одной настройки, @jsotola
Обновлено, чтобы показать функцию настройки., @Snappawapa
Я сказал настройки «последовательной консоли», @jsotola
Обновлено для отображения настроек (новая строка, 9600 бод)., @Snappawapa