Table des matières:

Wallace - Robot autonome DIY - Partie 5 - Ajouter IMU : 9 étapes
Wallace - Robot autonome DIY - Partie 5 - Ajouter IMU : 9 étapes

Vidéo: Wallace - Robot autonome DIY - Partie 5 - Ajouter IMU : 9 étapes

Vidéo: Wallace - Robot autonome DIY - Partie 5 - Ajouter IMU : 9 étapes
Vidéo: ЗАПРЕЩЁННЫЕ ТОВАРЫ с ALIEXPRESS 2023 ШТРАФ и ТЮРЬМА ЛЕГКО! 2024, Novembre
Anonim
Image
Image

Nous avançons avec Wallace. Le nom Wallace vient d'un mélange de "Wall-E" et d'un projet précédent (reconnaissance vocale), et en utilisant l'utilitaire "espeak", cela sonnait un peu british. Et comme un valet ou un majordome. Et c'est l'objectif final: que ce projet se transforme en quelque chose d'utile. Ainsi "Wallace".

Wallace peut se déplacer, il peut éviter les obstacles à l'aide de capteurs de distance IR (récemment, ils ont frit (?) temps, avec un expandeur MCP23017), et enfin, peut détecter les changements de courant du moteur pour savoir quand il est heurté quelque chose.

En plus des capteurs, Wallace "se souvient" des 100 mouvements et dispose d'une analyse rudimentaire utilisant l'historique des mouvements.

L'objectif jusqu'à présent pour Wallace est simplement d'essayer de continuer à avancer et de savoir quand il est coincé dans un schéma répétitif (comme dans un coin) et n'avance pas vraiment.

J'ai effectué plusieurs itérations pour le mouvement et la navigation, et le mal de tête constant a été pendant la rotation.

Étant donné que Wallace est un robot à chenilles et que je voulais garder les choses plus simples dans le logiciel (pour plus tard), afin de le faire pivoter, je l'ai juste fait pivoter/tourner en place. Ainsi, appliquez une puissance / un rapport cyclique égaux mais opposés aux moteurs.

Le problème rencontré est dû à la conception de la plateforme robotique Agent 390. Les courroies de chenille ont tendance à frotter contre les côtés. Et pire, un côté le fait plus que l'autre.

Au sol et en ligne droite, cela n'a pas posé de problème. Il apparaît sur la moquette. J'ai choisi de garder Wallace hors de la moquette après que ses pistes soient devenues sales (elles ramassent la saleté extrêmement facilement).

Le vrai problème, c'est quand on pivote sur le sol.

Si le logiciel applique un cycle de service de haut niveau, il tourne plus ou moins régulièrement. Cependant, au cours d'un cycle de service faible, il peut ou non tourner. Ou il peut tourner un peu puis ralentir. L'action de pivotement semble être incontrôlable via le logiciel, ou au mieux très difficile.

Le problème apparaît pendant la navigation et le contournement ou l'éloignement d'obstacles. Il peut soit s'éloigner trop brutalement, soit rester bloqué en essayant de faire des changements très infimes, sans même vraiment bouger.

Et donc l'explication ci-dessus a motivé ce Instructable.

Au départ, je voulais me passer d'une unité de détection de mouvement (IMU) ou retarder l'introduction d'une unité de détection de mouvement (IMU), car elle est A) compliquée, B) bruyante, C) des erreurs peuvent s'introduire avec le temps, etc., etc. été que nous pouvions très bien faire en sautant avant les capteurs laser IR à temps de vol. Et nous pouvions - en utilisant des lasers, nous pouvions savoir si le robot tournait ou non, en suivant les changements de distance.

En fait, nous pourrions aussi (en quelque sorte) le faire maintenant, avec les capteurs acoustiques.

Cependant, tout cela est une manière très indirecte et compliquée de répondre à une question simple: « avons-nous effectué une rotation ou non ? »

Il m'a semblé que sauter pour utiliser les capteurs laser ToF me mènerait au prochain niveau de logiciel; à savoir, SLAM (localisation et cartographie simultanées). Je n'étais pas encore prêt à y aller.

C'est une bonne chose de faire un projet de robot en couches, les premières couches (inférieures) étant plus simples et les dernières couches (supérieures) étant plus abstraites et abordant des problèmes plus difficiles.

Les calques peuvent être considérés comme quelque chose comme ceci:

  1. cadre physique de robot / base structurelle mécanique
  2. système d'entraînement rudimentaire (Raspberry, Roboclaw, moteurs, câblage, etc., logiciel de base, piloté par clavier)
  3. circuits essentiels pour prendre en charge les capteurs (décaleur de tension bidirectionnel, extension de port, arrêt d'urgence, distribution d'alimentation, etc.)
  4. capteurs d'évitement d'obstacles (acoustique, IR)
  5. essentiel, positionnement de base et détection de mouvement (accéléromètre, gyroscope, magnétomètre, encodeurs de moteur, encodeurs de roue)

Vous pouvez créer votre propre liste. Les points à propos de cette liste sont que vous devriez probablement les faire plus ou moins dans cet ordre, et aussi que si vous passez un peu de temps sur chaque couche pour les mettre en bon état de fonctionnement, cela devrait vous aider plus tard, car les choses se compliquent.

La liste ci-dessus pourrait être plus ou moins mappée à ces couches conceptuelles dans le logiciel.

  • SLAM (localisation et cartographie simultanées)
  • Contrôle et conscience du mouvement, rotation
  • Évitement d'obstacles de base
  • Contrôle et détection des données du capteur
  • Mouvement essentiel en avant, en arrière, à gauche et à droite, accélérer, ralentir, arrêter

Comme vous pouvez le voir, pour cette liste, les premiers éléments seraient les couches supérieures, plus complexes, qui abordent des problèmes et des questions plus abstraits, tels que « où suis-je » et « où vais-je ? », tandis que les derniers éléments seraient les des couches logicielles inférieures qui gèrent le "comment parler/écouter le capteur A" ou "comment déplacer cette roue".

Maintenant, je ne dis pas que lorsque vous commencez à un calque, vous l'aurez terminé et puis c'est sur le calque suivant, pour ne jamais revenir au précédent. Un projet de robot peut ressembler beaucoup à des méthodes de développement logiciel modernes et itératives (agile, SCRUM, etc.).

Je dis juste de prendre du temps à chacun. Vous devrez équilibrer ce qu'il faut faire à chacun et décider ce que vous essayez à un certain niveau vaut le temps et la peine.

Il y a un certain « conflit » ou « tension » entre deux idées ou directions concurrentes.

L'un est ce que j'appellerais "plug-n-play" pour résoudre le problème A.

L'autre est le bricolage (faites-le vous-même). Et ce n'est peut-être même pas la meilleure étiquette pour cette autre idée.

Voici un exemple de chacun, j'espère que vous verrez la tension ou le conflit entre les deux choix.

Pour cet exemple, regroupons le SLAM, l'évitement d'obstacles et le mouvement de base essentiel comme un seul problème à résoudre en même temps.

  1. Si nous décidons d'emprunter la voie du plug-n-play, nous passons immédiatement (en fonction du budget) à des choses comme ces lasers rotatifs montés sur le dessus, ou la caméra à profondeur de champ, ou les lasers ToF, et l'IMU (sujet de ce Instructable).
  2. Si, d'un autre côté, nous voulons emprunter la deuxième voie, nous pouvons essayer d'extraire toutes les informations possibles de certains capteurs acoustiques ou capteurs IR, ou aucun capteur du tout - nous utilisons simplement la surveillance du courant moteur (bosse)

Que peut-on dire du #1 vs #2 ? Une chose serait que nous aurons appris beaucoup plus en faisant #2. Les limitations de n'avoir que des capteurs acoustiques avec lesquels travailler, nous obligent à réfléchir à beaucoup plus de problèmes.

D'un autre côté, si nous sommes trop concentrés sur le fait de faire les choses via #2, nous perdons peut-être du temps, car nous demandons plus que ce que nous devrions aux capteurs acoustiques.

Encore un concept ou une idée à laquelle réfléchir: quel mélange de matériel et de logiciel répond le mieux aux questions de « comment faire » et quel mélange de logiciel (et de matériel ?) répond à la question de « quoi », « quand », « où ». Parce que « comment » est généralement une question de niveau inférieur dont dépendent « quoi », « quand » et « où » pour obtenir une réponse.

Quoi qu'il en soit, tout ce qui précède était juste quelque chose à penser.

Dans mon cas, après beaucoup d'efforts et le problème constant du frottement des chenilles et incapable d'obtenir un contrôle et un mouvement constants, il est temps de faire autre chose.

Ainsi, ce Instructable - un IMU.

L'objectif est que si l'IMU dit que le robot ne pivote PAS, nous augmentons le cycle de service. Si nous pivotons trop vite, nous diminuons le cycle de service.

Étape 1: Le capteur IMU

Le capteur IMU
Le capteur IMU
Le capteur IMU
Le capteur IMU

Et donc notre prochain capteur à ajouter à Wallace est l'IMU. Après quelques recherches, je m'installais sur un MPU6050. Mais à cette époque, le MPU9050 (et encore plus récemment, le MPU9250) semblait être une idée encore meilleure.

Ma source de prédilection est Amazon (aux États-Unis). J'en ai donc commandé deux.

Ce que j'ai eu en fait (il ne semble y avoir aucun contrôle là-dessus; c'est ce que je n'aime pas chez Amazon) c'était deux MPU92/65. Je m'interroge un peu sur la désignation. Regardez les images; cela semble être une désignation "familiale". En tout cas, c'est ce qui me bloque.

L'ajouter est très simple - obtenez une carte proto avec des pistes de connexion, soudez le capteur à la carte, ajoutez un bornier à vis à 10 broches (j'ai eu le mien de Pololu).

Afin de minimiser toute interférence, j'ai essayé de placer ces capteurs loin de tout le reste.

Cela signifiait également utiliser des boulons/écrous en nylon.

Je vais utiliser le protocole I2C. Espérons que la longueur totale du fil ne sera pas trop mauvaise.

Il existe de nombreuses informations ailleurs sur les connexions de base et les niveaux de tension, etc., je ne le répéterai donc pas ici.

Étape 2: les choses ne sont pas toujours propres, faciles

Au moment d'écrire ces lignes, il ne semble pas y avoir beaucoup de choses en ligne pour ce MPU-92/65 en particulier. Ce qui est disponible, comme avec la plupart des capteurs, semble être des exemples utilisant Arduino.

J'essaie de rendre ces Instructables un peu différents en présentant un processus pas si propre, car les choses ne fonctionnent pas toujours tout de suite.

Je suppose que ces Instructables ressemblent plus à un blog qu'à A-B-C, 1-2-3 "c'est comme ça que vous le faites".

Étape 3: Test initial

Test initial
Test initial
Test initial
Test initial

D'après les images de l'étape précédente, les fils rouge et noir allant aux capteurs sont bien sûr VCC (5V) et GND. Les fils vert et jaune sont les connexions I2C.

Si vous avez fait d'autres projets I2C, ou avez suivi ces séries, alors vous connaissez déjà "i2cdetect", et c'est la première étape pour savoir si le Raspberry peut voir le nouveau capteur.

