clase I2C – un protocolo serie de dos hilos

I2C es un protocolo de dos hilos para la comunicación entre dispositivos. A nivel físico, consta de dos líneas, SCL (reloj) y SDA (datos). La OpenMV Cam no proporciona resistencias pull-up integradas en ninguna de las dos líneas – se requieren resistencias pull-up externas tanto en SCL como en SDA para que el bus funcione.

Los objetos I2C están asociados a un bus específico y pueden inicializarse en el momento de la construcción o más tarde mediante init().

Ejemplo:

from pyb import I2C

i2c = I2C(2)                              # create on bus 2 (uninitialised)
i2c = I2C(2, I2C.CONTROLLER)              # create and init as a controller
i2c.init(I2C.CONTROLLER, baudrate=20000)  # init as a controller
i2c.init(I2C.PERIPHERAL, addr=0x42)       # init as a peripheral with the given address
i2c.deinit()                              # turn off the peripheral

Al imprimir el objeto I2C se muestra su configuración.

Los métodos básicos son send() y recv():

i2c.send("abc")      # send 3 bytes
i2c.send(0x42)       # send a single byte, given by the number
data = i2c.recv(3)   # receive 3 bytes

Para recibir directamente, primero crea un bytearray:

data = bytearray(3)  # create a buffer
i2c.recv(data)       # receive 3 bytes, writing them into data

Puedes especificar un tiempo de espera (en ms):

i2c.send(b"123", timeout=2000)   # timeout after 2 seconds

Un controlador debe especificar la dirección del destinatario:

i2c.init(I2C.CONTROLLER)
i2c.send("123", 0x42)        # send 3 bytes to peripheral with address 0x42
i2c.send(b"456", addr=0x42)  # keyword for address

Un controlador también dispone de estos métodos:

# Check if peripheral 0x42 is ready.
i2c.is_ready(0x42)

# Scan the bus and return a list of responding addresses.
i2c.scan()

# Read 3 bytes from peripheral 0x42 starting at memaddr 2.
i2c.mem_read(3, 0x42, 2)

# Write 3 bytes to peripheral 0x42 at memaddr 2.
i2c.mem_write("abc", 0x42, 2, timeout=1000)

Constructores

class pyb.I2C(bus: int | str, *args, **kwargs)

Construye un objeto I2C en el bus indicado (un índice entero de periférico, p. ej. 2 para I2C2). Sin parámetros adicionales, el objeto se crea pero no se inicializa (conserva la configuración previa del bus, si la hay); si se proporcionan argumentos adicionales, el bus se inicializa. Consulta init() para conocer los parámetros disponibles.

I2C(2) está conectado a los mismos pines del conector en todas las OpenMV Cam que exponen pyb.I2C (M4 / M7 / H7 / H7 Plus / Pure Thermal):

Señal

Pin del conector

Notas

SCL

P4

SDA

P5

I2C(4) está disponible adicionalmente en las OpenMV Cam M7, H7, H7 Plus y Pure Thermal, con SCL en el pin del conector P7 y SDA en el pin del conector P8.

La OpenMV Cam N6 no expone pyb.I2C; usa machine.I2C en su lugar.

Métodos

deinit() None

Apaga el bus I2C.

init(mode: int, *, addr: int = 0x12, baudrate: int = 400000, gencall: bool = False, dma: bool = False) None

Inicializa el bus I2C con los parámetros indicados:

  • mode debe ser I2C.CONTROLLER o I2C.PERIPHERAL.

  • addr es la dirección de 7 bits (solo tiene sentido para un periférico).

  • baudrate es la frecuencia de reloj de SCL (solo tiene sentido para un controlador).

  • gencall indica si se admite el modo de llamada general (general-call).

  • dma indica si se permite el uso de DMA para las transferencias I2C (ten en cuenta que las transferencias DMA tienen una temporización más precisa, pero actualmente no gestionan correctamente los errores de bus).

La frecuencia de reloj real puede ser inferior a la frecuencia solicitada. Esto depende del hardware de la plataforma. La frecuencia real puede determinarse imprimiendo el objeto I2C.

is_ready(addr: int) bool

Comprueba si un dispositivo I2C responde a la dirección indicada. Solo es válido en modo controlador.

mem_read(data: int | bytearray, addr: int, memaddr: int, *, timeout: int = 5000, addr_size: int = 8) bytes

Lee de la memoria de un dispositivo I2C:

  • data puede ser un entero (número de bytes a leer) o un búfer en el que leer

  • addr es la dirección del dispositivo I2C

  • memaddr es la ubicación de memoria dentro del dispositivo I2C

  • timeout es el tiempo de espera en milisegundos para la lectura

  • addr_size selecciona el ancho de memaddr: 8 o 16 bits

Devuelve los datos leídos. Esto solo es válido en modo controlador.

mem_write(data: int | bytes | bytearray, addr: int, memaddr: int, *, timeout: int = 5000, addr_size: int = 8) None

Escribe en la memoria de un dispositivo I2C:

  • data puede ser un entero o un búfer desde el que escribir.

  • addr es la dirección del dispositivo I2C.

  • memaddr es la ubicación de memoria dentro del dispositivo I2C.

  • timeout es el tiempo de espera en milisegundos para la escritura.

  • addr_size selecciona el ancho de memaddr: 8 o 16 bits.

Solo es válido en modo controlador.

recv(recv: int | bytearray, addr: int = 0x00, *, timeout: int = 5000) bytes

Recibe datos en el bus:

  • recv puede ser un entero, que es el número de bytes a recibir, o un búfer mutable, que se rellenará con los bytes recibidos

  • addr es la dirección de la que recibir (solo se requiere en modo controlador)

  • timeout es el tiempo de espera en milisegundos para la recepción

Valor de retorno: si recv es un entero, entonces un nuevo búfer con los bytes recibidos; de lo contrario, el mismo búfer que se pasó a recv.

send(send: int | bytes | bytearray, addr: int = 0x00, *, timeout: int = 5000) None

Envía datos en el bus:

  • send son los datos a enviar (un entero para enviar, o un objeto búfer).

  • addr es la dirección a la que enviar (solo se requiere en modo controlador).

  • timeout es el tiempo de espera en milisegundos para el envío.

scan() List[int]

Escanea todas las direcciones I2C desde 0x01 hasta 0x7f y devuelve una lista de las que responden. Solo es válido en modo controlador.

Constantes

CONTROLLER: int

Inicializa el bus como maestro (controlador) – acciona SCL e inicia las transacciones.

PERIPHERAL: int

Inicializa el bus como esclavo (periférico) que escucha en la dirección addr establecida en init() y responde a las transacciones iniciadas por un controlador en el mismo bus.