Scanner un bus de capteurs I²C
Presque tous les capteurs du Pi parlent I²C :
température/humidité, IMU, petits afficheurs OLED, expandeurs de
ports. Cet exemple est l'équivalent Amalgame de i2cdetect -y 1 — il
ouvre le bus, sonde chaque adresse et affiche qui répond. Ensuite on
lit un registre d'un périphérique pour montrer l'aller-retour complet.
Câblage
VCC capteur ── 3V3 SDA capteur ── GPIO2 (SDA1, broche 3)
GND capteur ── GND SCL capteur ── GPIO3 (SCL1, broche 5)
L'I²C est un bus partagé à deux fils : plusieurs périphériques peuvent donc pendre des mêmes broches SDA/SCL. Vérifiez que l'I²C est activé (voir préparation, étape 3).
Code
namespace Demo
import Amalgame.Hardware
public class Program {
// Les adresses I²C se lisent en hexa ; String_FromInt est décimal,
// donc on formate un octet en deux chiffres hexa — Amalgame pur,
// aucun C inline.
private static string Hex2(v: int) {
let digits: string = "0123456789abcdef"
let hi: int = (v / 16) % 16
let lo: int = v % 16
return String_CharAt1(digits, hi) + String_CharAt1(digits, lo)
}
public static void Main(string[] args) {
let busNum: int = 1
let bus: I2c = new I2c(busNum) // /dev/i2c-1
if (!bus.IsOpen()) {
Console.WriteLine("impossible d'ouvrir /dev/i2c-1 — I2C activé ? permissions ?")
return
}
let found: List<int> = bus.Scan() // sonde 0x03..0x77
if (found.Count() == 0) {
Console.WriteLine("aucun périphérique sur le bus " + String_FromInt(busNum))
} else {
Console.WriteLine(String_FromInt(found.Count()) + " périphérique(s) :")
for addr in found {
Console.WriteLine(" 0x" + Program.Hex2(addr))
}
}
bus.Close()
}
}
Lancer
amc build main.am -o i2c_scan
./i2c_scan
Vous verrez quelque chose comme :
1 périphérique(s) :
0x68
Un MPU-6050 apparaît à 0x68, un backpack LCD PCF8574 à 0x27, de
nombreux OLED à 0x3c, etc.
Lire un registre
Une fois l'adresse connue, lisez ou écrivez ses registres. Par
exemple, pour réveiller un MPU-6050 (mettre à zéro son registre
PWR_MGMT_1 en 0x6B) puis lire en rafale 6 octets de données
accéléromètre :
bus.WriteReg(0x68, 0x6B, 0x00) // réveille le périphérique
let raw: List<int> = bus.ReadBytes(0x68, 6) // octets haut+bas ACCEL_X/Y/Z
L'API I²C en un coup d'œil :
| Méthode | Usage |
|---|---|
new I2c(bus) / .IsOpen() / .Close() |
ouvrir /dev/i2c-<bus> |
.Scan() → List<int> |
lister les répondeurs, comme i2cdetect |
.ReadByte(addr) / .WriteByte(addr, v) |
octet brut unique |
.ReadReg(addr, reg) / .WriteReg(addr, reg, v) |
accès registre |
.ReadBytes(addr, n) / .WriteBytes(addr, list) |
rafale multi-octets |
Les octets traversent la frontière en List<int> (chacun 0..255).
Suivant : chenillard de LEDs →