Πίνακας περιεχομένων:
- Βήμα 1: Ο αισθητήρας IMU
- Βήμα 2: Τα πράγματα δεν είναι πάντα καθαρά, εύκολα
- Βήμα 3: Αρχική δοκιμή
- Βήμα 4: Αντιμετώπιση προβλημάτων
- Βήμα 5: Ανάγνωση των δεδομένων του αισθητήρα
- Βήμα 6: Ας σκάψουμε περισσότερο στις αναγνώσεις / δεδομένα
- Βήμα 7: Είμαστε σε θέση να επηρεάσουμε τη θερμοκρασία και την επιτάχυνση
- Βήμα 8: Το επιταχυνσιόμετρο και το γυροσκόπιο
- Βήμα 9: (εργασία σε εξέλιξη) το Μαγνητόμετρο
2025 Συγγραφέας: John Day | [email protected]. Τελευταία τροποποίηση: 2025-01-13 06:57
Συνεχίζουμε μαζί με τον Wallace. Το όνομα Wallace προήλθε από ένα μείγμα "Wall-E", και από ένα προηγούμενο έργο (φωνητική αναγνώριση), και χρησιμοποιώντας το βοηθητικό πρόγραμμα "espeak", ακούστηκε λίγο βρετανικά. Και σαν παρκαδόρος ή μπάτλερ. Και αυτός είναι ο τελικός στόχος: το έργο αυτό να μετατραπεί σε κάτι χρήσιμο. Έτσι "Wallace".
Ο Wallace μπορεί να κινείται, μπορεί να αποφύγει εμπόδια χρησιμοποιώντας αισθητήρες απόστασης IR (πρόσφατα, κατά κάποιο τρόπο τηγανίστηκαν (;) (πρέπει να το εξετάσω όταν έχω την ευκαιρία), έχει επίσης μερικούς ακουστικούς αισθητήρες απόστασης (τρεις από αυτούς έπεσαν ταυτόχρονα άσχημα) χρόνο, μαζί με έναν διαστολέα MCP23017), και τέλος, μπορεί να ανιχνεύσει αλλαγές στο ρεύμα του κινητήρα για να μάθει πότε χτυπά σε κάτι.
Εκτός από τους αισθητήρες, ο Γουάλας «θυμάται» τις 100 κινήσεις και έχει κάποια στοιχειώδη ανάλυση χρησιμοποιώντας το ιστορικό των κινήσεων.
Ο στόχος μέχρι στιγμής για τον Wallace είναι απλώς να προσπαθήσει να συνεχίσει να προχωράει και να γνωρίζει πότε έχει κολλήσει σε κάποιο επαναλαμβανόμενο μοτίβο (όπως σε μια γωνία) και δεν προχωρά πραγματικά μπροστά.
Έχω περάσει από πολλές επαναλήψεις για κίνηση και πλοήγηση, και ο συνεπής πονοκέφαλος ήταν κατά τη διάρκεια της περιστροφής.
Δεδομένου ότι ο Wallace είναι ένα ρομπότ που παρακολουθείται, και ήθελα να κρατήσω τα πράγματα πιο απλά στο λογισμικό (για αργότερα), για να γυρίσω, απλώς τον περιστρέφω/περιστρέφεται στη θέση του. Έτσι, εφαρμόστε ίσο αλλά αντίθετο κύκλο ισχύος / λειτουργίας στους κινητήρες.
Το πρόβλημα που αντιμετωπίζεται οφείλεται στον σχεδιασμό της πλατφόρμας ρομπότ Agent 390. Οι ζώνες τροχιάς τείνουν να τρίβονται στα πλάγια. Και το χειρότερο, η μία πλευρά το κάνει περισσότερο από την άλλη.
Στο πάτωμα και κατευθείαν, δεν υπήρξε πρόβλημα. Εμφανίζεται στο χαλί. Επέλεξα να κρατήσω τον Γουάλας μακριά από τα χαλιά αφού τα κομμάτια του έγιναν ζοφερά (μαζεύουν βρώμικα πολύ εύκολα).
Το πραγματικό πρόβλημα είναι όταν περιστρέφεστε στο δάπεδο.
Εάν έχω το λογισμικό να εφαρμόσει έναν κύκλο εργασιών υψηλού επιπέδου, τότε περιστρέφεται λίγο πολύ με συνέπεια. Ωστόσο, κατά τη διάρκεια ενός κύκλου χαμηλών καθηκόντων, μπορεί να στρίψει ή όχι. Or μπορεί να γυρίσει για λίγο και μετά να επιβραδύνει. Η περιστροφική ενέργεια φαίνεται να είναι ανεξέλεγκτη μέσω του λογισμικού ή στην καλύτερη περίπτωση πολύ δύσκολη.
Το πρόβλημα εμφανίζεται κατά τη διάρκεια της πλοήγησης και της μετακίνησης γύρω ή μακριά από εμπόδια. Μπορεί είτε να απομακρυνθεί πολύ άγρια, είτε να κολλήσει προσπαθώντας να κάνει πολύ μικρές βάρδιες, χωρίς καν να μετακινηθεί.
Και έτσι η παραπάνω εξήγηση παρακίνησε αυτό το Εκπαιδευτικό.
Αρχικά, ήθελα να απαλλαγώ ή να καθυστερήσω την εισαγωγή μιας μονάδας ανίχνευσης κίνησης (IMU), επειδή είναι Α) περίπλοκες, Β) θορυβώδεις, Γ) τα λάθη μπορούν να εισαχθούν με την πάροδο του χρόνου, κλπ, κλπ. Κ.λπ. Η σκέψη μου είχε θα μπορούσαμε να κάνουμε πολύ καλά πηδώντας μπροστά στους αισθητήρες λέιζερ IR πτήσης. Και θα μπορούσαμε - χρησιμοποιώντας λέιζερ να γνωρίζουμε αν το ρομπότ περιστράφηκε ή όχι, παρακολουθώντας τις αλλαγές στην απόσταση.
Στην πραγματικότητα, θα μπορούσαμε επίσης (κάπως) να το κάνουμε τώρα, με τους ακουστικούς αισθητήρες.
Ωστόσο, όλα αυτά είναι ένας πολύ έμμεσος, περίπλοκος τρόπος για να απαντήσουμε σε μια απλή ερώτηση: "περιστρέψαμε ή όχι;"
Μου φάνηκε ότι το να πηδήξω για να χρησιμοποιήσω τους αισθητήρες λέιζερ ToF θα με πάει στο επόμενο επίπεδο λογισμικού. δηλαδή SLAM (ταυτόχρονος εντοπισμός και χαρτογράφηση). Δεν ήμουν έτοιμος να πάω εκεί ακόμα.
Είναι καλό να κάνετε ένα έργο ρομπότ σε επίπεδα, με τα πρώτα (κάτω) επίπεδα να είναι πιο απλά και τα τελευταία (ανώτερα) επίπεδα να είναι πιο αφηρημένα και να αντιμετωπίζουν πιο δύσκολα θέματα.
Τα στρώματα μπορούν να σκεφτούν κάτι σαν αυτό:
- ρομπότ φυσικό πλαίσιο / μηχανική δομική βάση
- υποτυπώδες σύστημα κίνησης (Βατόμουρο, Roboclaw, κινητήρες, καλωδίωση κ.λπ., βασικό λογισμικό, με πληκτρολόγιο)
- βασικό κύκλωμα για την υποστήριξη αισθητήρων (μετατροπέας τάσης διπλής κατεύθυνσης, επέκταση θύρας, E-Stop, διανομή ισχύος, κλπ)
- αισθητήρες αποφυγής εμποδίων (ακουστική, IR)
- βασική, βασική τοποθέτηση και κίνηση - ανίχνευση (επιταχυνσιόμετρο, γυροσκόπιο, μαγνητόμετρο, κωδικοποιητές κινητήρων, κωδικοποιητές τροχών)
Μπορείτε να βρείτε τη δική σας λίστα. Τα σημεία αυτής της λίστας είναι ότι μάλλον θα πρέπει να τα κάνετε πάνω κάτω με αυτή τη σειρά και επίσης ότι αν αφιερώσετε λίγο χρόνο σε κάθε στρώμα για να φτάσετε σε καλή κατάσταση, αυτό θα σας βοηθήσει αργότερα καθώς τα πράγματα γίνονται πιο περίπλοκα.
Η παραπάνω λίστα θα μπορούσε λίγο πολύ να αντιστοιχιστεί σε αυτά τα εννοιολογικά επίπεδα στο λογισμικό.
- SLAM (ταυτόχρονος εντοπισμός και χαρτογράφηση)
- Έλεγχος και επίγνωση της κίνησης, περιστροφή
- Βασική αποφυγή εμποδίων
- Έλεγχος και ανίχνευση δεδομένων αισθητήρα
- Βασική κίνηση προς τα εμπρός, προς τα πίσω, αριστερά και δεξιά, επιτάχυνση, επιβράδυνση, διακοπή
Όπως μπορείτε να δείτε, για αυτήν τη λίστα, τα πρώτα στοιχεία θα ήταν τα ανώτερα, πιο περίπλοκα στρώματα που αντιμετωπίζουν πιο αφηρημένα θέματα και ερωτήσεις, όπως "πού είμαι" και "πού πηγαίνω", ενώ τα τελευταία στοιχεία θα είναι χαμηλότερα επίπεδα λογισμικού που χειρίζονται το "πώς να μιλάτε/να ακούτε στον αισθητήρα Α" ή "πώς να μετακινείτε αυτόν τον τροχό".
Τώρα, δεν λέω ότι όταν ξεκινάτε σε ένα επίπεδο, θα το έχετε ολοκληρώσει και μετά είναι στο επόμενο επίπεδο, για να μην επιστρέψετε ποτέ στο προηγούμενο. Ένα έργο ρομπότ μπορεί να μοιάζει πολύ με σύγχρονες, επαναληπτικές μεθόδους ανάπτυξης λογισμικού (ευέλικτο, SCRUM, κλπ).
Απλώς λέω να αφιερώσω χρόνο στο καθένα. Θα πρέπει να ισορροπήσετε πόσο να κάνετε σε κάθε μία και να αποφασίσετε τι προσπαθείτε σε ένα συγκεκριμένο επίπεδο που αξίζει τον χρόνο και τον κόπο.
Υπάρχει μια ορισμένη «σύγκρουση» ή «ένταση» μεταξύ δύο ανταγωνιστικών ιδεών ή κατευθύνσεων.
Ένα είναι αυτό που θα αποκαλούσα "plug-n-play" για την επίλυση του προβλήματος Α.
Το άλλο είναι DIY (κάντε το μόνοι σας). Και αυτό μπορεί να μην είναι καν η καλύτερη ετικέτα για αυτήν την άλλη ιδέα.
Ακολουθεί ένα παράδειγμα για το καθένα, ελπίζουμε ότι θα δείτε την ένταση ή τη σύγκρουση μεταξύ των δύο επιλογών.
Για αυτό το παράδειγμα, ας συνοψίσουμε το SLAM, την αποφυγή εμποδίων και τη βασική βασική κίνηση όλα ως ένα πρόβλημα που πρέπει να επιλυθεί ταυτόχρονα.
- Εάν αποφασίσουμε να ακολουθήσουμε τη διαδρομή plug-n-play, πηγαίνουμε αμέσως (ανάλογα με τον προϋπολογισμό) σε πράγματα όπως τα περιστρεφόμενα λέιζερ στην κορυφή ή την κάμερα βάθους πεδίου ή τα λέιζερ ToF και το IMU (θέμα αυτού Διδάξιμο).
- Εάν, από την άλλη πλευρά, θέλουμε να ακολουθήσουμε τη δεύτερη διαδρομή, μπορεί να προσπαθήσουμε να εξαγάγουμε κάθε πιθανή πληροφορία από κάποιους ακουστικούς αισθητήρες ή αισθητήρες IR ή καθόλου αισθητήρες - χρησιμοποιούμε απλώς παρακολούθηση ρεύματος κινητήρα (χτύπημα)
Τι μπορεί να ειπωθεί για το #1 έναντι του #2; Ένα πράγμα θα ήταν ότι θα έχουμε μάθει πολλά περισσότερα κάνοντας το #2. Οι περιορισμοί του να έχουμε μόνο ακουστικούς αισθητήρες για να δουλέψουμε, μας αναγκάζει να σκεφτούμε πολύ περισσότερα θέματα.
Από την άλλη πλευρά, εάν είμαστε πολύ συγκεντρωμένοι στο να κάνουμε πράγματα μέσω του #2, μπορεί να χάνουμε χρόνο, επειδή ζητάμε περισσότερα από ό, τι πρέπει από ακουστικούς αισθητήρες.
Μια ακόμη ιδέα ή ιδέα για σκέψη: Ποιο μείγμα υλικού και λογισμικού απαντά καλύτερα στις ερωτήσεις "πώς να" και ποιο μείγμα λογισμικού (και υλικού;) απαντά στην ερώτηση "τι", "πότε", "πού" Το Επειδή το «πώς» είναι τυπικά μια ερώτηση χαμηλότερου επιπέδου από την οποία εξαρτώνται τα «τι», «πότε» και «πού» για να λάβετε μια απάντηση.
Τέλος πάντων, όλα τα παραπάνω ήταν απλώς κάτι για σκέψη.
Στην περίπτωσή μου, μετά από πολλή προσπάθεια και έχοντας το σταθερό ενοχλητικό ζήτημα της τριβής τροχιάς και αδυνατώντας να αποκτήσω συνεπή έλεγχο και κίνηση, ήρθε η ώρα να κάνουμε κάτι άλλο.
Έτσι αυτό το Instructable - ένα IMU.
Ο στόχος είναι ότι εάν η IMU πει ότι το ρομπότ ΔΕΝ περιστρέφεται, αυξάνουμε τον κύκλο εργασιών. Εάν στρέφουμε πολύ γρήγορα, μειώνουμε τον κύκλο εργασίας.
Βήμα 1: Ο αισθητήρας IMU
Και έτσι ο επόμενος αισθητήρας που θα προσθέσουμε στο Wallace είναι το IMU. Μετά από κάποια έρευνα, έκανα λύση σε ένα MPU6050. Αλλά τότε αυτή τη στιγμή, το MPU9050 (και ακόμη πιο πρόσφατα, το MPU9250) φαινόταν ακόμα καλύτερη ιδέα.
Η πηγή μου ήταν η Amazon (στις ΗΠΑ). Έτσι παρήγγειλα δύο από αυτά.
Αυτό που πήρα στην πραγματικότητα (φαίνεται ότι δεν υπάρχει κανένας έλεγχος σε αυτό. Αυτό δεν μου αρέσει στο Amazon) ήταν δύο MPU92/65. Αναρωτιέμαι λίγο για τον χαρακτηρισμό. Ρίξτε μια ματιά στις εικόνες. φαίνεται να είναι ένας «οικογενειακός» προσδιορισμός. Σε κάθε περίπτωση, με αυτό έχω κολλήσει.
Η προσθήκη του είναι πολύ απλή -πάρτε έναν πίνακα proto με συνδετικά κομμάτια, κολλήστε τον αισθητήρα στην πλακέτα, προσθέστε ένα τερματικό μπλοκ 10 ακίδων (πήρα το δικό μου από την Pololu).
Για να ελαχιστοποιήσω τυχόν παρεμβολές, προσπάθησα να τοποθετήσω αυτούς τους αισθητήρες μακριά από κάθε τι άλλο.
Αυτό σήμαινε επίσης τη χρήση ορισμένων νάιλον μπουλονιών/παξιμαδιών.
Θα χρησιμοποιήσω το πρωτόκολλο I2C. Ας ελπίσουμε ότι το συνολικό μήκος καλωδίου δεν θα είναι πολύ κακό.
Υπάρχουν πολλές πληροφορίες αλλού σχετικά με τις βασικές συνδέσεις και τα επίπεδα τάσης κ.λπ., οπότε δεν θα το επαναλάβω εδώ.
Βήμα 2: Τα πράγματα δεν είναι πάντα καθαρά, εύκολα
Σε αυτό το γράψιμο, δεν φαίνεται να υπάρχουν πολλά στο διαδίκτυο για το συγκεκριμένο MPU-92/65. Αυτό που είναι διαθέσιμο, όπως και με τους περισσότερους αισθητήρες, φαίνεται να είναι παραδείγματα χρήσης του Arduino.
Προσπαθώ να κάνω αυτά τα Instructables λίγο διαφορετικά παρουσιάζοντας μια όχι και τόσο καθαρή διαδικασία, γιατί τα πράγματα δεν λειτουργούν πάντα αμέσως.
Υποθέτω ότι αυτά τα Instructables μοιάζουν περισσότερο με ένα blog παρά με απλό A-B-C, 1-2-3 "έτσι το κάνεις".
Βήμα 3: Αρχική δοκιμή
Από τις εικόνες στο προηγούμενο βήμα, τα κόκκινα και μαύρα καλώδια που πηγαίνουν στους αισθητήρες είναι φυσικά VCC (5V) και GND. Τα πράσινα και κίτρινα καλώδια είναι οι συνδέσεις I2C.
Εάν έχετε κάνει άλλα έργα I2C ή έχετε παρακολουθήσει μαζί με αυτές τις σειρές, τότε γνωρίζετε ήδη το "i2cdetect" και αυτό είναι το πρώτο βήμα για να μάθετε εάν το Raspberry μπορεί να δει τον νέο αισθητήρα.
Όπως μπορείτε να δείτε από τις εικόνες σε αυτό το βήμα, η πρώτη μας προσπάθεια ήταν ανεπιτυχής. Το IMU δεν εμφανίζεται (θα πρέπει να είναι αναγνωριστικό συσκευής 0x68).
Ωστόσο, τα καλά νέα είναι ότι ο δίαυλος I2C λειτουργεί. Βλέπουμε όντως μία συσκευή 0x20 και είναι ο διαστολέας θύρας MCP23017 (επί του παρόντος υπεύθυνος για τους ακουστικούς αισθητήρες HCSR04).
Δεν είναι εύκολο να το δείτε στην εικόνα, αλλά συνέδεσα τα ίδια χρωματιστά πράσινα και κίτρινα καλώδια από το IMU στο MCP23017 (δείτε κάτω αριστερά στην εικόνα)
Θα πρέπει να κάνουμε κάποια αντιμετώπιση προβλημάτων.
Βήμα 4: Αντιμετώπιση προβλημάτων
Χρησιμοποιώντας τη ρύθμιση συνέχειας σε ένα βολτόμετρο (αυτό με τον υψηλό τόνο), δοκίμασα συνδέσεις VCC (5V), GND, SDA και SCL. Αυτά ήταν καλά.
Η επόμενη προσπάθεια ήταν να αποσυνδέσετε το MCP23017 από το δίαυλο I2C, αφήνοντας μόνο το MPU-92/65 στο δίαυλο. Αυτό αποδείχθηκε άκαρπο - το "i2cdetect" τότε δεν έδειξε καμία συσκευή.
Έτσι, στη συνέχεια, αποσυναρμολόγησα τον αισθητήρα από τον τοτέμ πόλο και τον επανασυνδέσακα κατευθείαν στο αμφίδρομο δίαυλο 5V-to-3V. δηλαδή, κατευθείαν στο Βατόμουρο. (κοντύτερα καλώδια;).
Και voila. Αυτή τη φορά υπάρχει επιτυχία. Βλέπουμε το 0x68 να εμφανίζεται χρησιμοποιώντας το "i2cdetect".
Αλλά δεν ξέρουμε ακόμη γιατί λειτούργησε αυτή τη φορά. Θα μπορούσε να είναι το μήκος των καλωδίων; Η προηγούμενη τοποθεσία;
Σημείωση: Δεν είχε καμία διαφορά εάν το ADO ήταν γειωμένο ή όχι. Couldσως υπάρχουν αντιστάσεις έλξης και πτώσης επί του σκάφους. Το ίδιο μπορεί να ισχύει και για το FSYNC.
Στη συνέχεια, συνέδεσα ξανά το MCP23017. Έτσι τώρα έχουμε δύο συσκευές στο δίαυλο I2C. (δείτε την εικόνα). Επιτυχία, τώρα βλέπουμε τόσο το 0x20 όσο και το 0x68 με το i2cdetect.
Τα βίντεο περιγράφουν λίγο περισσότερο τι συνέβη κατά την αντιμετώπιση προβλημάτων.
Βήμα 5: Ανάγνωση των δεδομένων του αισθητήρα
Διάφορες Προσεγγίσεις
Αποφάσισα να ακολουθήσω πολλαπλές προσεγγίσεις για να λάβω χρήσιμες πληροφορίες από τον αισθητήρα. Εδώ είναι, όχι με καμία σειρά:
- δοκιμάστε κάποιο βασικό προγραμματισμό
- ανατρέξτε σε κάποια διαδικτυακή τεκμηρίωση για τα μητρώα
- ρίξτε μια ματιά στα παραδείγματα και / ή τον κώδικα άλλων
Γιατί αυτές οι προσεγγίσεις; Γιατί να μην αναζητήσετε απλώς κάποια υπάρχουσα βιβλιοθήκη ή κώδικα;
Πειραματίζοντας και δοκιμάζοντας κάποιες ιδέες, μπορούμε να απορροφήσουμε καλύτερα κάποιες γνώσεις όχι μόνο για τον συγκεκριμένο αισθητήρα, αλλά και να αποκτήσουμε κάποια τεχνική, δεξιότητα και τρόπους σκέψης για την αντιμετώπιση κάτι καινούργιου και κάτι που μπορεί να μην έχει πολλά έγγραφα. κάτι που μπορεί να έχει πολλά άγνωστα.
Επίσης, μόλις παίξουμε και δοκιμάσουμε μερικές από τις δικές μας ιδέες και αποκτήσουμε κάποια διορατικότητα, είμαστε σε καλύτερη θέση να αξιολογήσουμε τον κώδικα ή τη βιβλιοθήκη κάποιου άλλου.
Για παράδειγμα, αφού κοίταξα κάποιον κωδικό C ++ για το MPU9250 στο github, συνειδητοποίησα ότι με ανάγκαζε να χρησιμοποιήσω διακοπές, κάτι που δεν θέλω ακόμη να κάνω.
Επίσης, έρχεται με επιπλέον πράγματα όπως βαθμονόμηση. πάλι, κάτι που δεν με ενδιαφέρει ακόμα.
Αυτό που πρέπει να κάνω για να απαντήσω στην απλή ερώτηση "το ρομπότ περιστρέφεται ναι ή όχι" θα μπορούσε να απαντηθεί πολύ απλά διαβάζοντας μερικούς καταχωρητές.
Μητρώα
Σε αυτό το γράψιμο, δεν φαίνεται να υπάρχουν πολλά διαθέσιμα σε αυτόν τον αισθητήρα. Στην πραγματικότητα, αν ρίξετε μια ματιά στις εικόνες που συνοδεύουν αυτό το Instructable και ρίξετε μια προσεκτική ματιά στις επιγραφές στις πραγματικές μάρκες, με κάνει να αναρωτηθώ αν αυτό δεν είναι νοκ-άφ. Δεν συνδέω αυτό που βλέπω με τίποτα από το Invense. Ανεξάρτητα από αυτό, επέλεξα να εξετάσω τις πληροφορίες μητρώου για τα μοντέλα που βρήκα: το MPU-6050 και το MPU-9250.
Και στις δύο περιπτώσεις, το ακόλουθο είναι το ίδιο και για τα δύο. Και για αρχή, υποθέτουμε ότι θα είναι επίσης το ίδιο για αυτό το MPU-92/65.
59 έως 64 - μετρήσεις επιταχυνσιόμετρου
65, 66 - μετρήσεις θερμοκρασίας 67 έως 72 - μετρήσεις γυροσκοπίου 73 έως 96 - δεδομένα εξωτερικών αισθητήρων
Σημείωση: Το MPU-6050 φαίνεται να ΔΕΝ έχει μαγνητόμετρο, ενώ το MPU-9250 (και υποθέτουμε και αυτό) έχει ένα.
Μερικές πιο ενδιαφέρουσες, ελπίζω χρήσιμες πληροφορίες που συλλέχθηκαν από το μητρώο-έγγραφο:
Πληροφορίες μαγνητόμετρου:
magnetometer id: 0x48 καταχωρεί 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 HXHXHX HX5 HX5 HX4 HX4 HX5 HX4 HX4 HX4 HX4 HXH HX15 HX14 HX13 HX12 HX11 HX10 HX9 HX8 05H HYL HY7 HY6 hY5 HY4 HY3 HY2 ΗΥ1 HY0 06H hyh HY15 HY14 HY13 HY12 HY11 HY10 HY9 HY8 07H HZL HZ7 HZ6 HZ5 HZ4 HZ3 HZ2 HZ1 HZ0 08H HZH HZ15 HZ14 HZ13 HZ12 HZ11 HZ10 Ηζ9 HZ8 09h ST2 0 0 0 BITM HOFL 0 0 0 ανάλυση του τι σημαίνει κάθε καταχωρητής: HXL [7: 0]: δεδομένα μέτρησης αξόνων Χ χαμηλότερα 8bit HXH [15: 8]: δεδομένα μέτρησης άξονα Χ υψηλότερα 8bit HYL [7: 0]: Δεδομένα μέτρησης άξονα Υ χαμηλότερα 8bit HYH [15: 8]: Δεδομένα μέτρησης άξονα Υ υψηλότερα 8bit HZL [7: 0]: Δεδομένα μέτρησης άξονα Ζ χαμηλότερα 8bit HZH [15: 8]: Δεδομένα μέτρησης άξονα Ζ υψηλότερα 8bit
Προγραμματισμός
Μια άλλη πληροφορία από τα έγγραφα μητρώου είναι ότι φάνηκε ότι υπήρχαν μόνο περίπου 100 περίπου καταχωρητές. Έτσι, μια τακτική θα μπορούσε να είναι η συγγραφή ενός απλού προγράμματος που έχει πρόσβαση στη συσκευή (0x68) και επιχειρεί να διαβάσει μια σειρά καταχωρητών διαδοχικά, χωρίς να λαμβάνει υπόψη το νόημά τους, απλώς για να δει ποια δεδομένα μπορούν να προβληθούν.
Στη συνέχεια, κάντε διαδοχικά περάσματα, χρησιμοποιώντας τον ίδιο κωδικό και συγκρίνετε τα δεδομένα από το ένα πέρασμα με το άλλο.
Η ιδέα είναι ότι θα μπορούσαμε πιθανώς να εξαλείψουμε τους καταχωρητές που φαίνεται ότι δεν έχουν δεδομένα (μηδενικά ή FF;) ή που δεν αλλάζουν απολύτως ποτέ, και θα μπορούσαμε επίσης να επικεντρωθούμε σε αυτούς που αλλάζουν.
Στη συνέχεια, μια που εξετάζουμε μόνο αυτές που αλλάζουν, προσθέστε μια συνάρτηση μέσου όρου που έχει τον μέσο όρο των τελευταίων Ν ανάγνωσης αυτού του καταχωρητή, για να δείτε αν υπάρχει πράγματι μια σταθερή τιμή για αυτόν τον καταχωρητή. Αυτό θα υποθέσει ότι κρατάμε τον αισθητήρα πολύ ακίνητο και στην ίδια θέση.
Τέλος, θα μπορούσαμε στη συνέχεια να δοκιμάσουμε απαλά πράγματα με τον αισθητήρα, όπως να τον σπρώξουμε (επιταχυνσιόμετρο, γυροσκόπιο) ή να τον φυσήξουμε (θερμοκρασία) ή να τον περιστρέψουμε (τα δύο προηγούμενα συν μαγνητόμετρο) και να δούμε τι επίδραση έχει αυτό στις τιμές.
Μου αρέσει να χρησιμοποιώ τη βιβλιοθήκη wiringPi όσο το δυνατόν περισσότερο. Διαθέτει υποστήριξη για I2C.
Πρώτη εκτέλεση:
/********************************************************************************
* για δημιουργία: gcc first.test.mpu9265.c -o first.test.mpu9265 -lwiringPi * * για εκτέλεση: sudo./first.test.mpu9265 * * αυτό το πρόγραμμα εξάγει μια σειρά (πιθανών) καταχωρητών από το MCP23017, * και στη συνέχεια από το MPU9265 (ή οποιοδήποτε άλλο MPU σε αυτήν τη διεύθυνση 0x68) * * Το χρησιμοποίησα για να επικυρώσω αν μπορούσα να διαβάσω ακόμη και από τον αισθητήρα, αφού είχα ήδη * εμπιστοσύνη στο MCP23017. ********************************************** **************************/ #include #include #include #include #include int main (int argc, char ** argv) {βάζει ("Ας δούμε τι έχει να πει το MCP23017 @ 0x20:"); errno = 0; int deviceId1 = 0x20; int fd1 = καλωδίωσηPiI2CSetup (συσκευήId1); if (-1 == fd1) {fprintf (stderr, "Δεν είναι δυνατό το άνοιγμα της καλωδίωσης της συσκευής I2C: %s / n", strerror (errno)); επιστροφή 1? } για (int reg = 0; reg <300; reg ++) {fprintf (stderr, "%d", wiringPiI2CReadReg8 (fd1, reg)); fflush (stderr); καθυστέρηση (10)? } βάζει (""); βάζει ("Ας δούμε τι έχει να πει το MPU9265 @ 0x20:"); errno = 0; int συσκευήId2 = 0x68; int fd2 = καλωδίωσηPiI2CSetup (συσκευήId2); if (-1 == fd2) {fprintf (stderr, "Δεν είναι δυνατό το άνοιγμα της καλωδίωσης της συσκευής I2C: %s / n", strerror (errno)); επιστροφή 1? } για (int reg = 0; reg <300; reg ++) {fprintf (stderr, "%d", wiringPiI2CReadReg8 (fd2, reg)); fflush (stderr); καθυστέρηση (10)? } βάζει (""); επιστροφή 0? }
Το δεύτερο τρέξιμο:
/********************************************************************************
* για δημιουργία: gcc second.test.mpu9265.c -o second.test.mpu9265 -lwiringPi * * για εκτέλεση: sudo./second.test.mpu9265 * * Αυτό το πρόγραμμα εξάγει τον αριθμό μητρώου παράλληλα με την τιμή που διαβάζεται. * * Αυτό καθιστά χρήσιμο τον σωλήνα (ανακατεύθυνση) της εξόδου σε ένα αρχείο και, στη συνέχεια, * μπορούν να γίνουν πολλές εκτελέσεις, για σύγκριση. Μπορεί να δώσει κάποια εικόνα για το * ποιο μητρώο είναι σημαντικό και πώς μπορεί να συμπεριφέρονται τα δεδομένα. ********************************************** *************************** # #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; } βάζει ("Ας δούμε τι έχει να πει το MPU9265 @ 0x20:"); errno = 0; int fd = wiringPiI2CSetup (deviceId); if (-1 == fd) {fprintf (stderr, "Δεν είναι δυνατό το άνοιγμα της καλωδίωσης της συσκευής I2C: %s / n", strerror (errno)); επιστροφή 1? } για (int reg = 0; reg <300; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); καθυστέρηση (10)? } επιστροφή 0; }
Το τρίτο τρέξιμο:
/********************************************************************************
* για δημιουργία: gcc third.test.mpu9265.c -o third.test.mpu9265 -lwiringPi * * για εκτέλεση: sudo./third.test.mpu9265 * * Αυτό το πρόγραμμα είναι αποτέλεσμα του δεύτερου. Διαβάζεται μόνο από τους καταχωρητές * που υποδεικνύουν διαφορά μεταξύ της μιας εκτέλεσης και της επόμενης.********************************************** *************************** # #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; } βάζει ("Ας δούμε τι έχει να πει το MPU9265 @ 0x20:"); errno = 0; int fd = wiringPiI2CSetup (deviceId); if (-1 == fd) {fprintf (stderr, "Δεν είναι δυνατό το άνοιγμα της καλωδίωσης της συσκευής I2C: %s / n", strerror (errno)); επιστροφή 1? } για (int reg = 61; reg <= 73; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); καθυστέρηση (10)? } για (int reg = 111; reg <= 112; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); καθυστέρηση (10)? } για (int reg = 189; reg <= 201; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); καθυστέρηση (10)? } για (int reg = 239; reg <= 240; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); καθυστέρηση (10)? } επιστροφή 0; }
Τι μάθαμε λοιπόν μέχρι τώρα; Η εικόνα του πίνακα με έγχρωμες επισημασμένες περιοχές υποδεικνύει ότι η έξοδος φαίνεται να ταιριάζει με τα πρώτα σύνολα καταχωρητών.
Τα μέχρι τώρα αποτελέσματα μπορούν να δημιουργήσουν νέες ερωτήσεις.
Ερώτηση: γιατί υπάρχει μόνο ένα αποτέλεσμα εγγραφής για την "εξωτερική" ομάδα;
Ερώτηση: ποια είναι όλα αυτά τα άγνωστα μητρώα "??????"
Ερώτηση: δεδομένου ότι το πρόγραμμα δεν λειτουργεί με διακοπή, ζήτησε δεδομένα πολύ αργά; πολύ γρήγορα?
Ερώτηση: μπορούμε να επηρεάσουμε τα αποτελέσματα δοκιμάζοντας πράγματα με τον ίδιο τον αισθητήρα καθώς λειτουργεί;
Βήμα 6: Ας σκάψουμε περισσότερο στις αναγνώσεις / δεδομένα
Νομίζω ότι το επόμενο βήμα πριν από οτιδήποτε άλλο είναι να βελτιώσουμε το πρόγραμμα:
- να είστε ευέλικτοι σε πόση καθυστέρηση βρόχου (ms)
- να είστε ευέλικτοι σε πόσες αναγνώσεις θα δώσετε έναν τρέχοντα μέσο όρο ανά καταχωρητή
(Έπρεπε να επισυνάψω το πρόγραμμα ως αρχείο. Φαινόταν να υπάρχει πρόβλημα με την εισαγωγή του εδώ. "4th.test.mpu9265.c")
Ακολουθεί μια εκτέλεση χρησιμοποιώντας τις τελευταίες 10 αναγνώσεις κατά μέσο όρο, σε βρόχο 10ms:
sudo./fourth.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
Η πρώτη, αριστερή στήλη είναι ο αριθμός μητρώου. Στη συνέχεια, έρχονται οι τελευταίες 10 αναγνώσεις για αυτό το μητρώο. Τέλος, η τελευταία στήλη είναι ο μέσος όρος για κάθε σειρά.
Φαίνεται ότι οι καταχωρητές 61, 69, 71, 189, 197 και 199 είναι είτε μόνο δυαδικοί, είτε έτοιμοι / όχι έτοιμοι, είτε είναι το υψηλό byte μιας τιμής 16-bit (αρνητικό;).
Άλλες ενδιαφέρουσες παρατηρήσεις:
- καταχωρητές 65, 193 - πολύ σταθερή και ίδια τιμή
- μητρώο 63, 191 - πολύ σταθερή και ίδια τιμή
- μητρώα 73, 112, 195, 201, 240 - όλα στο μηδέν
Ας συσχετίσουμε αυτές τις παρατηρήσεις με την πολύχρωμη, τονισμένη εικόνα πίνακα από παλαιότερα.
Εγγραφή 65 - θερμοκρασία
Εγγραφή 193 - ??????
Μητρώο 63 - επιταχυνσιόμετρο
Εγγραφή 191 - ??????
Μητρώο 73 - εξωτερικό
Εγγραφή 112 και επάνω - ??????
Λοιπόν, έχουμε ακόμα άγνωστα, ωστόσο, έχουμε μάθει κάτι χρήσιμο.
Το μητρώο 65 (θερμοκρασία) και το μητρώο 63 (επιταχυνσιόμετρο) ήταν και τα δύο πολύ σταθερά. Αυτό είναι κάτι που θα περιμέναμε. Δεν έχω αγγίξει τον αισθητήρα. δεν κινείται, εκτός από τυχαίες δονήσεις, καθώς το ρομπότ ακουμπάει στο ίδιο τραπέζι με τον υπολογιστή μου.
Υπάρχει μια ενδιαφέρουσα δοκιμή που μπορούμε να κάνουμε για κάθε έναν από αυτούς τους καταχωρητές θερμοκρασίας/επιταχυνσιόμετρου. Για αυτό το τεστ, χρειαζόμαστε μια άλλη έκδοση του προγράμματος.
Βήμα 7: Είμαστε σε θέση να επηρεάσουμε τη θερμοκρασία και την επιτάχυνση
Στα προηγούμενα βήματα περιορίσαμε τουλάχιστον έναν καταχωρητή θερμοκρασίας και έναν για επιτάχυνση.
Με αυτήν την επόμενη έκδοση του προγράμματος ("5th.test.mpu9265.c"), μπορούμε πραγματικά να δούμε μια αλλαγή να γίνεται και για τα δύο μητρώα. Παρακαλώ δείτε τα βίντεο.
Περισσότερο σκάψιμο
Αν πάμε πίσω και ρίξουμε μια ματιά στις πληροφορίες του μητρώου, βλέπουμε ότι υπάρχουν:
- τρεις έξοδοι 16 bit για γυροσκόπιο
- τρεις έξοδοι 16 bit για επιταχυνσιόμετρο
- τρεις έξοδοι 16 bit για μαγνητόμετρο
- μία έξοδος 16 bit για θερμοκρασία
Ωστόσο, τα αποτελέσματα που ελήφθησαν από τα απλά δοκιμαστικά μας προγράμματα ήταν όλα μεμονωμένες έξοδοι 8 bit. (ενιαία μητρώα).
Ας δοκιμάσουμε λοιπόν περισσότερο την ίδια προσέγγιση, αλλά αυτή τη φορά διαβάζουμε 16 bit αντί για 8.
Μάλλον θα πρέπει να κάνουμε κάτι όπως παρακάτω. Ας χρησιμοποιήσουμε τη θερμοκρασία ως παράδειγμα, αφού είναι μόνο μία έξοδος 16 bit.
// λήψη περιγραφής αρχείων fd…
int tempRegHi = 65; int tempRegLo = 66; int hiByte = καλωδίωσηPiI2CReadReg8 (fd, tempRegHi); int loByte = καλωδίωσηPiI2CReadReg8 (fd, tempRegLo); int αποτέλεσμα = hiByte << 8; // βάλτε την τάξη hi 8 bits στο πάνω μέρος ενός αποτελέσματος τιμής 16 bit | = loByte; // τώρα προσθέστε στην τάξη lo 8 bit, αποδίδοντας έναν πλήρη αριθμό 16 bit // εκτυπώστε αυτόν τον αριθμό ή χρησιμοποιήστε τη λειτουργία οριζόντιας γραφικής παράστασης από πριν
Από τα προηγούμενα βήματά μας είδαμε ότι το μητρώο 65 είναι αρκετά σταθερό, ενώ το μητρώο 66 είναι πολύ θορυβώδες. Δεδομένου ότι το 65 είναι το byte υψηλής τάξης και το 66 το byte χαμηλής τάξης, αυτό έχει νόημα.
Για ανάγνωση, μπορούμε να πάρουμε τα δεδομένα του καταχωρητή 65 ως έχουν, αλλά θα μπορούσαμε να υπολογίσουμε κατά μέσο όρο τις τιμές του καταχωρητή 66.
Or μπορούμε απλά να υπολογίσουμε ολόκληρο το αποτέλεσμα.
Ρίξτε μια ματιά στο τελευταίο βίντεο για αυτό το μέρος. επιδεικνύει την ανάγνωση ολόκληρης της τιμής θερμοκρασίας 16 bit. Ο κωδικός είναι "sixth.test.mpu9265.c"
Βήμα 8: Το επιταχυνσιόμετρο και το γυροσκόπιο
Τα βίντεο για αυτήν την ενότητα δείχνουν έξοδο από το επιταχυνσιόμετρο και το γυροσκόπιο, χρησιμοποιώντας ένα δοκιμαστικό πρόγραμμα "heftth.test.mpu9265.c". Αυτός ο κώδικας μπορεί να διαβάσει 1, 2 ή 3 συνεχόμενα ζεύγη byte (hi και lo bytes) και να μετατρέψει τις τιμές σε μία τιμή 16 bit. Έτσι, μπορούμε να διαβάσουμε οποιονδήποτε άξονα, ή μπορούμε να διαβάσουμε δύο από αυτούς μαζί (και αθροίζει τις αλλαγές), ή μπορούμε να διαβάσουμε και τους τρεις (και αθροίζει τις αλλαγές).
Για να επαναλάβω, για αυτή τη φάση, για αυτό το Instructable, απλώς κοιτάζω να απαντήσω σε μια απλή ερώτηση: "το ρομπότ περιστράφηκε/περιστρέφεται;". Δεν ψάχνω για ακριβή τιμή, όπως, περιστρέφεται κατά 90 μοίρες. Αυτό θα έρθει αργότερα όταν φτάσουμε να κάνουμε SLAM, αλλά δεν απαιτείται για απλή αποφυγή εμποδίων και τυχαία κίνηση.
Βήμα 9: (εργασία σε εξέλιξη) το Μαγνητόμετρο
όταν χρησιμοποιείτε το εργαλείο i2cdetect, το MPU9265 εμφανίζεται ως 0x68 στον πίνακα:
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: -- -- -- -- -- -- -- --
Απαιτούνται επιπλέον βήματα για την ανάγνωση από το τμήμα μαγνητόμετρου της IMU.
Από το αρχείο Invesense PDF PDF:
ΕΓΓΡΑΦΕΣ 37 ΕΩΣ 39 - ΕΛΕΓΧΟΣ I2C SLAVE 0
- ΕΓΓΡΑΦΗ 37 - I2C_SLV0_ADDR
- ΕΓΓΡΑΦΗ 38 - I2C_SLV0_REG
- ΕΓΓΡΑΦΗ 39 - I2C_SLV0_CTRL