Fixing error IncompleteInput

When you read from a Stream, deserializeJson() and deserializeMsgPack() can return IncompleteInput if a timeout occurs.

Indeed, the stream waits for the data coming from the other peer, but if there is no data for an extended period, the stream returns a timeout error. The timeout is set to 1 second by default, but you can change this value in your program.

To configure the timeout, you must call Stream::setTimeout() before calling deserializeJson() or deserializeMsgPack(), like that:

// set timeout to 10 seconds
Serial.setTimeout(10000);

// read JSON document from Serial
deserializeJson(doc, Serial);

The example above uses the serial port, but you can use the same technique for any class derived from Stream, like EthernetClient, WifiClient, SoftwareSerial.

Still not working?

If increasing the timeout doesn’t solve your problem, you can diagnose the problem with the ReadLoggingStream decorator from the StreamUtils library. This class adds the logging functionality to an existing stream class, so you can see what is read from the stream.

Here is how to use ReadLoggingStream:

// set timeout to 10 seconds
wifiClient.setTimeout(10000);

// decorate the WifiClient so it logs its content to Serial
ReadLoggingStream wifiClientWithLog(wifiClient, Serial);

// read JSON document from the WifiClient
deserializeJson(doc, wifiClientWithLog);

This way, you’ll see where the reading stops and why ArduinoJson returns IncompleteInput.

StreamUtils is a powerful library that deserves more attention. Please give it a star to spread the word.

See also

Global warming stripes by Professor Ed Hawkins (University of Reading)