Datos erroneos al recibir bytes por I2C usando ESP32

Es primera vez que uso la Plataforma, requiero ayuda con un proyecto de mis practicas.
Estoy tratando de enviar datos de un esclavo a un maestro por I2C, el esclavo envia un texto de Char y dos datos Int (lectura digital y analogica), el esclavo trabaja correctamente, el problema radica a la hora de que el maestro reciba los datos, recibe bien los datos del texto Char, sin embargo la lectura analogica y digital no son los correctos (Dispositivo encontrado en la dirección 0x8 - Sensor de Flama , -16777216, -1), Quisiera saber si alguien ha tenido este problema o como solucionarlo

Codigo del Esclavo:

#include <Wire.h>

char charData[] = "Sensor de Flama";
int analogData = 0;
int digitalData = 0;

void setup() {
  Serial.begin(9600);
  Wire.begin(0x08); // Inicia el I2C con la dirección 0x08
  Wire.onRequest(requestEvent); // Registra la función de solicitud
  pinMode(27, INPUT);

}

void loop() {

// Simular la obtención de datos
  analogData = analogRead(26);  // Lectura analógica
  digitalData = digitalRead(27); // Lectura digital en el pin 5 (por ejemplo)
  Serial.println(digitalData);
  Serial.println(analogData);
  Serial.println(charData);
  delay(200);
}

void requestEvent() {
  

    // Enviar datos al maestro cuando sea solicitado
    byte charLength = strlen(charData);  // Longitud de la cadena de caracteres
    byte buffer[charLength + sizeof(analogData) + sizeof(digitalData)];

    // Copiar dato char a buffer
    memcpy(buffer, charData, charLength);

    // Copiar dato analógico a buffer después del dato char
    memcpy(buffer + charLength, &analogData, sizeof(analogData));

    // Copiar dato digital a buffer después del dato analógico
    memcpy(buffer + charLength + sizeof(analogData), &digitalData, sizeof(digitalData));

    Wire.write(buffer, charLength + sizeof(analogData) + sizeof(digitalData));
}

Codigo del Maestro:

#include <Wire.h>

#define SLAVE_ADDRESS 0x08
#define SLAVE_ADDRESS_2 0x07

char receivedChar[20];  // Se asume una longitud máxima para la cadena de caracteres
int receivedAnalog;
int receivedDigital;

void setup() {
  Serial.begin(9600);
  Wire.begin(); // Inicia el I2C como maestro
  Serial.println("Buscando dispositivos I2C...");
}

void loop() {

  for (byte address = 1; address < 127; address++) {
    Wire.beginTransmission(address);
    byte error = Wire.endTransmission();

    if (error == 0) {
      Serial.print("\nDispositivo encontrado en la dirección 0x");
      Serial.println(address, HEX);
  
   Wire.requestFrom(address, sizeof(receivedChar) + sizeof(receivedAnalog) + sizeof(receivedDigital));
    
    while (Wire.available() < sizeof(receivedChar) + sizeof(receivedAnalog) + sizeof(receivedDigital)) {
        // Espera a que todos los bytes estén disponibles
    }
    
    byte buffer[sizeof(receivedChar) + sizeof(receivedAnalog) + sizeof(receivedDigital)];

    // Leer dato char
    Wire.readBytes(buffer, sizeof(receivedChar));
    memcpy(receivedChar, buffer, sizeof(receivedChar));

    // Leer dato analógico
    Wire.readBytes(buffer + sizeof(receivedChar), sizeof(receivedAnalog));
    memcpy(&receivedAnalog, buffer + sizeof(receivedChar), sizeof(receivedAnalog));

    // Leer dato digital
    Wire.readBytes(buffer + sizeof(receivedChar) + sizeof(receivedAnalog), sizeof(receivedDigital));
    memcpy(&receivedDigital, buffer + sizeof(receivedChar) + sizeof(receivedAnalog), sizeof(receivedDigital));
    Serial.print(receivedChar);
    Serial.print(", ");
    Serial.print(receivedAnalog);
    Serial.print(", ");
    Serial.println(receivedDigital);
    }
  }
  delay(2000); // Espera 2 segundos antes de Volver a escanear

}

El foro tiene una sección dedicada para aquellos que prefieren escribir en español. Tu tema ha sido movido allí.

¿Estoy equivocado o el maestro le pide al esclavo 28 bytes cuando el esclavo solo tiene 23 bytes (15 + 4 + 4) para enviar?

Asumes una cadena máxima de 20 caracteres entonces esperas 20 bytes, pero resulta que la cadena en el esclavo tiene 15 caracteres.

Prueba reduciendo receivedChar a 15.

He hecho este código usando ArduinoJSON

Esclavo

#include <Wire.h>
#include <ArduinoJson.h>

const byte I2C_SLAVE_ADDR = 0x08;
#define BUFFER 100

const int sensorAnalogicoPin = A0;  // Pin del sensor analógico
const int valorDigitalPin = 2;      // Pin del valor digital
int sensorAnalogico;
int valorDigital;
boolean flag = false;

void setup() {
  Wire.begin(I2C_SLAVE_ADDR);  // Dirección I2C del esclavo
  Wire.onRequest(requestEvent);
  pinMode(valorDigitalPin, INPUT);
  Serial.begin(9600);
}

void loop() {
  // El esclavo no necesita hacer nada en el loop
  // if (flag) {
  //   Serial.print("String: ");
  //   Serial.println("Sensor de Flama");
  //   Serial.print("Sensor Analogico: ");
  //   Serial.println(sensorAnalogico);
  //   Serial.print("Valor Digital: ");
  //   Serial.println(valorDigital);
  //   flag = false;
  // }
}

void requestEvent() {
  sensorAnalogico = analogRead(sensorAnalogicoPin);  // Lee el sensor analógico
  valorDigital = digitalRead(valorDigitalPin);       // Lee el valor digital

  // Crea un objeto JSON
  StaticJsonDocument<BUFFER> doc;
  String str = "Sensor de Flama";
  doc["String"] = str;
  doc["SensorAnalogico"] = sensorAnalogico;
  doc["ValorDigital"] = valorDigital;

  // Serializa el JSON a una cadena
  char jsonBuffer[BUFFER];
  size_t len = serializeJson(doc, jsonBuffer);

  // // Imprime el contenido del buffer para depuración
  Serial.print("Sending JSON: ");
  Serial.println(jsonBuffer);

  // Envia los datos por I2C
  Wire.write(jsonBuffer, len);
  flag = true;
}

Maestro

#include <Wire.h>
#include <ArduinoJson.h>

const byte I2C_SLAVE_ADDR = 0x08;
#define BUFFER 100

void setup() {
  Wire.begin();  // Inicia como maestro
  // set timeout to 10 seconds
  Serial.begin(9600);
}

void loop() {
  // Solicita datos del esclavo con la dirección 8
  Wire.requestFrom(I2C_SLAVE_ADDR, BUFFER);  // Solicita hasta 200 bytes

  char jsonBuffer[BUFFER];
  int index = 0;

  // Lee los datos recibidos
  while (Wire.available() && index < sizeof(jsonBuffer) - 1) {
    char c = Wire.read();
    jsonBuffer[index++] = c;
  }
  jsonBuffer[index] = '\0';  // Asegúrate de que la cadena esté terminada

  // Imprime el contenido del buffer para depuración
  Serial.print("Received JSON: ");
  Serial.println(jsonBuffer);

  // Deserializa el JSON
  StaticJsonDocument<BUFFER> doc;
  DeserializationError error = deserializeJson(doc, jsonBuffer);

  if (!error) {
    String stringData = doc["String"];
    int sensorAnalogico = doc["SensorAnalogico"];
    int valorDigital = doc["ValorDigital"];

    // Muestra los datos recibidos
    Serial.print("String: ");
    Serial.println(stringData);
    Serial.print("Sensor Analogico: ");
    Serial.println(sensorAnalogico);
    Serial.print("Valor Digital: ");
    Serial.println(valorDigital);
  } else {
    switch (error.code()) {
      case DeserializationError::Ok:
        Serial.print(F("Deserialization succeeded"));
        break;
      case DeserializationError::InvalidInput:
        Serial.print(F("Invalid input!"));
        break;
      case DeserializationError::NoMemory:
        Serial.print(F("Not enough memory"));
        break;
      default:
        Serial.print(F("Deserialization failed"));
        break;
    }
  }

  delay(2000);  // Espera un segundo antes de la próxima solicitud
}

En la simulación recibo errores de entrada.
A ver si es un problema de simulación o funciona realmente.