Innholdsfortegnelse:

Kontrollere en Neopixel Led -ring med en bevegelsessensor: 3 trinn (med bilder)
Kontrollere en Neopixel Led -ring med en bevegelsessensor: 3 trinn (med bilder)

Video: Kontrollere en Neopixel Led -ring med en bevegelsessensor: 3 trinn (med bilder)

Video: Kontrollere en Neopixel Led -ring med en bevegelsessensor: 3 trinn (med bilder)
Video: Пульт + Arduino Uno + Адресная лента WS2812B 2024, November
Anonim
Image
Image
Montering og opplasting
Montering og opplasting

I denne opplæringen skal vi leke med en bevegelsessensor (APDS-9960) og en neopikselring for å lære å kombinere dem begge med en Arduino UNO.

Sluttproduktet vil reagere på venstre - høyre bevegelser ved å animere leddbevegelse til høyre eller venstre, og til opp -ned -bevegelser ved å endre lysdiodernes farge.

I de neste trinnene får du en kort oversikt over delelisten og hvordan du kobler til komponentene. Og så går vi gjennom koden trinn for trinn for å lære hvordan den fungerer.

Trinn 1: Komponenter

1. Arduino UNO

2. usb -kabel

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

4. 24 led neopiksel ledring (https://www.adafruit.com/product/1586)

5. hann-hunn, mann-hann-brødbrettkabler

6. brødbrett

7. 5 V strømforsyning til LED -ringen (jeg bruker et batteri på 4 batterier)

8. For å feste neopikselringen til brødbrettet må du lodde tre hannpinner: GND, PWR og kontrollnål. For dette trenger du et loddejern og fluss

Hovedkomponentene her er APDS-9960 gest-sensor og 24 neopiksler. Du kan bytte forskjellige arduinoer, usb -kabler strømforsyninger og brødbrett som du ønsker.

Trinn 2: Montering og opplasting

montering

Før du begynner, må du kontrollere at du har alle komponentene på bordet. Vi har noen fine trinn å følge:). Jeg har også lagt ved Fritzing -skjemaet som et bilde og også i fritzing -format.

1. Lodd 3 hannpinner til neopikselringen (GND, PWR, kontrollpinne)

2. fest neopikselringen til brødbrettet

3. fest APDS9960 -sensoren til brødbrettet

4. koble bakken: batteripakke, arduino UNO, APDS9960 og neopixel til brødbrettet

5. koble strømmen: arduino UNO 3V til APDS9960 strømstift, neopiksel til batteripakke

6. koble neopikslens kontrollpinne til arduino D6 -pinnen

7. koble SDA og SCL på APDS9960 til henholdsvis A4 og A5

8. koble APDS9960 -avbruddspinnen til arduino D2

Last opp kode

Først av alt må du laste ned og installere de nødvendige arduino -bibliotekene:

1. Neopixel ringbibliotek:

2. Gestusensorbibliotek:

Hvis du ikke vet hvordan du installerer arduino -biblioteker, sjekk ut denne opplæringen.

Etter at du har lastet ned og installert bibliotekene ovenfor, kan du klone eller laste ned arduino -depotet mitt her: https://github.com/danionescu0/arduino, så bruker vi denne skissen: https://github.com/danionescu0 /arduino/tree/master/projects/neopixel_ring_gestures

I den neste delen legger jeg inn koden direkte i denne opplæringen, så hvis du vil kan du kopiere og lime den inn derfra.

Til slutt kobler du arduino -datamaskinen til ved hjelp av usb -kabelen, setter 1,5 volt batterier i batteripakken og laster opp skissen til arduinoen.

Trinn 3: Hvordan fungerer det?

I denne siste delen lærer vi hvordan disse komponentene kombineres, hvordan de bruker bibliotekene deres og hvordan jeg har strukturert koden min:

La oss først få et raskt blikk gjennom sensoren og neopikselbibliotekets API -metoder som vi vil bruke

1. Neopixel API fra adafruit

Fra dette biblioteket bruker vi metodene som kontrollerer fargen på den enkelte LED og bruker dem

- inkluderer biblioteket:

#inkludere

- erklære biblioteket

#define NEOPIXED_CONTROL_PIN 6

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

- initialiser

#typisk inne i installasjonsblokken

ugyldig oppsett () {strip.begin (); # kanskje noen andre ting her #…. }

- lys opp individuelle piksler, og bruk deretter alle modifikasjoner på stripen (gjengi den på en måte)

# sett opp piksel 0 til å være rød

strip.setPixelColor (0, strip. Color (255, 0, 0)); # sette opp piksel 1 til å være grønn strip.setPixelColor (1, strip. Color (0, 255, 0)); # sette opp piksel 2 til å være blå strip.setPixelColor (2, strip. Color (0, 0 255)); strip.show ();

2. APDS 9960 gest -sensor

Fra dette biblioteket bruker vi funksjonen "les gest". Denne funksjonen vil kunne skille mellom venstre-høyre, opp-ned, nær-fjern kommandoer. Det er et triks her, vi kommer ikke til å be sensoren kontinuerlig om den siste gesten som ble oppfattet. Styret har evnen til å "pinge" gjennom et avbrudd for at en gest er funnet.

- inkludere biblioteket, som ligner på neopiksel

- erklære biblioteket for avbruddsnålen og avbruddsflagget

#define APDS9960_INT 2

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

- initialiser biblioteket, vanligvis inne i oppsettfunksjonen

ugyldig oppsett ()

{ # erklær avbruddsnålen som INNGANG og knytt en funksjon til den pinMode (APDS9960_INT, INPUT); attachInterrupt (0, interruptRoutine, FALLING); if (apds.init () && apds.enableGestureSensor (true)) {Serial.println ("APDS-9960 initialisering fullført"); } else {Serial.println ("Noe gikk galt under APDS-9960 init!"); } # initialiser andre ting kanskje}

- definere avbrytingsfunksjonen, her setter vi bare et flagg

void interruptRoutine () {

isr_flag = 1; }

- inne i sløyfefunksjonen, sjekk flagget med jevne mellomrom for å se om en gest er oppdaget

hulrom ()

{ # sjekk flagget hvis (isr_flag == 1) { # hvis flagget er satt, fjern avbruddet, utfør nødvendig behandling inne i handleGesture () -funksjonen # og tilbakestill deretter flagget og fest avbruddet detachInterrupt igjen (0); handleGesture (); isr_flag = 0; attachInterrupt (0, interruptRoutine, FALLING); } # noen annen kode her kanskje}

- definere handleGesture () -funksjonen der vi kan be om den siste gesten

void handleGesture () {

# hvis ingen gest er tilgjengelig retur, er dette bare en sikker sjekk om (! apds.isGestureAvailable ()) {return; } # leser den siste gesten, sammenligner med de kjente og skriv ut en meldingsbryter (apds.readGesture ()) {case DIR_UP: Serial.println ("UP"); gå i stykker; sak DIR_DOWN: Serial.println ("NED"); gå i stykker; sak DIR_LEFT: Serial.println ("LEFT"); gå i stykker; sak DIR_RIGHT: Serial.println ("RIGHT"); gå i stykker; sak DIR_FAR: Serial.println ("FAR"); gå i stykker; }}

La oss nå se hele koden i aksjon:

Så jeg har forklart basis -API -en for gestsensoren og neopikselringen, la oss sette sammen ting:

Algoritmen kjører slik:

- initialiser bibliotekene (se koden ovenfor)

- Lag en rekke ledede intensiteter kalt "ledStates". Denne matrisen vil inneholde 24 led -intensiteter som er ordnet på en synkende måte fra 150 til 2

- inne i hovedsløyfen, sjekk om avbruddsnålen er endret i så fall er det på tide å endre leddens animasjon eller farge

- "handleGesture ()" -funksjonen sjekker den siste gesten og kaller funksjonen "toggleColor" for OPP -NED -bevegelser eller angi en global variabel "ledDirection" for VENSTRE - HØYRE bevegelser

- funksjonen "toggleColor ()" endrer ganske enkelt en global variabel som heter "colorSelection" med en av verdiene 0, 1, 2

- også inne i hovedløyfefunksjonen en annen funksjon som heter "animateLeds ();" er kalt. Denne funksjonen sjekker om 100 millisekunder har passert, og i så fall roterer den lysdiodene ved hjelp av "rotateLeds ()" -funksjonen og tegner dem deretter på nytt

- "rotateLeds ()" vil "rotere" lysdiodene fremover eller bakover ved å bruke en annen matrise kalt "intermediateLedStates".

Rotasjonseffekten vil se slik ut:

# etter initialisering

{150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # after rotateLeds () kalles {0, 150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # after rotateLeds () kalles igjen {0, 0, 150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # og så videre

For dette oppretter først det nye arrayet og kopierer de gamle led -intensitetene på de nye posisjonene (øk posisjonen eller reduser den). Etter det overskriver det "ledStates" -matrisen med "intermediateLedStates", slik at prosessen vil fortsette etter ytterligere 100 millisekunder.

#inkludere "SparkFun_APDS9960.h"

#include "Adafruit_NeoPixel.h"

#inkludere "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 (NE_PLO_ENG, NEOPIX_ SparkFun_APDS9960 apds = SparkFun_APDS9960 (); unsigned long lastLedChangeTime = 0; kort ledDirection = 0; kort colorSelection = 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; ugyldig oppsett () {Serial.begin (9600); Serial.println ("Programmet startet"); strip.begin (); pinMode (APDS9960_INT, INPUT); attachInterrupt (0, interruptRoutine, FALLING); if (apds.init () && apds.enableGestureSensor (true)) {Serial.println ("initialisering av APDS-9960 fullført"); } else {Serial.println ("Noe gikk galt under APDS-9960 init!"); } lastLedChangeTime = millis (); Serial.println ("Init vellykket"); } void loop () {if (isr_flag == 1) {detachInterrupt (0); handleGesture (); isr_flag = 0; attachInterrupt (0, interruptRoutine, FALLING); } animateLeds (); } void interruptRoutine () {isr_flag = 1; }}; } switch (apds.readGesture ()) {case DIR_UP: Serial.println ("UP"); toggleColor (); gå i stykker; sak DIR_DOWN: Serial.println ("NED"); toggleColor (); gå i stykker; sak DIR_LEFT: ledDirection = 1; Serial.println ("LEFT"); gå i stykker; sak DIR_RIGHT: ledDirection = -1; Serial.println ("HØYRE"); gå i stykker; sak DIR_FAR: ledDirection = 0; Serial.println ("FAR"); gå i stykker; }} / ** * Endre dagens lysdiodefarge * Hver gang denne funksjonen kalles, endres lysdiodens tilstand * / void toggleColor () {if (colorSelection == 0) {colorSelection = 1; } annet hvis (colorSelection == 1) {colorSelection = 2; } annet {colorSelection = 0; }} / ** * Animasjonen kjøres etter LED_SPEED_STEP_INTERVAL millis * Først kalles rotateLeds -funksjonen, deretter settes ledsfargene ved hjelp av stripe api * / void animateLeds () {if (millis () - lastLedChangeTime <LED_SPEED_STEP_INTERVAL) {retur; } rotateLeds (); for (int i = 0; i <NUM_LEDS; i ++) {strip.setPixelColor (i, getColor (ledStates )); strip.show (); } lastLedChangeTime = millis (); } /** * Ved å bruke en sekundær matrise "intermediateLedStates", blir lysintensitetene animert * Først blir verdiene fra "ledStates" kopiert på "intermediateLedStates" som så * la oss sette "ledStates" -matrisen {100, 80, 60, 0, 0, 0} og ledDirection er 1 * og etter at denne funksjonen kalles "ledStates", er matrisen {0, 100, 80, 60, 0, 0} som simulerer en rotasjonseffekt */ void rotateLeds () {byte intermediateLedStates [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 ; } annet {intermediateLedStates [i + 1] = ledStates ; }} annet {if (i == 0) {intermediateLedStates [NUM_LEDS - 1] = ledStates ; } else {intermediateLedStates [i - 1] = ledStates ; }}} for (int i = 0; i <NUM_LEDS; i ++) {ledStates = intermediateLedStates ; }} uint32_t getColor (int intensitet) {switch (colorSelection) {case 0: return strip. Color (intensitet, 0, 0); sak 1: returstrimmel. Farge (0, intensitet, 0); standard: returstrimmel. Farge (0, 0, intensitet); }}

Jeg håper du likte dette, du kan bruke kommentarfeltet til å stille meg spørsmål.

Anbefalt: