scanner_i2c.py
Avant d’écrire le pilote d’un capteur I2C, encore faut-il que le bus réponde : ce script balaie SCL/SDA de 0x08 à 0x77 et liste les adresses présentes. Le réflexe câblage de tout projet CircuitPython avec capteur externe.
Matériel requis
Une Adafruit Feather nRF52840 Express (SoC nRF52840 Cortex-M4F, BLE 5 / 802.15.4) avec NeoPixel embarqué, LED rouge, 2 Mo de flash QSPI pour le système de fichiers CircuitPython et connecteur batterie LiPo. Un capteur ou module I2C (BME680, MPU6050, écran OLED…) branché sur les broches SCL/SDA marquées sur la Feather.
Câblage
SCL→SCL, SDA→SDA, VCC→3V3, GND→GND. Des résistances de pull-up sont déjà présentes sur la plupart des modules ; en l’absence, ajouter 4,7 kΩ vers 3,3 V.
Fonctionnement
busio.I2C ouvre le bus matériel ; try_lock prend le bus puis scan() interroge chaque adresse par ACK. Les réponses sont affichées en hexadécimal, prêtes à coller dans le code du pilote.
Exécution
CircuitPython (build feather_nrf52840_express) installé via le bootloader UF2 (double reset) ; éditer code.py sur le lecteur CIRCUITPY, console dans Mu/Thonny.
Variantes
Changer de broches pour un second bus logiciel, boucler le scan pour détecter les déconnexions, ou enchaîner directement sur la lecture du capteur trouvé.
scanner_i2c.py
# Scanner le bus I2C du board (SCL/SDA) et lister les adresses vives.
# Utile avant d'ajouter un capteur : confirme câblage et adresse.
import time
import board
import busio
scl = board.SCL
sda = board.SDA
i2c = busio.I2C(scl, sda)
print("Balayage I2C de 0x08 à 0x77...")
trouves = []
for adresse in range(0x08, 0x78):
# try_lock/unlock = la méthode portable pour sonder un esclave
if i2c.try_lock():
try:
if adresse in i2c.scan():
pass
finally:
i2c.unlock()
# scan() renvoie la liste complète : on la prend une fois
if i2c.try_lock():
try:
tr = i2c.scan()
finally:
i2c.unlock()
for a in tr:
if a not in trouves:
trouves.append(a)
print("Esclave trouvé : 0x%02X" % a)
print("Terminé :", len(trouves), "périphérique(s).")