Tabla de contenido:

Diversión con giroscopio con anillo Neopixel: 4 pasos (con imágenes)
Diversión con giroscopio con anillo Neopixel: 4 pasos (con imágenes)

Video: Diversión con giroscopio con anillo Neopixel: 4 pasos (con imágenes)

Video: Diversión con giroscopio con anillo Neopixel: 4 pasos (con imágenes)
Video: Arduino Unboxing: Self-Balancing Robot Kit ELEGOO Tumbller 2024, Noviembre
Anonim
Image
Image

En este tutorial usaremos el giroscopio MPU6050, un anillo de neopixel y un arduino para construir un dispositivo que encienda los leds correspondientes al ángulo de inclinación.

Este es un proyecto simple y divertido y se ensamblará en una placa de pruebas. Si sigue los pasos, construirá lo que vio en el video. Es un buen tutorial para aprender sobre el giroscopio y el anillo de neopixel.

Estoy construyendo este tutorial debido al interés que vi en mi primer instructable aquí (Gyroscope Led Control With Arduino). En este instructivo, reemplacé los leds simples con un anillo de neopixel. El anillo es más simple de usar a través de una biblioteca de Adafruit y definitivamente es más espectacular.

Entonces, si tiene estos componentes por ahí, esta es una excelente manera de hacer uso de ellos, intentaré guiarlo paso a paso en la construcción del dispositivo y también explicar cómo funciona en el último paso.

Paso 1: Cosas necesarias

Montaje
Montaje

Partes

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

2. Tablero de pruebas

3. Giroscopio MPU6050 (eBay) 1,2 $

4. 24 anillo led neopixel (Adafruit) 17 $

5. Paquete de 4 pilas AA con 4 pilas

6. Cables de puente en forma de U (opcional). He usado estos cables de puente porque se ven mejor en la placa de pruebas y los leds son más visibles de esta manera. Puede encontrar una caja de 140 en eBay a unos 4 $. Si no tiene estos cables, puede reemplazarlos con cables dupont.

Instrumentos:

1. Adaptador FTDI FT232RL de USB a serie para programar el arduino pro mini

2. IDE de Arduino

Habilidades: 1. Soldadura, consulte este tutorial

3. Programación básica de arduino, este tutorial puede ser útil

Paso 2: Montaje

Montaje
Montaje

Adjunté el esquema de fritzing en formato fzz y una imagen del mismo para una fácil visualización de las conexiones.

1. Necesita soldar 3 pines macho en la parte posterior del anillo de neopixel como se muestra en la imagen.

- soldar el pin positivo

- soldar el suelo

- soldar el pin de entrada de datos

2. Luego, el soporte de la batería 4x debe tener una forma de conectarse a la placa de prueba, una solución fácil es soldar dos cables dupont macho a sus terminales.

3. Prepare la placa de pruebas.

- coloque el anillo de neopixel, el microcontrolador y el giroscopio en el tablero como en la imagen

- coloque todos los cables negativos: al microcontrolador, anillo neopixel, giroscopio

- coloque todos los cables positivos: al microcontrolador, anillo neopixel, giroscopio

- coloque todos los cables de datos:

* SDA y SCL del microcontrolador al giroscopio

* pin D6 del microcontrolador al anillo neopixel

- revise todas las conexiones antes de encender

- Opcionalmente usando cinta adhesiva, pegue el paquete de baterías en la parte posterior del tablero para mantenerlo en su lugar y hacerlo más portátil

Paso 3: el código y la calibración

Primero necesitas descargar e instalar dos bibliotecas:

1. Biblioteca de Adafruit neopixel abeto que controla el neopixel

2. Biblioteca MPU6050 para el giroscopio

3. Fuente de la biblioteca I2CDev

¡Son dos grandes bibliotecas que harán el trabajo pesado!

Más detalles sobre los neopíxeles aquí.

Luego descargue e instale mi biblioteca desde aquí o cópiela desde abajo:

#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; Adafruit_NeoPixel strip = Adafruit_NeoPixel (NUM_LEDS, NEOPIXED_CONTROL_PIN, NEO_RBG + NEO_KHZ800); unsigned long lastPrintTime = 0; inicialización bool = falso; // establecer verdadero si DMP init fue exitoso uint8_t mpuIntStatus; // contiene el byte de estado de interrupción actual de MPU uint8_t devStatus; // devuelve el estado después de cada operación del dispositivo (0 = éxito,! 0 = error) uint16_t packetSize; // tamaño esperado del paquete DMP (el valor predeterminado es 42 bytes) uint16_t FIFoCount; // recuento de todos los bytes actualmente en FIFO uint8_t fifoBuffer [64]; // Búfer de almacenamiento FIFO Quaternion q; // [w, x, y, z] contenedor de cuaterniones VectorFloat gravity; // [x, y, z] vector de gravedad float ypr [3]; // [guiñada, cabeceo, balanceo] guiñada / cabeceo / balanceo contenedor y vector de gravedad volátil bool mpuInterrupt = false; // indica si el pin de interrupción de MPU se ha elevado

configuración vacía ()

