Comment interfacer un accéléromètre en I2C ?
NIVEAU 4
Objectifs
- Mettre en oeuvre le protocole I2C
- Trouver les informations dans une documentation technique complexe
- Ecrire des fonctions pour une application spécifique
Pré-requis
Accéléromètre et I2C
ADXL 350
Dans la rubrique I2C de la documentation technique (pages 20 et 21), on trouve l’adresse du composant.
Il est mentionné plusieurs adresses possibles selon quels potentiels sont appliqués sur certaines broches.
L’adresse de base est 0x1D. Mais sur ce module, c’est l’adresse alternative qui est utilisée et qui vaut 0x53.
Altimu 10v5
Interfaçage et récupération de données
ADXL 350
Brochage
Afin de pouvoir utiliser l’accéléromètre 3 axes ADXL350, il est indispensable de l’alimenter.
Pour cela, il faut relier les deux broches GND du module accéléromètre à la masse de votre circuit de pilotage.
Il faut également connecter les broches VS (alimentation du capteur) et VIO (alimentation de la partie numérique) à un potentiel de 3.3V (par exemple celui de la carte Nucléo).
Ensuite, pour pouvoir échanger des informations, il faut relier les broches SDA et SCL de la liaison I2C de l’accéléromètre avec les broches SDA et SCL de la carte de commande (voir schéma ci-dessous – tirée de la Documentation technique).
Les résistances de Pull-Up sont obligatoires. Elles dépendent de la fréquence du réseau I2C voulue et du type de connectique utilisée. Essayez avec des résistances de \(1.2k\Omega\) pour une fréquence de 100kHz. Selon l’allure des signaux sur SCL et SDA, il faudra peut-être les modifier.
Il faut également relier la broche CS à un potentiel de 3.3V. Il peut aussi être intéressant de forcer la broche SDO à 0V pour être sur de l’adresse (ici adresse alternative 0x53).
Initialisation
Récupération des données
Exemple complet
#include "mbed.h" #define ADXL_ADDR 0x53 // Specifique module ADXL350 #define ADXL_DEVID 0x00 #define ADXL_BW_RATE 0x2C #define ADXL_POWER_CTL 0x2D #define ADXL_DATAX0 0x32 #define ADXL_DATAX1 0x33 #define ADXL_DATAY0 0x34 #define ADXL_DATAY1 0x35 #define ADXL_DATAZ0 0x36 #define ADXL_DATAZ1 0x37 DigitalOut myled(LED1); I2C my_i2c(D14, D15); Serial pc(SERIAL_TX, SERIAL_RX); int k1, k2; char data[10]; char acceleration[6]; char device_reg; int adxl_x_data, adxl_y_data, adxl_z_data; /* * Envoyer une donnée dans un registre de l'ADXL350 */ void ADXL350_setReg(char ad_reg, char value){ data[0] = ad_reg; data[1] = value; k1 = my_i2c.write(ADXL_ADDR << 1, data, 2); // write pc.printf("K1 = %d / WRITE \r\n"); return; } /* * Recevoir une donnée d'un registre de l'ADXL350 */ char ADXL350_getReg(char ad_reg){ char data_reg; device_reg = ad_reg; k1 = my_i2c.write(ADXL_ADDR << 1, &device_reg, 1, true); // write k2 = my_i2c.read(ADXL_ADDR << 1, &data_reg, 1, false); // read pc.printf("K1 = %d / K2 = %d / READ \r\n"); return data_reg; } /* * Recevoir des données de registres successifs de l'ADXL350 */ char ADXL350_getReg(char ad_reg, char *dat, int n_data){ char data_reg; device_reg = ad_reg; k1 = my_i2c.write(ADXL_ADDR << 1, &device_reg, 1, true); // write k2 = my_i2c.read(ADXL_ADDR << 1, dat, n_data, false); // read pc.printf("K1 = %d / K2 = %d / READ \r\n"); return data_reg; } /* * Initialisation de l'ADXL350 */ bool ADXL350_begin(void) { ADXL350_setReg(ADXL_BW_RATE, 0b00001000); // 25 Hz wait_ms(10); ADXL350_setReg(ADXL_POWER_CTL, 0b00001000); // Normal Mode / Measurement mode wait_ms(10); return true; } /* * Lecture des données X, Y, Z de l'ADXL350 */ void ADXL350_read(void) { ADXL350_getReg(ADXL_DATAX0, data, 6); adxl_x_data = data[0] << 8 + data[1]; adxl_y_data = data[2] << 8 + data[3]; adxl_z_data = data[4] << 8 + data[5]; return; } /* Fonction principale */ int main() { /* Initialisation */ int i; char adxl_reg = 0; my_i2c.frequency(100000); myled = 1; // LED is ON wait(0.2); ADXL350_begin(); adxl_reg = ADXL350_getReg(ADXL_DEVID); pc.printf("REG = %x \r\n", adxl_reg); /* Boucle principale */ while(1) { i++; ADXL350_read(); pc.printf("[%d] X = %d / Y = %d / Z = %d \r\n", i, adxl_x_data, adxl_y_data, adxl_z_data); myled = !myled; wait_ms(500); } }
MInE Prototyper Prototyper avec Nucleo et MBED