Comme vous pouvez le voir sur les images de cette étape, notre première tentative a échoué. L'IMU n'apparaît pas (devrait être l'ID de périphérique 0x68).

Cependant, la bonne nouvelle est que le bus I2C fonctionne. Nous voyons un périphérique 0x20 et c'est l'extenseur de port MCP23017 (actuellement responsable des capteurs acoustiques HCSR04).

Ce n'est pas facile à voir sur l'image, mais j'ai connecté les mêmes fils verts et jaunes de l'IMU au MCP23017 (voir en bas à gauche dans l'image)

Nous devrons faire un dépannage.

Étape 4: Dépannage

Image
Image
Dépannage
Dépannage
Dépannage
Dépannage

En utilisant le réglage de continuité sur un voltmètre (celui avec la tonalité aiguë), j'ai testé les connexions VCC (5V), GND, SDA et SCL. C'était bien.

Le prochain essai consistait à déconnecter le MCP23017 du bus I2C, en ne laissant que le MPU-92/65 sur le bus. Cela s'est avéré infructueux - "i2cdetect" n'a alors montré aucun périphérique.

Ensuite, j'ai démonté le capteur du totem et l'ai recâblé directement sur le bus bidirectionnel 5V à 3V; c'est-à-dire directement à la framboise. (fils plus courts ?).

Et voilà. Cette fois, c'est le succès. Nous voyons 0x68 apparaître en utilisant "i2cdetect".

Mais nous ne savons pas encore pourquoi cela a fonctionné cette fois. Serait-ce la longueur des fils? L'emplacement précédent ?

Remarque: cela ne faisait aucune différence que ADO soit mis à la terre ou non. Il se peut qu'il y ait des résistances de pullup et de pull-down intégrées. La même chose pourrait être vraie pour FSYNC.

Ensuite, j'ai reconnecté le MCP23017. Nous avons donc maintenant deux appareils sur le bus I2C. (voir photo). Succes, nous voyons maintenant à la fois 0x20 et 0x68 avec i2cdetect.

Les vidéos expliquent un peu plus ce qui s'est passé pendant le dépannage.

Étape 5: Lecture des données du capteur

Image
Image
Lecture des données du capteur
Lecture des données du capteur
Lecture des données du capteur
Lecture des données du capteur

Différentes approches

J'ai décidé d'adopter plusieurs approches pour obtenir des informations utiles du capteur. Les voici, pas dans n'importe quel ordre:

  1. essayez un peu de programmation de base
  2. parcourir de la documentation en ligne sur les registres
  3. jeter un œil aux exemples et/ou au code des autres

Pourquoi ces approches ? Pourquoi ne pas simplement rechercher une bibliothèque ou un code existant ?

En expérimentant et en essayant quelques idées, nous pouvons mieux absorber certaines connaissances non seulement sur ce capteur particulier, mais aussi acquérir des techniques, des compétences et des façons de penser pour aborder quelque chose de nouveau et quelque chose qui peut ne pas avoir beaucoup de documentation; quelque chose qui peut avoir beaucoup d'inconnues.

De plus, une fois que nous avons joué avec et essayé certaines de nos propres idées et obtenu un aperçu, nous sommes dans une meilleure position pour évaluer le code ou la bibliothèque de quelqu'un d'autre.

Par exemple, après avoir regardé du code C++ pour le MPU9250 dans github, j'ai réalisé que cela m'obligeait à utiliser des interruptions, ce que je ne souhaite pas encore faire.

En outre, il est livré avec des éléments supplémentaires tels que l'étalonnage; encore une fois, quelque chose qui ne m'intéresse pas encore.

Il se peut que ce que je dois faire pour répondre à la simple question "est-ce que le robot tourne oui ou non" pourrait être répondu très simplement en lisant simplement quelques registres.

Registres

Au moment d'écrire ces lignes, il ne semble pas y avoir grand-chose de disponible sur ce capteur. En fait, si vous jetez un œil aux images fournies avec ce Instructable et regardez de près les inscriptions sur les puces réelles, cela me fait me demander si ce n'est pas une contrefaçon. Je ne relie pas ce que je vois à quoi que ce soit d'Invense. Quoi qu'il en soit, j'ai choisi de regarder les informations de registre pour les modèles que j'ai trouvés: le MPU-6050 et le MPU-9250.

Dans les deux cas, ce qui suit est le même pour les deux. Et pour commencer, nous supposons qu'il en sera de même pour ce MPU-92/65.

59 à 64 - mesures accélérométriques

65, 66 - mesures de température 67 à 72 - mesures de gyroscope 73 à 96 - données de capteur externe

Un élément à noter: le MPU-6050 ne semble PAS avoir de magnétomètre, alors que le MPU-9250 (et nous supposons que celui-ci aussi) en a un.

Quelques informations plus intéressantes et, espérons-le, utiles, glanées dans le document du registre:

Informations sur le magnétomètre:

identifiant magnétomètre: 0x48 registres 00 à 09: 00H WIA 0 1 0 0 1 0 0 0 01H INFO INFO7 INFO6 INFO5 INFO4 INFO3 INFO2 INFO1 INFO0 02H ST1 0 0 0 0 0 0 DOR DRDY 03H HXL HX7 HX6 HX5 HX4 HX3 HX2 HX1 HX0 04 HXH HX15 HX14 HX13 HX12 HX11 HX10 HX9 HX8 05H HYL HY7 HY6 HY5 HY4 HY3 HY2 HY1 HY0 06H HYH HY15 HY14 HY13 HY12 HY11 HY10 HY9 HY8 HZ HZ 09 HZH1 HZ7 HZ4 H15 ST2 0 0 0 BITM HOFL 0 0 0 une ventilation de la signification de chaque registre: HXL[7:0]: données de mesure de l'axe X inférieures 8 bits HXH[15:8]: données de mesure de l'axe X supérieures 8 bits HYL[7:0]: données de mesure de l'axe Y inférieures 8 bits HYH[15:8]: données de mesure de l'axe Y supérieures 8 bits HZL[7:0]: données de mesure de l'axe Z inférieures 8 bits HZH[15:8]: données de mesure de l'axe Z supérieures 8 bits

La programmation

Une autre information provenant des documents du registre est qu'il ne semblait y avoir qu'une centaine de registres environ. Ainsi, une tactique pourrait consister à écrire un programme simple qui accède au périphérique (0x68) et tente de lire une série de registres de manière séquentielle, sans aucun égard à leur signification, juste pour voir quelles données peuvent être vues.

Et puis, faites des passes successives, en utilisant le même code, et comparez les données d'une passe par rapport à la suivante.

L'idée est que nous pourrions probablement éliminer tous les registres qui semblent n'avoir aucune donnée (zéros ou FF ?) ou qui ne changent absolument jamais, et nous pourrions également nous concentrer sur ceux qui changent.

Ensuite, nous examinons uniquement ceux qui changent, ajoutez une fonction de moyenne qui fait la moyenne des N dernières lectures de ce registre, pour voir s'il existe en fait une certaine valeur stable pour ce registre. Cela supposerait que nous gardons le capteur très immobile et au même endroit.

Enfin, nous pourrions ensuite essayer doucement des choses avec le capteur, comme le pousser (accéléromètre, gyroscope), ou souffler dessus (température), ou le faire tourner (les deux précédents plus le magnétomètre) et voir quel effet cela a sur les valeurs.

J'aime utiliser autant que possible la bibliothèque de câblagePi. Il prend en charge I2C.

Première exécution:

/********************************************************************************

* pour construire: gcc first.test.mpu9265.c -o first.test.mpu9265 -lwiringPi * * pour exécuter: sudo./first.test.mpu9265 * * ce programme vient de sortir une plage de registres (possibles) du MCP23017, * puis à partir du MPU9265 (ou de tout autre MPU à cette adresse 0x68) * * Je l'ai utilisé pour valider si je pouvais même lire à partir du capteur, car j'avais déjà * confiance dans le MCP23017. * ******************************************************* **************************/ #include #include #include #include #include int main(int argc, char** argv) { puts("Voyons ce que MCP23017 @ 0x20 a à dire:"); errno = 0; int deviceId1 = 0x20; int fd1 = câblagePiI2CSetup(deviceId1); if (-1 == fd1) { fprintf (stderr, "Impossible d'ouvrir le périphérique I2C wirePi: %s\n", strerror (errno)); retour 1; } pour (int reg=0;reg<300;reg++) { fprintf(stderr, "%d ", wirePiI2CReadReg8(fd1, reg));fflush(stderr); retard(10); } met(""); puts("Voyons ce que MPU9265 @ 0x20 a à dire:"); errno = 0; int deviceId2 = 0x68; int fd2 = câblagePiI2CSetup(deviceId2); if (-1 == fd2) { fprintf (stderr, "Impossible d'ouvrir le périphérique I2C wirePi: %s\n", strerror (errno)); retour 1; } for (int reg=0;reg<300;reg++) { fprintf(stderr, "%d ", wirePiI2CReadReg8(fd2, reg));fflush(stderr); retard(10); } met(""); renvoie 0; }

La deuxième manche:

/********************************************************************************

* pour construire: gcc second.test.mpu9265.c -o second.test.mpu9265 -lwiringPi * * pour exécuter: sudo./second.test.mpu9265 * * Ce programme affiche le numéro de registre à côté de la valeur lue. * * Cela rend utile de rediriger (rediriger) la sortie vers un fichier, puis * plusieurs exécutions peuvent être effectuées, pour comparer. Cela peut donner un aperçu de * quels registres sont importants et comment les données peuvent se comporter. * ******************************************************* **************************/ #include #include #include #include #include #include int main(int argc, char** argv) { int deviceId = -1; if (0) { } else if (!strncmp(argv[1], "0x20", strlen("0x20"))) { deviceId = 0x20; } else if (!strncmp(argv[1], "0x68", strlen("0x68"))) { deviceId = 0x68; } else if (!strncmp(argv[1], "0x69", strlen("0x69"))) { deviceId = 0x69; } puts("Voyons ce que MPU9265 @ 0x20 a à dire:"); errno = 0; int fd = câblagePiI2CSetup(deviceId); if (-1 == fd) { fprintf (stderr, "Impossible d'ouvrir le périphérique I2C CâblagePi: %s\n", strerror (errno)); retour 1; } for (int reg=0;reg<300;reg++) { fprintf(stderr, "%d:%d\n", reg, wirePiI2CReadReg8(fd, reg));fflush(stderr); retard(10); } renvoie 0; }

La troisième manche:

/********************************************************************************

* pour compiler: gcc third.test.mpu9265.c -o third.test.mpu9265 -lwiringPi * * pour exécuter: sudo./third.test.mpu9265 * * Ce programme est le résultat du second. Il ne lit que les registres * qui indiquaient une différence entre une exécution et la suivante.* ******************************************************* **************************/ #include #include #include #include #include #include int main(int argc, char** argv) { int deviceId = -1; if (0) { } else if (!strncmp(argv[1], "0x68", strlen("0x68"))) { deviceId = 0x68; } else if (!strncmp(argv[1], "0x69", strlen("0x69"))) { deviceId = 0x69; } puts("Voyons ce que MPU9265 @ 0x20 a à dire:"); errno = 0; int fd = câblagePiI2CSetup(deviceId); if (-1 == fd) { fprintf (stderr, "Impossible d'ouvrir le périphérique I2C CâblagePi: %s\n", strerror (errno)); retour 1; } pour (int reg=61;reg<=73;reg++) { fprintf(stderr, "%d:%d\n", reg, wirePiI2CReadReg8(fd, reg));fflush(stderr); retard(10); } pour (int reg=111;reg<=112;reg++) { fprintf(stderr, "%d:%d\n", reg, wirePiI2CReadReg8(fd, reg));fflush(stderr); retard(10); } pour (int reg=189;reg<=201;reg++) { fprintf(stderr, "%d:%d\n", reg, wirePiI2CReadReg8(fd, reg));fflush(stderr); retard(10); } pour (int reg=239;reg<=240;reg++) { fprintf(stderr, "%d:%d\n", reg, câblagePiI2CReadReg8(fd, reg));fflush(stderr); retard(10); } renvoie 0; }

Alors, qu'avons-nous appris jusqu'à présent? L'image du tableau avec des zones colorées en surbrillance indique que la sortie semble correspondre aux premiers ensembles de registres.

Les résultats obtenus jusqu'à présent peuvent générer de nouvelles questions.

Question: pourquoi n'y a-t-il qu'un seul résultat de registre pour le groupe « externe » ?

Question: c'est quoi tous ces registres inconnus "??????"

Question: étant donné que le programme n'est pas piloté par interruption, a-t-il demandé des données trop lentement ? trop vite?

Question: pouvons-nous affecter les résultats en essayant des choses avec le capteur lui-même pendant qu'il fonctionne ?

Étape 6: Explorons davantage les lectures/données

Je pense que la prochaine étape avant toute autre chose est d'améliorer le programme pour:

  • être flexible dans combien de délai de boucle (ms)
  • être flexible sur le nombre de lectures pour donner une moyenne courante par registre

(J'ai dû joindre le programme en tant que fichier. Cela a semblé être un problème de l'insérer ici. "fourth.test.mpu9265.c")

Voici une analyse utilisant les 10 dernières lectures pour une moyenne, à une boucle de 10 ms:

sudo./quatrième.test.mpu9265 0x68 10 10

61:255 0 255 0 255 0 255 0 0 0: 102 62:204 112 140 164 148 156 188 248 88 228: 167 63:189 188 189 187 189 188 188 188 188 189: 188 64: 60 40 16 96 208 132 116 252 172 36: 112 65: 7 7 7 7 7 7 7 7 7 7: 7 66:224 224 224 240 160 208 224 208 144 96: 195 67: 0 0 0 0 0 0 0 0 0 0: 0 68:215 228 226 228 203 221 239 208 214 187: 216 69: 0 255 0 255 255 0 255 0 0 0: 102 70:242 43 253 239 239 45 206 28 247 207: 174 71: 0 255 255 0 255 255 255 255 255 255: 204 72: 51 199 19 214 11 223 21 236 193 8: 117 73: 0 0 0 0 0 0 0 0 0 0: 0 111: 46 149 91 199 215 46 142 2 233 199: 132 112: 0 0 0 0 0 0 0 0 0 0: 0 189:255 0 255 0 255 0 0 255 0 255: 127 190: 76 36 240 36 100 0 164 164 152 244: 121 191:188 188 188 188 187 188 187 189 187 189: 187 192: 8 48 48 196 96 220 144 0 76 40: 87 193: 7 7 7 7 7 8 7 7 7 7: 7 194:208 224 144 240 176 240 224 208 240 224: 212 195: 0 0 0 0 0 0 0 0 0 0: 0 196:243 184 233 200 225 192 189 242 188 203: 209 197:255 0 0 0 255 0 255 0 0 255: 102 198:223 39 247 43 245 22 255 221 0 6: 130 199: 0 255 255 255 0 255 255 255 255 0: 178 200:231 225 251 1 252 20 211 216 218 16: 164 201: 0 0 0 0 0 0 0 0 0 0: 0 239: 21 138 196 87 26 89 16 245 187 144: 114 240: 0 0 0 0 0 0 0 0 0 0: 0

La première colonne la plus à gauche est le numéro de registre. Viennent ensuite les 10 dernières lectures de ce registre. Enfin, la dernière colonne est la moyenne pour chaque ligne.

Il semble que les registres 61, 69, 71, 189, 197 et 199 ne soient soit que binaires, soit prêts/pas prêts, soit l'octet de poids fort d'une valeur de 16 bits (négatif ?).

Autres remarques intéressantes:

  • registres 65, 193 - très stable et même valeur
  • registre 63, 191 - très stable et même valeur
  • registres 73, 112, 195, 201, 240 - tous à zéro

Relions ces observations à l'image du tableau multicolore et en surbrillance de tout à l'heure.

Registre 65 - température

Registre 193 - ??????

Registre 63 - accéléromètre

Registre 191 - ??????

Registre 73 - externe

Inscrivez-vous 112 et plus - ??????

Eh bien, nous avons encore des inconnues, cependant, nous avons appris quelque chose d'utile.

Le registre 65 (température) et le registre 63 (accéléromètre) étaient tous deux très stables. C'est quelque chose que nous attendrions. Je n'ai pas touché le capteur; il ne bouge pas, à part des vibrations accidentelles, car le robot repose sur la même table que mon ordinateur.

Il y a un test intéressant que nous pouvons pour chacun de ces registres de température/accéléromètre. Pour ce test, nous avons besoin d'une autre version du programme.

Étape 7: Nous sommes capables d'affecter la température et l'accélération

Dans les étapes précédentes, nous avons réduit au moins un registre pour la température et un pour l'accélération.

Avec cette prochaine version du programme ("fifth.test.mpu9265.c"), on peut effectivement voir un changement se produire pour les deux registres. Veuillez regarder les vidéos.

Plus de creuser

Si nous revenons en arrière et regardons les informations du registre, nous voyons qu'il y a:

  • trois sorties 16 bits pour gyroscope
  • trois sorties 16 bits pour accéléromètre
  • trois sorties 16 bits pour magnétomètre
  • une sortie 16 bits pour la température

Cependant, les résultats obtenus par nos programmes de test simples étaient tous des sorties simples de 8 bits. (registres uniques).

Essayons donc plus de la même approche, mais cette fois en lisant 16 bits au lieu de 8.

Nous allons probablement devoir faire quelque chose comme ci-dessous. Prenons la température comme exemple, puisqu'il ne s'agit que d'une sortie 16 bits.

// obtenir le descripteur de fichier fd…

int tempRegHi = 65; int tempRegLo = 66; int hiByte = câblagePiI2CReadReg8(fd, tempRegHi); int loByte = câblagePiI2CReadReg8(fd, tempRegLo); résultat int = hiByte << 8; // met l'ordre hi 8 bits dans la partie supérieure d'une valeur de 16 bits result |= loByte; // ajoutez maintenant dans l'ordre inférieur 8 bits, ce qui donne un nombre complet de 16 bits // imprimez ce nombre ou utilisez la fonction graphique horizontale d'affichage d'avant

De nos étapes précédentes, nous avons vu que le registre 65 est assez stable, tandis que le registre 66 est très bruyant. Puisque 65 est l'octet de poids fort et 66 l'octet de poids faible, cela a du sens.

Pour la lecture, nous pouvons prendre les données du registre 65 telles quelles, mais nous pourrions faire la moyenne des valeurs du registre 66.

Ou nous pouvons simplement faire la moyenne du résultat entier.

Jetez un œil à la dernière vidéo de cette partie; il montre la lecture de l'intégralité de la valeur de température de 16 bits. Le code est "sixth.test.mpu9265.c"

Étape 8: L'accéléromètre et le gyroscope

Image
Image

Les vidéos de cette section montrent la sortie de l'accéléromètre et du gyroscope, en utilisant un programme de test "seventh.test.mpu9265.c". Ce code peut lire 1, 2 ou 3 paires d'octets consécutives (octets hi et lo) et convertit les valeurs en une seule valeur de 16 bits. Ainsi, nous pouvons lire n'importe quel axe unique, ou nous pouvons en lire deux ensemble (et cela additionne les changements), ou nous pouvons lire les trois (et cela additionne les changements).

Pour réitérer, pour cette phase, pour ce Instructable, je cherche juste à répondre à une question simple: « le robot a-t-il tourné/pivoté ? ». Je ne cherche pas de valeur précise, par exemple, a-t-il pivoté de 90 degrés. Cela viendra plus tard lorsque nous commencerons à faire du SLAM, mais ce n'est pas nécessaire pour un simple évitement d'obstacles et un mouvement aléatoire.

Étape 9: (travaux en cours) le magnétomètre

lors de l'utilisation de l'outil i2cdetect, le MPU9265 apparaît sous la forme 0x68 dans le tableau:

0 1 2 3 4 5 6 7 8 9 a b c d e f

00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --

Des étapes supplémentaires sont nécessaires pour lire à partir de la partie magnétomètre de l'IMU.

À partir du document PDF des registres Invesense:

REGISTRES 37 À 39 – CONTRLE I2C ESCLAVE 0

  • REGISTRE 37 - I2C_SLV0_ADDR
  • REGISTRE 38 - I2C_SLV0_REG
  • REGISTRE 39 - I2C_SLV0_CTRL

Conseillé: