Comunicación I2C entre Raspberry Pi y Arduino (1) – comunicación básica

main3

I2C es un protocolo que permite la comunicación entre dispositivos mediante dos hilos, el primero transporta la información y el segundo sirve como reloj. Este protocolo se define según una arquitectura maestro-esclavo donde un único maestro podrá comunicarse con cualquier esclavo y donde los esclavos se comunicarán con el maestro siempre que éste lo ordene explícitamente a uno de ellos.

Consideraremos un escenario donde un Raspberry PI (maestro) y un Arduino (esclavo) se comunican entre sí de las siguientes cuatro formas:

  1. PI (Maestro) solicita 1 byte a un Arduino (esclavo)
  2. PI (Maestro) envía 1 byte a un Arduino (esclavo)
  3. PI (Maestro) solicita más de 1 byte a un Arduino (esclavo)
  4. PI (Maestro) envía más de 1 byte a un Arduino (esclavo)

Para los siguientes ejemplos se ha empleado Arduino C con la librería Wire para Arduino y Python 2.7 con la librería smbus para el Raspberry pi. Todo el código puede encontrarse en este repositorio de GitHub .

Código

PI (Maestro) solicita 1 byte a un Arduino (esclavo)
Arduino

PI

PI (Maestro) envía 1 byte a un Arduino (esclavo)
Arduino

PI

PI (Maestro) solicita más de 1 byte a un Arduino (esclavo)
Arduino

PI

PI (Maestro) envía más de 1 byte a un Arduino (esclavo)
Arduino

PI

 

I2C se emplea para la comunicación entre dispositivos, muchos de ellos tienen asociados registros para este protocolo. Estos registros son espacios de memoria que pueden ser escritos o leídos, y dado que un dispositivo puede tener más de un registro, I2C permite especificar la dirección del registro a la hora de entablar una comunicación para según que operación.

Estos registros estarán presentes en elementos como sensores o relojes en tiempo real y, si bien, se presupone su uso en operaciones de transmisión de más de un byte, no existen para las comunicaciones directas entre Arduinos y Pi’s, pero deben especificarse para algunas operaciones.

En los anteriores ejemplos, las operaciones en el maestro donde se obliga a usar una dirección de registro son:

Para ambas operaciones, el registro corresponde al segundo parámetro ‘0’, que representa un byte que será mandado al esclavo Arduino.

Analicemos que ocurrirá en la parte del esclavo para estas operaciones:

Maestro ejecuta

El esclavo requiere de la llamada a la función en el manejador Wire.onRequest(función); , y en el caso en que existiese manejador para Wire.onReceive(función); , este sería ejecutado recibiendo únicamente el byte de registro (0 en este ejemplo).

Maestro ejecuta

En el esclavo se ejecuta únicamente Wire.onReceive(función); , resultando en que se añadirá un byte extra al inicio de la transmisión con el valor especificado en ese parámetro (en este caso 0).

Para ambos casos, este valor puede ser interpretado como un byte a descartar, el primer byte de la información útil a recibir o como un comando de control.

Acerca de

Ver todas las entradas de