1

I have a setup that reads from serial when I sense that there is something to be read (and always assume that what is sent to the arduino is valid 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();
    }
}

Given the following input from ArduinoIDE's serial monitor (Set to newline setting, 9600 baud):

{"hello": "world"}

This produces the following:

{"hello": "world"}
null

I have two questions:

  • Is this setup correct/ how I should be waiting and retrieving json from serial?
  • Why the additional null input? Looks like there is something still in the serial buffer even after the first iteration?
  • How to detect the second case where the resulting document gets re-serialized as null? Comparing to 0, NULL, and nullptr seem to not work Figured this one out, found out about DeserializationError

Upon utilizing DeserializationError, looks like the null parsing had an error of EmptyInput

6
  • what is sending the data? ... what is the actual data that is sent?
    – jsotola
    Aug 31, 2023 at 19:01
  • The Arduino IDE serial console
    – Snappawapa
    Aug 31, 2023 at 19:02
  • manual input data then .... what are the serial console settings? ... there is more than one setting
    – jsotola
    Aug 31, 2023 at 19:05
  • Updated to show setup function
    – Snappawapa
    Aug 31, 2023 at 19:06
  • I said serial console settings
    – jsotola
    Aug 31, 2023 at 19:08

1 Answer 1

1

As observed on your serial console settings, it mentions both newline and 9600 baud. Let's break this down:

Issue with Serial Communication

  1. Partial Payloads: You are currently assuming that when Serial.available() returns true, the entire JSON payload has been received. However, due to the nature of serial communication (especially at 9600 baud), data can arrive in fragmented chunks. Invoking deserializeJson() on a partial JSON payload can result in incomplete or corrupted data.

  2. End-of-Message Ambiguity: Lacking a definitive end-of-message marker makes it challenging to discern when a complete JSON payload has been received. For instance, when sending {"hello": "world"} from the Arduino IDE's serial monitor, it automatically appends a newline (or a carriage return based on your configuration). This newline is then misinterpreted as another JSON payload, leading to the undesired null output.

How you can solve this:

  1. Use a Delimiter: Choose a specific character or sequence to act as an end-of-message delimiter. The newline character (\n) is a typical choice, especially if data is exclusively sent from the Arduino IDE's serial monitor. Nevertheless, if you anticipate newlines within your JSON data, you might consider another distinct character, like #.

  2. Read Until Delimiter: Adjust your code to continuously read characters from the serial port until the chosen delimiter is encountered. Upon receipt of the entire message, it can then be parsed.

Code Example

Here's a sample code employing the newline character as a delimiter:

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;  // Reset buffer pos
        } else if (bufferPos < maxBuffer - 1) {  // Avoid buffer overflow
            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();
    }
}

This way you ensure the entirety of message is parsed and received and therefore avoiding unwanted null outputs.

I hope this helps ^_^

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.