Sommario:
- Passaggio 1: modulo MPU-6050
- Passaggio 2: calcoli
- Passaggio 3: connessioni MPU6050-Atmega328p
- Passaggio 4: codici e spiegazioni
- Passaggio 5: comprensione dell'angolo di inclinazione
Video: MPU 6050 Gyro, comunicazione accelerometro con Arduino (Atmega328p): 5 passaggi
2024 Autore: John Day | [email protected]. Ultima modifica: 2024-01-30 10:00
L'IMU MPU6050 ha sia l'accelerometro a 3 assi che il giroscopio a 3 assi integrati su un singolo chip.
Il giroscopio misura la velocità di rotazione o la velocità di variazione della posizione angolare nel tempo, lungo gli assi X, Y e Z.
Le uscite del giroscopio sono in gradi al secondo, quindi per ottenere la posizione angolare è sufficiente integrare la velocità angolare.
D'altra parte, l'accelerometro MPU6050 misura l'accelerazione misurando l'accelerazione gravitazionale lungo i 3 assi e usando alcuni calcoli trigonometrici possiamo calcolare l'angolo al quale è posizionato il sensore. Quindi, se fondiamo o combiniamo i dati dell'accelerometro e del giroscopio, possiamo ottenere informazioni molto accurate sull'orientamento del sensore.
Giroscopio a 3 assi L'MPU-6050 è costituito da un giroscopio a 3 assi in grado di rilevare la velocità di rotazione lungo l'asse x, y, z con tecnologia di sistema micro elettromeccanico (MEMS). Quando il sensore viene ruotato lungo qualsiasi asse viene prodotta una vibrazione dovuta all'effetto Coriolis che viene rilevato dal MEMS. L'ADC a 16 bit viene utilizzato per digitalizzare la tensione per campionare ciascun asse. +/- 250, +/- 500, +/- 1000, +/- 2000 sono la gamma completa di output. La velocità angolare viene misurata lungo ciascun asse in gradi al secondo.
Link Utili:…………….
Scheda Arduino:.……….
MPU6050 IMU ……………https://compoindia.com/product/mpu6050-3-axis-accelerometro-e-sensore-giroscopio/
Passaggio 1: modulo MPU-6050
Il modulo MPU-6050 ha 8 pin,
INT: Interrompere il pin dell'uscita digitale.
AD0: pin LSB dell'indirizzo slave I2C. Questo è il bit 0 nell'indirizzo slave a 7 bit del dispositivo. Se connesso a VCC allora viene letto come uno logico e cambia l'indirizzo dello slave.
XCL: pin orologio seriale ausiliario. Questo pin viene utilizzato per collegare altri sensori abilitati all'interfaccia I2C pin SCL a MPU-6050.
XDA: pin dati seriali ausiliari. Questo pin viene utilizzato per collegare altri sensori abilitati all'interfaccia I2C pin SDA a MPU-6050.
SCL: Pin orologio seriale. Collegare questo pin al pin SCL del microcontrollore. SDA: pin dati seriali. Collegare questo pin al pin SDA del microcontrollore.
GND: pin di terra. Collegare questo pin alla connessione a terra.
VCC: pin di alimentazione. Collegare questo pin all'alimentazione +5V DC. Il modulo MPU-6050 ha indirizzo Slave (Quando AD0 = 0, cioè non è connesso a Vcc) come, Indirizzo di scrittura slave (SLA+W): 0xD0
Indirizzo di lettura slave (SLA+R): 0xD1
Passaggio 2: calcoli
I dati del sensore giroscopio e accelerometro del modulo MPU6050 sono costituiti da dati grezzi a 16 bit in forma di complemento di 2.
I dati del sensore di temperatura del modulo MPU6050 sono costituiti da dati a 16 bit (non in complemento di 2).
Supponiamo ora di aver selezionato,
- - Campo di fondo scala dell'accelerometro di +/- 2 g con fattore di scala di sensibilità di 16, 384 LSB (conteggio)/g.
- - Giroscopio a fondo scala di +/- 250 °/s con fattore di scala di sensibilità di 131 LSB (Count)/°/s. poi,
Per ottenere i dati grezzi del sensore, dobbiamo prima eseguire il complemento a 2 sui dati del sensore dell'accelerometro e del giroscopio. Dopo aver ottenuto i dati grezzi del sensore, possiamo calcolare l'accelerazione e la velocità angolare dividendo i dati grezzi del sensore con il loro fattore di scala di sensibilità come segue:
Valori dell'accelerometro in g (forza g)
- Accelerazione lungo l'asse X = (dati grezzi dell'asse X dell'accelerometro/16384) g.
- Accelerazione lungo l'asse Y = (dati grezzi dell'asse Y dell'accelerometro/16384) g.
- Accelerazione lungo l'asse Z = (dati grezzi dell'asse Z dell'accelerometro/16384) g.
Valori del giroscopio in °/s (gradi al secondo)
- Velocità angolare lungo l'asse X = (Dati grezzi dell'asse X del giroscopio/131) °/s.
- Velocità angolare lungo l'asse Y = (Dati grezzi dell'asse Y del giroscopio/131) °/s.
- Velocità angolare lungo l'asse Z = (Dati grezzi dell'asse Z del giroscopio/131) °/s.
Valore della temperatura in °/c (gradi per Celsius)
Temperatura in gradi C = ((dati sensore di temperatura)/340 + 36,53) °/c.
Per esempio, Supponiamo che, dopo il complemento di 2', otteniamo il valore grezzo dell'asse X dell'accelerometro = +15454
Quindi Ax = +15454/16384 = 0,94 g.
Di più,
Quindi sappiamo che stiamo correndo a una sensibilità di +/-2G e +/- 250deg/s ma come fanno i nostri valori a corrispondere a quelle accelerazioni/angoli.
Questi sono entrambi grafici a linee rette e possiamo ricavare da essi che per 1G leggeremo 16384 e per 1degree/sec leggeremo 131.07 (Anche se.07 verrà ignorato a causa del binario) questi valori sono stati appena calcolati disegnando il grafico a retta con 2G a 32767 e -2G a -32768 e 250/-250 agli stessi valori.
Quindi ora conosciamo i nostri valori di sensibilità (16384 e 131.07), dobbiamo solo ridurre gli offset dai nostri valori e quindi dividere per la sensibilità.
Questi funzioneranno bene per i valori X e Y, ma poiché la Z è stata registrata a 1G e non a 0, dovremo ridurre 1G (16384) prima di dividere per la nostra sensibilità.
Passaggio 3: connessioni MPU6050-Atmega328p
Basta collegare tutto come indicato nel diagramma…
I collegamenti sono forniti come segue:-
MPU6050 Arduino Nano
Pin uscita VCC 5v
GND Pin di terra
Pin SDA A4 //dati seriali
Pin SCL A5 // orologio seriale
Calcolo del passo e del rollio: il rollio è la rotazione attorno all'asse x e il pitch è la rotazione lungo l'asse y.
Il risultato è in radianti. (converti in gradi moltiplicando per 180 e dividendo per pi greco)
Passaggio 4: codici e spiegazioni
/*
Tutorial Arduino e MPU6050 Accelerometro e sensore giroscopio di Dejan, https://howtomechatronics.com */ #include const int MPU = 0x68; // MPU6050 Indirizzo I2C float AccX, AccY, AccZ; galleggiante GyroX, GyroY, GyroZ; float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ; rollio galleggiante, beccheggio, imbardata; float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, GyroErrorZ; float tempo trascorso, ora corrente, ora precedente; intero c = 0; void setup() { Serial.begin(19200); Wire.begin(); // Inizializza la comunicazione Wire.beginTransmission(MPU); // Avvia la comunicazione con MPU6050 // MPU=0x68 Wire.write(0x6B); // Parla al registro 6B Wire.write(0x00); // Reimposta - metti uno 0 nel registro 6B Wire.endTransmission(true); //termina la trasmissione /* // Configura la sensibilità dell'accelerometro - Intervallo di fondo scala (predefinito +/- 2g) Wire.beginTransmission(MPU); Wire.write(0x1C); //Parla con il registro ACCEL_CONFIG (1C hex) Wire.write(0x10); //Imposta i bit di registro come 00010000 (+/- 8g intervallo di fondo scala) Wire.endTransmission(true); // Configura la sensibilità del giroscopio - Gamma completa (predefinito +/- 250deg/s) Wire.beginTransmission(MPU); Wire.write(0x1B); // Parla con il registro GYRO_CONFIG (1B esadecimale) Wire.write(0x10); // Imposta i bit di registro come 00010000 (1000deg/s fondo scala) Wire.endTransmission(true); ritardo(20); */ // Chiama questa funzione se hai bisogno di ottenere i valori di errore IMU per il tuo modulo calcola_IMU_error(); ritardo(20); } void loop() { // === Legge i dati dell'accelerometro === // Wire.beginTransmission(MPU); Wire.write(0x3B); // Inizia con il registro 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(MPU, 6, vero); // Leggi 6 registri in totale, ogni valore dell'asse è memorizzato in 2 registri // Per un intervallo di +-2 g, dobbiamo dividere i valori grezzi per 16384, secondo il foglio dati AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; // Valore dell'asse X AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // Valore dell'asse Y AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // Valore dell'asse Z // Calcolo di rollio e beccheggio dai dati dell'accelerometro accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI) - 0,58; // AccErrorX ~(0.58) Per maggiori dettagli, vedere la funzione translate_IMU_error()custom accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI) + 1.58; // AccErrorY ~(-1.58) // === Legge i dati del giroscopio === // previousTime = currentTime; // L'ora precedente viene memorizzata prima dell'ora effettiva letta currentTime = millis(); // Ora attuale ora effettiva letta elapsedTime = (currentTime - previousTime) / 1000; // Dividi per 1000 per ottenere secondi Wire.beginTransmission(MPU); Wire.write(0x43); // Indirizzo del primo registro dei dati del giroscopio 0x43 Wire.endTransmission(false); Wire.requestFrom(MPU, 6, vero); // Legge 4 registri in totale, ogni valore dell'asse è memorizzato in 2 registri GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // Per un intervallo di 250deg/s dobbiamo prima dividere il valore grezzo per 131.0, secondo il datasheet GyroY = (Wire.read() << 8 | Wire.read()) / 131.0; GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0; // Correggere le uscite con i valori di errore calcolati GyroX = GyroX + 0,56; // GyroErrorX ~(-0.56) GyroY = GyroY - 2; // GyroErrorY ~(2) GyroZ = GyroZ + 0.79; // GyroErrorZ ~ (-0.8) // Attualmente i valori grezzi sono in gradi al secondo, deg/s, quindi dobbiamo moltiplicare per sendnd (s) per ottenere l'angolo in gradi gyroAngleX = gyroAngleX + GyroX * elapsedTime; // gradi/s * s = gradi gyroAngleY = gyroAngleY + GyroY * tempo trascorso; imbardata = imbardata + GyroZ * tempo trascorso; // Filtro complementare - combina i valori dell'accelerometro e dell'angolo del giroscopio roll = 0,96 * gyroAngleX + 0,04 * accAngleX; passo = 0,96 * gyroAngleY + 0,04 * accAngleY; // Stampa i valori sul monitor seriale Serial.print(roll); Serial.print("/"); Serial.print(passo); Serial.print("/"); Serial.println(yaw); } void calcola_IMU_error() { // Possiamo chiamare questa funzione nella sezione di configurazione per calcolare l'errore dei dati dell'accelerometro e del giroscopio. Da qui otterremo i valori di errore utilizzati nelle equazioni di cui sopra stampati sul monitor seriale. // Nota che dovremmo posizionare l'IMU in modo piatto per ottenere i valori corretti, in modo da poter poi ottenere i valori corretti // Leggi i valori dell'accelerometro 200 volte while (c < 200) { Wire.beginTransmission(MPU); Wire.write(0x3B); Wire.endTransmission(false); Wire.requestFrom(MPU, 6, vero); AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // Somma tutte le letture AccErrorX = AccErrorX + ((atan((AccY) / sqrt(pow((AccX), 2) + pow((AccZ), 2))) * 180 / PI)); AccErrorY = AccErrorY + ((atan(-1 * (AccX) / sqrt(pow((AccY), 2) + pow((AccZ), 2))) * 180 / PI)); c++; } //Dividi la somma per 200 per ottenere il valore di errore AccErrorX = AccErrorX / 200; ACCErrorY = ACCErrorY / 200; c = 0; // Legge i valori del giroscopio 200 volte while (c < 200) { Wire.beginTransmission(MPU); Wire.write(0x43); Wire.endTransmission(false); Wire.requestFrom(MPU, 6, vero); GyroX = Wire.read() << 8 | Wire.read(); GyroY = Wire.read() << 8 | Wire.read(); GyroZ = Wire.read() << 8 | Wire.read(); // Somma tutte le letture GyroErrorX = GyroErrorX + (GyroX / 131.0); GyroErrorY = GyroErrorY + (GyroY / 131.0); GyroErrorZ = GyroErrorZ + (GyroZ / 131.0); c++; } //Dividi la somma per 200 per ottenere il valore di errore GyroErrorX = GyroErrorX / 200; GyroErrorY = GyroErrorY / 200; GyroErrorZ = GyroErrorZ / 200; // Stampa i valori di errore sul monitor seriale Serial.print("AccErrorX: "); Serial.println(AccErrorX); Serial.print("AccErrorY: "); Serial.println(AccErrorY); Serial.print("GyroErrorX: "); Serial.println(GyroErrorX); Serial.print("GyroErrorY: "); Serial.println(GyroErrorY); Serial.print("GyroErrorZ: "); Serial.println(GyroErrorZ); } -------------------------------------------------- ------------------------------- Risultati:- X = Y = Z = ------------------------------- ----------------------------------------------- Nota importante: - ----------------
Nella sezione loop iniziamo leggendo i dati dell'accelerometro. I dati per ogni asse sono memorizzati in 2 byte o registri e possiamo vedere gli indirizzi di questi registri dal datasheet del sensore.
Per leggerli tutti, partiamo dal primo registro, e usando la funzione requiestFrom() richiediamo di leggere tutti e 6 i registri per gli assi X, Y e Z. Quindi leggiamo i dati da ciascun registro e, poiché le uscite sono complementari a due, le combiniamo in modo appropriato per ottenere i valori corretti.
Passaggio 5: comprensione dell'angolo di inclinazione
Accelerometro
La gravità terrestre è un'accelerazione costante in cui la forza punta sempre verso il centro della Terra.
Quando l'accelerometro è parallelo alla gravità, l'accelerazione misurata sarà 1G, quando l'accelerometro è perpendicolare alla gravità, misurerà 0G.
L'angolo di inclinazione può essere calcolato dall'accelerazione misurata utilizzando questa equazione:
θ = sin-1 (accelerazione misurata / accelerazione di gravità)
Il giroscopio (a.k.a. sensore di velocità) viene utilizzato per misurare la velocità angolare (ω).
Per ottenere l'angolo di inclinazione di un robot, dobbiamo integrare i dati dal giroscopio come mostrato nell'equazione seguente:
= dθ / dt, θ = ∫ ω dt
Fusione del sensore giroscopio e accelerometroDopo aver studiato le caratteristiche sia del giroscopio che dell'accelerometro, sappiamo che hanno i loro punti di forza e di debolezza. L'angolo di inclinazione calcolato dai dati dell'accelerometro ha un tempo di risposta lento, mentre l'angolo di inclinazione integrato dai dati del giroscopio è soggetto a deriva per un periodo di tempo. In altre parole, possiamo dire che i dati dell'accelerometro sono utili a lungo termine mentre i dati del giroscopio sono utili a breve termine.
Link per una migliore comprensione: clicca qui
Consigliato:
Comunicazione wireless a lungo raggio, 1,8 km, da Arduino ad Arduino con l'HC-12: 6 passaggi (con immagini)
Comunicazione wireless a lungo raggio, 1,8 km, da Arduino ad Arduino con l'HC-12: in questo tutorial imparerai come comunicare tra Arduino su una lunga distanza fino a 1,8 km all'aperto. L'HC-12 è una porta seriale wireless modulo di comunicazione molto utile, estremamente potente e facile da usare. Per prima cosa partirai
Tappeto con sensori/Comunicazione RF con Arduino Micro: 4 passaggi (con immagini)
Tappeto Con Sensori/Comunicazione RF Con Arduino Micro: Ho recentemente terminato l'installazione Ugualmente diversa, che è composta da una serie di lampade che reagiscono ai sensori posti in un tappeto sotto le lampade. Ecco come ho realizzato il tappeto con i sensori di pressione. Spero che lo troverai utile
Come misurare l'angolo con MPU-6050 (GY-521): 3 passaggi
Come misurare l'angolo con MPU-6050 (GY-521): In questo Instructable, misureremo l'angolo con un Arduino. Abbiamo bisogno di alcuni cavi, un Arduino UNO e GY-521 (MPU-6050) per misurare l'angolo
Registrazione dati MPU-6050/A0 in tempo reale con Arduino e Android: 7 passaggi (con immagini)
Registrazione dati MPU-6050/A0 in tempo reale con Arduino e Android: ero interessato a utilizzare Arduino per l'apprendimento automatico. Come primo passo, voglio creare un visualizzatore di dati e un logger in tempo reale (o abbastanza vicino) con un dispositivo Android. Voglio acquisire i dati dell'accelerometro dall'MPU-6050, quindi progetto
Preliminare* SPI sul Pi: comunicazione con un accelerometro a 3 assi SPI utilizzando un Raspberry Pi: 10 passaggi
Preliminare* SPI sul Pi: comunicazione con un accelerometro a 3 assi SPI utilizzando un Raspberry Pi: guida passo passo su come configurare Raspbian e comunicare con un dispositivo SPI utilizzando la libreria SPI bcm2835 (NON bit banged!) Questo è ancora molto preliminare… ho bisogno di aggiungere immagini migliori del collegamento fisico e lavorare su un po' del codice scomodo