{Serial.begin (9600); Serial.println ("Programa iniciado"); inicialización = initializeGyroscope (); strip.begin (); } bucle vacío () {if (! inicialización) {retorno; } mpuInterrupt = falso; mpuIntStatus = mpu.getIntStatus (); FifoCount = mpu.getFIFOCount (); if (hasFifoOverflown (mpuIntStatus, FifoCount)) {mpu.resetFIFO (); regreso; } if (mpuIntStatus & 0x02) {while (FifoCount <tamaño del paquete) {FifoCount = mpu.getFIFOCount (); } mpu.getFIFOBytes (FifoBuffer, packetSize); FifoCount - = tamaño del paquete; mpu.dmpGetQuaternion (& q, FIFoBuffer); mpu.dmpGetGravity (& gravedad, & q); mpu.dmpGetYawPitchRoll (ypr, & q y gravedad); redibujados (ypr [0] * 180 / M_PI, ypr [1] * 180 / M_PI, ypr [2] * 180 / M_PI); }} booleano hasFifoOverflown (int mpuIntStatus, int FIFoCount) {return mpuIntStatus & 0x10 || FifoCount == 1024; } void redrawLeds (int x, int y, int z) {x = restringir (x, -1 * MAX_ANGLE, MAX_ANGLE); y = restringir (y, -1 * MAX_ANGLE, MAX_ANGLE); if (y 0) {lightLeds (y, z, 0, 5, 0, 89); } más si (y <0 y z 0 y z 0 y z> 0) {lightLeds (y, z, 20, 24, 89, 0); }} void lightLeds (int x, int y, int fromLedPosition, int toLedPosition, int fromAngle, int toAngle) {ángulo doble = (atan ((doble) abs (x) / (doble) abs (y)) * 4068) / 71; int ledNr = map (ángulo, fromAngle, toAngle, fromLedPosition, toLedPosition); printDebug (x, y, ledNr, ángulo); uint32_t color; for (int i = 0; i posición + LED_OFFSET) {posición de retorno + LED_OFFSET; } posición de retorno + LED_OFFSET - NUM_LEDS; } vacío printDebug (int y, int z, int lightLed, int angle) {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 ("Conexión MPU6050 exitosa"): F ("Error de conexión MPU6050")); 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 ("Error al inicializar DMP (código")); Serial.println (devStatus); return false;} mpu.setDMPEnabled (true); Serial.println (F ("Habilitar detección de interrupciones (interrupción externa Arduino 0)… ")); attachInterrupt (0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus (); Serial.println (F (" DMP listo! Esperando la primera interrupción … ")); packetSize = mpu.dmpGetFIFOPacketSize (); return true;} void dmpDataReady () {mpuInterrupt = true;}

Sube el código:

Usando el adaptador FTDI, cargue el código en el arduino.

Conecte la fuente de alimentación (baterías)

Calibración:

Lo más importante para calibrar aquí es la constante "LED_OFFSET". En mi ejemplo es 12. Necesitas ajustar esto de 0 a 23 para que después de encender la placa, el LED se ilumine en la dirección en la que inclinas la placa.

Si desea obtener más detalles sobre cómo funciona, consulte el último paso.

Paso 4: Cómo funciona (opcional)

Cómo funciona (opcional)
Cómo funciona (opcional)

Primero, un poco de información sobre el giroscopio MPU6050. Este es un giroscopio MEMS (MEMS significa sistemas microelectromecánicos).

Cada tipo de giroscopio MEM tiene alguna forma de componente oscilante desde donde se puede detectar la aceleración y, por lo tanto, el cambio de dirección. Esto se debe a que, de acuerdo con la ley de conservación del movimiento, a un objeto que vibra le gusta continuar vibrando en el mismo plano, y cualquier desviación vibratoria puede usarse para derivar un cambio de dirección.

El giróscopo también contiene un microcontrolador propio para calcular el balanceo, cabeceo y guiñada a través de algunas matemáticas sofisticadas.

Pero los datos brutos del giróscopo sufren de ruido y deriva, por lo que usamos una biblioteca externa para suavizar las cosas y brindarnos datos útiles y limpios.

Los Neopixel son leds RGB direccionables individualmente y encadenados en bandas y anillos. Funcionan con 5V y contienen sus propios circuitos, por lo que solo necesita alimentar los neopíxeles y comunicarse con ellos mediante la línea de datos. La comunicación se realiza con una única línea de datos que contiene el reloj y los datos (más detalles aquí). Adafruit proporciona una biblioteca limpia para interactuar con los anillos de neopixel.

El código

Dentro de la función l oop () se llama a la biblioteca MPU6050_6Axis_MotionApps20. Cuando la biblioteca tiene nuevos datos del gyroscpe, llama a redrawLeds (x, y, z) con 3 argumentos que representan guiñada, cabeceo y balanceo.

Dentro de redrawLeds ():

- nos estamos enfocando en dos ejes: y, z

- estamos restringiendo ambos ejes de -MAX_ANGLE a + MAX_ANGLE, definimos el ángulo máximo a 45 y se puede cambiar

- Estamos dividiendo 360 grados en 4 cuadrantes y llamamos a las funciones lightLeds () para cada uno de la siguiente manera:

* y negativo, z positivo el primer cuadrante controlará los LED de 0 a 5, el ángulo será de 0 a 89

* y negativo, z negativo el segundo cuadrante controla los LED de 6 a 12, el ángulo será de 89 a 0

*… Etc.

- dentro de la función lightLeds

* Estoy calculando un ángulo basado en los dos ejes usando un arco tangente (verifique la imagen adjunta)

* Estoy calculando lo que llevó a mostrar usando la función de mapa arduino

* Estoy reiniciando la tira de led todos menos dos led, el correspondiente a la posición del led que he calculado antes y una posición del led antes (para mostrar un efecto de desvanecimiento)

* Estoy usando una función llamada normalizeLedPosition () para tener en cuenta la calibración de neopixel. La calibración es útil porque el anillo de neopixel se puede girar como se desee y debe alinearse con el giroscopio.

* También estoy imprimiendo el eje de remolque, qué led tiene luz y el ángulo

Las matemáticas

Adjunté una imagen con el anillo led y la función trigonométrica utilizada para determinar el ángulo.

Recomendado: