class I2C – ein serielles Zweidraht-Protokoll

I2C ist ein Zweidraht-Protokoll für die Kommunikation zwischen Geräten. Auf der physischen Ebene besteht es aus zwei Leitungen, SCL (Takt) und SDA (Daten). Die OpenMV Cam stellt keine integrierten Pull-up-Widerstände an einer der beiden Leitungen bereit – externe Pull-ups sind sowohl an SCL als auch an SDA erforderlich, damit der Bus funktioniert.

I2C-Objekte sind an einen bestimmten Bus gebunden und können bei der Konstruktion oder später über init() initialisiert werden.

Beispiel:

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

Das Ausgeben des I2C-Objekts zeigt seine Konfiguration an.

Die grundlegenden Methoden sind send() und 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

Um direkt am Ort zu empfangen, erstellen Sie zunächst ein bytearray:

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

Sie können einen Timeout (in ms) angeben:

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

Ein Controller muss die Adresse des Empfängers angeben:

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

Ein Controller verfügt außerdem über diese Methoden:

# 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)

Konstruktoren

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

Erstellt ein I2C-Objekt auf dem angegebenen bus (ein ganzzahliger Peripherie-Index, z. B. 2 für I2C2). Ohne zusätzliche Parameter wird das Objekt erstellt, aber nicht initialisiert (es behält die vorherigen Bus-Einstellungen bei, falls vorhanden); werden zusätzliche Argumente angegeben, wird der Bus initialisiert. Siehe init() für die verfügbaren Parameter.

I2C(2) ist auf jeder OpenMV Cam, die pyb.I2C bereitstellt (M4 / M7 / H7 / H7 Plus / Pure Thermal), an dieselben Header-Pins verdrahtet:

Signal

Header-Pin

Hinweise

SCL

P4

SDA

P5

I2C(4) ist zusätzlich auf der OpenMV Cam M7, H7, H7 Plus und Pure Thermal verfügbar, mit SCL an Header-Pin P7 und SDA an Header-Pin P8.

Die OpenMV Cam N6 stellt pyb.I2C nicht bereit; verwenden Sie stattdessen machine.I2C.

Methoden

deinit() None

Schaltet den I2C-Bus aus.

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

Initialisiert den I2C-Bus mit den angegebenen Parametern:

  • mode muss entweder I2C.CONTROLLER oder I2C.PERIPHERAL sein.

  • addr ist die 7-Bit-Adresse (nur sinnvoll für ein Peripheriegerät).

  • baudrate ist die SCL-Taktrate (nur sinnvoll für einen Controller).

  • gencall gibt an, ob der General-Call-Modus unterstützt werden soll.

  • dma gibt an, ob die Verwendung von DMA für die I2C-Transfers erlaubt sein soll (beachten Sie, dass DMA-Transfers ein präziseres Timing haben, derzeit aber Bus-Fehler nicht korrekt behandeln).

Die tatsächliche Taktfrequenz kann niedriger als die angeforderte Frequenz sein. Dies hängt von der Plattform-Hardware ab. Die tatsächliche Rate kann durch Ausgeben des I2C-Objekts ermittelt werden.

is_ready(addr: int) bool

Prüft, ob ein I2C-Gerät an der angegebenen Adresse antwortet. Nur im Controller-Modus gültig.

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

Liest aus dem Speicher eines I2C-Geräts:

  • data kann eine Ganzzahl (Anzahl der zu lesenden Bytes) oder ein Puffer sein, in den gelesen wird

  • addr ist die Adresse des I2C-Geräts

  • memaddr ist die Speicherstelle innerhalb des I2C-Geräts

  • timeout ist der Timeout in Millisekunden, der auf das Lesen gewartet wird

  • addr_size wählt die Breite von memaddr: 8 oder 16 Bit

Gibt die gelesenen Daten zurück. Dies ist nur im Controller-Modus gültig.

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

Schreibt in den Speicher eines I2C-Geräts:

  • data kann eine Ganzzahl oder ein Puffer sein, aus dem geschrieben wird.

  • addr ist die Adresse des I2C-Geräts.

  • memaddr ist die Speicherstelle innerhalb des I2C-Geräts.

  • timeout ist der Timeout in Millisekunden, der auf das Schreiben gewartet wird.

  • addr_size wählt die Breite von memaddr: 8 oder 16 Bit.

Nur im Controller-Modus gültig.

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

Empfängt Daten auf dem Bus:

  • recv kann eine Ganzzahl sein, die die Anzahl der zu empfangenden Bytes angibt, oder ein veränderbarer Puffer, der mit den empfangenen Bytes gefüllt wird

  • addr ist die Adresse, von der empfangen werden soll (nur im Controller-Modus erforderlich)

  • timeout ist der Timeout in Millisekunden, der auf den Empfang gewartet wird

Rückgabewert: Wenn recv eine Ganzzahl ist, ein neuer Puffer mit den empfangenen Bytes, andernfalls derselbe Puffer, der an recv übergeben wurde.

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

Sendet Daten auf dem Bus:

  • send sind die zu sendenden Daten (eine zu sendende Ganzzahl oder ein Pufferobjekt).

  • addr ist die Adresse, an die gesendet werden soll (nur im Controller-Modus erforderlich).

  • timeout ist der Timeout in Millisekunden, der auf das Senden gewartet wird.

scan() List[int]

Durchsucht alle I2C-Adressen von 0x01 bis 0x7f und gibt eine Liste derjenigen zurück, die antworten. Nur im Controller-Modus gültig.

Konstanten

CONTROLLER: int

Initialisiert den Bus als Master (Controller) – er treibt SCL und initiiert Transaktionen.

PERIPHERAL: int

Initialisiert den Bus als Slave (Peripheriegerät), das auf die in init() festgelegte addr hört und auf Transaktionen antwortet, die von einem Controller auf demselben Bus gestartet werden.