Le Allegro A31301 est un capteur angulaire magnétique de haute précision qui communique via le bus I²C. L’un des grands avantages du capteur A31301 est que son adresse I²C est configurable (16 adresses possibles via des résistances externes et jusqu’à 127 via la programmation). Par défaut, il utilise l’adresse I²C EEPROM 0x6F, mais dans certaines applications, vous pouvez souhaiter la modifier — par exemple, si vous avez plusieurs capteurs A31301 sur le même bus I²C.
Ce guide explique comment changer l’adresse I²C stockée dans l’EEPROM du A31301 à l’aide d’un ESP32 et de la bibliothèque Wire.
L’expérience a été réalisée sur une plaque d’essai (breadboard) avec un ESP32 FireBeetle 2 et une petite carte d’adaptation faite maison pour le capteur A31301.

Voici comment le capteur A31301 a été câblé sur l’ESP32 :

Tout d’abord, le capteur A31301 doit être alimenté. Comme il s’agit d’un composant basse consommation fonctionnant sous 3,3 V, il peut être connecté directement au régulateur de tension de l’ESP32 sans problème. Les broches SA0 et SA1 doivent être reliées à VCC, afin que le périphérique réponde à l’adresse stockée dans l’EEPROM.
Le capteur A31301 stocke sa configuration, y compris son adresse I²C, dans une EEPROM interne. Pour modifier les valeurs de l’EEPROM, il faut utiliser les registres d’accès indirect, en suivant la procédure d’écriture EEPROM suivante :
L’adresse EEPROM contenant l’adresse I²C est indiquée dans la documentation du composant (page 35) : 0x0015.
Voici un exemple complet de programme Arduino qui effectue la séquence de changement d’adresse I²C :
#include <Wire.h>
#define A31301_ADDR 0x6F // Default I²C address
// Lecture de deux octets à partir d’un registre
uint8_t read(uint8_t address, uint8_t reg_addr, uint8_t* msb, uint8_t* lsb) {
Wire.beginTransmission(address);
Wire.write(reg_addr);
if (Wire.endTransmission(false) != 0) {
Serial.println("ERREUR NACK ?");
return 1;
}
Wire.requestFrom(address, (uint8_t)2);
if (Wire.available() != 2) {
Serial.println("ERREUR : devrait lire 2 octets");
return 2;
}
*msb = Wire.read();
*lsb = Wire.read();
return 0;
}
// Écriture de deux octets dans un registre
uint8_t write(uint8_t address, uint8_t reg_addr, uint8_t msb, uint8_t lsb) {
Wire.beginTransmission(address);
Wire.write(reg_addr);
Wire.write(msb);
Wire.write(lsb);
if (Wire.endTransmission() != 0) {
Serial.println("ERREUR NACK ?");
return 1;
}
return 0;
}
void setup() {
Serial.begin(115200);
delay(1000); // Délai de mise sous tension sécurisé
Serial.println("\n\n\n ::::: Changer l’adresse I²C dans l’EEPROM :::::");
Wire.begin();
// 1. Code d’accès
Serial.println("1. Écriture du code d’accès");
write(A31301_ADDR, 0x3E, 0x43, 0x55);
write(A31301_ADDR, 0x3E, 0x53, 0x54);
// 2. Chargement de l’adresse EEPROM cible (0x0015 = emplacement de l’adresse I²C)
Serial.println("2. Chargement de INDIRECT_WR_ADDR avec l’adresse cible EEPROM");
write(A31301_ADDR, 0x02, 0x00, 0x15);
// 3. Chargement des données à écrire (nouvelle adresse I²C)
// Exemple : nouvelle adresse = 0x2A
Serial.println("3. Chargement des registres INDIRECT_WR_DATA avec la nouvelle adresse");
write(A31301_ADDR, 0x04, 0x00, 0x01); // Donnée MSB
write(A31301_ADDR, 0x06, 0x2A, 0x00); // Donnée LSB (0x2A = nouvelle adresse I2C)
// 4. Déclenchement de l’écriture étendue
Serial.println("4. Démarrage de l’écriture EEPROM");
write(A31301_ADDR, 0x08, 0x80, 0x00); // Bit EXW = 1
// 5. Attente de la fin d’écriture (lecture du bit WDN)
Serial.println("5. Attente de la fin de l’écriture EEPROM...");
uint8_t WDN = 0;
do {
uint8_t msb, lsb;
read(A31301_ADDR, 0x08, &msb, &lsb);
WDN = lsb & 0x01;
} while (!WDN);
Serial.println("Écriture EEPROM terminée. Adresse modifiée.");
Serial.println(️"Redémarrez le capteur pour que la nouvelle adresse I²C prenne effet.");
}
void loop() {}
Déverrouiller l’accès en écriture à l’EEPROM
Les deux écritures dans le registre 0x3E envoient le code d’accès requis (CUST) :
0x3E ← 0x43 0x55
0x3E ← 0x53 0x54
Cette séquence déverrouille l’accès à l’EEPROM.
Sélection de l’adresse EEPROM cible
L’adresse mémoire EEPROM (ici 0x0015) est chargée dans le registre INDIRECT_WR_ADDR (0x02).
Chargement des données à écrire
La nouvelle valeur d’adresse I²C (par ex. 0x55) est écrite dans les registres INDIRECT_WR_DATA_MSB et LSB (0x04 et 0x06).
Déclenchement de l’écriture
L’écriture de 0x80 0x00 dans le registre INDIRECT_WR_STATUS (0x08) active le bit EXW, ce qui lance la procédure d’écriture EEPROM.
Lecture du bit WDN
Le bit WDN (Write Done) indique la fin de l’opération d’écriture. Le programme interroge ce bit jusqu’à ce qu’il passe à 1.
Après redémarrage du capteur, vous pouvez scanner le bus I²C (grâce à un petit programme Arduino) pour confirmer que le capteur A31301 répond désormais à sa nouvelle adresse :
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(115200);
Serial.println("Scan du bus I2C...");
for (byte addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
if (Wire.endTransmission() == 0) {
Serial.print("Appareil trouvé à l’adresse 0x");
Serial.println(addr, HEX);
delay(5);
}
}
}
void loop() {}
| Étape | Action | Registre | Description |
|---|---|---|---|
| 1 | Code d’accès | 0x3E |
Déverrouiller l’EEPROM |
| 2 | Définir l’adresse EEPROM | 0x02 |
Cible = 0x0015 |
| 3 | Écrire les données | 0x04 / 0x06 |
Nouvelle adresse I²C |
| 4 | Lancer l’écriture | 0x08 |
Activer le bit EXW |
| 5 | Attendre la fin d’écriture | 0x08 |
Lire le bit WDN |
Après cette séquence et un redémarrage, votre capteur A31301 répondra à la nouvelle adresse I²C que vous avez programmée dans son EEPROM.