arduinoarduino-unoi2carduino-c++

Arduino I2C communication not receiving sent bytes completely


I'm trying the I2C protocol between Arduinos and I got it to work. I am still missing the 4th sensor reading on the master arduino but on the slave I read it. Also, sometimes when starting the arduinos I get these symbols. Then they disappear. Is this just a miss use of my loop on the slave or how I'm using the Wire library?

S_1, 22.46
S_2, 15.14
����������
S_1, 21.97
S_2, 10.25
����������

Master Arduino

#include <Wire.h>

void setup() {
  Serial.begin(9600);
  //Begin I2C communication protocol
  Wire.begin();
}

void loop() {
  char buffer[64];
  Wire.requestFrom(1,sizeof(buffer));

  while (Wire.available()){
    char c = Wire.read();
    Serial.print(c);
  }
}

Master Output

S_1, 21.97
S_2, 7.32
S_3, 21.48

S_1, 21.97
S_2, 7.32
S_3, 21.48

#include <Wire.h>

String Sensors[4] = {"A0", "A1", "A2", "A3"};
String logData;

void setup() {
  Wire.begin(1);
  Wire.onRequest(loop);
  Serial.begin(9600);
}

void loop() {
  for (int i = 0; i < 4; i++) {
    int reading = analogRead(A0 + i);
    float voltage = reading * (5000 / 1024.0);
    float temp = voltage / 10;
    logData = "S_" + String(i + 1) + ", " + String(temp) + "\n";
    Serial.print(logData);
    Wire.write(logData.c_str());
  }
  delay(1000);
}

Slave Output

S_1, 22.95
S_2, 8.30
S_3, 21.97
S_4, 492.68

The master should receive the readings from A0 to A 3. Just like the slave output.


Solution

  • Some help for your code:

    Do not use A0 + j
    Every Arduino has another pin mapping. Even if it works, this can give you some errors on some boards.
    Use an array and set every pin:

    uint8_t Sensors[4] = {A0, A1, A2, A3};
    int reading = analogRead(Sensors[i]);
    

    Do not use int
    int has a different size on each platform. It is not well defined and the max number on Arduino it is typically 32,767. Please use int16_t. On your code, you are multiplying it with a big number, so you could have 4096 * 5000 = 20'480'000.
    It would be better if you use bigger variables and unsigned (even if it would work in your example):

    uint32_t reading = analogRead(Sensors[i]);
    float voltage = reading * (5000 / 1024.0);
    

    The error in your code
    The error is probably in the Wire.onRequest(loop); call. You set a function to call, when the slave is answering. In this way, when you send some data from master on the loop, Wire will call this function too. So the function is executed twice. You do not need onRequest on your example, so remove it and it should work.