sábado, 9 de abril de 2011

Comunicación i2c con Arduino

El i2c es un bus serie para la transmisión de datos. Aquí seguro que lo explican mucho mejor que yo. Pero como pequeño resumen, el bus i2c tiene dos líneas importantes SDA para datos y SCL para la señal del reloj.

Las placas Arduino tienen soporte para este protocolo en los pines analógicos 4 y 5 y se proporciona una librería, Wire, para trabajar.

Así que lo que voy a explicar a continuación es un pequeño ejemplo de como dos placas Arduino se pueden comunicar a través de i2c.

El escenario será el habitual. Un Arduino hará de maestro y enviará al Arduino esclavo si se ha pulsado un botón para que ilumine un led y otro.

Aquí va el código para el maestro
#include 

int pinBotonRojo = 2;
int pinBotonVerde = 3;

int rojo = 1;
int verde = 2;
int azul = 3;
int nada = 4;

void setup(){
Wire.begin();
Serial.begin(9600);

pinMode( pinBotonRojo , INPUT );
pinMode( pinBotonVerde , INPUT );
}//setup

void loop(){

Wire.beginTransmission(4);

int valorBotonRojo = digitalRead ( pinBotonRojo );
int valorBotonVerde = digitalRead ( pinBotonVerde );

if ( (valorBotonRojo == HIGH) && (valorBotonVerde == HIGH) ){
Wire.send(nada);
Serial.println("Envío -> nada");
}else if ( (valorBotonRojo == HIGH) && (valorBotonVerde == LOW) ){
Wire.send(rojo);
Serial.println("Envío -> rojo");
}else if ( (valorBotonRojo == LOW) && (valorBotonVerde == HIGH) ){
Wire.send(verde);
Serial.println("Envío -> verde");
}else if ( (valorBotonRojo == LOW) && (valorBotonVerde == LOW) ){
Wire.send(azul);
Serial.println("Envío -> azul");
}

Wire.endTransmission();

delay(500);
}//loop


Y aquí va el código para el esclavo
#include 

int pinLedRojo = 2;
int pinLedVerde = 3;

int rojo = 1;
int verde = 2;
int azul = 3;
int nada = 4;

void setup() {
Wire.begin(4);
Wire.onReceive(receiveEvent);
Serial.begin(9600);
pinMode( pinLedRojo , OUTPUT );
pinMode( pinLedVerde , OUTPUT );
}

void loop(){}

void receiveEvent(int howMany) {
int recibo = Wire.receive();
Serial.print("Recibo : ");
Serial.println(recibo);
Serial.print("howMany : ");
Serial.println(howMany);

if( recibo == nada ){
digitalWrite( pinLedRojo , HIGH );
digitalWrite( pinLedVerde , HIGH );
}else if ( recibo == rojo ){
digitalWrite( pinLedRojo , HIGH );
digitalWrite( pinLedVerde , LOW );
}else if ( recibo == verde ){
digitalWrite( pinLedRojo , LOW );
digitalWrite( pinLedVerde , HIGH );
}else if ( recibo == azul ){
digitalWrite( pinLedRojo , LOW );
digitalWrite( pinLedVerde , LOW );
}
}//receiveEvent


Aquí hay una foto del montaje final.



Y aquí un pequeño video para los incrédulos.



Como se puede ver es bastante sencillo utilizar el i2c del Arduino. Por lo menos para comunicar dos Arduinos.

El paso siguiente será conectar un Lego(c) NXT con un Arduino usando i2c. De este modo podré usar un Arduino como sensor para el NXT.