Tabla de contenido:

Controlar un anillo LED de Neopixel con un sensor de gestos: 3 pasos (con imágenes)
Controlar un anillo LED de Neopixel con un sensor de gestos: 3 pasos (con imágenes)

Video: Controlar un anillo LED de Neopixel con un sensor de gestos: 3 pasos (con imágenes)

Video: Controlar un anillo LED de Neopixel con un sensor de gestos: 3 pasos (con imágenes)
Video: Primeros pasos con Arduino Nano 33 IoT - Curso Objetos Conectados v2 2024, Noviembre
Anonim
Image
Image
Montaje y carga
Montaje y carga

En este tutorial vamos a jugar con un sensor de gestos (APDS-9960) y un anillo de neopixel para aprender a combinar ambos usando un Arduino UNO.

El producto final responderá a los gestos de izquierda a derecha animando el movimiento del led hacia la derecha o hacia la izquierda, y a los gestos de arriba hacia abajo cambiando el color de los leds.

En los siguientes pasos, verá brevemente la lista de piezas y cómo conectar los componentes. Y luego revisaremos el código paso a paso para aprender cómo funciona.

Paso 1: componentes

1. Arduino UNO

2. cable usb

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

4. Anillo de 24 led de neopixel led (https://www.adafruit.com/product/1586)

5. cables de placa de pruebas macho-hembra, macho-macho

6. tablero

7. Fuente de alimentación de 5 V para el anillo de led (estoy usando una parte posterior de 4 baterías)

8. Para conectar el anillo de neopixel a la placa de prueba, necesitará soldar tres pines macho: GND, PWR y pin de control. Para ello, necesitará un soldador y un fundente.

Los componentes principales aquí son el sensor de gestos APDS-9960 y el anillo de 24 neopíxeles. Puede cambiar diferentes arduinos, fuentes de alimentación de cables USB y placas de pruebas como desee.

Paso 2: Montaje y carga

Montaje

Antes de comenzar, asegúrese de tener todos los componentes en su mesa. Tendremos algunos buenos pasos a seguir:). También adjunté el esquema de Fritzing como una imagen y también en formato de fritzing.

1. Suelde 3 pines macho al anillo neopixel (GND, PWR, pin de control)

2. coloque el anillo de neopixel en la placa de pruebas

3. conecte el sensor APDS9960 a la placa de pruebas

4. conecte las tierras: paquete de baterías, arduino UNO, APDS9960 y neopixel a la tierra de la placa de pruebas

5. Conecte la alimentación: arduino UNO 3V al pin de alimentación APDS9960, neopixel a la alimentación de la batería

6. conecte el pin de control neopixel al pin arduino D6

7. conecte SDA y SCL del APDS9960 al A4 y A5 respectivamente

8. conecte el pin de interrupción APDS9960 al arduino D2

Carga de código

En primer lugar, deberá descargar e instalar las bibliotecas arduino necesarias:

1. Biblioteca de anillos de Neopixel:

2. Biblioteca de sensores de gestos:

Si no sabe cómo instalar las bibliotecas arduino, consulte este tutorial.

Una vez que haya descargado e instalado las bibliotecas anteriores, puede clonar o descargar mi repositorio de arduino ubicado aquí: https://github.com/danionescu0/arduino, y usaremos este boceto: https://github.com/danionescu0 / arduino / árbol / maestro / proyectos / neopixel_ring_gestures

En la siguiente sección, incrustaré el código directamente en este tutorial, por lo que si lo desea, puede copiarlo y pegarlo desde allí.

Finalmente, conecte el arduino a la computadora usando el cable usb, coloque baterías de 1.5 v en el paquete de baterías y cargue el boceto en el arduino.

Paso 3: ¿Cómo funciona?

En esta última parte, aprenderemos cómo se combinan estos componentes, cómo usar sus bibliotecas y cómo he estructurado mi código:

Primero, echemos un vistazo rápido a través del sensor y los métodos API de la biblioteca neopixel que usaremos

1. API de Neopixel de adafruit

Desde esta biblioteca usaremos los métodos que controlan el color del led individual y los aplicaremos

- incluir la biblioteca:

#incluir

- 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);

- inicializar

# típicamente dentro del bloque de configuración

configuración vacía () {strip.begin (); # tal vez algunas otras cosas aquí #…. }

- ilumine píxeles individuales y luego aplique todas las modificaciones a la tira (renderícela de alguna manera)

# configurar el píxel 0 para que sea rojo

strip.setPixelColor (0, strip. Color (255, 0, 0)); # configurar el píxel 1 para que sea verde strip.setPixelColor (1, strip. Color (0, 255, 0)); # configurar el píxel 2 para que sea azul strip.setPixelColor (2, strip. Color (0, 0 255)); strip.show ();

2. Sensor de gestos APDS 9960

Desde esta biblioteca usaremos la función "gesto de lectura". Esta función podrá distinguir entre comandos de izquierda a derecha, arriba-abajo, cerca-lejos. Aquí hay un truco, no vamos a pedir al sensor continuamente el último gesto percibido. La placa tiene la capacidad de "hacer ping" a través de una interrupción de que se ha encontrado un gesto.

- incluir la biblioteca, similar al neopixel

- declarar la biblioteca el pin de interrupción y la bandera de interrupción

#define APDS9960_INT 2

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

- inicializar la biblioteca, normalmente dentro de la función de configuración

configuración vacía ()

{# declarar el pin de interrupción como INPUT y adjuntarle una función pinMode (APDS9960_INT, INPUT); attachInterrupt (0, interruptRoutine, FALLING); if (apds.init () && apds.enableGestureSensor (true)) {Serial.println ("Inicialización APDS-9960 completa"); } else {Serial.println ("¡Algo salió mal durante la inicialización de APDS-9960!"); } # inicializar otras cosas tal vez}

- defina la función de interrupción, aquí estableceremos solo una bandera

void interruptRoutine () {

isr_flag = 1; }

- dentro de la función de bucle, verifique la bandera periódicamente para ver si se ha detectado un gesto

bucle vacío ()

{# verifique el indicador if (isr_flag == 1) {# si el indicador está establecido, elimine la interrupción, realice el procesamiento necesario dentro de la función handleGesture () # y luego restablezca el indicador y vuelva a conectar la interrupción detachInterrupt (0); handleGesture (); isr_flag = 0; attachInterrupt (0, interruptRoutine, FALLING); } # algún otro código aquí tal vez}

- define la función handleGesture () donde podemos pedir el último gesto

void handleGesture () {

# si no hay ningún gesto disponible, regrese, esto es solo una verificación segura si (! apds.isGestureAvailable ()) {return; } # lee el último gesto, compara con los conocidos e imprime un cambio de mensaje (apds.readGesture ()) {case DIR_UP: Serial.println ("UP"); rotura; case DIR_DOWN: Serial.println ("DOWN"); rotura; case DIR_LEFT: Serial.println ("IZQUIERDA"); rotura; case DIR_RIGHT: Serial.println ("DERECHA"); rotura; case DIR_FAR: Serial.println ("FAR"); rotura; }}

Ahora veamos todo el código en acción:

Así que he explicado la API base del sensor de gestos y el anillo de neopixel, ahora juntemos las cosas:

El algoritmo funciona así:

- inicializar las bibliotecas (ver el código anterior)

- crear una serie de intensidades de led llamadas "ledStates". Esta matriz contendrá 24 intensidades de led que se ordenan de manera descendente de 150 a 2

- dentro del bucle principal, verifique si el pin de interrupción se ha modificado, si es así, es hora de cambiar la animación o el color del led

- la función "handleGesture ()" comprueba el último gesto y llama a la función "toggleColor" para los gestos ARRIBA-ABAJO o establece una variable global "ledDirection" para los gestos IZQUIERDA - DERECHA

- la función "toggleColor ()" simplemente cambia una variable global llamada "colorSelection" con uno de los valores 0, 1, 2

- también dentro de la función de bucle principal otra función llamada "animateLeds ();" se llama. Esta función verifica si pasaron 100 milisegundos, y si es así, gira los leds usando la función "rotateLeds ()" y luego los vuelve a dibujar.

- el "rotateLeds ()" "rotará" los leds hacia adelante o hacia atrás mediante el uso de otra matriz llamada "intervalLedStates".

El "efecto" de rotación se verá así:

# después de la inicialización

{150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # después de que rotateLeds () se llame {0, 150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # después de que se vuelva a llamar a rotateLeds () {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

Para esto, primero crea la nueva matriz y copia las intensidades de led antiguas en las nuevas posiciones (incrementar la posición o decrementarla). Después de eso, sobrescribe la matriz "ledStates" con "intervalLedStates", por lo que el proceso continuará después de otros 100 milisegundos.

#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, NEOROL_PIXEDIN_Z) SparkFun_APDS9960 apds = SparkFun_APDS9960 (); unsigned long lastLedChangeTime = 0; ledDirection corto = 0; short 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; configuración vacía () {Serial.begin (9600); Serial.println ("Programa iniciado"); strip.begin (); pinMode (APDS9960_INT, ENTRADA); attachInterrupt (0, interruptRoutine, FALLING); if (apds.init () && apds.enableGestureSensor (true)) {Serial.println ("Inicialización APDS-9960 completa"); } else {Serial.println ("¡Algo salió mal durante la inicialización de APDS-9960!"); } lastLedChangeTime = millis (); Serial.println ("Inicia con éxito"); } bucle vacío () {if (isr_flag == 1) {detachInterrupt (0); handleGesture (); isr_flag = 0; attachInterrupt (0, interruptRoutine, FALLING); } animateLeds (); } void interruptRoutine () {isr_flag = 1; } / ** * Esto manejará los gestos del sensor APDS9960 * Los gestos hacia arriba y hacia abajo llamarán la función toggleColor * Los gestos hacia la izquierda y hacia la derecha cambiarán la animación LED * / void handleGesture () {if (! Apds.isGestureAvailable ()) {return; } switch (apds.readGesture ()) {case DIR_UP: Serial.println ("ARRIBA"); toggleColor (); rotura; case DIR_DOWN: Serial.println ("DOWN"); toggleColor (); rotura; caso DIR_LEFT: ledDirection = 1; Serial.println ("IZQUIERDA"); rotura; caso DIR_RIGHT: ledDirection = -1; Serial.println ("DERECHA"); rotura; caso DIR_FAR: ledDirection = 0; Serial.println ("FAR"); rotura; }} / ** * Cambiar el color actual de los leds * Cada vez que se llame a esta función cambiará el estado de los leds * / void toggleColor () {if (colorSelection == 0) {colorSelection = 1; } else if (colorSelection == 1) {colorSelection = 2; } más {colorSelection = 0; }} / ** * La animación se ejecutará después de LED_SPEED_STEP_INTERVAL millis * Primero se llama a la función rotateLeds, luego se establecen los colores de los leds usando 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 (); } / ** * Usando un arreglo secundario "IntermedioLedStates", las intensidades de los leds se animan * Primero, los valores de "ledStates" se copian en "IntermedioLedStates" así * vamos a decir que el arreglo "ledStates" es {100, 80, 60, 0, 0, 0} y ledDirection es 1 *, luego de que esta función se llame "ledStates", la matriz es {0, 100, 80, 60, 0, 0} simulando un efecto de rotación * / void rotateLeds () {byte intermedioLedStates [NUM_LEDS]; para (int i = 0; i <NUM_LEDS; i ++) {intervalLedStates = 0; } para (int i = 0; i <NUM_LEDS; i ++) {if (ledDirection == 1) {if (i == NUM_LEDS -1) {IntermedioLedStates [0] = ledStates ; } else {intermediosLedStates [i + 1] = ledStates ; }} else {if (i == 0) {IntermedioLedStates [NUM_LEDS - 1] = ledStates ; } else {intermediosLedStates [i - 1] = ledStates ; }}} para (int i = 0; i <NUM_LEDS; i ++) {ledStates = intervalLedStates ; }} uint32_t getColor (int intensidad) {switch (colorSelection) {caso 0: return strip. Color (intensidad, 0, 0); caso 1: tira de retorno. Color (0, intensidad, 0); predeterminado: return strip. Color (0, 0, intensidad); }}

Espero que hayas disfrutado esto, puedes usar la sección de comentarios para hacerme preguntas.

Recomendado: