Inhaltsverzeichnis:

Steuern eines Neopixel-LED-Rings mit einem Gestensensor - Gunook
Steuern eines Neopixel-LED-Rings mit einem Gestensensor - Gunook

Video: Steuern eines Neopixel-LED-Rings mit einem Gestensensor - Gunook

Video: Steuern eines Neopixel-LED-Rings mit einem Gestensensor - Gunook
Video: Arduino Zusatzlektion: Ansteuerung eines Adafruit NeoPixel LED-Rings 2024, November
Anonim
Image
Image
Zusammenbau & Hochladen
Zusammenbau & Hochladen

In diesem Tutorial werden wir mit einem Gestensensor (APDS-9960) und einem Neopixel-Ring spielen, um zu lernen, wie man beide mit einem Arduino UNO kombiniert.

Das Endprodukt reagiert auf Links-Rechts-Gesten, indem die LED-Bewegung nach rechts oder links animiert wird, und auf Auf-Ab-Gesten, indem die LED-Farbe geändert wird.

In den nächsten Schritten erhalten Sie einen kurzen Überblick über die Stückliste und wie Sie die Komponenten anschließen. Und dann werden wir den Code Schritt für Schritt überprüfen, um zu erfahren, wie er funktioniert.

Schritt 1: Komponenten

1. Arduino UNO

2. USB-Kabel

3. APDS9960 Gestensensor (https://www.sparkfun.com/products/12787)

4. 24 LED Neopixel LED Ring (https://www.adafruit.com/product/1586)

5. männlich-weiblich, männlich-männlich Steckbrettkabel

6. Steckbrett

7. 5-V-Stromversorgung für den LED-Ring (ich verwende eine 4-Batterie-Rückseite)

8. Um den Neopixel-Ring am Steckbrett zu befestigen, müssen Sie drei männliche Stifte daran anlöten: GND, PWR und Steuerstift. Dafür benötigst du einen Lötkolben und Flussmittel

Die Hauptkomponenten sind hier der Gestensensor APDS-9960 und der 24 Neopixel-Ring. Sie können verschiedene Arduinos, USB-Kabel, Netzteile und Steckbretter nach Belieben umschalten.

Schritt 2: Zusammenbau & Hochladen

Montage

Bevor Sie beginnen, stellen Sie sicher, dass Sie alle Komponenten auf Ihrem Tisch haben. Wir werden ein paar nette Schritte haben, denen wir folgen können:). Den Fritzing-Schema habe ich auch als Bild und auch im Fritzing-Format angehängt.

1. Löten Sie 3 Stifte an den Neopixel-Ring (GND, PWR, Steuerstift)

2. Befestigen Sie den Neopixel-Ring am Steckbrett

3. Befestigen Sie den APDS9960-Sensor am Steckbrett

4. Verbinden Sie die Masse: Akku, Arduino UNO, APDS9960 und Neopixel mit der Steckplatinenmasse

5. Schließen Sie die Stromversorgung an: Arduino UNO 3V an den APDS9960-Stromanschluss, Neopixel an die Stromversorgung des Akkus

6. Verbinden Sie den Neopixel-Steuerstift mit dem Arduino D6-Pin

7. Verbinden Sie SDA und SCL des APDS9960 mit A4 bzw. A5

8. Verbinden Sie den APDS9960-Interrupt-Pin mit dem Arduino D2

Code-Upload

Zunächst müssen Sie die erforderlichen Arduino-Bibliotheken herunterladen und installieren:

1. Neopixel-Ringbibliothek:

2. Gestensensorbibliothek:

Wenn Sie nicht wissen, wie Sie Arduino-Bibliotheken installieren, lesen Sie dieses Tutorial.

Nachdem Sie die obigen Bibliotheken heruntergeladen und installiert haben, können Sie mein Arduino-Repository klonen oder herunterladen, das sich hier befindet: https://github.com/danionescu0/arduino, und wir verwenden diese Skizze: https://github.com/danionescu0 /arduino/tree/master/projects/neopixel_ring_gestures

Im nächsten Abschnitt werde ich den Code direkt in dieses Tutorial einbetten. Wenn Sie möchten, können Sie ihn also von dort kopieren und einfügen.

Schließen Sie schließlich das Arduino mit dem USB-Kabel an den Computer an, legen Sie 1,5-V-Batterien in den Akku und laden Sie die Skizze in das Arduino hoch.

Schritt 3: Wie funktioniert es?

In diesem letzten Teil erfahren wir, wie diese Komponenten miteinander kombiniert werden, wie man ihre Bibliotheken verwendet und wie ich meinen Code strukturiert habe:

Werfen wir zunächst einen kurzen Blick auf den Sensor und die API-Methoden der Neopixel-Bibliothek, die wir verwenden werden

1. Neopixel-API von Adafruit

Aus dieser Bibliothek werden wir die Methoden verwenden, die die Farbe einzelner LEDs steuern und anwenden

- die Bibliothek einbeziehen:

#enthalten

- deklarieren Sie die Bibliothek

#define NEOPIXED_CONTROL_PIN 6

#define NUM_LEDS 24 Adafruit_NeoPixel-Streifen = Adafruit_NeoPixel(NUM_LEDS, NEOPIXED_CONTROL_PIN, NEO_RBG + NEO_KHZ800);

- initialisieren

#normalerweise im Einrichtungsblock

Void setup () { strip.begin (); # vielleicht noch ein paar andere Sachen hier # …. }

- leuchten Sie einzelne Pixel auf und wenden Sie dann alle Änderungen auf den Streifen an (rendern Sie ihn in einer Weise)

# Pixel 0 so einrichten, dass es rot ist

strip.setPixelColor(0, strip. Color(255, 0, 0)); # Pixel 1 als grün einrichten strip.setPixelColor(1, strip. Color(0, 255, 0)); # Pixel 2 als blau einrichten strip.setPixelColor(2, strip. Color(0, 0 255)); Strip-Show();

2. APDS 9960 Gestensensor

Aus dieser Bibliothek werden wir die Funktion "Lesegeste" verwenden. Diese Funktion kann zwischen Links-Rechts-, Auf-Ab- und Nah-Fern-Befehlen unterscheiden. Hier gibt es einen Trick, wir werden den Sensor nicht ständig nach der zuletzt wahrgenommenen Geste fragen. Das Board hat die Fähigkeit, durch einen Interrupt zu "pingen", dass eine Geste gefunden wurde.

- Binden Sie die Bibliothek ein, ähnlich dem Neopixel

- Deklarieren Sie die Bibliothek zum Interrupt-Pin und zum Interrupt-Flag

#define APDS9960_INT 2

SparkFun_APDS9960 apds = SparkFun_APDS9960(); int isr_flag = 0;

- Initialisieren Sie die Bibliothek, normalerweise innerhalb der Setup-Funktion

Void-Setup ()

{ # den Interrupt-Pin als INPUT deklarieren und eine Funktion daran anhängen pinMode(APDS9960_INT, INPUT); AttachInterrupt(0, InterruptRoutine, FALLING); if (apds.init () && apds.enableGestureSensor (true)) { Serial.println ("APDS-9960-Initialisierung abgeschlossen"); } else { Serial.println ("Bei der APDS-9960-Initialisierung ist etwas schief gelaufen!"); } # vielleicht andere Dinge initialisieren }

- Definiere die Interrupt-Funktion, hier setzen wir nur ein Flag

Void InterruptRoutine () {

isr_flag = 1; }

- Überprüfen Sie innerhalb der Loop-Funktion regelmäßig die Flagge, um zu sehen, ob eine Geste erkannt wurde

Leere Schleife ()

{ # Flag überprüfen if(isr_flag == 1) { # Wenn das Flag gesetzt ist, entfernen Sie den Interrupt, führen Sie die erforderliche Verarbeitung in der Funktion handleGesture() durch # und setzen Sie dann das Flag zurück und fügen Sie den Interrupt erneut an detachInterrupt(0); handleGesture(); isr_flag = 0; AttachInterrupt(0, InterruptRoutine, FALLING); } # vielleicht ein anderer Code hier }

- Definiere die Funktion handleGesture(), wo wir nach der letzten Geste fragen können

void handleGesture() {

# wenn keine Geste verfügbar ist return, dies ist nur eine sichere Prüfung if (!apds.isGestureAvailable()) { return; } # liest die letzte Geste, vergleicht mit den bekannten und gibt einen Nachrichtenwechsel aus (apds.readGesture()) { case DIR_UP: Serial.println("UP"); brechen; case DIR_DOWN: Serial.println("DOWN"); brechen; case DIR_LEFT: Serial.println("LEFT"); brechen; Fall DIR_RIGHT: Serial.println ("RECHTS"); brechen; Fall DIR_FAR: Serial.println ("FAR"); brechen; } }

Sehen wir uns nun den gesamten Code in Aktion an:

Ich habe also die Basis-API des Gestensensors und des Neopixel-Rings erklärt, nun lasst uns die Dinge zusammenstellen:

Der Algorithmus läuft so ab:

- Initialisieren der Bibliotheken (siehe Code oben)

- Erstellen Sie ein Array von LED-Intensitäten namens "ledStates". Dieses Array enthält 24 LED-Intensitäten, die absteigend von 150 bis 2. angeordnet sind

- Überprüfen Sie in der Hauptschleife, ob der Interrupt-Pin geändert wurde. Wenn ja, ist es an der Zeit, die Animation oder Farbe der LED zu ändern

- die Funktion "handleGesture()" prüft die letzte Geste und ruft die Funktion "toggleColor" für UP -DOWN Gesten auf oder setzt eine globale Variable "ledDirection" für LEFT - RIGHT Gesten

- die Funktion "toggleColor()" ändert einfach eine globale Variable namens "colorSelection" mit einem der Werte 0, 1, 2

- auch innerhalb der Hauptschleifenfunktion eine weitere Funktion namens "animateLeds();" wird genannt. Diese Funktion prüft, ob 100 Millisekunden vergangen sind, und wenn ja, dreht sie die LEDs mit der Funktion "rotateLeds()" und zeichnet sie dann neu

- "rotateLeds()" "rotiert" die LEDs vorwärts oder rückwärts, indem ein anderes Array namens "intermediateLedStates" verwendet wird.

Der Rotations-"Effekt" sieht so aus:

# nach der Initialisierung

{150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # nachdem rotateLeds() aufgerufen wird {0, 150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # nach RotateLeds() wird erneut aufgerufen {0, 0, 150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # und so weiter

Dazu wird zuerst das neue Array erstellt und die alten LED-Intensitäten auf die neuen Positionen kopiert (Position erhöhen oder verringern). Danach überschreibt es das Array "ledStates" mit den "intermediateLedStates", sodass der Vorgang nach weiteren 100 Millisekunden fortgesetzt wird.

#include "SparkFun_APDS9960.h"

#include "Adafruit_NeoPixel.h"

#include "Wire.h" #define NEOPIXED_CONTROL_PIN 6 #define NUM_LEDS 24 #define APDS9960_INT 2 #define LED_SPEED_STEP_INTERVAL 100 Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, NEOPIXED_CONTROL_PIN + N_HRGZ800); SparkFun_APDS9960 apds = SparkFun_APDS9960(); unsigned long lastLedChangeTime = 0; kurze ledDirection = 0; kurze Farbauswahl = 0; Byte ledStates = {150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int isr_flag = 0; Void setup () { Serial.begin (9600); Serial.println ("Programm gestartet"); strip.begin(); pinMode (APDS9960_INT, INPUT); AttachInterrupt(0, InterruptRoutine, FALLING); if (apds.init () && apds.enableGestureSensor (true)) { Serial.println ("APDS-9960 Initialisierung abgeschlossen"); } else { Serial.println ("Bei der APDS-9960-Initialisierung ist etwas schief gelaufen!"); } lastLedChangeTime = millis(); Serial.println ("Init erfolgreich"); aufrechtzuerhalten. Void Schleife () { if (isr_flag == 1) { detachInterrupt (0); handleGesture(); isr_flag = 0; AttachInterrupt(0, InterruptRoutine, FALLING); } animateLeds(); aufrechtzuerhalten. Void InterruptRoutine () {isr_flag = 1; } /** * Dies verarbeitet Gesten vom APDS9960-Sensor * Auf- und Ab-Gesten rufen die Funktion toggleColor auf * Links- und Rechts-Gesten ändern die LED-Animation */ void handleGesture() { if (!apds.isGestureAvailable()) { return; } Schalter (apds.readGesture ()) { Fall DIR_UP: Serial.println ("UP"); toggleColor(); brechen; case DIR_DOWN: Serial.println("DOWN"); toggleColor(); brechen; Fall DIR_LEFT: ledDirection = 1; Serial.println ("LINKS"); brechen; case DIR_RIGHT: ledDirection = -1; Serial.println ("RECHTS"); brechen; Fall DIR_FAR: ledDirection = 0; Serial.println("FAR"); brechen; } } /** * Aktuelle LED-Farbe ändern * Jedes Mal, wenn diese Funktion aufgerufen wird, ändert sich der LED-Status */ void toggleColor () { if (colorSelection == 0) { colorSelection = 1; aufrechtzuerhalten. Sonst if (colorSelection == 1) { colorSelection = 2; aufrechtzuerhalten. Sonst { colorSelection = 0; } } /** * Die Animation wird nach LED_SPEED_STEP_INTERVAL millis ausgeführt * Zuerst wird die rotateLeds-Funktion aufgerufen, dann werden die LED-Farben mit der Streifen-API gesetzt */ void animateLeds() { if (millis() - lastLedChangeTime < LED_SPEED_STEP_INTERVAL) { return; } RotateLeds(); for (int i=0; i < NUM_LEDS; i++) { strip.setPixelColor(i, getColor(ledStates)); Strip-Show(); } lastLedChangeTime = millis(); } /** * Unter Verwendung eines sekundären Arrays "intermediateLedStates" werden die LED-Intensitäten animiert * Zuerst werden die Werte von "ledStates" auf "intermediateLedStates" kopiert * Nehmen wir an, das "ledStates"-Array ist {100, 80, 60, 0, 0, 0} und die ledDirection ist 1 * dann, nachdem diese Funktion aufgerufen wurde, ist das Array "ledStates" {0, 100, 80, 60, 0, 0} simuliert einen Rotationseffekt */ void rotateLeds() { byte betweenLedStates[NUM_LEDS]; for (int i=0; i < NUM_LEDS; i++) {intermediateLedStates = 0; } for (int i=0; i < NUM_LEDS; i++) { if (ledDirection == 1) { if (i == NUM_LEDS -1) {intermediateLedStates[0] = ledStates; aufrechtzuerhalten. Else { ZwischenLedStates[i + 1] = ledStates; }} else { if (i == 0) {intermediateLedStates[NUM_LEDS - 1] = ledStates; aufrechtzuerhalten. Else { ZwischenLedStates[i - 1] = ledStates; } } } for (int i=0; i < NUM_LEDS; i++) {ledStates = betweenLedStates; }} uint32_t getColor (int Intensität) { switch (colorSelection) { Fall 0: Streifen zurückgeben. Color (Intensität, 0, 0); Fall 1: Rückkehr strip. Color (0, Intensität, 0); Vorgabe: Streifen zurückgeben. Farbe(0, 0, Intensität); } }

Ich hoffe, es hat Ihnen gefallen, Sie können den Kommentarbereich verwenden, um mir Fragen zu stellen.

Empfohlen: