Εισαγωγή
Κίνηση είναι η συνεχής μεταβολή της θέσης ενός αντικειμένου στο χώρο. Εδώ θα σας παρουσιάσω με απλά λόγια τον αισθητήρα 9 αξόνων, τον τον MPU 9250, που παρακολουθεί τη μεταβολή της θέσης του στο χώρο των τριών διαστάσεων.
Στη συνέχεια θα σας παρουσιάσω μία απλή κατασκευή με τον αισθητήρα MPU 9250 βασισμένη στην κατασκευή που έκανα με τους σερβοκινητήρες.
Ο αισθητήρας μεταβολής της θέσης μπορεί να χρησιμοποιηθεί σε αεροσκάφη (διάφορα drones και τετρακόπτερα) σε smartphones και στη ρομποτική, σε διάφορους χειρισμούς και σε συσκευές που σχετίζονται με τρισδιάστατο έλεγχο και την αναγνώριση κινήσεων.
Το MPU-9250 είναι ένα System in Package (SiP) που συνδυάζει δύο τσιπ: το γυροσκόπιο τριών αξόνων MPU-6500 που είναι και επιταχυνσιόμετρο τριών αξόνων, και το AK8963 που είναι μαγνητόμετρο τριών αξόνων. Έτσι το MPU 9250 εκτελεί τις λειτουργίες πολλών αισθητήρων ταυτόχρονα: είναι γυροσκόπιο, επιταχυνσιόμετρο και μαγνητόμετρο.
Ας σταθούμε λίγο περισσότερο σε καθένα από αυτά. Το γυροσκόπιο είναι ένας αισθητήρας που ανταποκρίνεται στις αλλαγές των γωνιών προσανατολισμού στο διάστημα. Στο τετραπτέριγο (drone), χρησιμοποιείται για τη σταθεροποίηση της θέσης της συσκευής στον αέρα και την προστασία από τον άνεμο.
Το επιταχυνσιόμετρο συγκρίνει την προβολή της επιτάχυνσης ενός αντικειμένου με την επιτάχυνση της βαρύτητας και είναι ικανό να μετρήσει τη γραμμική ταχύτητα του αντικειμένου και, μαζί με το γυροσκόπιο, τη θέση του στο χώρο.
Το μαγνητόμετρο είναι μια συσκευή για τη μέτρηση της έντασης του πλησιέστερου μαγνητικού πεδίου που δρα σε ένα αντικείμενο (το όνομα του αισθητήρα μιλά από μόνο του).
Σύμφωνα με ορισμένες πηγές, η μονάδα MPU 9250 είναι ο μικρότερος αισθητήρας εννέα αξόνων στον κόσμο. Αυτό υποδεικνύει την υψηλή απόδοση του τσιπ, το οποίο παρέχεται με τη χρήση της τεχνολογίας CMOS MEMS (μικροηλεκτρομηχανικά συστήματα ).
Η θήκη της μονάδας αποτελείται από δύο μικρότερους κρυστάλλους, ένας από τους οποίους είναι υπεύθυνος για το γυροσκόπιο και το επιταχυνσιόμετρο και ο άλλος για το μαγνητόμετρο. Τα δεδομένα από αυτούς τους κρυστάλλους επεξεργάζονται από τον ενσωματωμένο επεξεργαστή σήματος DMP (Data Management Platform) χρησιμοποιώντας αλγόριθμους Motion Fusion και μεταδίδονται μέσω των διεπαφών I2C ή SPI.
Εκτός από τις υψηλές επιδόσεις, η μονάδα είναι αρκετά δημοφιλής μεταξύ των ηλεκτρολόγων μηχανικών και εκείνων που αγαπούν τις συσκευές για τηλεχειρισμό, ενώ έχει επίσης χαμηλή κατανάλωση ενέργειας και κόστος. Η επόμενη εικόνα δείχνει ένα MPU 9250.

Αρχή λειτουργίας του επιταχυνσιόμετρου
Ένα επιταχυνσιόμετρο μετρά το ρυθμό μεταβολής της ταχύτητας ενός αντικειμένου σε σχέση με το χρόνο, γνωστό και σαν επιτάχυνση. Με ένα επιταχυνσιόμετρο, μπορείτε επίσης να καταλάβετε τη γωνία κλίσης του αισθητήρα σε σχέση με το έδαφος.
Ένα επιταχυνσιόμετρο έχει μικροσκοπικούς κρυστάλλους που υφίστανται πίεση όταν συμβαίνουν δονήσεις. Από αυτήν την πίεση, παράγεται μια τάση που δημιουργεί μια ένδειξη σε οποιαδήποτε επιτάχυνση. Η μονάδα μέτρησης για την επιτάχυνση είναι το μέτρο ανά δευτερόλεπτο στο τετράγωνο (m/s^2). Αλλά καθώς οι αισθητήρες του επιταχυνσιόμετρου εκφράζουν μετρήσεις σε “g”, ένα “g” είναι η τιμή της βαρύτητας της γης που είναι ίση με 9,8 μέτρα ανά δευτερόλεπτο στο τετράγωνο. Το επόμενο σχήμα δίνει την εικόνα ενός επιταχυνσιόμετρου.

Για παράδειγμα, σε ένα επιταχυνσιόμετρο 3 αξόνων όπως ο αισθητήρας επιταχυνσιόμετρου MPU9250, όταν τοποθετείται σε οριζόντιο επίπεδο με τον άξονα Ζ προς τα πάνω, η έξοδος του άξονα Ζ του αισθητήρα ισούται με 1 g ή 9,8m/s2 ενώ X και Y = 0. Αυτό συμβαίνει λόγω της δύναμης της βαρύτητας που είναι κάθετη στους άξονες Χ και Υ και έτσι δεν τους επηρεάζει. Από αυτά τα δεδομένα, με απλά μαθηματικά τριγωνομετρίας, μπορεί κανείς να υπολογίσει τη γωνία του αισθητήρα και κατ’ επέκταση της κατασκευής επάνω στην οποία ο αισθητήρας είναι προσδεμένος.
Αρχή λειτουργίας γυροσκοπίου
Το γυροσκόπιο μετρά την ταχύτητα περιστροφής ή το ρυθμό αλλαγής της γωνιακής θέσης με την πάροδο του χρόνου. Η λειτουργία του βασίζεται στο φαινομένο Coriolis.
Όταν μια μάζα κινείται σε μια συγκεκριμένη κατεύθυνση με μια συγκεκριμένη ταχύτητα και εφαρμοστεί ένας εξωτερικός ρυθμός γωνιακής περιστροφής, τότε θα προκύψει μια δύναμη την οποία ο αισθητήρας θα ανιχνεύσει.
Οι έξοδοι του γυροσκοπίου είναι σε μοίρες ανά δευτερόλεπτο
Εάν γνωρίζουμε την αρχική γωνία του IMU, μπορούμε να προσθέσουμε την τιμή που μας δίνει το γυροσκόπιο για να γνωρίσουμε τη νέα γωνία κάθε στιγμή. Ας υποθέσουμε ότι ξεκινάμε το IMU από 0 °. Εάν το όργανο μας δίνει μια μέτρηση κάθε δευτερόλεπτο και σημειώνει 3 στον άξονα Χ, θα έχουμε τη γωνία με αυτόν τον απλό τύπο:
AngleX=PreviousAngleX + GyroDataX * elapsedTime
AngleY=PreviousAngleY + GyroDataY * elapsedTime
Όπου elapsedTime είναι ο χρόνος που μεσολαβεί κάθε φορά που υπολογίζεται αυτός ο τύπος εντός του βρόχου, PreviousAngle είναι η γωνία που υπολογίστηκε την τελευταία φορά που κλήθηκε αυτός ο τύπος και GyroData είναι η ανάγνωση της γωνίας Y ή X του γυροσκοπίου.
Το μαγνητόμετρο
Το τσιπ MPU-9250 περιλαμβάνει το AK8963 που είναι το μαγνητόμετρο. Αυτό μπορεί να γνωρίζει τον προσανατολισμό σε σχέση με τον μαγνητικό βορρά, παρόμοια με το πώς λειτουργεί μια πυξίδα χειρός. Οι ενσωματωμένοι ADC 16-bit δειγματίζουν ταυτόχρονα τους 3 άξονες κίνησης (X, Y, Z).
Η βαθμονόμηση του μαγνητόμετρου μπορεί να γίνει αυτόματα με χρήση της συνάρτησης magcalMPU9250 (float * dest1, float * dest2) και βαθμονομεί το μαγνητόμετρο ενώ μετακινείτε τον αισθητήρα σε σχήμα οκτώ. Αποθηκεύει τις μέγιστες και ελάχιστες ενδείξεις και παίρνει το μέσο όρο.
Κατασκευή
Η κατασκευή είναι συνέχεια της προηγούμενης κατασκευής που έκανα με τους δύο σερβοκινητήρες. Σε αυτή θα προσθέσουμε τον αισθητήρα MPU-9250. Το σημαντικότερο για την κατασκευή είναι το λογισμικό που θα γράψουμε έτσι ώστε η κίνηση στους σερβοκινητήρες να ελέγχεται πλέον από τον αισθητήρα και όχι από τα ποτενσιόμετρα.
Το επόμενο σχήμα μας δείχνει το κύκλωμα σύνδεσης του αισθητήρα με το Arduino UNO.

Η σύνδεση γίνεται με το I2C (Inter-Integrated Circuit) bus, πρωτόκολλο επικοινωνίας με δύο αγωγούς που διαθέτει ο αισθητήρας.
Για χάρη απλότητας θα χρησιμοποιήσω τρεις από τους εννέα άξονες που διαθέτει ο αισθητήρας. Θα χρησιμοποιήσω μόνο το επιταχυνσιόμετρο για τους άξονες x, y και z. Η κίνηση θα γίνεται σε δύο επίπεδα κάθετα μεταξύ τους και θα εξασφαλίζεται από τους δύο σερβοκινητήρες. Όπως βλέπετε επάνω στην πλακέτα του αισθητήρα ο κατασκευαστής έχει σημειώσει τους άξονες. Οι άξονες είναι παράλληλοι προς τα επίπεδα κίνησης, ο καθένας με ένα επίπεδο κίνησης.
Ο στόχος της κατασκευής είναι να παραμένει σε οριζόντιο επίπεδο ο αισθητήρας όπως και να στρέφω εγώ το επίπεδο στήριξης της κατασκευής.
Ο αισθητήρας βρίσκεται τοποθετημένος σε μία βάση που στην κατάσταση ηρεμίας είναι οριζόντια. Την τοποθετούμε έτσι ώστε να είναι παράλληλη με τη βάση στήριξης. Στη συνέχεια ενόσω εγώ θα περιστρέφω τη βάση στήριξης θα παρατηρώ πώς οι σερβοκινητήρες φέρνουν σε οριζόντια θέση τον αισθητήρα.
Από το καλάθι με τα παιχνίδια των εγγονιών μου πήρα ένα στρουμφάκι, τον Σπιρτούλη, και το έβαλα στην πλατφόρμα με τον αισθητήρα. Η όρθια στάση του Σπιρτούλη επισημαίνει άμεσα ότι ο αισθητήρας είναι οριζόντιος.
Στη φωτογραφία που ακολουθεί φαίνεται η κατασκευή και στο βίντεο που σας δίνω στο τέλος του άρθρου φαίνεται η λειτουργία της κατασκευής.

Προγραμματισμός
Η συμβουλή μου είναι οι βιβλιοθήκες που χρησιμοποιείτε για το Arduino IDE να βρίσκονται στο φάκελο του project που δουλεύετε. Η βιβλιοθήκη που χρησιμοποίησα για τον MPU9250 είναι η Bolder_Flight_Systems_MPU9250 που αν δεν την έχετε εγκατεστημένη είναι εύκολο να κατεβάσετε από το internet.
Στη συνέχεια παραθέτω τον κώδικα που έγραψα τον οποίο μπορείτε να κατεβάσετε από το εδώ
//Author : Manolis Aristovoulidis
//Το πρόγραμμα αυτό χρησιμοποιεί ένα MPU-9250 και δύο σερβοκινητήρες
//με τη λειτουργία του προγράμματος οισερβοκινητήρες κρατουν πάντα σε
//οριζόντια θέση τον αισθητήρα
#include <Wire.h>
#include <MPU9250.h>
#include <Servo.h>
Servo servo_x; // δημιουργία ενός servo object για τον έλεγχο του servo
Servo servo_y;
int val_x = 95; // μεταβλητή για την γωνια κίνησης του servo_x
int val_y = 100; // μεταβλητή για την γωνια κίνησης του servo_y
// an MPU9250 object with the MPU-9250 sensor on I2C bus 0 with address 0x68
MPU9250 IMU(Wire,0x68);
int status;
//Acc Variables
float rad_to_deg = 180/3.141592654; //This value is for pasing from radians to degrees values
float Acc_rawX, Acc_rawY, Acc_rawZ; //Here we store the raw data read
float Acc_angle_x, Acc_angle_y; //Here we store the angle value obtained with Acc data
float Total_angle_x, Total_angle_y; //Here we store the final total angle
int x_tilt = 0;
int y_tilt = 0;
int i;
void setup() {
// serial to display data
Serial.begin(115200);
while(!Serial) {}
servo_x.attach(4); //κάνει προσάρτηση του servo στο pin 4 του servo object
servo_y.attach(5); //κάνει προσάρτηση του servo στο pin 5 του servo object
//περιστοφή των σερβοκινητήρων
servo_x.write(val_x); //Μετά από πειραματισμούς αυτή είναι η
servo_y.write(val_y); //οριζόντια θέση για τη βάση του MPU9250
delay(1000);
// start communication with IMU
status = IMU.begin();
if (status < 0) {
Serial.println("IMU initialization unsuccessful");
Serial.println("Check IMU wiring or try cycling power");
Serial.print("Status: ");
Serial.println(status);
while(1) {}
}
/* Default values of MPU9250
* accel range to 16G as default
* gyro range to 2000DPS as default
* bandwidth to 184Hz as default
* sample rate divider to 0 as default
*
*/
// αναμονή για το calibration που προκαλει η IMU.begin()
delay(3000);
}
void loop() {
IMU.readSensor();
Acc_rawX = IMU.getAccelX_mss();
Acc_rawY = IMU.getAccelY_mss();
Acc_rawZ = IMU.getAccelZ_mss();
/*---Y---*/
Acc_angle_x = (atan((Acc_rawY)/sqrt(pow((Acc_rawX),2) + pow((Acc_rawZ),2)))*rad_to_deg) ;
/*---Y---*/
Acc_angle_y = (atan(-1*(Acc_rawX)/sqrt(pow((Acc_rawY),2) + pow((Acc_rawZ),2)))*rad_to_deg) ;
////////////////////////////////////// Γωνία κλίσης και φίλτρο /////////////////////////////////////
Total_angle_x = 0.94 *Total_angle_x + 0.06*Acc_angle_x;
Total_angle_y = 0.94 *Total_angle_y + 0.06*Acc_angle_y;
x_tilt = (int)Total_angle_x ;
y_tilt = (int)Total_angle_y ;
//********************* Υπολογισμός κίνηση επαναφοράς στον άξονα των Χ **************************************
if(x_tilt > 1){
val_x--;
}
if(x_tilt < -1){
val_x++;
}
if(val_x > 180){val_x = 180;}
if(val_x < 0){val_x = 0;}
//********************* Υπολογισμός κίνηση επαναφοράς στον άξονα των Υ ****************************************
if(y_tilt > 1){
val_y++;
}
if(y_tilt < -1){
val_y--;
}
if(val_y > 180){val_y = 180;}
if(val_y < 0){val_y = 0;}
//******************* Κίνηση των σερβοκινητήρων σε γωνία μεταξύ 0-180 μοιρών ******************************************
servo_x.write(val_x); // ρυθμίζει τη θέση του servo στην τιμή της κλίμακας
servo_y.write(val_y); // ρυθμίζει τη θέση του servo στην τιμή της κλίμακας
delay(50);
}
Με τη χρήση δύο σερβοκινητήρων διατηρείται σε οριζόντια θέση πάντα η πλατφόρμα που στηρίζει τον αισθητήρα κίνησης MPU9250. Όπως και να περιστρέψω εγώ τη βάση στην οποία στηρίζεται ολόκληρος ο μηχανισμός η πλατφόρμα επανέρχεται σε οριζόντια θέση.
Στην εικόνα που ακολουθεί βλέπετε τις τιμές που δίνει το επιταχυνσιόμετρο του αισθητήρα κατά την κίνηση, ενόσω προσπαθεί να ισορροπήσει στην τιμή μηδέν για τον άξονα x. Η κόκκινη γραμμή παρουσιάζει τις τιμές του αισθητήρα και η πράσινη παρουσιάζει τις τιμές που δίνει το φίλτρο εξομάλυνσης στη γραμμή 166 του προγράμματος και οι οποίες τιμές κινούν το σερβοκινητήρα x.

Η κατασκευή σε λειτουργία φαίνεται εδώ.