class I2C – un protocole série à deux fils¶
I2C est un protocole à deux fils permettant la communication entre périphériques. Au niveau physique, il se compose de 2 fils : SCL et SDA, respectivement la ligne d’horloge et la ligne de données.
Les objets I2C sont créés en étant rattachés à un bus spécifique. Ils peuvent être initialisés lors de leur création, ou initialisés ultérieurement.
L’affichage de l’objet I2C fournit des informations sur sa configuration.
Il existe des implémentations matérielles et logicielles de l’I2C via les classes I2C et SoftI2C. L’I2C matériel utilise le support matériel sous-jacent du système pour effectuer les lectures/écritures ; il est généralement efficace et rapide, mais peut imposer des restrictions sur les broches utilisables. L’I2C logiciel est implémenté par bit-banging et peut être utilisé sur n’importe quelle broche, mais il est moins efficace. Ces classes proposent les mêmes méthodes et diffèrent principalement par la façon dont elles sont construites.
Note
Le bus I2C nécessite un circuit de pull-up sur SDA et SCL pour fonctionner. Il s’agit généralement de résistances comprises entre 1 et 10 kOhm, reliant chaque ligne SDA/SCL à Vcc. Sans elles, le comportement est indéfini et peut aller du blocage, à une réinitialisation inattendue par chien de garde, jusqu’à de simples valeurs erronées. Souvent, ce circuit de pull-up est déjà intégré à la carte du MCU ou aux cartes d’extension de capteurs, mais ce n’est pas une règle. Veuillez donc le vérifier en cas de problème. Voir aussi cet excellent guide d’apprentissage d’Adafruit sur le câblage I2C.
Exemple d’utilisation
from machine import I2C
i2c = I2C(freq=400000) # create I2C peripheral at frequency of 400kHz
# depending on the port, extra parameters may be required
# to select the peripheral and/or pins to use
i2c.scan() # scan for peripherals, returning a list of 7-bit addresses
i2c.writeto(42, b'123') # write 3 bytes to peripheral with 7-bit address 42
i2c.readfrom(42, 4) # read 4 bytes from peripheral with 7-bit address 42
i2c.readfrom_mem(42, 8, 3) # read 3 bytes from memory of peripheral 42,
# starting at memory-address 8 in the peripheral
i2c.writeto_mem(42, 2, b'\x10') # write 1 byte to memory of peripheral 42
# starting at address 2 in the peripheral
Constructeurs¶
- class machine.I2C(id: int, *, scl: Pin | None = None, sda: Pin | None = None, freq: int = 400000, timeout: int = 50000)¶
Construit et renvoie un nouvel objet I2C en utilisant les paramètres suivants :
id identifie un périphérique I2C particulier. Les valeurs autorisées dépendent du port/de la carte considérés
scl doit être un objet broche spécifiant la broche à utiliser pour SCL.
sda doit être un objet broche spécifiant la broche à utiliser pour SDA.
freq doit être un entier qui définit la fréquence maximale pour SCL.
timeout est le temps maximal en microsecondes autorisé pour les transactions I2C. Ce paramètre n’est pas autorisé sur certains ports.
Notez que certains ports/cartes auront des valeurs par défaut de scl et sda qui peuvent être modifiées dans ce constructeur. D’autres auront des valeurs fixes de scl et sda qui ne peuvent pas être modifiées.
Méthodes générales¶
- init(scl: Pin, sda: Pin, *, freq: int = 400000) None¶
Initialise le bus I2C avec les arguments donnés :
scl est un objet broche pour la ligne SCL
sda est un objet broche pour la ligne SDA
freq est la fréquence d’horloge SCL
Dans le cas de l’I2C matériel, la fréquence d’horloge réelle peut être inférieure à la fréquence demandée. Cela dépend du matériel de la plateforme. La fréquence réelle peut être déterminée en affichant l’objet I2C.
Opérations I2C primitives¶
Les méthodes suivantes implémentent les opérations de bus primitives du contrôleur I2C et peuvent être combinées pour réaliser n’importe quelle transaction I2C. Elles sont fournies si vous avez besoin de plus de contrôle sur le bus ; sinon, les méthodes standard (voir ci-dessous) peuvent être utilisées.
Ces méthodes ne sont disponibles que sur la classe
SoftI2C.- start() None¶
Génère une condition START sur le bus (SDA passe à l’état bas pendant que SCL est à l’état haut).
- stop() None¶
Génère une condition STOP sur le bus (SDA passe à l’état haut pendant que SCL est à l’état haut).
- readinto(buf: bytearray, nack: bool = True, /) None¶
Lit des octets depuis le bus et les stocke dans buf. Le nombre d’octets lus correspond à la longueur de buf. Un ACK sera envoyé sur le bus après réception de tous les octets sauf le dernier. Après réception du dernier octet, si nack est vrai, un NACK sera envoyé ; sinon, un ACK sera envoyé (et dans ce cas, le périphérique suppose que d’autres octets seront lus lors d’un appel ultérieur).
Opérations de bus standard¶
Les méthodes suivantes implémentent les opérations standard de lecture et d’écriture du contrôleur I2C qui ciblent un périphérique donné.
- readfrom(addr: int, nbytes: int, stop: bool = True, /) bytes¶
Lit nbytes depuis le périphérique spécifié par addr. Si stop est vrai, une condition STOP est générée à la fin du transfert. Renvoie un objet
bytescontenant les données lues.
- readfrom_into(addr: int, buf: bytearray, stop: bool = True, /) None¶
Lit dans buf depuis le périphérique spécifié par addr. Le nombre d’octets lus correspond à la longueur de buf. Si stop est vrai, une condition STOP est générée à la fin du transfert.
La méthode renvoie
None.
- writeto(addr: int, buf: bytes, stop: bool = True, /) int¶
Écrit les octets de buf vers le périphérique spécifié par addr. Si un NACK est reçu après l’écriture d’un octet de buf, les octets restants ne sont pas envoyés. Si stop est vrai, une condition STOP est générée à la fin du transfert, même si un NACK est reçu. La fonction renvoie le nombre d’ACK reçus.
- writevto(addr: int, vector: tuple | list, stop: bool = True, /) int¶
Écrit les octets contenus dans vector vers le périphérique spécifié par addr. vector doit être un tuple ou une liste d’objets prenant en charge le protocole tampon. L’adresse addr est envoyée une seule fois, puis les octets de chaque objet de vector sont écrits de façon séquentielle. Les objets de vector peuvent avoir une longueur de zéro octet, auquel cas ils ne contribuent pas à la sortie.
Si un NACK est reçu après l’écriture d’un octet de l’un des objets de vector, les octets restants ainsi que tous les objets restants ne sont pas envoyés. Si stop est vrai, une condition STOP est générée à la fin du transfert, même si un NACK est reçu. La fonction renvoie le nombre d’ACK reçus.
Opérations sur la mémoire¶
Certains périphériques I2C agissent comme un dispositif de mémoire (ou un ensemble de registres) accessible en lecture et en écriture. Dans ce cas, deux adresses sont associées à une transaction I2C : l’adresse du périphérique et l’adresse mémoire. Les méthodes suivantes sont des fonctions de commodité permettant de communiquer avec de tels périphériques.
- readfrom_mem(addr: int, memaddr: int, nbytes: int, *, addrsize: int = 8) bytes¶
Lit nbytes depuis le périphérique spécifié par addr à partir de l’adresse mémoire spécifiée par memaddr. L’argument addrsize spécifie la taille de l’adresse en bits. Renvoie un objet
bytescontenant les données lues.
- readfrom_mem_into(addr: int, memaddr: int, buf: bytearray, *, addrsize: int = 8) None¶
Lit dans buf depuis le périphérique spécifié par addr à partir de l’adresse mémoire spécifiée par memaddr. Le nombre d’octets lus correspond à la longueur de buf. L’argument addrsize spécifie la taille de l’adresse en bits.
La méthode renvoie
None.
class SoftI2C – bus I2C émulé par logiciel¶
La classe SoftI2C implémente l’I2C par bit-banging de broches GPIO arbitraires. Elle expose la même interface de méthodes que I2C, ainsi que les opérations de bus primitives de bas niveau (start(), stop(), readinto(), write()) pour les appelants qui ont besoin d’assembler des transactions non standard. Utilisez-la lorsque les broches dont vous avez besoin ne sont pas reliées à un bloc I2C matériel, lorsque vous avez besoin de plus de bus que ce que le matériel fournit, ou pour dialoguer avec des périphériques qui exigent des séquences inhabituelles (horloges supplémentaires, redémarrages répétés après écritures, etc.).
Constructeurs¶
- class machine.SoftI2C(scl: Pin, sda: Pin, *, freq: int = 400000, timeout: int = 50000)¶
Construit un bus I2C logiciel piloté par
scl/sda.freqest la fréquence d’horloge SCL cible en Hz (la fréquence réelle est généralement plus faible en raison de la surcharge de la boucle de bit-banging).timeoutest le temps maximal en microsecondes à attendre pour l’étirement d’horloge (SCL maintenu à l’état bas par un autre périphérique du bus) ; à son expiration, une exceptionOSError(ETIMEDOUT)est levée.Méthodes générales¶
Opérations I2C primitives¶
Les méthodes suivantes implémentent les opérations de bus primitives du contrôleur I2C et peuvent être combinées pour réaliser n’importe quelle transaction I2C. Elles sont propres à SoftI2C – la classe matérielle
I2Cne les expose pas.- start() None¶
Génère une condition START sur le bus (SDA passe à l’état bas pendant que SCL est à l’état haut).
- stop() None¶
Génère une condition STOP sur le bus (SDA passe à l’état haut pendant que SCL est à l’état haut).
- readinto(buf: bytearray, nack: bool = True, /) None¶
Lit des octets depuis le bus dans
buf.len(buf)octets sont lus ; un ACK est envoyé après chaque octet sauf le dernier. Après le dernier octet,nack=True(la valeur par défaut) envoie un NACK pour terminer le transfert ;nack=Falseenvoie un ACK afin que le périphérique reste sélectionné pour unreadinto()ultérieur.
Opérations de bus standard¶
Les méthodes suivantes implémentent les opérations standard de lecture et d’écriture du contrôleur I2C qui ciblent un périphérique donné.
- readfrom(addr: int, nbytes: int, stop: bool = True, /) bytes¶
Lit
nbytesdepuis le périphérique à l’adresse 7 bitsaddr. Sistopest vrai, une condition STOP est générée à la fin du transfert.
- readfrom_into(addr: int, buf: bytearray, stop: bool = True, /) None¶
Lit
len(buf)octets depuis le périphérique à l’adresseaddrdansbuf. Sistopest vrai, une condition STOP est générée à la fin du transfert.
Opérations sur la mémoire¶
Certains périphériques I2C agissent comme un dispositif de mémoire (ou un ensemble de registres) accessible en lecture et en écriture. Dans ce cas, deux adresses sont associées à une transaction I2C : l’adresse du périphérique et l’adresse mémoire. Les méthodes suivantes sont des fonctions de commodité pour dialoguer avec de tels périphériques.
- readfrom_mem(addr: int, memaddr: int, nbytes: int, *, addrsize: int = 8) bytes¶
Lit
nbytesdepuis le périphérique à l’adresseaddrà partir du registrememaddr.addrsizeest la largeur de l’adresse de registre en bits (généralement8ou16).