scanner_i2c.py
Antes de escribir el driver de un sensor I2C, el bus debe responder: este script barre SCL/SDA de 0x08 a 0x77 y lista las direcciones presentes. El reflejo de cableado de todo proyecto CircuitPython con sensor externo.
Hardware
Una Adafruit Feather nRF52840 Express (nRF52840, BLE 5) con NeoPixel, LED rojo, 2 MB de flash QSPI para CircuitPython y conector LiPo. Un sensor o módulo I2C (BME680, MPU6050, OLED…) conectado a los pines SCL/SDA marcados en la Feather.
Cableado
SCL→SCL, SDA→SDA, VCC→3V3, GND→GND. Las resistencias pull-up ya van en la mayoría de módulos; si no, añadir 4,7 kΩ a 3,3 V.
Funcionamiento
busio.I2C abre el bus hardware; try_lock toma el bus y scan() sondea cada dirección por ACK. Las respuestas se imprimen en hexadecimal, listas para pegar en el driver.
Ejecución
CircuitPython (build feather_nrf52840_express) vía bootloader UF2 (doble reset); editar code.py en la unidad CIRCUITPY.
Variantes
Cambiar pines para un segundo bus software, repetir el scan para detectar desconexiones, o encadenar directamente con la lectura del sensor encontrado.
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).")