Получение всех данных моего объекта JSON из Serial.read() сразу

Я новичок в Arduino и создаю проект, который извлекает данные с веб-сайта (используя ESP8266), а затем передает их на мой Arduino UNO через последовательный порт.

Данные, поступающие от с ESP8266 каждый 20 - х гг. [{"Х": 0,"г": 0,"РГБ": [255, 200, 174]},{"х": 1,"г": 0,"РГБ": [255, 200, 174]},{"х": 2,"г": 0,"РГБ": [255, 200, 174]}]

Но когда я печатаю данные вот так


void loop() {
  
  if (Serial.available()) {
    Serial.write(Serial.read()); // This line prints only one character out of whole string
    
    data =  Serial.read(); // so this doesn't work

    DeserializationError error = deserializeJson(response, data);
    if (error) {
      Serial.print(F("deserializeJson() failed: "));
      Serial.println(error.f_str());
      return;
    }
    for (JsonObject elem : response.as<JsonArray>()) {
      int x = elem["x"]; // 2, 2, 2
      int y = elem["y"]; // 2, 2, 2
      JsonArray rgb = elem["rgb"];
    
      int rgb_0 = rgb[0]; // 255, 255, 255
      int rgb_1 = rgb[1]; // 255, 255, 255
      int rgb_2 = rgb[2]; // 255, 255, 255
      //Serial.print(x);
    }
  }
  delay(1000);   //then it waits 1 second and goes from the start
}

Как я могу сделать так, чтобы получить всю строку и сохранить ее в переменную?

Большое спасибо за ответ.

, 👍3

Обсуждение

В сериале нет такого понятия, как "целая строка". Существует только один байт. Ваша задача-решить (и запрограммировать его так, чтобы он понимал), что такое строка., @Majenko

Тогда как я могу наблюдать, например, за разрывом строки?, @krystof18

Почему вы думаете, что вам это нужно? И если вы хотите получить последовательные данные в переменную, а затем использовать эти последовательные данные для чего-то другого, просто используйте то, что вы сохранили в своей переменной. Как только вы читаете из сериала, он исчезает из сериала навсегда. Но вы сохранили его в "данных", так что просто используйте его оттуда?, @Majenko

А как насчет Serial.readStringUntil() и read to e. g. \n?, @Python Schlange


1 ответ


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

6

Я собирался сказать это как комментарий, но, может быть, это и есть ответ:

Как бы то ни было, ArduinoJson , похоже , способен десериализоваться непосредственно из потока, то есть серийного, что может устранить заданный вопрос. По-видимому, он знает, где остановить десериализацию, потому что он знает, когда он получил весь объект JSON; будучи правильным синтаксическим анализатором JSON, он, вероятно, может решить эту проблему лучше, чем вы, не написав синтаксический анализатор JSON.

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

#include <ArduinoJson.h>


void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
  Serial.setTimeout(30000);
}


void print_transmission_counter( {
    static unsigned long received_object_counter;
    Serial.println(F("\n\n\n\n"));
    for (int i = 0; i < 30; ++i) {
        Serial.write('-');
    }
    Serial.write('[');
    Serial.print(received_object_counter++);
    Serial.println(']');
}


void loop() {
    static StaticJsonDocument<256> json_doc;
    static bool led_state;

    print_transmission_counter();

    const auto deser_err = deserializeJson(json_doc, Serial);
    if (deser_err) {
        Serial.print(F("Failed to deserialize, reason: \""));
        Serial.print(deser_err.c_str());
        Serial.println('"');
    } else  {
        Serial.print(F("Recevied valid json document with "));
        Serial.print(json_doc.size());
        Serial.println(F(" elements."));
        Serial.println(F("Pretty printed back at you:"));
        serializeJsonPretty(json_doc, Serial);
        Serial.println();
    }


    // Just give some visual indication that the loop is progressing
    led_state = !led_state;
    digitalWrite(LED_BUILTIN, led_state);
}


//  vim:sw=2:ts=2:et:nowrap:ft=cpp:
,

Большое спасибо, это похоже на то, что мне нужно., @krystof18

**Если** это в конечном итоге окажется выбранным вами путем, **и**, если это не приведет к аннулированию любых других ответов (которые могут появиться в промежутке времени), вы можете немного изменить заголовок вопроса на "Получение всех данных моего объекта JSON из Serial.read() сразу", чтобы улучшить поиск и сопоставление между вопросом и ответом., @timemage

Это определенно выглядит как отличный способ сделать это, но я, похоже, не могу заставить его работать, когда я меняю переменную "данные" на " Serial.read ()", как это "Ошибка ошибки десериализации = deserializeJson(ответ, Serial.read()); Я получаю" Ошибка компиляции для платы arduino UNO, @krystof18

Это может занять некоторое время, но я перечитаю ваш комментарий выше и посмотрю, не смогу ли я привести минимальный пример. Документация по ArduinoJson довольно хороша, поэтому я ожидаю, что она там тоже будет., @timemage

@krystof18, пожалуйста, взгляните на [Как обеспечить последовательную связь между двумя платами?](https://arduinojson.org/v6/how-to/do-serial-communication-between-two-boards/), @Benoit Blanchon

@krystof18, в отношении конкретной строки, приведенной выше, ожидается ссылка на "Поток, который является "Последовательным". Вызывая". read (), вы пытаетесь передать один символ (или указание на отсутствие символа; -1) в функцию "deserializeJson"., @timemage

@BenoitBlanchon, вы не возражаете, если я внесу ваш комментарий в текст ответа?, @timemage

@timemage, я не возражаю; пожалуйста, сделайте это., @Benoit Blanchon