Er zijn maar weinig modules op de markt die de afgelopen maanden zo'n hype hebben veroorzaakt als de MPU-6050 module. Het twee-in-één bord combineert twee populaire sensoreigenschappen: De module kan tegelijkertijd gebruikt worden als gyroscoop en als versnellingssensor.
Hoe dan? De sensor bestaat uit een 3-assige gyroscoop en een 3-assige versnellingsmeter op één en dezelfde chip. Dit betekent dat alle (!) sensorwaarden tegelijkertijd kan oproepen. Dit betekent dat hobbyisten altijd goed op de hoogte zijn van de huidige sensorpositie. Deze functie is vooral interessant voor modelbouw, met name voor het uitbalanceren van chassis of drones.
Daarnaast zijn externe magnetometers of andere sensoren toegankelijk via een extra master I2C bus, zodat ook deze sensorgegevens volledig kunnen worden vastgelegd.
De sensorgegevens van de MPU-6050 (GY-521) in één oogopslag:
- Chipset: MPU-6050 (ook bekend als GY-521)
- Voeding: 3,3 - 5V DC
- Vrijheidslijn: 6*
- Interface: I2C
- Pinafstand: 2,54 mm
Nu komen we bij het spannende gedeelte: de praktijk. Om je een goed overzicht te geven van de nuttige functies van de MPU-6050 module, hebben we een voorbeeldschakelschema voor je ontwikkeld. De MPU-6050 module wordt uitgelezen door een Funduino UNO R3 en de geregistreerde gegevens worden geëvalueerd.
We zijn voornamelijk geïnteresseerd in de sensorgegevens van de gyroscoop. We willen de waarden van de X-, Y- en Z-as uitlezen en bepalen of er een verandering is opgetreden in de positie van de sensor. De verandering in positie moet ons worden getoond met gekleurde LED's.
Tot zover alles goed: maar hoe implementeren we dit?
De programmacode van de MPU-6050 module
Nu is het tijd voor het echte werk: nou ja, de helft ervan. Eerst moeten we de juiste bibliotheek voor de MPU6050 module downloaden en deze integreren in onze Arduino IDE. De bibliotheek heet "<MPU6050_tockn.h>" en kan direct worden gevonden en geïnstalleerd via het bibliotheekbeheer van de Arduino IDE.
Na deze eerste stap beginnen we met de eigenlijke code. Eerst definiëren we de LED-aansluitingen voor onze LED's, die ons moeten dienen als indicatoren voor de aspositie. Daarna definiëren we twee variabelen voor de aspositie van elk van de drie assen.
Je vraagt je waarschijnlijk af waarom we twee variabelen per as nodig hebben. Omdat we willen bepalen of de positie van de betreffende as is veranderd, moeten we eerst bepalen welke waarde de sensor heeft geregistreerd voor de huidige positie. We slaan deze sensorwaarde van de MPU-6050 voor een korte periode op in de eerste variabele.
De waarde van de aspositie wordt even later opnieuw opgeslagen in de tweede variabele. We kunnen nu de twee geregistreerde meetwaarden met elkaar vergelijken. Als er een afwijking van de positie met een eerder gedefinieerd minimum is geregistreerd (+-3 in ons codevoorbeeld), kunnen we aannemen dat de sensor de positie heeft gewijzigd. In dat geval schakelen we de toegewezen LED in.
Extra leuk: de vastgelegde meetgegevens kunnen goed worden weergegeven in de seriële plotter van de Arduino IDE.
// Deze sketch vergelijkt de hoeken van de X/Y/Z assen met de vorige waarden.
// Als ze +/-3° verschillen, schakelt de sketch de LEDs om. (elk.1 voor POS of voor NEG)
// Let op: dit zijn niet de absolute waarden, maar RELATIEVE waarden vergeleken met de vorige meting
#include <MPU6050_tockn.h> // Include bibliotheken
#include <Wire.h> // <-
MPU6050 mpu6050(Wire, 0.1, 0.1); // Demping van de waarden. Hoe kleiner (richting "0"), hoe nerveuzer de // waarden
// hoe groter (richting "1"), hoe trager de waarden
const int ledXpos =2; //***
const int ledXneg =3; // *
const int ledYpos =4; // * Stel de LED-aansluitingen in
const int ledYneg =5; //*
const int ledZpos =6; //*
const int ledZneg =7; //***
int xNowPos; // variabele HUIDIGE X-Pos
int yNowPos; // variabele HUIDIGE Y-Pos
int zNowPos; // variabele HUIDIGE Z-Pos
int xPrePos; // variabele HUIDIGE X-Pos
int yPrePos; // Variabele HUIDIGE Y-Pos
int zPrePos; // Variabele VORIGE Z-Pos
int verschil = 3;
void setup() { // Beginn Setup-Funktion
Serial.begin(115200); // Öffne serielle Übertragung (115200Baud) !!! Am Monitor ebenfalls einstellen !!!
pinMode(ledXpos, OUTPUT); //***
pinMode(ledXneg, OUTPUT); // *
pinMode(ledYpos, OUTPUT); // * Festlegen dass LED-Anschlüsse Ausgänge sind
pinMode(ledYneg, OUTPUT); // *
pinMode(ledZpos, OUTPUT); // *
pinMode(ledZneg, OUTPUT); //***
Wire.begin(); // Beginn I2C Protokoll
mpu6050.begin(); // Start des Gyros
mpu6050.calcGyroOffsets(); // Gyro kalkuliert seine Offsets !!! Währenddessen ruhig liegen lassen !!!
// Benutze mpu6050.calcGyroOffsets(true), um es im seriellen Monitor zu verfolgen.
delay(1000); // Darauf warten wir...
}
void loop() { // begin van de lus
mpu6050.update(); // Nieuwe gegevensset in de gyro aanmaken
xNowPos=(mpu6050.getGyroAngleX()); // Vraag nieuwe dataset op van de gyro, schrijf naar X variabele
yNowPos=(mpu6050.getGyroAngleY()); // Verzoek nieuwe dataset van gyro, schrijf naar Yvariabele
zNowPos=(mpu6050.getGyroAngleZ()); // Verzoek nieuwe dataset van de gyro, schrijf naar Z variabele
if (xNowPos < xPrePos-(verschil)) // Vergelijk oude dataset met nieuwe. Verschil < -3 ?
{digitalWrite(ledXpos, LOW); digitalWrite(ledXneg, HIGH);} // Schakel dan de LEDs overeenkomstig
anders als (xNowPos > xVorPos+(verschil)) // Vergelijk oude dataset met nieuwe. Verschil < +3 ?
{digitalWrite(ledXpos, HIGH); digitalWrite(ledXneg, LOW);} // Schakel dan de LEDs overeenkomstig
anders // Of schakel alle X LED's uit...
{digitalWrite(ledXpos, LOW); digitalWrite(ledXneg, LOW);} // Schakel dan de LEDs dienovereenkomstig
if (yNowPos < yPrePos-(verschil)) // Vergelijk oude dataset met nieuwe. Verschil < -3 ?
{digitalWrite(ledYpos, LOW); digitalWrite(ledYneg, HIGH);} // Schakel dan de LEDs overeenkomstig
anders als (yNowPos > yVorPos+(verschil)) // Vergelijk oude dataset met nieuwe. Verschil < +3 ?
{digitalWrite(ledYpos, HIGH); digitalWrite(ledYneg, LOW);} // Schakel dan de LEDs overeenkomstig
anders // Of schakel alle Y-LED's uit...
{digitalWrite(ledYpos, LOW); digitalWrite(ledYneg, LOW);} // Schakel dan de LEDs dienovereenkomstig
if (zNowPos < zPrePos-(verschil)) // Vergelijk oude dataset met nieuwe. Verschil < -3 ?
{digitalWrite(ledZpos, LOW); digitalWrite(ledZneg, HIGH);} // Schakel dan de LEDs overeenkomstig
anders als (zNowPos > zPrePos+(verschil)) // Vergelijk oude dataset met nieuwe. Verschil < +3 ?
{digitalWrite(ledZpos, HIGH); digitalWrite(ledZneg, LOW);} // Schakel dan de LEDs overeenkomstig
anders // Of schakel alle Z-LED's uit...
{digitalWrite(ledZpos, LOW); digitalWrite(ledZneg, LOW);} // Schakel dan de LEDs dienovereenkomstig
xVorPos=xJetztPos; // Werk de (tot nu toe) oude dataset bij
yVorPos=yJetztPos; // Werk de (tot nu toe) oude dataset bij
zVorPos=zJetztPos; // Werk de (tot nu toe) oude gegevensreeks bij
// Dan kan het in de volgende run weer vergeleken worden met "ervoor"
Serial.print(xNowPos); // >> seriële plotter<< eerlijke spelling [output X]
Serial.print(" ");Serial.print(yJetztPos); // (" ") = (\t) = Nieuwe kleur[output Y]
Serial.print("");Serial.println(zNowPos); // (" ") = (\t) = Nieuwe kleur [output Z]
delay(15); // (minimale vertraging kalmeert de seriële uitvoer)
// einde van de lus
// Voel je vrij om een beetje te experimenteren met de demping in de derde regel van het programma
//-> MPU6050 mpu6050(Draad, 0,3, 0,3);
// of met de delay() aan het einde. Observeer dan de waarden in de >>seriële PLOTTER <<