Sommario:

Controllo di un anello LED Neopixel con un sensore di gesti: 3 passaggi (con immagini)
Controllo di un anello LED Neopixel con un sensore di gesti: 3 passaggi (con immagini)

Video: Controllo di un anello LED Neopixel con un sensore di gesti: 3 passaggi (con immagini)

Video: Controllo di un anello LED Neopixel con un sensore di gesti: 3 passaggi (con immagini)
Video: Usare VIA Pixetto con Arduino: una CAM per riconoscere oggetti, forme e colori con AI e ML. 2024, Dicembre
Anonim
Image
Image
Assemblaggio e caricamento
Assemblaggio e caricamento

In questo tutorial giocheremo con un sensore di gesti (APDS-9960) e un anello di neopixel per imparare a combinarli entrambi usando un Arduino UNO.

Il prodotto finale risponderà ai gesti sinistra - destra animando il movimento del led a destra oa sinistra e ai gesti su-giù cambiando il colore dei led.

Nei passaggi successivi, verrà presentata una breve panoramica dell'elenco delle parti e di come collegare i componenti. E poi esamineremo il codice passo dopo passo per imparare come funziona.

Passaggio 1: componenti

1. Arduino UNO

2. cavo USB

3. Sensore di gesti APDS9960 (https://www.sparkfun.com/products/12787)

4. Anello led neopixel a 24 led (https://www.adafruit.com/product/1586)

5. cavi breadboard maschio-femmina, maschio-maschio

6. tagliere

7. Alimentazione 5 V per l'anello led (sto usando una batteria da 4 indietro)

8. Per collegare l'anello neopixel alla breadboard dovrai saldare tre pin maschio: GND, PWR e pin di controllo. Per questo avrai bisogno di un saldatore e flusso

I componenti principali qui sono il sensore di gesti APDS-9960 e l'anello da 24 neopixel. Puoi cambiare diversi arduino, cavi di alimentazione USB e breadboard come desideri.

Passaggio 2: assemblaggio e caricamento

Assemblea

Prima di iniziare assicurati di avere tutti i componenti sul tuo tavolo. Avremo dei bei passaggi da seguire:). Ho anche allegato lo schema di Fritzing come immagine e anche in formato Fritzing.

1. Saldare 3 pin maschio all'anello neopixel (GND, PWR, pin di controllo)

2. attaccare l'anello neopixel alla breadboard

3. collegare il sensore APDS9960 alla breadboard

4. collegare le masse: pacco batterie, arduino UNO, APDS9960 e neopixel alla massa della breadboard

5. collegare l'alimentazione: arduino UNO 3V al pin di alimentazione APDS9960, neopixel alla batteria

6. collegare il pin di controllo neopixel al pin arduino D6

7. collegare SDA e SCL dell'APDS9960 rispettivamente all'A4 e all'A5

8. collegare il pin di interruzione APDS9960 all'arduino D2

Caricamento del codice

Prima di tutto dovrai scaricare e installare le librerie arduino necessarie:

1. Libreria di anelli Neopixel:

2. Libreria di sensori di gesti:

Se non sai come installare le librerie arduino, dai un'occhiata a questo tutorial.

Dopo aver scaricato e installato le librerie sopra, puoi clonare o scaricare il mio repository arduino che si trova qui: https://github.com/danionescu0/arduino, e useremo questo sketch: https://github.com/danionescu0 /arduino/tree/master/projects/neopixel_ring_gestures

Nella prossima sezione inserirò il codice direttamente in questo tutorial, quindi se vuoi puoi copiarlo e incollarlo da lì.

Infine collega l'arduino al computer usando il cavo usb, inserisci le batterie da 1,5 V nel pacco batterie e carica lo schizzo nell'arduino.

Passaggio 3: come funziona?

In quest'ultima parte impareremo come questi componenti sono combinati insieme, come usare le loro librerie e come ho strutturato il mio codice:

Per prima cosa diamo una rapida occhiata al sensore e ai metodi API della libreria neopixel che useremo

1. API Neopixel di adafruit

Da questa libreria utilizzeremo i metodi che controllano il colore dei singoli led e li applicheremo

- includere la biblioteca:

#includere

- dichiarare la biblioteca

#define NEOPIXED_CONTROL_PIN 6

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

- inizializzare

#tipicamente all'interno del blocco di installazione

void setup() { strip.begin(); # forse qualche altra cosa qui # …. }

- illumina i singoli pixel quindi applica tutte le modifiche alla striscia (renderla in un certo senso)

# imposta il pixel 0 come rosso

strip.setPixelColor(0, strip. Color(255, 0, 0)); # imposta il pixel 1 come verde strip.setPixelColor(1, strip. Color(0, 255, 0)); # imposta il pixel 2 come blu strip.setPixelColor(2, strip. Color(0, 0 255)); strip.show();

2. Sensore di gesti APDS 9960

Da questa libreria utilizzeremo la funzione "gesto di lettura". Questa funzione sarà in grado di distinguere tra comandi sinistra-destra, su-giù, vicino-lontano. C'è un trucco qui, non chiederemo continuamente al sensore l'ultimo gesto percepito. La scheda ha la capacità di "pingare" attraverso un'interruzione che è stato trovato un gesto.

- includi la libreria, simile al neopixel

- dichiarare alla libreria il pin di interruzione e il flag di interruzione

#define APDS9960_INT 2

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

- inizializza la libreria, tipicamente all'interno della funzione setup

configurazione nulla()

{ # dichiara il pin di interrupt come INPUT e allega una funzione ad esso pinMode(APDS9960_INT, INPUT); attachInterrupt(0, interruptRoutine, FALLING); if (apds.init() && apds.enableGestureSensor(true)) { Serial.println("inizializzazione APDS-9960 completata"); } else { Serial.println("Qualcosa è andato storto durante l'inizializzazione di APDS-9960!"); } # inizializza altre cose forse }

- definire la funzione di interruzione, qui imposteremo solo un flag

void interruptRoutine() {

isr_flag = 1; }

- all'interno della funzione loop controlla periodicamente il flag per vedere se è stato rilevato un gesto

ciclo vuoto()

{ # controlla il flag if(isr_flag == 1) { # se il flag è impostato, rimuove l'interrupt, effettua l'elaborazione necessaria all'interno della funzione handleGesture() # e poi resetta il flag e riattacca l'interrupt detachInterrupt(0); handleGesture(); isr_flag = 0; attachInterrupt(0, interruptRoutine, FALLING); } # qualche altro codice qui forse }

- definire la funzione handleGesture() dove possiamo chiedere l'ultimo gesto

void handleGesture() {

# se nessun gesto è disponibile return, questo è solo un controllo sicuro if (!apds.isGestureAvailable()) { return; } # legge l'ultimo gesto, confronta con quelli conosciuti e stampa un messaggio switch (apds.readGesture()) { case DIR_UP: Serial.println("UP"); rottura; case DIR_DOWN: Serial.println("DOWN"); rottura; case DIR_LEFT: Serial.println("LEFT"); rottura; case DIR_RIGHT: Serial.println("RIGHT"); rottura; case DIR_FAR: Serial.println("FAR"); rottura; } }

Ora vediamo l'intero codice in azione:

Quindi ho spiegato l'API di base del sensore di gesti e l'anello neopixel, ora mettiamo insieme le cose:

L'algoritmo funziona così:

- inizializzare le librerie (vedi codice sopra)

- creare una serie di intensità led chiamate "ledStates". Questo array conterrà 24 intensità di led che sono disposte in modo decrescente da 150 a 2

- all'interno del ciclo principale controlla se il pin di interrupt è stato modificato se è così è il momento di cambiare l'animazione o il colore del led

- la funzione "handleGesture()" controlla l'ultimo gesto e chiama la funzione "toggleColor" per i gesti SU - GI o imposta una variabile globale "ledDirection" per i gesti SINISTRA - DESTRA

- la funzione "toggleColor()" cambia semplicemente una variabile globale denominata "colorSelection" con uno dei valori 0, 1, 2

- anche all'interno della funzione del ciclo principale un'altra funzione denominata "animateLeds();" è chiamato. Questa funzione controlla se sono trascorsi 100 millisecondi, e in tal caso ruota i led utilizzando la funzione "rotateLeds()" e poi li ridisegna

- il "rotateLeds()" "ruoterà" i led in avanti o indietro utilizzando un altro array chiamato "intermediateLedStates".

L'"effetto" di rotazione sarà simile a questo:

# dopo l'inizializzazione

{150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # dopo che rotateLeds() viene chiamato {0, 150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # dopo che rotateLeds() è stato chiamato di nuovo {0, 0, 150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # e così via

Per questo prima crea il nuovo array e copia le vecchie intensità dei led sulle nuove posizioni (incrementa la posizione o decrementala). Dopodiché sovrascrive l'array "ledStates" con "intermediateLedStates" in modo che il processo continui dopo altri 100 millisecondi.

#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 + NEO_RB); SparkFun_APDS9960 apds = SparkFun_APDS9960(); unsigned long lastLedChangeTime = 0; ledDirection breve = 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 flag_isr = 0; void setup() { Serial.begin(9600); Serial.println("Programma avviato"); strip.begin(); pinMode(APDS9960_INT, INPUT); attachInterrupt(0, interruptRoutine, FALLING); if (apds.init() && apds.enableGestureSensor(true)) { Serial.println("APDS-9960 inizializzazione completata"); } else { Serial.println("Qualcosa è andato storto durante l'inizializzazione di APDS-9960!"); } lastLedChangeTime = millis(); Serial.println("Inizia con successo"); } void loop() { if(isr_flag == 1) { detachInterrupt(0); handleGesture(); isr_flag = 0; attachInterrupt(0, interruptRoutine, FALLING); } animateLed(); } void interruptRoutine() { flag_isr = 1; } /** * Questo gestirà i gesti dal sensore APDS9960 * I gesti Su e Giù chiameranno la funzione toggleColor * I gesti sinistro e destro cambieranno l'animazione del led */ void handleGesture() { if (!apds.isGestureAvailable()) { return; } switch (apds.readGesture()) { case DIR_UP: Serial.println("UP"); toggleColor(); rottura; case DIR_DOWN: Serial.println("DOWN"); toggleColor(); rottura; caso DIR_LEFT: ledDirection = 1; Serial.println("SINISTRA"); rottura; caso DIR_RIGHT: ledDirection = -1; Serial.println("DESTRA"); rottura; caso DIR_FAR: ledDirection = 0; Serial.println("FAR"); rottura; } } /** * Cambia il colore dei led correnti * Ogni volta che questa funzione viene chiamata cambierà lo stato dei led */ void toggleColor() { if (colorSelection == 0) { colorSelection = 1; } else if (colorSelection == 1) { colorSelection = 2; } else { colorSelection = 0; } } /** * L'animazione verrà eseguita dopo LED_SPEED_STEP_INTERVAL millis * Prima viene chiamata la funzione rotateLeds, quindi i colori dei led vengono impostati utilizzando la strip api */ void animateLeds() { if (millis() - lastLedChangeTime < LED_SPEED_STEP_INTERVAL) { return; } ruotareLed(); for (int i=0; i < NUM_LEDS; i++) { strip.setPixelColor(i, getColor(ledStates)); strip.show(); } lastLedChangeTime = millis(); } /** * Usando un array secondario "intermediateLedStates", le intensità dei led sono animate * Prima i valori di "ledStates" vengono copiati su "intermediateLedStates" in questo modo * poniamo che l'array "ledStates" sia {100, 80, 60, 0, 0, 0} e ledDirection è 1 * quindi dopo che questa funzione viene chiamata "ledStates" l'array è {0, 100, 80, 60, 0, 0} simulando un effetto di rotazione */ void rotateLeds() { byte intermediLedStates[NUM_LEDS]; for (int i=0; i < NUM_LEDS; i++) { statoLedintermedi = 0; } for (int i=0; i < NUM_LEDS; i++) { if (ledDirection == 1) { if (i == NUM_LEDS -1) { intermediLedStates[0] = ledStates; } else { StatiLedIntermedi[i + 1] = StatiStati; } } else { if (i == 0) { statiLedintermedi[NUM_LEDS - 1] = statiLED; } else { statiLedintermedi[i - 1] = StatiStati; } } } for (int i=0; i < NUM_LEDS; i++) { ledStates = intermediLedStates; } } uint32_t getColor(int intensive) { switch (colorSelection) { case 0: return strip. Color(intensity, 0, 0); caso 1: striscia di ritorno. Colore (0, intensità, 0); default: return strip. Color(0, 0, intensità); } }

Spero che ti sia piaciuto, puoi usare la sezione commenti per farmi domande.

Consigliato: