3

I'm new to Arduino and I'm building a project that fetches data from a website (using ESP8266) and then transfers them to my Arduino UNO via serial port.

Data coming from ESP8266 every 20s - [{"x": 0,"y": 0,"rgb": [255, 200, 174]},{"x": 1,"y": 0,"rgb": [255, 200, 174]},{"x": 2,"y": 0,"rgb": [255, 200, 174]}]

But when I print the data like this


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
}

How can I make it to get the whole string and save it into a variable?

Thanks, much for answering.

4
  • 1
    There is no such thing as "a whole string" in serial. There is only single bytes. It is your job to decide (and program it so it understands) what a string is.
    – Majenko
    Commented May 22, 2021 at 15:06
  • Then how can I watch for example for line break?
    – krystof18
    Commented May 22, 2021 at 15:15
  • WHy do yoiu ithink you need to? And if you want to get serial data into a variable and then use that serial data for some other thing, just use whatever you stored in your variable. Once you read from serial it's gone from serial forever. But you saved it in data, so just use it from there?
    – Majenko
    Commented May 22, 2021 at 15:19
  • What about Serial.readStringUntil() and read to e. g. \n? Commented May 22, 2021 at 16:05

1 Answer 1

6

I was going to put this as a comment, but maybe it belongs as an answer:

For what it's worth, ArduinoJSON seems to be able to deserialize directly from a stream, i.e. Serial, which may obviate the question as asked. Presumably it knows where to stop deserializing, because it knows when it has received an entire JSON object; being a proper JSON parser, it can probably work this out better than you can without, you know, writing a JSON parser.

The following was just thrown together, now the author is here you should probably just follow their direction, but here's the code anyway:

#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:
8
  • Thanks much, this sounds like the thing I need.
    – krystof18
    Commented May 22, 2021 at 15:18
  • If this ends up being the route you take, and doing so doesn't invalidate any other answers (that may appear between now and then), you might consider changing the question title slightly to "Getting all data of my JSON object from Serial.read() at once" to improve findability and matching between question and answer.
    – timemage
    Commented May 22, 2021 at 15:39
  • It definitely looks like a great way to do it, but I can't seem to make it work, when I change the data variable to Serial.read() like this DeserializationError error = deserializeJson(response, Serial.read()); I get ` Error compiling for board arduino UNO`
    – krystof18
    Commented May 22, 2021 at 15:43
  • It may be a while, but I'll reread your comment above and see if I can't provide a minimal example. The ArduinoJSON documentation is quite good though, so I expect there will be one there as well.
    – timemage
    Commented May 22, 2021 at 15:53
  • 1
    @krystof18, please have a look at How to do serial communication between two boards? Commented May 22, 2021 at 16:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.