Je suis tombé sur ce lien le capteur n'est pas le même mais la personne travail sans librairie avec le capteur directement en i2C avec les registre et fait ensuite des conversions, ne devrais je pas moi aussi récuprer les datas brutes du capteur via les registres et ensuite travailler sur ces données comme dans l'exemple ? Ou bien aussi comme ici
c'est une option oui. l'article sur le MPU6050 est intéressant
Appliquer un filtre de Kalman est une solution souvent utilisée en traitement du signal, pas toujours simple à configurer.
Oui je pense que je vais essayer de faire comme sur le liens deux que je t'ai envoyé. Au final c'est la même chose, juste mon capteur qui change et les registres qui sont différents, je vais me plonger dans le datasheet du capteur pour prendre les registres qui m'intéresse :), et en option, à voir en fonction des résultats je me pencherais sur le filtre de kalman
si vous regardez dans la bibliothèque que vous utilisez, vous verrez la lecture directe des registres
Oui j'ai bien retrouvé les regitres qui m'intéresse pour les configs, les lectures de données, mais je ne trouve pas de registre de configuration pour une gestion ou une selection de l'oscillateur pour cadencer le capteur, pourtant il doit en avoir un non?
faudrait trouver la spec exacte du composant et voir à quelle adresse sont les registres et ce qu'ils font
Oui je suis dans la datasheet du LSM6DSO32 mais aucune trace d'un registre de config pour une selection d'un oscillateur ou ce genre de chose. Je vois bien les registres de config du gyro etc, les registres pour récupérer les données et leurs adresses, mais aucun trace d'un registre pour une config de l'alimentation du capteur ou de selection d'oscillation il doit pourtant bien y avoir quelque chose comme ça quelque part
certains modules sont plus configurables que d'autres...
Oui très bien j'ai bien l'impression que le LSM6DSO32 ne dispose pas d'un registre de contrôle pour choisir une quelconque fréquence d'oscillation, je vais faire mes tests comme ça on verra bien si je récupère des données ;D
J'ai une petite question, je suis entrain de récupérer pour le moment la valeur brute de température d emon capteur. Si je me réfère page 29 du datasheet je vois temperature sensitivity 256 LSB/°C et je lis plus bas 0 LSB at 25°C, donc pour avoir ma température je fait :
(valeur_brute / 256) + 25
Or de base mon capteur me retourne une valeur d'envron 1200 ce qui me donne 29° et c'est impossible vu la température de la pièce qui est plus aux alentours de 20-22 grand max je pense. Et deuxième suspicion, si je pose mon doight sur le capteur ma valeur chute vers 600 ce qui me donne 27° or la logique voudrait que la tempèrature augmente avec mon doight dessus non?
Je récupère mes valeurs comme suit :
int raw_temperature = 0;
int gyro_raw[3] = {0, 0, 0};
int acc_raw[3] = {0, 0, 0};
Wire.beginTransmission(DSO_ADDRESS);
Wire.write(0x20);
Wire.endTransmission();
Wire.requestFrom(DSO_ADDRESS, 14);
uint8_t buff[14];
Wire.readBytes(buff, 14);
temperature = buff[1] << 8 | buff[0];
gyro_raw[X] = buff[3] << 8 | buff[2];
gyro_raw[Y] = buff[5] << 8 | buff[4];
gyro_raw[Z] = buff[7] << 8 | buff[6];
acc_raw[X] = buff[9] << 8 | buff[8];
acc_raw[Y] = buff[11] << 8 | buff[10];
acc_raw[Z] = buff[13] << 8 | buff[12];
Est-ce que je fait quelque chose de mal? Pour le moment je recupère seulement la valeur brute je fait le calcul manuellement
Edit : même soucis quand je tente de calibrer le gyro
Si j'appel ma fonction qui lis les données 2000 fois pour avoir un offset je me retrouve avec en X 22 (ce qui me semble cohérent) par contre en Y et Z j'ai 65515 et 65521 et ça pour moi c'est pas cohérent du tout
Peut être que j'oublie d'initialiser quelque chose quand je set les registres dans mon setup
Voici mon setup
//gyro 500°
Wire.beginTransmission(DSO_ADDRESS);
Wire.write(0x11);
Wire.write(0x54);
Wire.endTransmission();
//accel 8g
Wire.beginTransmission(DSO_ADDRESS);
Wire.write(0x10);
Wire.write(0x58);
Wire.endTransmission();
//filtre gyro
Wire.beginTransmission(DSO_ADDRESS);
Wire.write(0x15);
Wire.write(0x05);
Wire.endTransmission();
//filtre accel
Wire.beginTransmission(DSO_ADDRESS);
Wire.write(0x17);
Wire.write(0xA0);
Wire.endTransmission();
Edit 2 : j'ai le même problème si j'essaie de lire les registres après avoir initialiser une instance du capteur via la librairie Adafruit, je récupère le même genre de valeur pour mon gyro, je trouve ça vraiment étrange d'avoir des valeurs qui sont autour de 65500 pour Y et Z alors que le capteur est à plat et ne bouge pas
Pour la t° vérifiez dans la spec si ce n’est pas juste la température de la puce (qui sera plus chaude que l’environnement)
Pour la lecture des valeurs, vous recevez des octets donc quand vous les décalez de 8 vous videz l’octet ... il faut passer l’octet en 16 bits avant le décalage, essayez avec gyro_raw[X] = (((uint16_t) buff[3]) << 8) | buff[2];
Oui effectivement déjà après lecture de la datasheet sur les spécifications du capteur de température je vois que l'offset peut être de +/- 15° :o il faut donc faire une calibration logiciel.
Pour la lecture des valeurs je vais essayer votre technique, après au final je fait la même chose que dans la librairie Adafruit du capteur ici
oui, la promotion en int doit se faire pour les valeurs en fait donc pas la peine
(essayez de prendre des int16_t pour le type des gyro_raw)
Oui c'est ce que je vient de fair eet je commence à avoir des valeurs cohérente ça y est :). Par contre je me pose une question maintenant plus niveau techniuq ede codage. Pour le moment quand j'ecris dans u nregistre en i2C je fait par exemple pour écrire 0x02 à l'adresse 0x18:
Wire.beginTransmission(DSO_ADDRESS);
Wire.write(0x18);
Wire.write(0x02);
Wire.endTransmission();
J'aimerais utiliser une structure pour représenter le registre par exemple pour le registre 0x18 quelque chose comme ça
typedef struct {
uint8_t not_used_01 : 1;
uint8_t i3c_disable : 1;
uint8_t den_lh : 1;
uint8_t den_xl_g : 2;
uint8_t den_z : 1;
uint8_t den_y : 1;
uint8_t den_x : 1;
} reg_ctrl9_xl_t;
Normalement cette structure représente le registre CTRL9_XL. Mon problème maintenant c'est est-ce que je peux envoyer cette structure via
Wire.write();
Le soucis c'est que j'ai compris comment déclarer la structure mais j'ai un peu de mal à trouver un exemple d'utilisation, comment par exemple set l'attribut i3c_disable à 1 et ensuite envoyer ça en i2C ?
Comme ça peut être ?
reg_ctrl9_xl = ctrl9_xl;
ctrl9_xl.i3c_disable = 1;
//code
Wire.write(ctrl9_xl);
Mon problème maintenant c'est est-ce que je peux envoyer cette structure via ..
oui il suffit d'utiliser le format où l'on envoie un buffer
Wire.write(&maStructure, sizeof maStructure);
mais ici le buffer aura comme taille 1 seul octet
éventuellement pour avoir plus de chance que la structure soit bien sur un octet, faites un struct __attribute__ ((packed)) {...} c'est une option du compilateur qui demande de "packer" les données le plus possible
(sinon on fait plutôt ce que vous voulez avec des masques et en conservant un uint8_t)
Ok donc si j'ai bien compris si je fait sur le registre CTRL9_XL de mon capteur représenté sur 8bits
reg_ctrl9_xl = ctrl9_xl;
ctrl9_xl.i3c_disable = 1;
ctrl9_xl.den_lh = 1;
Ce qui correspond à 0x06h, et qu'ensuite je fait
Wire.beginTransmission(DSO_ADDRESS);
Wire.write(0x18);
Wire.write(&ctrl9_xl, sizeof ctrl9_xl);
Wire.endTransmission();
Ca revient à faire au même que
Wire.beginTransmission(DSO_ADDRESS);
Wire.write(0x18);
Wire.write(0x06);
Wire.endTransmission();
Est-ce que j'ai bien tout compris ?
Autre question par exemple si j'ai un attribut de ma structure qui fait 3bits, quand je déclare vaut-il mieux faire
struc.mon_attr = (uint8_t)B110
ou
struc.mon_attr = (uint8_t)6
ou
struc.mon_attr = (uint8_t)0x06
est-ce qu'il a une norme ou une écriture qui permet d'être plus lisible ?
je ne connais pas les types de vos variables, par exemple je ne suis pas sûr de ce que vous voulez faire là: reg_ctrl9_xl = ctrl9_xl
le mieux quand on a un champ de bit c'est de montrer les bits que l'on écrit donc struc.mon_attr = 0b110;mais tout revient au même.
Pour revenir à ce que je disais précédemment, on définit généralement l'octet sous forme d'octet et ensuite des masques et on fait des OU
uint8_t ctrl9_xl = XXX | YYY ; // avec XXX et YYY définis comme un masque adapté
Oui c'est une erreur de ma part quand j'ai écrit, il n'y a pas d'égale ![]()
reg_ctrl9_xl_t ctrl9_xl;
ctrl9_xl.i3c_disable = (unit8_t) 1;
ctrl9_xl.den_lh = (unit8_t) 1;
Ma structure est définie comme ça
typedef struct {
uint8_t not_used_01 : 1;
uint8_t i3c_disable : 1;
uint8_t den_lh : 1;
uint8_t den_xl_g : 2;
uint8_t den_z : 1;
uint8_t den_y : 1;
uint8_t den_x : 1;
} reg_ctrl9_xl_t;
Edit: super merci pour tes réponse j'ai de quoi m'amuser, je vais faire des essaies en envoyant une structure pour voir ![]()
OK. ça peut le faire (à condition que les bits soient mis dans le bon ordre, à vérifier)
