Giroscópio divertido com anel de neopixel: 4 etapas (com fotos)
Giroscópio divertido com anel de neopixel: 4 etapas (com fotos)
Anonim
Image
Image

Neste tutorial usaremos o giroscópio MPU6050, um anel de neopixel e um arduino para construir um dispositivo que acende os led's correspondentes ao ângulo de inclinação.

Este é um projeto simples e divertido e será montado em uma placa de ensaio. Se você seguir os passos, construirá o que viu no vídeo. É um bom tutorial para aprender sobre giroscópio e anel de neopixel.

Estou construindo este tutorial por causa do interesse que vi no meu primeiro instructable aqui (Gyroscope Led Control With Arduino). Neste instrutível, substituí o led simples por um anel de neopixel. O anel é mais simples de usar através de uma biblioteca Adafruit e é definitivamente mais espetacular.

Então, se você tem esses componentes espalhados, esta é uma ótima maneira de usá-los. Vou tentar guiá-lo passo a passo pela construção do dispositivo e também explicar como ele funciona na última etapa.

Etapa 1: Coisas necessárias

conjunto
conjunto

Peças

1. Arduino pro mini 328p (eBay) 2 $

2. Placa de ensaio

3. Giroscópio MPU6050 (eBay) 1,2 $

4. 24 anel led de neopixel (Adafruit) 17 $

5. 4 baterias AA com 4 baterias

6. Cabos de ligação em U (opcional). Usei esses cabos jumper porque eles ficam melhores na placa de ensaio e os leds são mais visíveis dessa forma. Você pode encontrar uma caixa de 140 no ebay por cerca de 4 $. Se você não tiver esses cabos, pode substituí-los por fios duplos.

Ferramentas:

1. USB para adaptador FTDI serial FT232RL para programar o arduino pro mini

2. Arduino IDE

Habilidades: 1. Soldando, verifique este tutorial

3. Programação básica do Arduino, este tutorial pode ser útil

Etapa 2: Montagem

conjunto
conjunto

Anexei o esquema fritzing no formato fzz e uma imagem dele para facilitar a visualização das conexões

1. Você precisa soldar 3 pinos machos na parte de trás do anel de neopixel como mostrado na imagem

- solde o pino positivo

- soldar o solo

- soldar o pino de entrada de dados

2. Em seguida, o suporte da bateria 4x deve ter uma maneira de se conectar à placa de ensaio, uma solução fácil é soldar dois fios duplos machos em seus terminais.

3. Prepare a placa de ensaio.

- coloque o anel de neopixel, microcontrolador e giroscópio na placa de ensaio como na imagem

- coloque todos os fios negativos: para o microcontrolador, anel de neopixel, giroscópio

- coloque todos os fios positivos: para o microcontrolador, anel de neopixel, giroscópio

- coloque todos os fios de dados:

* SDA e SCL do para o microcontrolador para o giroscópio

* pino D6 do microcontrolador para o anel de neopixel

- verifique todas as conexões antes de ligar

- opcionalmente, usando fita adesiva, prenda a bateria na parte de trás do bradboard para prendê-la no lugar e torná-la mais portátil

Etapa 3: O Código e Calibração

Primeiro você precisa baixar e instalar duas bibliotecas:

1. Biblioteca de neopixel Adafruit para controlar o neopixel

2. Biblioteca MPU6050 para o giroscópio

3. Fonte da biblioteca I2CDev

São duas grandes bibliotecas que farão o trabalho pesado!

Mais detalhes sobre os neopixels aqui

Em seguida, baixe e instale minha biblioteca aqui ou copie abaixo:

#include "I2Cdev.h"

#include #include "MPU6050_6Axis_MotionApps20.h" #include "Wire.h" #define NEOPIXED_CONTROL_PIN 6 #define NUM_LEDS 24 const int MAX_ANGLE = 45; const int LED_OFFSET = 12; MPU6050 mpu; Tira Adafruit_NeoPixel = Adafruit_NeoPixel (NUM_LEDS, NEOPIXED_CONTROL_PIN, NEO_RBG + NEO_KHZ800); não assinado long lastPrintTime = 0; inicialização bool = falso; // define verdadeiro se a inicialização DMP foi bem-sucedida uint8_t mpuIntStatus; // mantém o byte de status de interrupção real do MPU uint8_t devStatus; // retorna o status após cada operação do dispositivo (0 = sucesso,! 0 = erro) uint16_t packetSize; // tamanho do pacote DMP esperado (o padrão é 42 bytes) uint16_t fifoCount; // contagem de todos os bytes atualmente em FIFO uint8_t fifoBuffer [64]; // buffer de armazenamento FIFO Quaternion q; // [w, x, y, z] contêiner de quatérnio VectorFloat gravity; // [x, y, z] vetor de gravidade float ypr [3]; // [yaw, pitch, roll] yaw / pitch / roll container e vetor de gravidade volátil bool mpuInterrupt = false; // indica se o pino de interrupção MPU foi alto

void setup ()

{Serial.begin (9600); Serial.println ("Programa iniciado"); inicialização = inicializarGiroscópio (); strip.begin (); } void loop () {if (! inicialização) {return; } mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus (); fifoCount = mpu.getFIFOCount (); if (hasFifoOverflown (mpuIntStatus, fifoCount)) {mpu.resetFIFO (); Retorna; } if (mpuIntStatus & 0x02) {while (fifoCount <packetSize) {fifoCount = mpu.getFIFOCount (); } mpu.getFIFOBytes (fifoBuffer, packetSize); fifoCount - = tamanho do pacote; mpu.dmpGetQuaternion (& q, fifoBuffer); mpu.dmpGetGravity (& gravity, & q); mpu.dmpGetYawPitchRoll (ypr, & q, & gravity); redrawLeds (ypr [0] * 180 / M_PI, ypr [1] * 180 / M_PI, ypr [2] * 180 / M_PI); }} boolean hasFifoOverflown (int mpuIntStatus, int fifoCount) {return mpuIntStatus & 0x10 || fifoCount == 1024; } void redrawLeds (int x, int y, int z) {x = constrain (x, -1 * MAX_ANGLE, MAX_ANGLE); y = restrição (y, -1 * MAX_ANGLE, MAX_ANGLE); if (y 0) {lightLeds (y, z, 0, 5, 0, 89); } else if (y <0 e z 0 e z 0 e z> 0) {lightLeds (y, z, 20, 24, 89, 0); }} void lightLeds (int x, int y, int fromLedPosition, int toLedPosition, int fromAngle, int toAngle) {ângulo duplo = (atan ((duplo) abs (x) / (duplo) abs (y)) * 4068) / 71; int ledNr = mapa (ângulo, deAngle, toAngle, fromLedPosition, toLedPosition); printDebug (x, y, ledNr, ângulo); uint32_t color; para (int i = 0; posição i + LED_OFFSET) {posição de retorno + LED_OFFSET; } posição de retorno + LED_OFFSET - NUM_LEDS; } void printDebug (int y, int z, int lightLed, int ângulo) {if (millis () - lastPrintTime <500) {return; } Serial.print ("a ="); Serial.print (ângulo); Serial.print (";"); Serial.print ("ll ="); Serial.print (lightLed); Serial.print (";"); Serial.print ("y ="); Serial.print (y); Serial.print (";"); Serial.print ("z ="); Serial.print (z); Serial.println (";"); lastPrintTime = millis (); } bool initializeGyroscope () {Wire.begin (); TWBR = 24; mpu.initialize (); Serial.println (mpu.testConnection ()? F ("MPU6050 conexão bem-sucedida"): F ("MPU6050 conexão falhou")); Serial.println (F ("Inicializando DMP…")); devStatus = mpu.dmpInitialize (); mpu.setXGyroOffset (220); mpu.setYGyroOffset (76); mpu.setZGyroOffset (-85); mpu.setZAccelOffset (1788); if (devStatus! = 0) {Serial.print (F ("Falha na inicialização do DMP (código")); Serial.println (devStatus); retornar falso;} mpu.setDMPEnabled (true); Serial.println (F ("Ativando detecção de interrupção (interrupção externa do Arduino 0)… ")); attachInterrupt (0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus (); Serial.println (F (" DMP pronto! Aguardando a primeira interrupção… ")); Tamanho do pacote = mpu.dmpGetFIFOPacketSize (); retornar verdadeiro;} void dmpDataReady () {mpuInterrupt = true;}

Faça upload do código:

Usando o adaptador FTDI, faça upload do código para o arduino.

Conecte a fonte de alimentação (baterias)

Calibração:

A coisa mais importante a calibrar aqui é a constante "LED_OFFSET". No meu exemplo é 12. Você precisa ajustar isso de 0 a 23 para que, após ligar a placa, o led acenda na direção em que você inclinar a placa.

Se você quiser saber mais detalhes sobre como funciona, dê uma olhada na última etapa

Etapa 4: como funciona (opcional)

Como funciona (opcional)
Como funciona (opcional)

Primeiro algumas informações sobre o giroscópio MPU6050. Este é um giroscópio MEMS (MEMS significa sistemas microeletromecânicos).

Cada tipo de giroscópio MEMs tem alguma forma de componente oscilante de onde a accleração e, portanto, a mudança de direção podem ser detectadas. Isso ocorre porque, de acordo com a lei de conservação do movimento, um objeto vibrando gosta de continuar vibrando no mesmo plano, e qualquer desvio vibracional pode ser usado para derivar uma mudança de direção.

O giroscópio também contém um microcontrolador próprio para calcular o roll, pitch e yaw por meio de algumas matemáticas sofisticadas.

Mas os dados brutos do giroscópio sofrem de ruído e deriva, então usamos uma biblioteca externa para suavizar as coisas e nos fornecer dados utilizáveis limpos.

Os Neopixel são leds RGB endereçáveis individualmente e encadeados em faixas e anéis. Eles funcionam em 5V e contêm seus próprios circuitos, então você só precisa alimentar os neopixels e se comunicar com eles usando a linha de dados. A comunicação é feita com uma única linha de dados contendo relógio e dados (mais detalhes aqui). Adafruit fornece uma biblioteca limpa para interagir com os anéis de neopixel.

O código

Dentro da função l oop (), a biblioteca MPU6050_6Axis_MotionApps20 é chamada. Quando a biblioteca tem novos dados do giroscópio, ela chama redrawLeds (x, y, z) com 3 argumentos que representam yaw, pitch e roll

Inside redrawLeds ():

- estamos nos concentrando em dois eixos: y, z

- estamos restringindo ambos os eixos de -MAX_ANGLE a + MAX_ANGLE, definimos o ângulo máximo para 45 e é alterável

- estamos dividindo 360 graus em 4 quadrantes e chamamos as funções lightLeds () para cada um da seguinte maneira:

* y negativo, z positivo no primeiro quadrante controlará os leds de 0 a 5, o ângulo será de 0 a 89

* y negativo, o segundo quadrante z negativo controla os leds de 6 a 12, o ângulo será de 89 a 0

* … etc

- dentro da função lightLeds

* estou calculando um ângulo com base nos dois eixos usando arco tangente (verifique a imagem anexa)

* Estou calculando o que levou a mostrar usando a função de mapa do Arduino

* Estou redefinindo a faixa de led, exceto dois led's, o que corresponde à posição led que calculei antes e uma posição led antes (para mostrar um efeito de desvanecimento)

* Estou usando uma função chamada normalizeLedPosition () para levar em consideração a calibração do neopixel. A calibração é útil porque o anel de neopixel pode ser girado conforme desejado e deve estar alinhado com o giroscópio

* também estou imprimindo o eixo de reboque, o led tem luz e o ângulo

A matemática

Anexei uma imagem com o anel led e a função trigonométrica usada para determinar o ângulo.