I2C Connection

I have been trying to make a network of arduinos

4 arduinos connected to sensors
1 arduino with a couple of LCDs
and a arduino to connect them all (and later to a PC)

At the moment of writing this, i have a sensor arduino setup and working.
The central arduino requests data from the sensor arduino (over I2C).
And then sends it to the LCD arduino.
(No direct connection between between LCD and sensor).

The central arduino does receive and send the data correctly.

But now the problem im having:
The LCD arduino starts to show some unexplained behavior.
I have seen a few diffrent outputs (over my serial monitor).

The output im getting with my current code
Working correctly 2 times, then stopping halfway receiving.(LCD side) The endTransmission(); is never finished on the central arduino.

Serial output:

-S-e-n-s-o-r-1- -2-2-f-5-4-f-5-2-f-ÿ-ÿ-ÿ-ÿ-ÿ-ÿ
Sensor1 22f54f52fÿÿÿÿÿÿ
-S-e-n-s-o-r-1- -2-2-f-5-4-f-5-2-f-ÿ-ÿ-ÿ-ÿ-ÿ-ÿ
Sensor1 22f54f52fÿÿÿÿÿÿsor4
-S-e-n-s-o-r-1-

(i print a - before printing a char)

The code im using:

LCD

#include<Wire.h>
void setup() {
  Serial.begin(115200);
  Wire.begin(8); //join I2C bus on adress 8
  Wire.onReceive(receiveHandler);
}
void loop() {
 
}
void receiveHandler(int num) {
  noInterrupts();
  char Str1[20] = "";
  int i = 0;
  while (Wire.available() > 0) {
    char c = Wire.read();
    Serial.print("-");
    Serial.print(c);
    Str1[i] = c;
    i++;
  }
  Serial.println();
  Serial.println(Str1);
  String sensor;
  int out1 = 0;
  int out2 = 0;
  int out3 = 0;
  char switch1 = 'f';
  char switch2 = 'f';
  char switch3 = 'f';
  char buff[30];

  sscanf(Str1, "%s %d %c %d %c %d %c", &sensor, &out1, &switch1, &out2, &switch2, &out3, &switch3);

  interrupts();
}

Sensor1 22f54f52fÿÿÿÿÿÿ is an expected output.
But afther that it seems to simply stop between pint - and the new char. (this position also slightly varies between each try, sometimes a few more sometimes a few less).

It might be something very obvious but im not very familiar with C or arduino. and still unexperienced in programming overall.

,Jesse

How long are the I2C wires ? I mean the total length of all pieces of wires for SDA and SCL. If that is no more than 50cm then it is okay.

The receiveHandler should be short and fast. You may not use Serial calls, you also don't need the noInterrupts() and interrupts() calls. Using the String object inside the receiveHandler is also not good. How do you know that the size of buf[30] with 30 bytes is enough ?

You’re overshooting the array… Because things like “Sensor1 22f54f52fÿÿÿÿÿÿ” is way to long for the arra which can hold 19 chars (+ a ‘\n’ char at the end)

So be sure you only receive data within that length

  char inString[20] = "";
  int i = 0;
  while (Wire.available() > 0 && i < 19) {
    char c = Wire.read();
    Serial.print("-");
    Serial.print(c);
    inString[i] = c;
    i++;
  }
  inString[i] = '\n'; //make sure to end it

Second, you totally forget the timings… I think the Wire.onreive() handler function is only called after a stop of repeat command but i’m not sure. That would mean there would indeed be at least one message in the receive buffer. But again, I’m not sure, could already happen after you receive the first byte. Hard to find in the documentation… But the fact it’s called doesn’t mean there is JUST one message in the buffer.

And yeay, it IS an interrupt driven routine like Koepel says so keep it short. Just grab the incoming data, save it to a global string and set a flag. Then in the loop do stuff with it (but as fast as possible). And to be sure not to miss anything, don’t write to the global buffer (no Wire.read()) untill you clear you’re flag and just clear the flag after you’re done with the buffer.