Connecting multiple Arduinos (or arduino and other boards): JSON over UART

Hi everyone,
I'm Marco and I'm a noob, i want to interface arduino with another arduino (or a NodeMCU). Arduino (It's an arduino NANO) is in charge of controlling an heat exchanger.
My plan is to send info about the exchanging efficency to the another controller and the controller sends some config parameter to the heat exchanger.
As a programmer my first idea was to use JSON.
Something like this:

{"temp_Hi":45,
"temp_Ho":40,
"temp_Ci":30,
"temp_Co":35,
"temp_caminetto":50,
"delta_H":5,
"delta_C":5,
"transmit":100,
"Tier":2,
"Rl_Ph":1,
"Rl_Pc":1,
"Rl_kill":0
}

I made some experiment from the serial monitor a can see the correct string but the recipient sees only the first part of the message:
{"temp_Hi":19.625,"temp_Ho":19.
Maybe is something like a buffer problem but i'm too noob to figure out.
Ore maybe my approach is wrong and i must nut use the UART..

Someone with more experience has an idea?

Thanks

Welcome to the forum

Please post your code for both ends of the Serial link. Which Arduino boards are you using ?

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination

This is the code (w/o the parts not involving the sending) for the sender (Arduino Nano)

#include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <ArduinoJson.h>


#define ONE_WIRE_BUS 7
#define Rl_Ph A1
//#define PWM_Ph 5
#define Rl_Pc A2
//#define PWM_Pc 6
#define Rl_kill A0
#define Button A3


#define pinClk_m 2
#define pinDt_m 3
#define pinSw_m 4



float counter;
float current;
float stepper;
int aState;
int aLastState;
int aState_m;
int aLastState_m;
///

int menu_H = 1;

char *D_Tier[] = {"T0>--------"
                  , "T0>T1>-----"
                  , "T0>T1>T2>--"
                  , "T0>T1>T2>T3"
                 };


LiquidCrystal_I2C lcd(0x27, 20 , 4);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

unsigned long DisplayRefreshTime = 500;
unsigned long t_DisplayRefresh = millis();
unsigned long algRefreshTime = 500;
unsigned long t_algRefresh = millis();

// Addresses of DS18B20 sensors connected to the 1-Wire bus
byte Sensor_Hi[8] = {0x28, 0xE6, 0x61, 0x75, 0xD0, 0x01, 0x3C, 0xB0};
byte Sensor_Ho[8] = {0x28, 0xE1, 0xAB, 0x75, 0xD0, 0x01, 0x3C, 0xAA};
byte Sensor_Ci[8] = {0x28, 0xC9, 0x8A, 0x75, 0xD0, 0x01, 0x3C, 0x88};
byte Sensor_Co[8] = {0x28, 0xD5, 0x6F, 0x75, 0xD0, 0x01, 0x3C, 0xA6};
byte Sensor_Caminetto[8] = {0x28, 0x21, 0xC7, 0x75, 0xD0, 0x01, 0x3C, 0x05};

// Variabili setup //
float TH_Caminetto = 25.0;
float TH_delta_C = 3.0; // Soglia su delta C
float TH_Differenziale = 3.0; // Differenza minima tra Hi e Ci
float TH_kill = 50.0;
int Tempo_assestamento = 1;
float isteresi = 1;
int Tier2_hold_time_set = 1; // tempo in min di attesa T2 prime di forzare T3
int Tier3_min_time_set = 1; // tempo min in min di permanenza in T3

unsigned long Tier2_hold_time = (unsigned long) Tier2_hold_time_set * 60 * 1000;
unsigned long Tier3_min_time = (unsigned long) Tier2_hold_time_set * 60 * 1000;
unsigned long Tempo_assestamento_m = (unsigned long) Tempo_assestamento * 1000;
// Variabili
float temp_Hi;
float temp_Ho;
float temp_Ci;
float temp_Co;
float temp_caminetto;
float delta_H;
float delta_C;
float transmit;

// funzioni
String Row_H0 , Row_H1 , Row_H2 , Row_H3 ;
int buttonState = 0;
unsigned long lastButtonRead = millis();
unsigned long lastOKButtonRead = millis();
unsigned long Ok_button = 250;
unsigned long t_CambioStato = millis();
unsigned long t_LastRefresh = millis();
unsigned long t_T2 = millis();
unsigned long t_T3 = millis();
int Tier = 0;
unsigned long lastTX = millis();
bool Rx_error;


void setup() {
  lcd.init();
  lcd.backlight();
  Serial.begin(9600);
  sensors.begin();
  pinMode(Button, INPUT_PULLUP);
  pinMode(Rl_kill, OUTPUT);
  pinMode(Rl_Ph, OUTPUT);
  pinMode(Rl_Pc, OUTPUT);
  //
  pinMode(pinClk_m, INPUT);
  pinMode(pinDt_m, INPUT);
  pinMode(pinSw_m, INPUT_PULLUP);
  aLastState_m = digitalRead(pinClk_m);
}

void loop() {
  // input //
  RefreshSensori(750);
  tx_data(1000);

}



void RefreshSensori(unsigned long RefreshTime) {
  if (millis() -  t_LastRefresh > RefreshTime) {
    // Serial.println("Refresh sensosi");
    sensors.requestTemperatures();
    temp_Hi = sensors.getTempC(Sensor_Hi);
    temp_Ho = sensors.getTempC(Sensor_Ho);
    temp_Ci = sensors.getTempC(Sensor_Ci);
    temp_Co = sensors.getTempC(Sensor_Co);
    temp_caminetto = sensors.getTempC(Sensor_Caminetto);
    delta_H = constrain((temp_Hi - temp_Ho), 0, 50);
    delta_C = constrain((temp_Co - temp_Ci), 0, 50);
    int trs = (int) ((delta_C / delta_H) * 100) ;
    transmit = constrain(trs, 0, 100);

    t_LastRefresh = millis();
  }
}

void tx_data(unsigned long Time) {
  String output;
  if ((millis() - lastTX) > Time) {
    StaticJsonDocument<128> valori;
    valori["temp_Hi"] = temp_Hi;
    valori["temp_Ho"] = temp_Ho;
    valori["temp_Ci"] = temp_Ci;
    valori["temp_Co"] = temp_Co;
    
    valori["temp_caminetto"] = temp_caminetto;
    valori["delta_H"] = delta_H;
    valori["delta_C"] = delta_C;
    valori["transmit"] = transmit;
    //valori["Tier"] = Tier;
    valori["Rl_Ph"] = digitalRead(Rl_Ph);
    valori["Rl_Pc"] = digitalRead(Rl_Pc);
    valori["Rl_kill"] = digitalRead(Rl_kill);

    serializeJson(valori, output);
    Serial.println();
    Serial.println(output);
    Serial.println();
    lastTX = millis();
  }

}

I also try using "serializeJson(valori,Serial)" but is almost the same.

This is the code in the receiver (Arduino UNO):

#include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>
#include <ArduinoJson.h>

LiquidCrystal_I2C lcd(0x27, 20 , 4);

float temp_Hi;
float temp_Ho;
float temp_Ci;
float temp_Co;
float temp_caminetto;
float delta_H;
float delta_C;
float transmit;
int Tier = 0;
bool Rl_Ph;
bool Rl_Pc;
bool Rl_kill;
bool Rx_error;

unsigned long lastTX = millis();


void setup() {
  lcd.init();
  lcd.backlight();
  Serial.begin(9600);
}

void loop() {
  //tx_data(1000);
  rx_data();
}

void rx_data() {
  StaticJsonDocument<256> valori;
  DeserializationError error = deserializeJson(valori, Serial);

  if (error) {
    Serial.println(error.f_str());
    lcd.setCursor(0, 0);
    lcd.print(error.f_str());
    return;
  }

  temp_Hi = valori["temp_Hi"];
  temp_Ho = valori["temp_Ho"];
  temp_Ci = valori["temp_Ci"];
  temp_Co = valori["temp_Co"];
  temp_caminetto = valori["temp_caminetto"];
  delta_H = valori["delta_H"];
  delta_C = valori["delta_C"];
  transmit = valori["transmit"];
  Rl_Ph = valori["Rl_Ph"];
  Rl_Pc = valori["Rl_Pc"];
  Rl_kill = valori["Rl_kill"];
}

The error is always "InvalidInput".

But maybe is a stupid idea using UART and there are other solution more suitable.
Additional info: I can't use I2C because the pins are used for the LCD screen.

Hi @marcogion
Without going into detail about what you're broadcasting,
change the speed of the serial from "Serial.begin(9600);"
to "Serial.begin(115200);" in both codes.

Thanks, it works!