Inhaltsverzeichnis:

Gyroskop-Spaß mit Neopixel-Ring - Gunook
Gyroskop-Spaß mit Neopixel-Ring - Gunook

Video: Gyroskop-Spaß mit Neopixel-Ring - Gunook

Video: Gyroskop-Spaß mit Neopixel-Ring - Gunook
Video: Gyroscope fun with Neopixel ring 2024, November
Anonim
Image
Image

In diesem Tutorial werden wir das Gyroskop MPU6050, einen Neopixel-Ring und ein Arduino verwenden, um ein Gerät zu bauen, das LEDs entsprechend dem Neigungswinkel beleuchtet.

Dies ist ein einfaches und unterhaltsames Projekt, das auf einem Steckbrett zusammengebaut wird. Wenn Sie die Schritte befolgen, bauen Sie das, was Sie im Video gesehen haben. Es ist ein gutes Tutorial zum Erlernen des Gyroskops und des Neopixel-Rings.

Ich baue dieses Tutorial wegen des Interesses, das ich an meinem ersten instructable hier gesehen habe (Gyroscope Led Control With Arduino). In diesem anweisbaren habe ich einfache LEDs durch einen Neopixel-Ring ersetzt. Der Ring ist durch eine Adafruit-Bibliothek einfacher zu verwenden und definitiv spektakulärer.

Wenn Sie also diese Komponenten herumliegen haben, ist dies eine großartige Möglichkeit, sie zu verwenden. Ich werde versuchen, Sie Schritt für Schritt durch den Aufbau des Geräts zu führen und auch im letzten Schritt zu erklären, wie es funktioniert.

Schritt 1: Erforderliche Dinge

Montage
Montage

Teile

1. Arduino pro mini 328p (eBay) 2 $

2. Steckbrett

3. MPU6050 Gyroskop (eBay) 1.2$

4. 24 Neopixel-LED-Ring (Adafruit) 17 $

5. 4 x AA Batteriepack mit 4 Batterien

6. U-förmige Überbrückungskabel (optional). Ich habe diese Überbrückungskabel verwendet, weil sie auf dem Steckbrett besser aussehen und die LEDs auf diese Weise besser sichtbar sind. Sie können eine Box mit 140 bei ebay für etwa 4 $ finden. Wenn Sie diese Kabel nicht haben, können Sie sie durch Dupont-Kabel ersetzen.

Werkzeuge:

1. USB-zu-Seriell-FTDI-Adapter FT232RL zum Programmieren des Arduino Pro Mini

2. Arduino-IDE

Fähigkeiten: 1. Löten, überprüfen Sie dieses Tutorial

3. Grundlegende Arduino-Programmierung, dieses Tutorial könnte nützlich sein

Schritt 2: Montage

Montage
Montage

Ich habe den Fritzing-Schema im fzz-Format und ein Bild davon zur einfachen Visualisierung der Verbindungen angehängt

1. Sie müssen 3 männliche Stifte auf der Rückseite des Neopixel-Rings löten, wie im Bild gezeigt

- Pluspol anlöten

- Masse verlöten

- Dateneingangspin verlöten

2. Dann sollte der 4x Batteriehalter eine Verbindung zum Steckbrett haben, eine einfache Lösung besteht darin, zwei männliche Dupont-Drähte an seine Anschlüsse zu löten.

3. Bereiten Sie das Steckbrett vor.

- Platzieren Sie den Neopixel-Ring, den Mikrocontroller und das Gyroskop wie im Bild auf dem Steckbrett

- Platzieren Sie alle negativen Drähte: zum Mikrocontroller, Neopixel-Ring, Gyro

- Platzieren Sie alle positiven Drähte: zum Mikrocontroller, Neopixel-Ring, Gyro

- Platzieren Sie alle Datenleitungen:

* SDA und SCL vom zum Mikrocontroller zum Kreisel

* Pin D6 vom Mikrocontroller zum Neopixel-Ring

- Überprüfen Sie alle Verbindungen, bevor Sie das Gerät einschalten

- Optional mit Klebeband kleben Sie den Akku auf die Rückseite des Bradboards, um ihn an Ort und Stelle zu halten und ihn tragbarer zu machen

Schritt 3: Der Code und die Kalibrierung

Zuerst müssen Sie zwei Bibliotheken herunterladen und installieren:

1. Adafruit Neopixel-Bibliothek, die das Neopixel steuert

2. MPU6050-Bibliothek für das Gyroskop

3. I2CDev-Bibliotheksquelle

Sie sind zwei großartige Bibliotheken, die die schwere Arbeit erledigen werden!

Mehr Details zu den Neopixeln hier

Dann laden Sie meine Bibliothek von hier herunter und installieren Sie sie oder kopieren Sie sie von unten:

#include "I2Cdev.h"

#include #include "MPU6050_6Axis_MotionApps20.h" #include "Wire.h" #define NEOPIXED_CONTROL_PIN 6 #define NUM_LEDS 24 const int MAX_ANGLE = 45; const int LED_OFFSET = 12; MPU6050 mpu; Adafruit_NeoPixel-Streifen = Adafruit_NeoPixel(NUM_LEDS, NEOPIXED_CONTROL_PIN, NEO_RBG + NEO_KHZ800); unsigned long lastPrintTime = 0; bool Initialisierung = false; // auf true setzen, wenn DMP-Init erfolgreich war uint8_t mpuIntStatus; // hält das aktuelle Interrupt-Statusbyte von der MPU uint8_t devStatus; // Status nach jeder Geräteoperation zurückgeben (0 = Erfolg, !0 = Fehler) uint16_t packetSize; // erwartete DMP-Paketgröße (Standard ist 42 Byte) uint16_t fifoCount; // Anzahl aller Bytes, die sich derzeit im FIFO befinden uint8_t fifoBuffer[64]; // FIFO-Speicherpuffer Quaternion q; // [w, x, y, z] Quaternion-Container VectorFloat Gravitation; // [x, y, z] Schwerkraftvektor float ypr[3]; // [Gieren, Nicken, Rollen] Gieren/Neigen/Rollen Container und Gravitationsvektor volatile bool mpuInterrupt = false; // zeigt an, ob der MPU-Interrupt-Pin hoch gegangen ist

Void-Setup ()

{ Serial.begin (9600); Serial.println ("Programm gestartet"); Initialisierung = initializeGyroscope(); strip.begin(); } void loop() { if (!initialization) { return; } mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus(); fifoCount = mpu.getFIFOCount(); if (hasFifoOverflown(mpuIntStatus, fifoCount)) {mpu.resetFIFO(); Rückkehr; } if (mpuIntStatus & 0x02) { while (fifoCount < Paketgröße) { fifoCount = mpu.getFIFOCount (); } mpu.getFIFOBytes(fifoBuffer, Paketgröße); fifoCount -= Paketgröße; mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); redrawLeds(ypr[0] * 180/M_PI, ypr[1] * 180/M_PI, ypr[2] * 180/M_PI); }} boolean hasFifoOverflown(int mpuIntStatus, int fifoCount) { return mpuIntStatus & 0x10 || fifoCount == 1024; aufrechtzuerhalten. Void redrawLeds (int x, int y, int z) { x = beschränken (x, -1 * MAX_ANGLE, MAX_ANGLE); y = einschränken(y, -1 * MAX_ANGLE, MAX_ANGLE); wenn (y 0) { lightLeds (y, z, 0, 5, 0, 89); aufrechtzuerhalten. Sonst wenn (y < 0 und z 0 und z 0 und z > 0) {lightLeds (y, z, 20, 24, 89, 0); aufrechtzuerhalten. 71; int ledNr = map(angle, fromAngle, toAngle, fromLedPosition, toLedPosition); printDebug(x, y, ledNr, Winkel); uint32_t Farbe; for (int i=0; i-Position + LED_OFFSET) { Rückkehrposition + LED_OFFSET; } Rückkehrposition + LED_OFFSET - NUM_LEDS; aufrechtzuerhalten. Void printDebug (int y, int z, int lightLed, int angle) { if (millis () - lastPrintTime < 500) { return; } Serial.print ("a="); Serial.print (Winkel); Serial.print ("; "); Serial.print ("ll="); Serial.print (lightLed); Serial.print ("; "); Serial.print("y=");Serial.print(y);Serial.print(";"); Serial.print("z=");Serial.print(z);Serial.println(";"); lastPrintTime = millis(); } bool initializeGyroscope() { Wire.begin(); TWBR = 24; mpu.initialize(); Serial.println (mpu.testConnection () ? F ("MPU6050-Verbindung erfolgreich"): F ("MPU6050-Verbindung fehlgeschlagen")); Serial.println (F ("Initializing DMP …")); devStatus = mpu.dmpInitialize(); mpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.setZAccelOffset(1788); if (devStatus!= 0) {Serial.print(F("DMP Initialization failed (code"));Serial.println(devStatus); return false;} mpu.setDMPEnabled(true); Serial.println(F("Enabling.) Interrupt-Erkennung (Arduino externer Interrupt 0)…")); attachInterrupt(0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus(); Serial.println(F("DMP ready! Waiting for first interrupt…")); packetSize = mpu.dmpGetFIFOPacketSize(); true zurückgeben; } void dmpDataReady() { mpuInterrupt = true; }

Laden Sie den Code hoch:

Laden Sie den Code mit dem FTDI-Adapter auf das Arduino hoch.

Stromversorgung anschließen (Batterien)

Kalibrierung:

Das Wichtigste, was hier zu kalibrieren ist, ist die Konstante "LED_OFFSET". In meinem Beispiel ist 12. Sie müssen dies von 0 bis 23 einstellen, damit die LED nach dem Einschalten des Boards in die Richtung leuchtet, in die Sie das Board neigen.

Wenn Sie mehr über die Funktionsweise erfahren möchten, lesen Sie den letzten Schritt

Schritt 4: Wie es funktioniert (optional)

Wie es funktioniert (optional)
Wie es funktioniert (optional)

Zunächst ein paar Informationen zum Gyroskop MPU6050. Dies ist ein MEMS-Gyroskop (MEMS steht für Microelectromechanical Systems).

Jeder Typ von MEMs-Gyroskop weist eine Art oszillierende Komponente auf, von der aus die Beschleunigung und damit die Richtungsänderung erfasst werden kann. Dies liegt daran, dass gemäß dem Bewegungserhaltungsgesetz ein vibrierendes Objekt gerne in derselben Ebene schwingt und jede Schwingungsabweichung verwendet werden kann, um eine Richtungsänderung abzuleiten.

Der Kreisel enthält auch einen eigenen Mikrocontroller, um das Rollen, Nicken und Gieren durch einige ausgefallene Mathematik zu berechnen.

Aber die Gyro-Rohdaten leiden unter Rauschen und Drift, daher haben wir eine externe Bibliothek verwendet, um die Dinge zu glätten und uns saubere nutzbare Daten zu liefern.

Die Neopixel sind RGB-LEDs, die einzeln adressierbar und zu Bändern und Ringen verkettet sind. Sie arbeiten mit 5V und enthalten eine eigene Schaltung, sodass Sie nur die Neopixel mit Strom versorgen und über die Datenleitung mit ihnen kommunizieren müssen. Die Kommunikation erfolgt über eine einzelne Datenleitung, die Takt und Daten enthält (mehr Details hier). Adafruit bietet eine saubere Bibliothek für die Interaktion mit den Neopixelringen.

Der Code

Innerhalb der Funktion loop() wird die Bibliothek MPU6050_6Axis_MotionApps20 aufgerufen. Wenn die Bibliothek neue Daten vom Kreisel hat, ruft sie redrawLeds(x, y, z) mit 3 Argumenten für Gieren, Nicken und Rollen auf

Innen redrawLeds ():

- wir konzentrieren uns auf zwei Achsen: y, z

- wir beschränken beide Achsen von -MAX_ANGLE auf +MAX_ANGLE, wir haben den maximalen Winkel auf 45 definiert und er ist veränderbar

- Wir teilen 360 Grad in 4 Quadranten auf und rufen die Funktionen lightLeds() für jeden wie folgt auf:

* y negativ, z positiv erster Quadrant steuert die LEDs von 0 bis 5, der Winkel beträgt 0 bis 89

* y negativ, z negativ zweiter Quadrant steuert die LEDs von 6 bis 12, der Winkel beträgt 89 bis 0

* …etc

- in der lightLeds-Funktion

* Ich berechne einen Winkel basierend auf den beiden Achsen mit Arkustangens (siehe angehängtes Bild)

* Ich berechne, was mit der Arduino-Kartenfunktion zur Anzeige geführt hat

* Ich setze den LED-Streifen alle bis auf zwei LEDs zurück, diejenige, die der zuvor berechneten LED-Position und einer zuvor berechneten LED-Position entspricht (um einen Fade-Effekt zu zeigen)

* Ich verwende eine Funktion namens normalizeLedPosition(), um die Neopixel-Kalibrierung zu berücksichtigen. Die Kalibrierung ist sinnvoll, da der Neopixelring beliebig gedreht werden kann und auf das Gyroskop ausgerichtet werden sollte

* Ich drucke auch die Schleppachse, die LED hat Licht und den Winkel

Die Mathematik

Ich habe ein Bild mit dem LED-Ring und der trigonometrischen Funktion zur Bestimmung des Winkels angehängt.

Empfohlen: