I2C with two arduino using JSON issue

I’m trying to send and receive some values simulated with two arduinos using JSON.

in the first code (for the first arduino A which will send the data) it will be deserialized an object called doc that is received from B, where there’s an element “type”.
If this doc[“type”] = “request” we enter the if statement and the arduino A serialize an object with these simulated data ready to be sent to arduino B.

My problem is that I’m able to read the value that are generated in arduino A, just one time in arduino B. After this first JsonDoc the arduino B cannot deserialize the data anymore and it gives me the error: invalid input

The wiring is just: rx–>tx | tx–>rx | gnd–>gnd

this below are the codes:

  • arduino A
#include <ArduinoJson.h>

int a;
int b;

String Serializ;
String message = "";
bool messageReady = false;

void setup() {
  Serial.begin(9600);
}

void loop() {

a = 10 + random(1,5);
b = 30 - random(1,5);
  
  // Monitor serial communication
  while(Serial.available()) {
    message = Serial.readString();
    messageReady = true;
  }
  // Only process message if there's one
  if(messageReady) {
    // The only messages we'll parse will be formatted in JSON
    DynamicJsonDocument doc(1024);
    // Attempt to deserialize the message
    DeserializationError error = deserializeJson(doc,message);
    if(error) {
      Serial.print(F("deserializeJson() failed: "));
      Serial.println(error.c_str());
      messageReady = false;
      return;
    }
    if(doc["type"] == "request") {
      doc["type"] = "response";
      // Get data from analog sensors
      doc["Humidity"] = a;
      doc["Temperature"] = b;
      Serializ = serializeJson(doc,Serial);
      Serial.println(Serializ);
    }
    messageReady = false;
  }
}

arduino B

#include <ArduinoJson.h>

String message;


void setup()
{
  Serial.begin(9600);
  
}

void loop()
{
  handleIndex();
}

void handleIndex()
{

  //DynamicJsonDocument doc(1024);
  StaticJsonDocument <1024> doc;
  double Humidity = 0, Temperature = 0;
  // Sending the request
  doc["type"] = "request";     //richiesta all altro
  serializeJson(doc, Serial);  //impacchetta
  // Reading the response
  boolean messageReady = false;
  
  while (messageReady == false) { // blocking but that's ok
    if (Serial.available()) {
      //String message;
      message = "" ;

      message = Serial.readString();
      messageReady = true;
    }
  }
  // Attempt to deserialize the JSON-formatted message
  DeserializationError error = deserializeJson(doc, message);
  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.c_str());
    return;
  }
  Humidity = doc["Humidity"];
  Temperature = doc["Temperature"];
  // Prepare the data for serving it over HTTP
  String output = "Humidity: " + String(Humidity) + "\n";
  output += "Temperature: " + String(Temperature);
  // Serve the data as plain text, for example
  Serial.println(output);
}

How can I send and receive continuosly these Json objects?
I’ve searched almost everywhere, but there are no no example. Do you have examples or good materials of this topic?

Thank You

DynamicJsonDocument doc(1024);

Bad idea on an UNO which has 2048 bytes RAM in total (we expect you to use an Arduino UNO if you do not explicitly mention another type).

String message;

Don’t use the String class on AVR Arduinos.

You use the hardware serial interface on both Arduinos for the transmission of the JSON document and for debugging. How would the opposite side Arduino distinguish between the JSON document it should receive and the debugging output you actually targeted to the PC?

BTW: Why do you mention I2C in the subject although this post is not related in any way to I2C?

BTW: Why do you mention I2C in the subject although this post is not related in any way to I2C?

My bad i wanted to say a communication between two arduinos.

pylon:
we expect you to use an Arduino UNO if you do not explicitly mention another type

Yes I'm using a uno. I reduced the dimension of the JsonDocument to 512, but still happens the same error.

How would the opposite side Arduino distinguish between the JSON document it should receive and the debugging output you actually targeted to the PC?

I have the arduinos (both UNO) connected to my computer and I'm reading the serial monitor of the receiving one, the Arduino B.

Anyway all works fine, but just one time. So Arduino B can read and deserialize the JsonDocument that arduino A has sent. After the first time I'm receiving the error: deserializeJson() failed: Invalid Input.

Let's say if I open and close every two second the serial monitor manually, I'm able to receive constantly the data from Arduino A.
So I think it's a problem of memory that doesn't clear, or maybe as you said, would be a problem of a dimension of the JsonDocument?

And my question is how can I make this communication continue?

Anyway I would like to send a and b that are floating numbers from an arduino to another, this is my goal.
Every solution it's ok

Yes I'm using a uno. I reduced the dimension of the JsonDocument to 512, but still happens the same error.

Don't use JSON to send data from an UNO to another UNO. JSON is a much too memory hungry format for such small processors. The right tool at the right place, you don't use a 20t excavator to plant a tulip in your garden.

Anyway all works fine, but just one time. So Arduino B can read and deserialize the JsonDocument that arduino A has sent. After the first time I'm receiving the error: deserializeJson() failed: Invalid Input.

That's because you're using the serial interface for the JSON transfer as well as the debugging output. The Arduinos try to interpret the debugging output as JSON and fail.

Anyway I would like to send a and b that are floating numbers from an arduino to another, this is my goal.

Then send them comma separated with carriage return as an inter-message delimiter:

45.8976,33.2234
89.3443,34.2244

Easy to parse, doesn't use much memory and quite reliable.

But you have to solve your above problem first.

I cant even grasp what is doing what form this line:

“in the first code (for the first arduino A which will send the data) it will be deserialized an object called doc that is received from B”

Either:
Arduino A sends the data…
or
Arduino B sends the data…

Which is it?

Arduino ‘B’ has some sort of ‘serailized’ object that is sent to Arduino ‘A’? Yes or no?

If yes… what does Arduino “A” do with the data after its been parsed??

Anywho…

As noted… do NOT use JSON… much better suited for WEB apps… (not this).

But in reality… you just need to define your own ‘protocol’… and parse it as such when the incoming data is received.

“I” personally like to use SOP and EOP *(start of packet/end of packet) characters… so I know when to start and stop parsing an incoming packet (action/command)…

Many here think its overkill and not needed.

Set up SOFTWARE SERIAL communications between your Arduinos… (so you can leave the HARDWARE SERIAL pins open for serial monitoring/debugging…etc)…

Then create a ‘protocol’ that you like. *(similar to what pylon has outlined above)

Example:

<value1, value2, value3…etc>

I have used this same approach for MANY projects…

*(reading params from a TEXT file to set variables in my sketch)

*(most recent/current project takes a ‘recipe’ that is submitted from a webpage, and sends the recipe (serial string data) to the connected Arduino so it can parse the drink recipe, and move tings around to make it happen)

Once you have this communication done… the possibilities are endless… you can send all sorts of data back and forth… only change is what the incoming packets are telling the Arduino to do.

Then send them comma separated with carriage return as an inter-message delimiter:

Nice idea, do you have any code of this?

I cant even grasp what is doing what form this line:

"in the first code (for the first arduino A which will send the data) it will be deserialized an object called doc that is received from B"

Both are sending and receiving JsonDocuments:

  • The Arduino A simulates the numbers and then serialize an DynamicJsonDocument, in which there are the numbers simulated and a "response" string to send to Arduino B.

  • The Arduino B will receive the DynamicJsonDocument that will be deserialized. After that Arduino(rx) will print the numbers, and sends a "request" char to Arduino A.

So the Arduino B is just sending a message bakc "request" to have a better sync (eg: ok Arduino A I'm ready to receive the next data, I'm sending you the request char).

But in reality.. you just need to define your own 'protocol'.. and parse it as such when the incoming data is received.

"I" personally like to use SOP and EOP *(start of packet/end of packet) characters.. so I know when to start and stop parsing an incoming packet (action/command)..

This is really interesting and challenging, i didn't take this in consideration. I'm currently study Serial Communication between two arduinos, so that in few weeks I could be able to perform this task. Do you have any complete codes of this topic that can helps?

Set up SOFTWARE SERIAL communications between your Arduinos... (so you can leave the HARDWARE SERIAL pins open for serial monitoring/debugging..etc)..

So basically rx(0) and tx(1) are the hardware serial ports, and if I use this to communicate with another arduino this can lead to have noise/not_precise output in the communication? Is this correct?
In this case using SoftwareSerial with different ports from 0 and 1 can optimize the communication?

Last question: when you say "debugging", are you referring to "a process that my computers uses to interpret arduino, and printing to my serial monitor"?

Great suggestion, thank you.
Anyway complete and reproducible codes of this topic would be really appreciated.

Have a look at the SerialTransfer library.

Never tried it myself; saw it suggested in another thread on this forum a while back and at least the description is very promising.

Also keep in mind that you have full control of both sides, so you know exactly what is being sent, in what order, and what protocol (delimiters and such). One of the uses of JSON is in situations where you do not have that control, and/or you want the transmission to be human readable. None of which appears to be a concern for you.

If you have multiple values to transmit the easiest way is to use a struct, as shown in the mutiple objects example.