Inhaltsverzeichnis:
- Schritt 1: Der IMU-Sensor
- Schritt 2: Die Dinge sind nicht immer sauber, einfach
- Schritt 3: Erster Test
- Schritt 4: Fehlerbehebung
- Schritt 5: Lesen der Sensordaten
- Schritt 6: Lassen Sie uns mehr in die Messwerte / Daten eintauchen
- Schritt 7: Wir sind in der Lage, Temperatur und Beschleunigung zu beeinflussen
- Schritt 8: Der Beschleunigungsmesser und das Gyroskop
- Schritt 9: (in Arbeit) das Magnetometer
Video: Wallace - Autonomer DIY-Roboter - Teil 5 - IMU hinzufügen - Gunook
2024 Autor: John Day | [email protected]. Zuletzt bearbeitet: 2024-01-30 07:20
Wir gehen zusammen mit Wallace vor. Der Name Wallace entstand aus einer Mischung aus "Wall-E" und einem früheren Projekt (Spracherkennung) und klang bei der Verwendung des "espeak"-Dienstprogramms etwas britisch. Und wie ein Kammerdiener oder Butler. Und das ist das Endziel: dass aus diesem Projekt etwas Nützliches wird. Also "Wallace".
Wallace kann sich bewegen, er kann mit IR-Distanzsensoren Hindernissen ausweichen (in letzter Zeit haben sie irgendwie gebraten(?) (muss bei Gelegenheit mal nachschauen), hat auch einige akustische Distanzsensoren (drei davon gingen gleichzeitig kaputt.) Zeit, zusammen mit einem MCP23017-Expander) und schließlich können Änderungen des Motorstroms erkennen, um zu wissen, wann er an etwas stößt.
Zusätzlich zu den Sensoren "merkt" sich Wallace die 100 Bewegungen und hat einige rudimentäre Analysen anhand des Bewegungsverlaufs.
Das Ziel von Wallace besteht bisher darin, nur zu versuchen, sich vorwärts zu bewegen und zu wissen, wann es in einem sich wiederholenden Muster (wie in einer Ecke) feststeckt und sich nicht wirklich vorwärts bewegt.
Ich habe mehrere Iterationen für Bewegung und Navigation durchlaufen, und die ständigen Kopfschmerzen waren während der Rotation.
Da Wallace ein getrackter Roboter ist und ich die Dinge in der Software (für später) einfacher halten wollte, lasse ich ihn nur drehen / drehen, um ihn zu drehen. Wenden Sie daher die gleiche, aber entgegengesetzte Leistung / Einschaltdauer an die Motoren an.
Das aufgetretene Problem ist auf das Design der Roboterplattform Agent 390 zurückzuführen. Die Raupenbänder neigen dazu, an den Seiten zu reiben. Und schlimmer noch, eine Seite tut dies mehr als die andere.
Auf dem Boden und geradeaus war es kein Problem. Es zeigt sich auf Teppichboden. Ich entschied mich, Wallace vom Teppichboden fernzuhalten, nachdem die Spuren schmutzig geworden waren (sie nehmen Schmutz extrem leicht auf).
Das eigentliche Problem ist beim Schwenken auf dem Boden.
Wenn ich die Software einen hohen Arbeitszyklus anwenden lasse, dann dreht sie sich mehr oder weniger konstant. Während eines niedrigen Arbeitszyklus kann es sich jedoch tatsächlich drehen oder nicht. Oder es kann sich ein wenig drehen und dann langsamer werden. Das Schwenken scheint über die Software unkontrollierbar oder bestenfalls sehr schwer zu sein.
Das Problem tritt während der Navigation auf und bewegt sich um oder von Hindernissen weg. Es kann entweder zu wild wegschwingen oder beim Versuch, sehr kleine Verschiebungen vorzunehmen, stecken bleiben, ohne sich wirklich zu bewegen.
Und so motivierte die obige Erklärung dieses Instructable.
Anfangs wollte ich auf eine Motion-Sensing-Unit (IMU) verzichten oder die Einführung verzögern, weil sie A) kompliziert, B) laut sind, C) Fehler im Laufe der Zeit auftreten können usw. usw. Mein Gedanke war war, dass wir sehr gut abschneiden konnten, indem wir auf Flugzeit-IR-Lasersensoren übergingen. Und wir könnten - mit Lasern könnten wir wissen, ob sich der Roboter dreht oder nicht, indem wir die Abstandsänderungen verfolgen.
Tatsächlich könnten wir das jetzt auch (irgendwie) mit den akustischen Sensoren tun.
All dies ist jedoch ein sehr indirekter, komplizierter Weg, um eine einfache Frage zu beantworten: "Haben wir gedreht oder nicht?"
Es schien mir, dass der Sprung zur Verwendung der ToF-Lasersensoren mich auf die nächste Stufe der Software bringen würde; nämlich SLAM (Simultaneous Localization and Mapping). Ich war noch nicht bereit, dorthin zu gehen.
Es ist gut, ein Roboterprojekt in Schichten durchzuführen, wobei die ersten (unteren) Schichten einfacher sind und die letzteren (oberen) Schichten abstrakter sind und schwierigere Probleme angehen.
Schichten kann man sich etwa so vorstellen:
- physikalischer Rahmen des Roboters / mechanische strukturelle Basis
- rudimentäres Antriebssystem (Raspberry, Roboclaw, Motoren, Verkabelung etc., Basissoftware, tastaturgesteuert)
- wichtige Schaltungen zur Unterstützung von Sensoren (bidirektionaler Spannungsschieber, Port-Expander, Not-Halt, Stromverteilung usw.)
- Hindernisvermeidungssensoren (Akustik, IR)
- Essential, Grundpositionierung und Bewegungserkennung (Beschleunigungsmesser, Kreisel, Magnetometer, Motorgeber, Radgeber)
Sie können Ihre eigene Liste erstellen. Die Punkte dieser Liste sind, dass Sie diese wahrscheinlich mehr oder weniger in dieser Reihenfolge ausführen sollten, und dass Ihnen dies später helfen sollte, wenn die Dinge komplizierter werden, wenn Sie einige Zeit auf jeder Ebene verbringen, um sie in einen guten Arbeitszustand zu bringen.
Die obige Liste könnte mehr oder weniger auf diese konzeptionellen Schichten in Software abgebildet werden.
- SLAM (Simultane Lokalisierung und Kartierung)
- Kontrolle und Wahrnehmung von Bewegung, Rotation
- Grundlegende Hindernisvermeidung
- Kontrolle und Erkennung von Sensordaten
- Wesentliche Bewegung vorwärts, rückwärts, links und rechts, beschleunigen, verlangsamen, stoppen
Wie Sie sehen können, wären die ersten Elemente für diese Liste die oberen, komplizierteren Schichten, die abstraktere Probleme und Fragen behandeln, wie z niedrigere Softwareschichten, die das "Sprechen/Hören von Sensor A" oder "Wie man dieses Rad bewegt" behandeln.
Ich sage nicht, dass Sie, wenn Sie mit einer Ebene beginnen, diese abgeschlossen haben und dann auf der nächsten Ebene sind, um nie zur vorherigen zurückzukehren. Ein Roboterprojekt kann modernen, iterativen Softwareentwicklungsmethoden (agil, SCRUM usw.) sehr ähnlich sein.
Ich sage nur, man sollte sich bei jedem Zeit nehmen. Sie müssen abwägen, wie viel Sie auf jeder Ebene tun müssen, und entscheiden, was Sie auf einer bestimmten Ebene versuchen, ist die Zeit und die Mühe wert.
Es gibt einen gewissen "Konflikt" oder "Spannung" zwischen zwei konkurrierenden Ideen oder Richtungen.
Eine davon würde ich "Plug-n-Play" nennen, um Problem A zu lösen.
Das andere ist DIY (mach es selbst). Und das ist vielleicht nicht einmal das beste Etikett für diese andere Idee.
Hier ist jeweils ein Beispiel. Hoffentlich werden Sie die Spannung oder den Konflikt zwischen den beiden Optionen erkennen.
Lassen Sie uns für dieses Beispiel SLAM, Hindernisvermeidung und wesentliche Grundbewegungen als ein Problem zusammenfassen, das es gleichzeitig zu lösen gilt.
- Wenn wir uns für den Plug-and-Play-Weg entscheiden, springen wir (je nach Budget) sofort zu Dingen wie diesen oben montierten Rotationslasern oder Tiefenschärfekameras oder ToF-Lasern und der IMU (Thema davon Lehrreich).
- Wenn wir hingegen den zweiten Weg gehen wollen, versuchen wir vielleicht, alle möglichen Informationen aus einigen akustischen Sensoren oder IR-Sensoren oder gar keinen Sensoren zu extrahieren - wir verwenden nur die Motorstromüberwachung (Bump).
Was kann man über #1 vs #2 sagen? Eine Sache wäre, dass wir mit #2 viel mehr gelernt haben. Die Beschränkungen, nur mit akustischen Sensoren arbeiten zu können, zwingen uns, über viel mehr Themen nachzudenken.
Auf der anderen Seite, wenn wir uns zu sehr darauf konzentrieren, Dinge über #2 zu tun, verschwenden wir möglicherweise Zeit, weil wir von akustischen Sensoren mehr verlangen, als wir sollten.
Noch ein Konzept oder eine Idee zum Nachdenken: Welche Mischung aus Hardware und Software beantwortet am besten die Fragen nach dem "Wie" und welche Mischung aus Software (und Hardware?) beantwortet die Frage nach "Was", "Wann", "Wo". Denn "wie" ist normalerweise eine untergeordnete Frage, von der "was", "wann" und "wo" abhängen, um eine Antwort zu erhalten.
Wie auch immer, all das war nur etwas zum Nachdenken.
In meinem Fall ist es nach viel Mühe und dem ständig nervigen Problem der Schienenreibung und der Unfähigkeit, eine gleichmäßige Kontrolle und Bewegung zu erhalten, an der Zeit, etwas anderes zu tun.
Somit ist dieses Instructable - eine IMU.
Das Ziel ist, dass wir den Arbeitszyklus erhöhen, wenn die IMU sagt, dass der Roboter NICHT schwenkt. Wenn wir zu schnell drehen, verringern wir den Arbeitszyklus.
Schritt 1: Der IMU-Sensor
Und so ist unser nächster Sensor, der Wallace hinzugefügt wird, die IMU. Nach einiger Recherche habe ich mich für eine MPU6050 entschieden. Aber zu diesem Zeitpunkt schien der MPU9050 (und in jüngerer Zeit der MPU9250) eine noch bessere Idee zu sein.
Meine bevorzugte Quelle war Amazon (in den USA). Also habe ich zwei davon bestellt.
Was ich tatsächlich bekommen habe (darüber scheint es keine Kontrolle zu geben; das mag ich an Amazon nicht) waren zwei MPU92/65. Ich wundere mich ein wenig über die Bezeichnung. Sehen Sie sich die Bilder an; das scheint eine "Familienbezeichnung" zu sein. Auf jeden Fall bleibe ich dabei.
Das Hinzufügen ist sehr einfach - besorgen Sie sich eine Proto-Platine mit Verbindungsschienen, löten Sie den Sensor an die Platine, fügen Sie eine 10-polige Schraubklemme hinzu (ich habe meine von Pololu).
Um Störungen zu minimieren, habe ich versucht, diese Sensoren von allem anderen entfernt zu platzieren.
Das bedeutete auch, einige Nylonschrauben / -muttern zu verwenden.
Ich werde das I2C-Protokoll verwenden. Hoffentlich ist die Gesamtdrahtlänge nicht so schlimm.
An anderer Stelle gibt es viele Informationen zu den grundlegenden Anschlüssen und Spannungspegeln usw. Ich werde das hier nicht wiederholen.
Schritt 2: Die Dinge sind nicht immer sauber, einfach
Zum jetzigen Zeitpunkt scheint es für diese spezielle MPU-92/65 nicht viel online zu geben. Was verfügbar ist, scheint wie bei den meisten Sensoren Beispiele zu sein, die Arduino verwenden.
Ich versuche, diese Instructables ein bisschen anders zu machen, indem ich einen nicht so sauberen Prozess präsentiere, da die Dinge nicht immer sofort funktionieren.
Ich nehme an, diese Instructables sind einem Blog ähnlicher als gerade A-B-C, 1-2-3 "so machst du es".
Schritt 3: Erster Test
Aus den Bildern im vorherigen Schritt sind die roten und schwarzen Drähte, die zu den Sensoren gehen, natürlich VCC (5V) und GND. Die grünen und gelben Drähte sind die I2C-Anschlüsse.
Wenn Sie andere I2C-Projekte gemacht haben oder diese Serien mitverfolgt haben, dann kennen Sie "i2cdetect" bereits und das ist der erste Schritt, um zu wissen, ob der Raspberry den neuen Sensor sehen kann.
Wie Sie auf den Bildern in diesem Schritt sehen können, war unser erster Versuch erfolglos. Die IMU wird nicht angezeigt (sollte die Geräte-ID 0x68 sein).
Die gute Nachricht ist jedoch, dass der I2C-Bus in Betrieb ist. Wir sehen ein Gerät 0x20 und es ist der MCP23017-Port-Expander (derzeit verantwortlich für die akustischen Sensoren HCSR04).
Auf dem Bild ist es nicht leicht zu erkennen, aber ich habe die gleichen farbigen grünen und gelben Drähte von der IMU an den MCP23017 angeschlossen (siehe unten links im Bild).
Wir müssen eine Fehlerbehebung durchführen.
Schritt 4: Fehlerbehebung
Mit der Kontinuitätseinstellung an einem Voltmeter (dem mit dem hohen Ton) habe ich VCC(5V)-, GND-, SDA- und SCL-Verbindungen getestet. Die waren gut.
Der nächste Versuch bestand darin, den MCP23017 vom I2C-Bus zu trennen und nur die MPU-92/65 am Bus zu belassen. Das erwies sich als fruchtlos - "i2cdetect" zeigte dann keine Geräte an.
Als nächstes habe ich den Sensor vom Totempfahl abmontiert und ihn direkt mit dem bidirektionalen 5-V-zu-3V-Bus neu verkabelt; d.h. direkt zum Raspberry. (kürzere Drähte?).
Und voila. Diesmal gibt es Erfolg. Wir sehen, dass 0x68 mit "i2cdetect" angezeigt wird.
Aber wir wissen noch nicht, warum es diesmal funktioniert hat. Kann es an der Kabellänge liegen? Der bisherige Standort?
Hinweis: Es machte keinen Unterschied, ob ADO geerdet war oder nicht. Es könnte sein, dass Pullup- und Pulldown-Widerstände auf der Platine vorhanden sind. Das gleiche könnte für FSYNC gelten.
Als nächstes habe ich den MCP23017 wieder angeschlossen. Jetzt haben wir also zwei Geräte am I2C-Bus. (siehe Bild). Erfolgreich, wir sehen jetzt sowohl 0x20 als auch 0x68 mit i2cdetect.
Die Videos gehen etwas mehr auf das ein, was während der Fehlerbehebung passiert ist.
Schritt 5: Lesen der Sensordaten
Verschiedene Ansätze
Ich beschloss, mehrere Ansätze zu verfolgen, um nützliche Informationen vom Sensor zu erhalten. Hier sind sie, nicht in beliebiger Reihenfolge:
- versuche es mit der grundlegenden Programmierung
- Sehen Sie sich einige Online-Dokumentationen zu Registern an
- Schauen Sie sich die Beispiele und / oder den Code von anderen an
Warum diese Ansätze? Warum nicht einfach nach einer vorhandenen Bibliothek oder Code suchen?
Durch Experimentieren und Ausprobieren einiger Ideen können wir nicht nur etwas Wissen über diesen speziellen Sensor aufnehmen, sondern auch einige Techniken, Fähigkeiten und Denkweisen erwerben, um etwas Neues anzugehen und etwas, das möglicherweise nicht viel Dokumentation hat. etwas, das viele Unbekannte haben kann.
Sobald wir mit unseren eigenen Ideen gespielt und ausprobiert und einen Einblick gewonnen haben, sind wir auch in einer besseren Position, den Code oder die Bibliothek anderer zu bewerten.
Nachdem ich mir zum Beispiel etwas C++-Code für den MPU9250 in github angesehen hatte, wurde mir klar, dass er mich dazu zwingt, Interrupts zu verwenden, was ich noch nicht tun möchte.
Außerdem sind zusätzliche Dinge wie die Kalibrierung enthalten; wieder etwas, was mich noch nicht interessiert.
Es kann sein, dass das, was ich tun muss, um die einfache Frage "Dreht sich der Roboter ja oder nein" zu beantworten, sehr einfach durch das Lesen einiger Register beantwortet werden kann.
Register
Zum jetzigen Zeitpunkt scheint auf diesem Sensor nicht viel verfügbar zu sein. In der Tat, wenn Sie sich die Bilder ansehen, die mit diesem Instructable geliefert werden, und die Inschriften auf den tatsächlichen Chips genau betrachten, frage ich mich, ob dies kein Knock-off ist. Ich verbinde das, was ich sehe, nicht mit irgendetwas von Invense. Unabhängig davon habe ich mich entschieden, die Registerinformationen für die Modelle, die ich gefunden habe, zu betrachten: die MPU-6050 und die MPU-9250.
In beiden Fällen ist das Folgende für beide gleich. Und für den Anfang gehen wir davon aus, dass es auch für diese MPU-92/65 genauso sein wird.
59 bis 64 - Beschleunigungsmessermessungen
65, 66 - Temperaturmessungen 67 bis 72 - Gyroskopmessungen 73 bis 96 - externe Sensordaten
Ein Hinweis: Der MPU-6050 scheint KEIN Magnetometer zu haben, während der MPU-9250 (und wir gehen davon aus, dass dieser auch einen hat) einen hat.
Einige weitere interessante, hoffentlich nützliche Informationen aus dem Register-Dokument:
Informationen zum Magnetometer:
Magnetometer-ID: 0x48 Register 00 bis 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 H0 04 H. H1 HX 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 07H HZL HZ5 HZ2 HZ HZ15 HZ2 HZ HZ5 HZ2 HZ HZ5 HZ2 HZ ST2 0 0 0 BITM HOFL 0 0 0 eine Aufschlüsselung der Bedeutung jedes Registers: HXL[7:0]: X-Achsen-Messdaten niedriger 8bit HXH[15:8]: X-Achsen-Messdaten höher 8bit HYL[7:0]: Y-Achsen-Messdaten niedriger 8bit HYH[15:8]: Y-Achsen-Messdaten höher 8bit HZL[7:0]: Z-Achsen-Messdaten niedriger 8bit HZH[15:8]: Z-Achsen-Messdaten höher 8 Bit
Programmierung
Eine weitere Information aus den Registerdokumenten ist, dass es nur etwa 100 Register zu geben schien. Eine Taktik könnte also darin bestehen, ein einfaches Programm zu schreiben, das auf das Gerät zugreift (0x68) und versucht, eine Reihe von Registern sequentiell ohne Rücksicht auf ihre Bedeutung zu lesen, nur um zu sehen, welche Daten zu sehen sind.
Führen Sie dann aufeinanderfolgende Durchgänge mit demselben Code durch und vergleichen Sie die Daten von einem Durchgang mit dem nächsten.
Die Idee ist, dass wir wahrscheinlich alle Register eliminieren könnten, die keine Daten zu haben scheinen (Nullen oder FF?) oder die sich absolut nie ändern, und wir könnten uns auch auf diejenigen konzentrieren, die sich ändern.
Dann betrachten wir nur diejenigen, die sich ändern, und fügen eine Mittelungsfunktion hinzu, die die letzten N Lesevorgänge dieses Registers mittelt, um zu sehen, ob es tatsächlich einen bestimmten konstanten Wert für dieses Register gibt. Dies würde annehmen, dass wir den Sensor sehr ruhig und an derselben Stelle halten.
Schließlich könnten wir dann mit dem Sensor vorsichtig etwas ausprobieren, wie ihn anstupsen (Beschleunigungsmesser, Kreisel) oder darauf pusten (Temperatur) oder ihn drehen (die vorherigen beiden plus Magnetometer) und sehen, wie sich dies auf die Werte auswirkt.
Ich nutze die wiringPi-Bibliothek so oft wie möglich. Es hat Unterstützung für I2C.
Erster Lauf:
/********************************************************************************
* zum erstellen: gcc first.test.mpu9265.c -o first.test.mpu9265 -lwiringPi * * zum Ausführen: sudo./first.test.mpu9265 * * dieses Programm gibt nur eine Reihe von (möglichen) Registern vom MCP23017 aus, * und dann von der MPU9265 (oder einer anderen MPU mit dieser 0x68-Adresse) * * Ich habe es verwendet, um zu überprüfen, ob ich überhaupt vom Sensor lesen konnte, da ich bereits * dem MCP23017 vertraute. ************************************************* ****************************/ #include #include #include #include #include int main(int argc, char** argv) { puts("Mal sehen, was MCP23017 @ 0x20 zu sagen hat:"); Fehler = 0; int deviceId1 = 0x20; int fd1 = wiringPiI2CSetup(deviceId1); if (-1 == fd1) { fprintf (stderr, "WiringPi I2C-Gerät kann nicht geöffnet werden: %s\n", strerror (errno)); 1 zurückgeben; } for (int reg=0;reg<300;reg++) { fprintf(stderr, "%d", wiringPiI2CReadReg8(fd1, reg));fflush(stderr); Verzögerung(10); } puts(""); puts("Mal sehen, was MPU9265 @ 0x20 zu sagen hat:"); Fehler = 0; int Geräte-ID2 = 0x68; int fd2 = wiringPiI2CSetup(deviceId2); if (-1 == fd2) { fprintf (stderr, "WiringPi I2C-Gerät kann nicht geöffnet werden: %s\n", strerror (errno)); 1 zurückgeben; } for (int reg=0;reg<300;reg++) { fprintf(stderr, "%d", wiringPiI2CReadReg8(fd2, reg));fflush(stderr); Verzögerung(10); } puts(""); 0 zurückgeben; }
Der zweite Lauf:
/********************************************************************************
* zu bauen: gcc second.test.mpu9265.c -o second.test.mpu9265 -lwiringPi * * ausführen: sudo./second.test.mpu9265 * * Dieses Programm gibt die Registernummer neben dem gelesenen Wert aus. * * Dies macht es nützlich, die Ausgabe in eine Datei umzuleiten (umzuleiten), und dann * können mehrere Durchläufe durchgeführt werden, um sie zu vergleichen. Es könnte einen Einblick geben, * welche Register wichtig sind und wie sich die Daten verhalten könnten. ************************************************* ****************************/ #include #include #include #include #include #include int main(int argc, char** argv) { int GeräteId = -1; if (0) {} else if (!strncmp(argv[1], "0x20", strlen("0x20"))) { deviceId = 0x20; aufrechtzuerhalten. Sonst if (!strncmp(argv[1], "0x68", strlen("0x68"))) { deviceId = 0x68; aufrechtzuerhalten. Sonst if (!strncmp(argv[1], "0x69", strlen("0x69"))) { deviceId = 0x69; } puts("Mal sehen, was MPU9265 @ 0x20 zu sagen hat:"); Fehler = 0; int fd = wiringPiI2CSetup(deviceId); if (-1 == fd) { fprintf (stderr, "WiringPi I2C-Gerät kann nicht geöffnet werden: %s\n", strerror (errno)); 1 zurückgeben; } for (int reg=0;reg<300;reg++) { fprintf(stderr, "%d:%d\n", reg, wiringPiI2CReadReg8(fd, reg));fflush(stderr); Verzögerung(10); } Rückgabe 0; }
Der dritte Lauf:
/********************************************************************************
* zu bauen: gcc dritter.test.mpu9265.c -o dritter.test.mpu9265 -lwiringPi * * ausführen: sudo./dritter.test.mpu9265 * * Dieses Programm ist ein Ergebnis des zweiten. Es liest nur aus den *-Registern, die einen Unterschied zwischen einem Lauf und dem nächsten anzeigten.************************************************* ****************************/ #include #include #include #include #include #include int main(int argc, char** argv) { int GeräteId = -1; if (0) {} else if (!strncmp(argv[1], "0x68", strlen("0x68"))) { deviceId = 0x68; aufrechtzuerhalten. Sonst if (!strncmp(argv[1], "0x69", strlen("0x69"))) { deviceId = 0x69; } puts("Mal sehen, was MPU9265 @ 0x20 zu sagen hat:"); Fehler = 0; int fd = wiringPiI2CSetup(deviceId); if (-1 == fd) { fprintf (stderr, "WiringPi I2C-Gerät kann nicht geöffnet werden: %s\n", strerror (errno)); 1 zurückgeben; } for (int reg=61;reg<=73;reg++) { fprintf(stderr, "%d:%d\n", reg, wiringPiI2CReadReg8(fd, reg));fflush(stderr); Verzögerung(10); } for (int reg=111;reg<=112;reg++) { fprintf(stderr, "%d:%d\n", reg, wiringPiI2CReadReg8(fd, reg));fflush(stderr); Verzögerung(10); } for (int reg=189;reg<=201;reg++) { fprintf(stderr, "%d:%d\n", reg, wiringPiI2CReadReg8(fd, reg));fflush(stderr); Verzögerung(10); } for (int reg=239;reg<=240;reg++) { fprintf(stderr, "%d:%d\n", reg, wiringPiI2CReadReg8(fd, reg));fflush(stderr); Verzögerung(10); } Rückgabe 0; }
Was haben wir also bisher gelernt? Das Bild der Tabelle mit farbig hervorgehobenen Bereichen zeigt an, dass die Ausgabe den ersten Registersätzen zu entsprechen scheint.
Die bisherigen Ergebnisse können neue Fragen aufwerfen.
Frage: Warum gibt es nur ein Registerergebnis für die Gruppe "extern"?
Frage: Was sind all diese unbekannten Register "??????"
Frage: Da das Programm nicht Interrupt-gesteuert ist, wurden Daten zu langsam angefordert? zu schnell?
Frage: Können wir die Ergebnisse beeinflussen, indem wir Dinge mit dem Sensor selbst ausprobieren, während er läuft?
Schritt 6: Lassen Sie uns mehr in die Messwerte / Daten eintauchen
Ich denke, der nächste Schritt vor allem anderen besteht darin, das Programm zu verbessern, um:
- Seien Sie flexibel in der Schleifenverzögerung (ms)
- Seien Sie flexibel bei der Anzahl der Messwerte, um einen laufenden Durchschnitt pro Register zu erhalten
(Ich musste das Programm als Datei anhängen. Scheint ein Problem zu sein, es hier einzufügen. "fourth.test.mpu9265.c")
Hier ist ein Lauf mit den letzten 10 Messwerten für einen Durchschnitt in einer 10-ms-Schleife:
sudo./vierter.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
Die erste Spalte ganz links ist die Registernummer. Dann kommen die letzten 10 Messwerte für dieses Register. Schließlich ist die letzte Spalte der Durchschnitt für jede Zeile.
Es sieht so aus, als wären die Register 61, 69, 71, 189, 197 und 199 entweder nur binär oder bereit / nicht bereit, oder sie sind das High-Byte eines 16-Bit-Werts (negativ?).
Weitere interessante Beobachtungen:
- Register 65, 193 - sehr stabil und gleicher Wert
- Register 63, 191 - sehr stabil und gleicher Wert
- Register 73, 112, 195, 201, 240 - alle auf Null
Lassen Sie uns diese Beobachtungen auf das mehrfarbige, hervorgehobene Tabellenbild von vorhin zurückführen.
Register 65 - Temperatur
Register 193 - ??????
Register 63 - Beschleunigungsmesser
Register 191 - ??????
Register 73 - extern
Registrieren Sie 112 und weiter - ??????
Nun, wir haben noch Unbekanntes, aber wir haben etwas Nützliches gelernt.
Register 65 (Temperatur) und Register 63 (Beschleunigungsmesser) waren beide sehr stabil. Dies ist etwas, was wir erwarten würden. Ich habe den Sensor nicht berührt; es bewegt sich nicht, abgesehen von zufälligen Vibrationen, da der Roboter auf demselben Tisch wie mein Computer ruht.
Es gibt einen interessanten Test, den wir für jedes dieser Temperatur-/Beschleunigungsmesser-Register durchführen können. Für diesen Test benötigen wir noch eine weitere Version des Programms.
Schritt 7: Wir sind in der Lage, Temperatur und Beschleunigung zu beeinflussen
In den vorherigen Schritten haben wir mindestens ein Register für die Temperatur und eines für die Beschleunigung eingegrenzt.
Mit dieser nächsten Version des Programms ("fifth.test.mpu9265.c") können wir tatsächlich eine Änderung für beide Register sehen. Bitte schauen Sie sich die Videos an.
Mehr Graben
Wenn wir zurückgehen und uns die Registerinformationen ansehen, sehen wir, dass es Folgendes gibt:
- drei 16-Bit-Ausgänge für Gyroskop
- drei 16-Bit-Ausgänge für Beschleunigungsmesser
- drei 16-Bit-Ausgänge für Magnetometer
- ein 16-Bit-Ausgang für Temperatur
Die Ergebnisse unserer einfachen Testprogramme waren jedoch alle einzelne 8-Bit-Ausgaben. (Einzelregister).
Versuchen wir also mehr von dem gleichen Ansatz, aber diesmal lesen wir 16 statt 8 Bit.
Wir werden wahrscheinlich etwas wie unten tun müssen. Nehmen wir die Temperatur als Beispiel, da es sich nur um einen 16-Bit-Ausgang handelt.
// Dateideskriptor fd abrufen…
int tempRegHi = 65; int tempRegLo = 66; int hiByte = wiringPiI2CReadReg8(fd, tempRegHi); int loByte = wiringPiI2CReadReg8(fd, tempRegLo); int Ergebnis = hiByte << 8; // setze die 8 Bits hoher Ordnung in den oberen Teil eines 16-Bit-Wert-Ergebnisses |= loByte; // Fügen Sie jetzt 8 Bit in der unteren Reihenfolge hinzu, was eine vollständige 16-Bit-Zahl ergibt // drucken Sie diese Zahl aus oder verwenden Sie die horizontale Grafikfunktion von zuvor
Aus unseren vorherigen Schritten haben wir gesehen, dass Register 65 ziemlich stabil ist, während Register 66 sehr laut ist. Da 65 das höherwertige Byte und 66 das niederwertige Byte ist, macht das Sinn.
Zum Lesen können wir die Daten von Register 65 unverändert übernehmen, aber wir könnten die Werte von Register 66 mitteln.
Oder wir können einfach das gesamte Ergebnis mitteln.
Schauen Sie sich das letzte Video zu diesem Teil an; es zeigt das Lesen des gesamten 16-Bit-Temperaturwertes. Der Code ist "sixth.test.mpu9265.c"
Schritt 8: Der Beschleunigungsmesser und das Gyroskop
Die Videos für diesen Abschnitt zeigen die Ausgabe des Beschleunigungsmessers und des Gyroskops unter Verwendung eines Testprogramms "seventh.test.mpu9265.c". Dieser Code kann 1, 2 oder 3 aufeinanderfolgende Byte-Paare (Hi- und Lo-Bytes) lesen und die Werte in einen einzelnen 16-Bit-Wert umwandeln. Somit können wir jede einzelne Achse lesen, oder wir können zwei davon zusammen lesen (und es summiert die Änderungen) oder wir können alle drei lesen (und es summiert die Änderungen).
Um für diese Phase für dieses Instructable zu wiederholen, suche ich nur eine einfache Frage zu beantworten: "Hat der Roboter gedreht / geschwenkt?". Ich suche keinen genauen Wert, wie zum Beispiel, ob er um 90 Grad gedreht wurde. Das kommt später, wenn wir SLAM machen, aber es ist nicht erforderlich für einfaches Umgehen von Hindernissen und zufällige Bewegungen.
Schritt 9: (in Arbeit) das Magnetometer
Bei Verwendung des i2cdetect-Tools wird der MPU9265 als 0x68 in der Tabelle angezeigt:
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: -- -- -- -- -- -- -- --
Es sind zusätzliche Schritte erforderlich, um aus dem Magnetometerteil der IMU zu lesen.
Aus dem PDF-Dokument der Invesense-Register:
REGISTER 37 BIS 39 – I2C SLAVE 0 CONTROL
- REGISTRIEREN 37 - I2C_SLV0_ADDR
- REGISTER 38 - I2C_SLV0_REG
- REGISTRIEREN 39 - I2C_SLV0_CTRL
Empfohlen:
DIY So zeigen Sie die Zeit auf dem M5StickC ESP32 mit Visuino an - Einfach zu tun: 9 Schritte
DIY So zeigen Sie die Zeit auf dem M5StickC ESP32 mit Visuino an - Einfach zu machen: In diesem Tutorial lernen wir, wie Sie den ESP32 M5Stack StickC mit Arduino IDE und Visuino programmieren, um die Zeit auf dem LCD anzuzeigen
DIY, wie man eine cool aussehende Uhr macht – StickC – Einfach zu tun: 8 Schritte
DIY Wie man eine cool aussehende Uhr macht - StickC - Einfach zu machen: In diesem Tutorial lernen wir, wie man ESP32 M5Stack StickC mit Arduino IDE und Visuino programmiert, um eine Zeit auf dem LCD anzuzeigen und die Zeit auch mit den StickC-Tasten einzustellen
DIY Bluetooth Boombox Lautsprecher - HOW TO: 13 Schritte (mit Bildern)
DIY Bluetooth Boombox Lautsprecher | WIE MAN: Hallo! Vielen Dank, dass Sie sich dieses Projekt angesehen haben, dieses ist auf meiner Favoritenliste! Ich freue mich sehr, dieses tolle Projekt realisiert zu haben. Während des gesamten Projekts wurden viele neue Techniken verwendet, um die Gesamtqualität und das Finish der Spea
Rocola (DIY): 3 Schritte
Rocola (DIY): Rocola interactive que te allowirá reproducir tu música favorita en cualquier lugar que cuente con un toma corriente! Esta rocola cuenta con 3 canciones establecidas que puedes conservar o cambiar según tu gusto musical.La rocola cuenta con 3 boton
Erstellen und Einfügen einer Tabelle und Hinzufügen zusätzlicher Spalten und/oder Zeilen zu dieser Tabelle in Microsoft Office Word 2007 – wikiHow
Erstellen und Einfügen einer Tabelle und Hinzufügen zusätzlicher Spalten und/oder Zeilen zu dieser Tabelle in Microsoft Office Word 2007: Hatten Sie schon einmal viele Daten, mit denen Sie arbeiten, und dachten Sie sich … dieser Daten besser und verständlicher aussehen?" Wenn ja, dann könnte eine Tabelle in Microsoft Office Word 2007 Ihre Antwort sein