Índice:

Controle de um anel LED de neopixel com um sensor de gestos: 3 etapas (com imagens)
Controle de um anel LED de neopixel com um sensor de gestos: 3 etapas (com imagens)

Vídeo: Controle de um anel LED de neopixel com um sensor de gestos: 3 etapas (com imagens)

Vídeo: Controle de um anel LED de neopixel com um sensor de gestos: 3 etapas (com imagens)
Vídeo: Adafruit Neopixel ring simulation with arduino and tinkercad 2024, Novembro
Anonim
Image
Image
Montagem e upload
Montagem e upload

Neste tutorial, vamos brincar com um sensor de gestos (APDS-9960) e um anel de neopixel para aprender como combiná-los usando um Arduino UNO.

O produto final responderá aos gestos esquerda - direita, animando o movimento do led para a direita ou esquerda, e aos gestos para cima e para baixo, alterando a cor dos leds.

Nas próximas etapas, você terá uma visão geral resumida da lista de peças e como conectar os componentes. E então revisaremos o código passo a passo para aprender como ele funciona.

Etapa 1: Componentes

1. Arduino UNO

2. cabo usb

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

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

5. cabos de placa de ensaio macho-fêmea, macho-macho

6. breadboard

7. Fonte de alimentação de 5 V para o anel led (estou usando uma bateria traseira de 4)

8. Para conectar o anel de neopixel à placa de ensaio, você precisará soldar três pinos machos nele: GND, PWR e pino de controle. Para isso, você precisará de um ferro de solda e fluxo

Os principais componentes aqui são o sensor de gestos APDS-9960 e o anel de 24 neopixels. Você pode alternar entre diferentes arduinos, fontes de alimentação de cabos USB e placas de ensaio como desejar.

Etapa 2: Montagem e upload

conjunto

Antes de começar, certifique-se de ter todos os componentes em sua mesa. Teremos alguns bons passos a seguir:). Também anexei o esquema Fritzing como uma imagem e também em formato fritzing.

1. Solde 3 pinos machos no anel de neopixel (GND, PWR, pino de controle)

2. anexe o anel de neopixel à placa de ensaio

3. conecte o sensor APDS9960 à placa de ensaio

4. conecte os aterramentos: bateria, arduino UNO, APDS9960 e neopixel ao aterramento da placa de ensaio

5. conecte a alimentação: arduino UNO 3V ao pino de alimentação APDS9960, neopixel à alimentação da bateria

6. conecte o pino de controle neopixel ao pino Arduino D6

7. conecte SDA e SCL do APDS9960 ao A4 e A5 respectivamente

8. conecte o pino de interrupção APDS9960 ao arduino D2

Upload de código

Em primeiro lugar, você precisará baixar e instalar as bibliotecas arduino necessárias:

1. Biblioteca de anéis de Neopixel:

2. Biblioteca do sensor de gestos:

Se você não sabe como instalar as bibliotecas do Arduino, verifique este tutorial.

Depois de baixar e instalar as bibliotecas acima, você pode clonar ou baixar meu repositório arduino localizado aqui: https://github.com/danionescu0/arduino, e usaremos este esboço: https://github.com/danionescu0 / arduino / tree / master / projects / neopixel_ring_gestures

Na próxima seção, incorporarei o código diretamente a este tutorial, para que, se desejar, você possa copiá-lo e colá-lo de lá.

Por fim, conecte o arduino ao computador usando o cabo USB, coloque baterias de 1,5 V na bateria e carregue o esboço no arduino.

Etapa 3: Como funciona?

Nesta última parte, aprenderemos como esses componentes são combinados, como usar suas bibliotecas e como estruturei meu código:

Primeiro, vamos dar uma olhada rápida no sensor e nos métodos da API da biblioteca neopixel que usaremos

1. Neopixel API da adafruit

A partir desta biblioteca, estaremos usando os métodos que controlam a cor do led individual e os aplicamos

- incluir a biblioteca:

#incluir

- declarar a 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

#tipicamente dentro do bloco de configuração

void setup () {strip.begin (); # talvez algumas outras coisas aqui #…. }

- ilumine pixels individuais e, em seguida, aplique todas as modificações à faixa (renderize de uma forma)

# configurar o pixel 0 para ser vermelho

strip.setPixelColor (0, strip. Color (255, 0, 0)); # configurar o pixel 1 para ser strip.setPixelColor (1, strip. Color (0, 255, 0)); # configurar o pixel 2 para ser azul strip.setPixelColor (2, strip. Color (0, 0 255)); strip.show ();

2. Sensor de gestos APDS 9960

Nesta biblioteca, usaremos a função "gesto de leitura". Esta função será capaz de distinguir entre comandos esquerda-direita, cima-baixo e perto. Há um truque aqui, não vamos pedir ao sensor continuamente o último gesto percebido. O conselho tem a capacidade de "pingar" por meio de uma interrupção de que um gesto foi encontrado.

- inclui a biblioteca, semelhante ao neopixel

- declara a biblioteca como o pino de interrupção e o sinalizador de interrupção

#define APDS9960_INT 2

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

- inicializar a biblioteca, normalmente dentro da função de configuração

void setup ()

{# declara o pino de interrupção como INPUT e anexa uma função a ele pinMode (APDS9960_INT, INPUT); attachInterrupt (0, interruptRoutine, FALLING); if (apds.init () && apds.enableGestureSensor (true)) {Serial.println ("inicialização do APDS-9960 concluída"); } else {Serial.println ("Algo deu errado durante a inicialização do APDS-9960!"); } # inicializar outras coisas talvez}

- definir a função de interrupção, aqui vamos definir apenas um sinalizador

void interruptRoutine () {

isr_flag = 1; }

- dentro da função de loop, verifique a bandeira periodicamente para ver se um gesto foi detectado

void loop ()

{# verifique o sinalizador if (isr_flag == 1) {# se o sinalizador estiver definido, remova a interrupção, faça o processamento necessário dentro da função handleGesture () # e então redefina o sinalizador e reconecte a interrupção detachInterrupt (0); handleGesture (); isr_flag = 0; attachInterrupt (0, interruptRoutine, FALLING); } # algum outro código aqui, talvez}

- definir a função handleGesture () onde podemos pedir o último gesto

void handleGesture () {

# se nenhum gesto estiver disponível, retornar, esta é apenas uma verificação segura if (! apds.isGestureAvailable ()) {return; } # lê o último gesto, compara com os conhecidos e imprime uma troca de mensagem (apds.readGesture ()) {case DIR_UP: Serial.println ("UP"); pausa; case DIR_DOWN: Serial.println ("DOWN"); pausa; case DIR_LEFT: Serial.println ("LEFT"); pausa; case DIR_RIGHT: Serial.println ("RIGHT"); pausa; case DIR_FAR: Serial.println ("FAR"); pausa; }}

Agora vamos ver todo o código em ação:

Então, eu expliquei a API base do sensor de gesto e do anel de neopixel, agora vamos juntar as coisas:

O algoritmo funciona assim:

- inicializar as bibliotecas (veja o código acima)

- crie um conjunto de intensidades de led denominado "ledStates". Esta matriz conterá 24 intensidades de led que são dispostas de forma descendente de 150 a 2

- dentro do loop principal, verifique se o pino de interrupção foi modificado, então é hora de mudar a animação ou cor do led

- a função "handleGesture ()" verifica o último gesto e chama a função "toggleColor" para gestos UP -DOWN ou define uma variável global "ledDirection" para gestos LEFT - RIGHT

- a função "toggleColor ()" simplesmente muda uma variável global chamada "colorSelection" com um dos valores 0, 1, 2

- também dentro da função de loop principal outra função chamada "animateLeds ();" é chamado. Esta função verifica se passaram 100 milissegundos e, em caso afirmativo, gira os leds usando a função "rotateLeds ()" e, em seguida, os redesenha

- o "rotateLeds ()" irá "girar" os leds para frente ou para trás usando outro array chamado "intermediárioLedStates".

O "efeito" de rotação será semelhante a este:

# após a inicialização

{150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # após rotateLeds () é chamado {0, 150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # após rotateLeds () ser chamado novamente {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 assim por diante

Para isso, primeiro cria a nova matriz e copia as intensidades do led antigo nas novas posições (aumente a posição ou diminua-a). Depois disso, ele sobrescreve a matriz "ledStates" pelos "intermediáriosLedStates" para que o processo continue após outros 100 milissegundos.

#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) SparkFun_APDS9960 apds = SparkFun_APDS9960 (); não assinado long lastLedChangeTime = 0; curto ledDirection = 0; seleção de cor 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; void setup () {Serial.begin (9600); Serial.println ("Programa iniciado"); strip.begin (); pinMode (APDS9960_INT, INPUT); attachInterrupt (0, interruptRoutine, FALLING); if (apds.init () && apds.enableGestureSensor (true)) {Serial.println ("inicialização do APDS-9960 concluída"); } else {Serial.println ("Algo deu errado durante a inicialização do APDS-9960!"); } lastLedChangeTime = millis (); Serial.println ("Init com sucesso"); } void loop () {if (isr_flag == 1) {detachInterrupt (0); handleGesture (); isr_flag = 0; attachInterrupt (0, interruptRoutine, FALLING); } animateLeds (); } void interruptRoutine () {isr_flag = 1; } / ** * Isso controlará os gestos do sensor APDS9960 * Os gestos para cima e para baixo chamarão a função toggleColor * Os gestos para a esquerda e para a direita mudarão a animação do led * / void handleGesture () {if (! Apds.isGestureAvailable ()) {return; } switch (apds.readGesture ()) {case DIR_UP: Serial.println ("UP"); toggleColor (); pausa; case DIR_DOWN: Serial.println ("DOWN"); toggleColor (); pausa; caso DIR_LEFT: ledDirection = 1; Serial.println ("LEFT"); pausa; case DIR_RIGHT: ledDirection = -1; Serial.println ("DIREITO"); pausa; caso DIR_FAR: ledDirection = 0; Serial.println ("FAR"); pausa; }} / ** * Alterar a cor atual dos leds * Cada vez que esta função é chamada mudará o estado dos leds * / void toggleColor () {if (colorSelection == 0) {colorSelection = 1; } else if (colorSelection == 1) {colorSelection = 2; } else {colorSelection = 0; }} / ** * A animação será executada após LED_SPEED_STEP_INTERVAL milis * Primeiro a função rotateLeds é chamada, então as cores dos leds são definidas usando a strip api * / void animateLeds () {if (millis () - lastLedChangeTime <LED_SPEED_STEP_INTERVAL) {retornar; } rotateLeds (); para (int i = 0; i <NUM_LEDS; i ++) {strip.setPixelColor (i, getColor (ledStates )); strip.show (); } lastLedChangeTime = millis (); } / ** * Usando uma matriz secundária "intermediáriosLedStates", as intensidades de leds são animadas * Primeiro, os valores de "ledStates" são copiados em "intermediáriosLedStates" assim * vamos sentar a matriz "ledStates" é {100, 80, 60, 0, 0, 0} e o ledDirection é 1 * então, após esta função ser chamada de "ledStates", a matriz é {0, 100, 80, 60, 0, 0} simulando um efeito de rotação * / void rotateLeds () {byte intermediárioLedStates [NUM_LEDS]; para (int i = 0; i <NUM_LEDS; i ++) {intermediárioLedStates = 0; } para (int i = 0; i <NUM_LEDS; i ++) {if (ledDirection == 1) {if (i == NUM_LEDS -1) {intermediárioLedStates [0] = ledStates ; } else {intermediárioLedStates [i + 1] = ledStates ; }} else {if (i == 0) {intermediárioLedStates [NUM_LEDS - 1] = ledStates ; } else {intermediárioLedStates [i - 1] = ledStates ; }}} para (int i = 0; i <NUM_LEDS; i ++) {ledStates = intermediárioLedStates ; }} uint32_t getColor (int intensidade) {switch (colorSelection) {case 0: return strip. Color (intensidade, 0, 0); caso 1: retorna strip. Color (0, intensidade, 0); padrão: retorna strip. Color (0, 0, intensidade); }}

Espero que tenham gostado, você pode usar a seção de comentários para me fazer perguntas.

Recomendado: