Taula de continguts:

Control d'un anell LED Neopixel amb un sensor de gest: 3 passos (amb imatges)
Control d'un anell LED Neopixel amb un sensor de gest: 3 passos (amb imatges)

Vídeo: Control d'un anell LED Neopixel amb un sensor de gest: 3 passos (amb imatges)

Vídeo: Control d'un anell LED Neopixel amb un sensor de gest: 3 passos (amb imatges)
Vídeo: Arduino: демонстрация кольца AdaFruit NeoPixel 2024, De novembre
Anonim
Image
Image
Muntatge i càrrega
Muntatge i càrrega

En aquest tutorial jugarem amb un sensor de gestos (APDS-9960) i un anell de neopixel per aprendre a combinar-los amb un Arduino UNO.

El producte final respondrà als gestos esquerra-dreta animant el moviment del led cap a la dreta o cap a l’esquerra, i als gestos cap amunt i cap avall canviant el color dels leds.

En els passos següents, veureu breument la llista de peces i com connectar els components. A continuació, revisarem el codi pas a pas per saber com funciona.

Pas 1: components

1. Arduino UNO

2. cable USB

3. Sensor de gestos APDS9960 (https://www.sparkfun.com/products/12787)

4. Anell de neopixels de 24 leds (https://www.adafruit.com/product/1586)

5. Cables de taulers de connexió mascle-femella, mascle-mascle

6. taulell de pa

7. Font d'alimentació de 5 V per a l'anell LED (estic fent servir una bateria de 4)

8. Per fixar l'anell de neopíxels a la placa de marc, haureu de soldar-hi tres pins masculins: GND, PWR i pin de control. Per a això, necessitareu un soldador i un flux

Els components principals són el sensor de gest APDS-9960 i l’anell de 24 neopíxels. Podeu canviar diferents arduinos, fonts d'alimentació de cables USB i taulers de configuració com vulgueu.

Pas 2: Muntatge i càrrega

muntatge

Abans de començar, assegureu-vos que teniu tots els components a la taula. Tindrem alguns bons passos a seguir:). També he adjuntat l’esquema de Fritzing com a imatge i també en format fritzing.

1. Soldeu 3 pins masculins a l'anell de neopixel (GND, PWR, pin de control)

2. connecteu l'anell de neopixel a la taula de tall

3. connecteu el sensor APDS9960 a la placa de control

4. connecteu els terrenys: bateria, arduino UNO, APDS9960 i neopixel a la placa de terra

5. connecteu l'alimentació: arduino UNO 3V al pin d'alimentació APDS9960, neopixel a la bateria

6. connecteu el pin de control del neopixel al pin arduino D6

7. connecteu SDA i SCL de l'APDS9960 a l'A4 i A5 respectivament

8. connecteu el pin d'interrupció APDS9960 a l'arduino D2

Càrrega de codi

Primer de tot, haureu de descarregar i instal·lar les biblioteques arduino necessàries:

1. Biblioteca d'anells Neopixel:

2. Biblioteca del sensor de gestos:

Si no sabeu com instal·lar biblioteques arduino, consulteu aquest tutorial.

Després de descarregar i instal·lar les biblioteques anteriors, podeu clonar o descarregar el meu dipòsit arduino situat aquí: https://github.com/danionescu0/arduino i utilitzarem aquest esbós: https://github.com/danionescu0 / arduino / tree / master / projects / neopixel_ring_gestures

A la següent secció inseriré el codi directament en aquest tutorial, de manera que si voleu el podeu copiar i enganxar des d'allà.

Finalment, connecteu l’arduino a l’ordinador mitjançant el cable USB, poseu piles d’1,5 V a la bateria i pengeu l’esbós a l’arduino.

Pas 3: Com funciona?

En aquesta última part, aprendrem com es combinen aquests components, com utilitzar les seves biblioteques i com he estructurat el meu codi:

Primer fem una ullada ràpida a través del mètode de l'API de la biblioteca de neopíxels i del sensor que utilitzarem

1. API Neopixel d'Adafruit

Des d’aquesta biblioteca farem servir els mètodes que controlen i apliquen el color del led individual

- inclou la biblioteca:

#incloure

- declarar la biblioteca

#define NEOPIXED_CONTROL_PIN 6

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

- inicialitzar

#típicament dins del bloc de configuració

void setup () {strip.begin (); # potser alguna cosa més aquí # … }

- il·lumineu píxels individuals i apliqueu totes les modificacions a la tira (renderitzeu-la d'una manera)

# configureu el píxel 0 perquè sigui vermell

strip.setPixelColor (0, strip. Color (255, 0, 0)); # configureu el píxel 1 perquè sigui verd strip.setPixelColor (1, strip. Color (0, 255, 0)); # configureu el píxel 2 perquè sigui blau strip.setPixelColor (2, strip. Color (0, 0 255)); strip.show ();

2. Sensor de gestos APDS 9960

Des d'aquesta biblioteca farem servir la funció "gest de lectura". Aquesta funció serà capaç de distingir entre ordres esquerra-dreta, amunt-avall i molt a prop. Aquí hi ha un truc, no anem a demanar al sensor contínuament l’últim gest percebut. La junta té la capacitat de "fer ping" mitjançant una interrupció que ha trobat un gest.

- inclou la biblioteca, similar al neopixel

- declarar la biblioteca el pin d'interrupció i el senyal d'interrupció

#define APDS9960_INT 2

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

- inicialitzar la biblioteca, normalment dins de la funció de configuració

configuració nul·la ()

{# declarar el pin d'interrupció com a INPUT i adjuntar-hi una funció pinMode (APDS9960_INT, INPUT); attachInterrupt (0, interruptRoutine, FALLING); if (apds.init () && apds.enableGestureSensor (true)) {Serial.println ("S'ha completat la inicialització APDS-9960"); } else {Serial.println ("S'ha produït un error durant l'inici de l'APDS-9960!"); } # inicialitzeu altres coses potser}

- definiu la funció d'interrupció, aquí establirem només una marca

void interruptRoutine () {

isr_flag = 1; }

- dins de la funció de bucle comproveu la senyal periòdicament per veure si s’ha detectat un gest

bucle buit ()

{# comproveu la marca si (isr_flag == 1) {# si la marca està configurada, elimineu la interrupció, feu el processament necessari a la funció handleGesture () # i, a continuació, reinicieu la marca i torneu a connectar la interrupció detachInterrupt (0); handleGesture (); isr_flag = 0; attachInterrupt (0, interruptRoutine, FALLING); } # algun altre codi aquí potser}

- defineix la funció handleGesture () on podem demanar l'últim gest

void handleGesture () {

# si no hi ha cap gest disponible, només és una comprovació segura si (! apds.isGestureAvailable ()) {return; } # llegeix l'últim gest, es compara amb els coneguts i imprimeix un commutador de missatges (apds.readGesture ()) {case DIR_UP: Serial.println ("UP"); trencar; cas DIR_DOWN: Serial.println ("DOWN"); trencar; cas DIR_LEFT: Serial.println ("ESQUERRA"); trencar; cas DIR_RIGHT: Serial.println ("DRETA"); trencar; cas DIR_FAR: Serial.println ("FAR"); trencar; }}

Ara vegem tot el codi en acció:

Així que he explicat l’API base del sensor de gestos i de l’anell de neopíxels, ara juntem les coses:

L'algorisme funciona així:

- inicialitzar les biblioteques (vegeu el codi anterior)

- Creeu un conjunt d'intensitats de leds anomenades "ledStates". Aquesta matriu contindrà 24 intensitats de leds que es disposen de manera descendent de 150 a 2

- dins del bucle principal comproveu si s'ha modificat el pin d'interrupció, si és així, és hora de canviar l'animació o el color del led

- la funció "handleGesture ()" comprova l'últim gest i crida a la funció "toggleColor" per als gestos AMUNT-BAIX o estableix una variable global "ledDirection" per als gestos ESQUERRA - DRETA

- la funció "toggleColor ()" simplement canvia una variable global anomenada "colorSelection" amb un dels valors 0, 1, 2

- també dins de la funció de bucle principal una altra funció anomenada "animateLeds ();" es diu. Aquesta funció comprova si passen 100 mil·lisegons i, en aquest cas, gira els leds mitjançant la funció "rotateLeds ()" i els torna a dibuixar

- el "rotateLeds ()" farà "rotar" els leds cap endavant o cap enrere mitjançant l'ús d'una altra matriu anomenada "intermediateLedStates".

L'efecte de rotació serà així:

# després de la inicialització

{150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # després de rotateLeds () s'anomena {0, 150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # després de rotateLeds () es torna a cridar {0, 0, 150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # etcètera

Per a això, primer es crea la nova matriu i es copia les antigues intensitats de leds a les noves posicions (incrementar la posició o disminuir-la). Després, sobreescriu la matriu "ledStates" amb el "intermediateLedStates", de manera que el procés continuarà després de 100 mil·lisegons més.

#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_P; SparkFun_APDS9960 apds = SparkFun_APDS9960 (); unsigned long lastLedChangeTime = 0; direcció LED curta = 0; selecció de color curta = 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; configuració nul·la () {Serial.begin (9600); Serial.println ("S'ha iniciat el programa"); strip.begin (); pinMode (APDS9960_INT, INPUT); attachInterrupt (0, interruptRoutine, FALLING); if (apds.init () && apds.enableGestureSensor (true)) {Serial.println ("S'ha completat la inicialització APDS-9960"); } else {Serial.println ("S'ha produït un error durant l'inici de l'APDS-9960!"); } lastLedChangeTime = millis (); Serial.println ("Inici amb èxit"); } void loop () {if (isr_flag == 1) {detachInterrupt (0); handleGesture (); isr_flag = 0; attachInterrupt (0, interruptRoutine, FALLING); } animateLeds (); } void interruptRoutine () {isr_flag = 1; } / ** * Això gestionarà els gestos del sensor APDS9960 * Els gestos amunt i avall cridaran a la funció toggleColor * Els gestos esquerre i dret canviaran l'animació del led * / void handleGesture () {if (! Apds.isGestureAvailable ()) {return; } switch (apds.readGesture ()) {case DIR_UP: Serial.println ("UP"); toggleColor (); trencar; cas DIR_DOWN: Serial.println ("BAIX"); toggleColor (); trencar; cas DIR_LEFT: ledDirection = 1; Serial.println ("ESQUERRA"); trencar; cas DIR_RIGHT: ledDirection = -1; Serial.println ("DRETA"); trencar; cas DIR_FAR: ledDirection = 0; Serial.println ("FAR"); trencar; }} / ** * Canvia el color dels leds actuals * Cada vegada que es crida aquesta funció canviarà l'estat dels leds * / void toggleColor () {if (colorSelection == 0) {colorSelection = 1; } else if (colorSelection == 1) {colorSelection = 2; } else {colorSelection = 0; }} / ** * L'animació s'executarà després de LED_SPEED_STEP_INTERVAL millis * Primer es crida la funció rotateLeds, després es configuren els colors dels leds mitjançant la tira api * / 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 (); } / ** * Utilitzant una matriu secundària "intermediateLedStates", s'intenten intensitats de leds * Primer es copien els valors de "ledStates" a "intermediateLedStates" com ara * sentem-nos que la matriu "ledStates" és {100, 80, 60, 0, 0, 0} i ledDirection és 1 *, després que aquesta funció s'anomeni "ledStates", la matriu és {0, 100, 80, 60, 0, 0} simulant un efecte de rotació * / void rotateLeds () {byte intermediateLedStates [NUM_LEDS]; for (int i = 0; i <NUM_LEDS; i ++) {intermèdiaStats = 0; } for (int i = 0; i <NUM_LEDS; i ++) {if (ledDirection == 1) {if (i == NUM_LEDS -1) {intermediateLedStates [0] = ledStates ; } else {intermitentsEstats [i + 1] = estats led ; }} else {if (i == 0) {intermediateLedStates [NUM_LEDS - 1] = ledStates ; } else {intermitentsEstats [i - 1] = ledEstats ; }}} per a (int i = 0; i <NUM_LEDS; i ++) {ledStates = intermediarisLedStates ; }} uint32_t getColor (int intensitat) {commutador (colorSelecció) {cas 0: tira de retorn. Color (intensitat, 0, 0); cas 1: tira de retorn. Color (0, intensitat, 0); per defecte: return strip. Color (0, 0, intensitat); }}

Espero que us hagi agradat, podeu fer servir la secció de comentaris per fer-me preguntes.

Recomanat: