comunicación i2c, transmitir y recibir palabras

Hola.

Soy nuevo en el tema de arduino, ahora estoy probando la comunicación I2C, mi programa envía dos palabras (maestro), y el otro las recibe,compara y enciende o apaga un led (esclavo), mi problema es que el esclavo no realiza la acción de encender o apagar el led, al enviar solo la palabra que enciende lo hace, pero con las dos no, no se que mas hacer, espero que me puedan ayudar.

Gracias

Emisor

#include <Wire.h>
void setup()
{
  Wire.begin(); // Se une con el bus I2C
  delay(200);
}


void loop()
{
  EnvioA();
  delay(1000);
  EnvioB();
}

void EnvioA(){
    delay(1000);
    Wire.beginTransmission(4);  //Dirección del Dispositivo esclavo
    Wire.write("ABC2 ");        // Envía 4 bytes      
    Wire.endTransmission();    // Detiene la transmisión       
    delay(1000);
 }



void EnvioB(){
    delay(1000);
    Wire.beginTransmission(4); 
    Wire.write("ABC1 ");     
    Wire.endTransmission();
    delay(1000);
}

Receptor

#include <Wire.h>

int nDato;
char dato;                   
char Cadena[11];
char Encender[9] = "ABC1";      //palabra para encender
char Apagar[7] = "ABC2";        //palabra para apagar

void setup()
{
  Wire.begin(4);                // Une el bus I2C con la dirección #4
  Wire.onReceive(evento);       // Registra el evento
  pinMode(13, OUTPUT);          // pin del led
}

void loop()
{

  CompararCadenas();
  delay(100);
}

void CompararCadenas(){
  if(strcmp(Cadena, Encender) == 0){ // Compara la entrada para encender el LED
    digitalWrite(13, HIGH);
  }
  
  else if(strcmp(Cadena, Apagar) == 0){ // Compara la entrada para apagar el LED
    digitalWrite(13, LOW);
  }
}

void evento(int cantidad) {  // Esta función se ejecuta cuando se recibe información del maestro
  while(1 < Wire.available())  {
    char dato = Wire.read(); // Recibe la palabra del i2c tx
    if (dato != '!')   {
          Cadena[nDato++] = dato;
         }
         else
            break;
  }
  Cadena[nDato] = '\0' ;
}

receptor.ino (1.02 KB)

emisor.ino (535 Bytes)

Los códigos siempre deben verse en el post a menos que todos combinados superen mas de 9k de caracteres y el sistema te informa de ello. No lo olvides y por favor lee las normas del foro

En el receptor esto

else if(strcmp(Cadena, Apagar) == 0){ // Compara la entrada para apagar el LED
    digitalWrite(13, LOW);
  }

no tiene sentido. Una cosa es enviar pero no hay ELSE posible son dos comandos distintos.

void CompararCadenas(){
  if(strcmp(Cadena, Encender) == 0){ // Compara la entrada para encender el LED
    digitalWrite(13, HIGH);
  }
  
  if (strcmp(Cadena, Apagar) == 0){ // Compara la entrada para apagar el LED
    digitalWrite(13, LOW);
  }
}

Otra cosa, estas enviando Wire.write("ABC2 "); con espacio y consultas sin el, la Cadena recibida puede contener el espacio y por eso no esta detectandolo como coincidentes.

Has probado simplemente que el receptor muestre lo recibido? Si lo recibe y no ves nada es porque un espacio simplemente no lo visualizarás.

Prueba como te digo y nos cuentas.

Hola, ya realice las correcciones que me aconsejaste, aun sigue sin funcionar. Probé visualizando lo que envió, al comienzo no mostraba nada, entonces le quite el EnvioB, para que solo enviara "ABC1", y en el monitor serie lo replica varias veces, cuando vuelvo a cargar el código del esclavo para mirar haber si lo enciende , no pasa nada, ya no se como mas probar, tienes alguna otra idea que me pueda ayudar.

Muchas Gracias.

Bueno lo resolví según parece.

EMISOR

#include <Wire.h>
#define Direccion 4

void setup() {
  Wire.begin(); // Se une con el bus I2C
  delay(200);
  Serial.begin(9600);
  Serial.println("Emisor arrancado.");
}

void loop() {
  EnvioA();
  delay(500);
  EnvioB();
  delay(500);

}

void EnvioA(){
    Wire.beginTransmission(Direccion );  //Dirección del Dispositivo esclavo
    Wire.write("ABC1");        // Envía 4 bytes      
    Wire.endTransmission();    // Detiene la transmisión       
    Serial.println("Envio ABC1");
 }

void EnvioB(){
    Wire.beginTransmission(Direccion ); 
    Wire.write("ABC2");     
    Wire.endTransmission();
    Serial.println("Envio ABC2");
}

RECEPTOR

#include <Wire.h>
#define Direccion 4
byte nDato = 0;
char Cadena[11];
char Encender[] = "ABC1";      //palabra para encender
char Apagar[]   = "ABC2";        //palabra para apagar
bool flag = false;

void setup()
{
  Wire.begin(Direccion );                // Une el bus I2C con la dirección #4
  Wire.onReceive(evento);       // Registra el evento
  pinMode(13, OUTPUT);          // pin del led
  Serial.begin(9600);
  Serial.println("Receptor arrancado");
}

void loop() {

  if (flag) {
      CompararCadenas();  
      flag = false;
  }
}

void CompararCadenas(){
  if(strcmp(Cadena, Encender) == 0){ // Compara la entrada para encender el LED
    digitalWrite(13, HIGH);
    Serial.println("Enciendo.");
  }
  
  if(strcmp(Cadena, Apagar) == 0){ // Compara la entrada para apagar el LED
    digitalWrite(13, LOW);
    Serial.println("Apago.");
  }
}


void evento(int cantidad) {  // Esta función se ejecuta cuando se recibe información del maestro}
  nDato = 0;
  strcpy(Cadena,"");
  while(Wire.available())   {
    char dato = Wire.read(); // Recibe la palabra del i2c tx
    if (dato != '\0')   {
        Cadena[nDato] = dato;
        //Serial.print(dato);
        //Serial.print(" ");
        nDato++;
        //Serial.print(nDato);
        //Serial.print(" ");
    }
    else
        break;
  }
  Cadena[nDato] = '\0' ;
  //Serial.println(Cadena);
  flag = true;
}

Si !!!!!!!!!!!!!!!

Funciona perfecto, muchas gracias por tu ayuda...

Disculpa me surgió una duda, en el transmisor al momento de querer asignarle una variable, porque el receptor ya no la reconoce ?

porque la forma de enviar los datos por I2C debe ser en forma de bytes. Cuando asignas una variables el tipo de variable debe ser convertida a bytes. Ese proceso requiere de alguna conversión. Una forma simple de hacerlo es usando strings o convertir datos en strings y enviarlos caracter por caracter.

Puntualmente que quieres enviar y como es la variable o mejor, de que tipo?