Comunicación I2C entre Raspberry PI Y Arduino (3) – Estudio e implementación de un sistema práctico

Con lo visto en los artículos anteriores podemos plantear sistemas más complejos haciendo uso de I2C.

En primer lugar, y partiendo de la arquitectura impuesta por I2C , supongamos un maestro que requiere una lectura periódica de la información manejada por sus esclavos. El método para obtener esta información por parte del maestro será mediante polling, esto es, un ciclo continuo de consultas desde el maestro hacia los esclavos solicitando datos.

En función de la información y de los requisitos del sistema, el mecanismo de polling variará. Como ejemplos pongamos estos tres casos:

  1. Maestro requiere la lectura de un valor en el esclavo de manera periódica. Caso típico donde queremos leer el valor de un sensor cada ‘x’ tiempo, dicho valor será medido en el momento en el que el esclavo reciba la solicitud.
  2. Maestro requiere ser informado de cuando un evento ocurre en un esclavo. En este caso el esclavo almacena la ocurrencia de este evento y lo informa cuando recibe la solicitud del maestro. Si el maestro requiere que dicho evento sea notificado cuando antes tendrá que efectuar una lectura de manera periódica con una alta frecuencia.
  3. Maestro requiere ser informado de una serie de eventos que ocurren en un esclavo. En este caso el esclavo almacena la ocurrencia y los instantes de tiempo en los que estos eventos han sido producidos y los informa cuando recibe la solicitud del maestro.

Ejemplo práctico

Para ilustrar lo anterior implementaremos un sistema con un PI como maestro y dos Arduinos (A y B) como esclavos donde las especificaciones son las siguientes:

  1. “Arduino A” mide luz vía foto resistor, PI necesita saber este valor cada ‘x’ tiempo.
  2. “Arduino B” mide temperatura, PI necesita saber este valor cada ‘x’ tiempo.
  3. “Arduino A” tiene un pulsador, en el momento en el que es pulsado PI necesita saberlo.
  4. “Arduino B” tiene un pulsador, puede ser pulsado varias veces durante un intervalo de tiempo determinado, PI necesita saber cuantas veces ha sido pulsado y los instantes de tiempo para cada pulsación.

Para cada uno de estos casos, se deciden las siguientes implementaciones:

  1. PI hace polling a “Arduino A” cada ‘x’ tiempo preguntando por el valor.
  2. PI hace polling a “Arduino B” cada ‘x’ tiempo preguntando por el valor.
  3. “Arduino A” almacena en una variable si el botón ha sido pulsado y transmite este estado al PI en cada ciclo de polling. Como se especifica que la notificación debe ser rápida la frecuencia de polling será alta.
  4. PI hace polling a “Arduino B” cada ‘x’ tiempo preguntando por el número de veces que ha sido pulsado el botón entre ciclos del polling y los instantes de tiempo en los que se produjeron. Esto se implementa de forma efectiva enviando solamente una lista de instantes de tiempo, el número de pulsaciones equivale al número de instantes. Teniendo en cuenta que el número de eventos posibles a informar en un ciclo de polling es variable, tendremos que informar al maestro, en primer lugar, de el número de eventos para que éste solicite al esclavo el número de bytes concreto que conforman la lista de instantes de tiempo asociados a las pulsaciones del botón.

Componentes

Amount Part Type Properties
1 Arduino Uno (Rev3) type Arduino UNO (Rev3)
1 Arduino Mega 2560 (Rev3) type Arduino MEGA 2560 (Rev3)
1 Photocell (LDR) resistance@ dark 300 kOhms@ 10 seconds; package THT; resistance@ luminance 16 kOhms@ 10 lux
2 220Ω Resistor bands 5; resistance 220Ω; tolerance ±1%; pin spacing 400 mil; package THT
1 1kΩ Resistor bands 5; resistance 1kΩ; tolerance ±1%; pin spacing 400 mil; package THT
1 Raspberry Pi B+ variant Raspberry Pi B+; processor Broadcom SoC BCM2835 ARMv6; revision RPI-BPLUS-V1.2
2 Pushbutton package [THT]
1 LM35 Temperature Sensor type LM35; package TO92 [THT]

Diagrama y foto del sistema

COMUNICACIÓN I2C ENTRE RASPBERRY PI Y ARDUINO (3)_bb
20150110_112112-1

Código

El código, a continuación, puede encontrarse en este repositorio de GitHub.

PI

 Arduino A (uno)

Arduino B (Mega)

Casos límite

Los casos límite son aquellos que ponen en compromiso el correcto funcionamiento del sistema en todo escenario posible y muchas veces son contemplados y descubiertos en las fases de análisis, implementación y testeo. Para este sistema existen una serie de casos límite que, con el fin de no complicar un código con fines demostrativos, no han sido tenidos en cuenta. Estos son:

  1. Longitud del buffer I2C en la librería wire establecido en 32 bytes. Si requerimos 4 bytes para informar de una pulsación de botón, el buffer nos limita a 8 pulsaciones a almacenar como máximo. La solución sería implementar un mecanismo que encadene más de una operación I2C de solicitud/escritura.
  2. Contemplar casos donde los esclavos puedan estar temporalmente desconectados del maestro. Habría que almacenar los valores a medir según la frecuencia de lectura deseada y guardarlos hasta que se recuperase la conexión con el maestro. Esto podría requerir un medio de almacenamiento externo en el Arduino (lector microSD) y la implementación de un mecanismo que permitiese el escaneo periódico de la red I2C mediante una librería como i2c-master para Arduino y el uso de i2ctools conjuntamente con smbus en python para Raspberry PI. Igualmente, contemplar la Implementación de un mecanismo ack/nak que aporte un nivel de comprobación en las transacciones de datos.

Acerca de

Ver todas las entradas de

One Response

  1. Jorge Molano dice

    Victor

    Te felicito por tu programa me ha sido de gran ayuda para un proyecto piloto, sin embargo me percato que estas usando ambos Arduinos SOLO para lectura mientras que Raspberry realiza SOLO escritura mediante el protocolo I2C, mi pregunta seria si ¿Haz logrado implementar lectura y escritura al tiempo entre estas 2 tarjetas? Me refiero a que Raspberry pi no solo reciba sino que tambien envie parametros hacia arduino con la estructura de programa que manejas. Quedo atento a tu respuesta gracias