PFG – Conexión I2C entre la Raspberry Pi y el Arduino
Se ha escogido el protocolo I2C de conexión debido a la facilidad que otorga a la hora de escalar el proyecto, ya que admite hasta 127 periféricos conectados entre sí. Las Raspberry Pi funciona a 3.3V y el Arduino Mega a 5V, lo cual no es un problema si usamos la Raspberry de maestro, ya que sus 3.3V de salida alta entran dentro del umbral de entradas altas del Arduino.
Conexión
Los puertos I2C de la Raspberry Pi ya incluyen resistencias Pull-Up de 1.8K. En el Arduino Mega son los puertos 20 (SDA) y 21 (SCL). Además, las placas deben compartir alimentación y tierra. Al tener alimentaciones distintas se mantienen separadas. Las conexiones quedan de esta forma:
A continuación vamos a configurar la placa Raspberry Pi para usar sus dos puertos I2C. En primer lugar instalamos el paquete i2c-tools:
> pacman -S i2c-tools
Después añadimos el módulo para que se cargue con el kernel, añadiendo “i2c-dev” al fichero /etc/modules-load.d/raspberrypi.conf
Reiniciamos y comprobamos que funciona.
> ls /dev/i2c* /dev/i2c-0
Leemos del puerto I2C:
> i2cdetect -y 0 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
Todo funciona correctamente. Ahora vamos a probar a enviar una señal de la Raspberry al Arduino y que este la devuelva.
Programa para el Arduino
Vamos a crear un programa que reciba un número por el puerto I2C y lo reenvie. Además, si el número es el 1 encenderá o apagará el LED que tiene integrado en la placa.
Hacemos uso de la libería Wire.h y de las llamadas Wire.begin(puerto), Wire.onReceive(funcion), Wire.onRequest(funcion), Wire.available(), Wire.read(), y Wire.write().
El programa queda así:
#include <Wire.h> #define SLAVE_ADDRESS 0x04 int number = 0; int state = 0; // configuracion inicial void setup() { pinMode(13, OUTPUT); // inicializamos i2c como esclavo Wire.begin(SLAVE_ADDRESS); // llamadas para la comunicacion Wire.onReceive(receiveData); Wire.onRequest(sendData); } // bucle principal (vacio) void loop() {} // llamada para recibir datos void receiveData(int byteCount) { while(Wire.available()) { number = Wire.read(); if (number == 1) { if (state == 0) { digitalWrite(13, HIGH); // set the LED on state = 1; } else{ digitalWrite(13, LOW); // set the LED off state = 0; } } } } // llamada para enviar datos void sendData() { Wire.write(number); }
Programa para la Raspberry Pi
Este programa escrito en C se conectará con la placa Arduino Mega mediante el protocolo I2C, enviará un 1 e imprimirá por pantalla la respuesta que reciba del Arduino.
#include <stdio.h> #include <stdlib.h> // exit #include <fcntl.h> // open modo O_RDWR #include <linux/i2c-dev.h> #define ADDRESS 0x04 int main() { int file; unsigned char cmd[16]; int enviado = 1; char buff[1]; int recibido; printf("I2C: Conectando...\n"); if ((file = open("/dev/i2c-0", O_RDWR)) < 0) { printf("I2C: error de acceso"); exit(1); } printf("I2C: Accediendo al dispositivo \n"); if (ioctl(file, I2C_SLAVE, ADDRESS) < 0) { printf("I2C: error al acceder al esclavo en 0x%x", ADDRESS); exit(1); } printf("Enviado %d\n", enviado); cmd[0] = enviado; if (write(file, cmd, 1) == 1) { usleep(10000); if (read(file, buff, 1) == 1) { recibido = (int) buff[0]; printf("Recibido %d\n", recibido); } } printf("I2C: Terminando...\n"); close(file); return (EXIT_SUCCESS); }
Compilamos el programa y lo ejecutamos.
> ./i2c I2C: Conectando... I2C: Accediendo al dispositivo Enviado 1 Recibido 1 I2C: Terminando...
Cada vez que ejecutamos el programa desde la Raspberry Pi, el LED integrado en el Arduino Mega se enciende o apaga correctamente.
Detectando de nuevo las conexiones I2C vemos que el Arduino está correctamente conectado en el puerto 4.
> i2cdetect -y 0 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- 04 -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
Recent Comments