Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Pantalla LED Interactiva con Giroscopio, Anillo NeoPixel y Arduino

Componentes y Suministros

ComponenteCantidadNotas
SparkFun Arduino Pro Mini 328 - 5V/16MHz1Microcontrolador compacto
Adafruit NeoPixel Ring: WS2812 5050 RGB LED1Anillo 24 LEDs direccionables
SparkFun IMU Breakout - MPU-92501Giroscopio + acelerómetro + magnetómetro (código usa MPU6050)
Protoboard (genérica)1Montaje sin soldar
Cables Macho-Macho1Conexiones
Cables Macho-Hembra1Conexiones
Portapilas 4x AA + pilas1Alimentación portátil

Sobre el Proyecto

En este tutorial usamos el giroscopio MPU6050, un anillo NeoPixel y un Arduino para construir un dispositivo que enciende LEDs correspondientes al ángulo de inclinación.

Proyecto simple y divertido, montado en protoboard. Siguiendo los pasos construirás lo que se ve en el video. Buen tutorial para aprender sobre giroscopio y anillo NeoPixel.

Lo hice por el interés visto en otro tutorial mío. Aquí reemplacé LEDs simples por anillo NeoPixel: más sencillo mediante librería Adafruit y visualmente más espectacular.

Si tienes estos componentes por ahí, es una gran forma de aprovecharlos. Te guiaré paso a paso en la construcción y explicaré el funcionamiento al final.

Paso 1: Materiales Necesarios

Pantalla LED Interactiva con Giroscopio, Anillo NeoPixel y Arduino

Piezas:

  1. Arduino Pro Mini 328P
  2. Protoboard
  3. Giroscopio MPU6050
  4. Anillo NeoPixel 24 LEDs
  5. Portapilas 4x AA con 4 pilas
  6. Cables jumper en U (opcional). Uso estos porque quedan mejor en protoboard y los LEDs son más visibles. Caja 140 en eBay ~4$. Si no tienes, sirve cable Dupont.

Herramientas:

  1. Adaptador USB-serie FTDI FT232RL para programar Arduino Pro Mini
  2. Arduino IDE

Habilidades: Soldadura básica, programación Arduino básica.

Paso 2: Montaje

Pantalla LED Interactiva con Giroscopio, Anillo NeoPixel y Arduino
Pantalla LED Interactiva con Giroscopio, Anillo NeoPixel y Arduino

Adjunto esquema Fritzing en formato .fzz e imagen para visualizar conexiones.

  1. Soldar 3 pines macho en parte trasera del anillo NeoPixel (ver foto): positivo, negativo, entrada datos.
  2. Portapilas 4x AA necesita conexión a protoboard: soldar dos cables Dupont a sus terminales.
  3. Preparar protoboard: colocar anillo NeoPixel, microcontrolador y giroscopio como en imagen. Conectar todos los negativos (microcontrolador, NeoPixel, giroscopio), todos los positivos, y cables de datos: SDA/SCL microcontrolador-giroscopio, pin D6 microcontrolador-NeoPixel. Revisar todas las conexiones antes de alimentar. Opcional: fijar portapilas a protoboard con cinta ducto para portabilidad.

Paso 3: Código y Calibración

Primero descargar e instalar dos librerías:

  1. Librería Adafruit NeoPixel (control NeoPixel)
  2. Librería MPU6050 (giroscopio)

Son dos excelentes librerías que hacen el trabajo pesado. Más detalles NeoPixels aquí.

Luego descargar e instalar mi librería desde GitHub o copiar abajo:

#include "I2Cdev.h"
#include <Adafruit_NeoPixel.h>
#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;
bool initialization = false;
uint8_t mpuIntStatus, devStatus;
uint16_t packetSize, fifoCount;
uint8_t fifoBuffer[64];
Quaternion q;
VectorFloat gravity;
float ypr[3];
volatile bool mpuInterrupt = false;

void setup() {
  Serial.begin(9600);
  Serial.println("Programa iniciado");
  initialization = initializeGyroscope();
  strip.begin();
}

void loop() {
  if (!initialization) return;
  mpuInterrupt = false;
  mpuIntStatus = mpu.getIntStatus();
  fifoCount = mpu.getFIFOCount();
  if (hasFifoOverflown(mpuIntStatus, fifoCount)) { mpu.resetFIFO(); return; }
  if (mpuIntStatus & 0x02) {
    while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
    mpu.getFIFOBytes(fifoBuffer, packetSize);
    fifoCount -= packetSize;
    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, -MAX_ANGLE, MAX_ANGLE);
  y = constrain(y, -MAX_ANGLE, MAX_ANGLE);
  if (y < 0 && z > 0) lightLeds(y, z, 0, 5, 0, 89);
  else if (y < 0 && z < 0) lightLeds(y, z, 6, 12, 89, 0);
  else if (y > 0 && z < 0) lightLeds(y, z, 13, 19, 0, 89);
  else if (y > 0 && z > 0) lightLeds(y, z, 20, 24, 89, 0);
}

void lightLeds(int x, int y, int fromLed, int toLed, int fromAngle, int toAngle) {
  double angle = (atan((double)abs(x) / (double)abs(y)) * 4068) / 71;
  int ledNr = map(angle, fromAngle, toAngle, fromLed, toLed);
  printDebug(y, z, ledNr, angle);
  uint32_t color;
  for (int i = 0; i < NUM_LEDS; i++) {
    color = strip.Color(0, 0, 0);
    if (i == ledNr) color = strip.Color(0, 180, 0);
    else if (i == ledNr - 1) color = strip.Color(0, 5, 0);
    strip.setPixelColor(normalizeLedPosition(i), color);
  }
  strip.show();
}

int normalizeLedPosition(int pos) {
  if (NUM_LEDS > pos + LED_OFFSET) return pos + LED_OFFSET;
  return pos + LED_OFFSET - NUM_LEDS;
}

void printDebug(int y, int z, int lightLed, int angle) {
  if (millis() - lastPrintTime < 500) return;
  Serial.print("a="); Serial.print(angle); 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; // 400kHz I2C
  mpu.initialize();
  Serial.println(mpu.testConnection() ? F("MPU6050 conexión OK") : F("MPU6050 conexión FALLÓ"));
  Serial.println(F("Inicializando DMP..."));
  devStatus = mpu.dmpInitialize();
  // Offsets de calibración (ajustar para tu sensor)
  mpu.setXGyroOffset(220);
  mpu.setYGyroOffset(76);
  mpu.setZGyroOffset(-85);
  mpu.setZAccelOffset(1788);
  if (devStatus != 0) {
    Serial.print(F("Fallo init DMP (código ")); Serial.println(devStatus);
    return false;
  }
  mpu.setDMPEnabled(true);
  Serial.println(F("Activando detección interrupción (int. externo 0 Arduino)..."));
  attachInterrupt(0, dmpDataReady, RISING);
  mpuIntStatus = mpu.getIntStatus();
  Serial.println(F("DMP listo! Esperando primera interrupción..."));
  packetSize = mpu.dmpGetFIFOPacketSize();
  return true;
}

void dmpDataReady() { mpuInterrupt = true; }

Subir el código: Usar adaptador FTDI para cargar en Arduino.

Conectar alimentación (pilas).

Calibración: Lo más importante es ajustar constante LED_OFFSET. En mi ejemplo es 12. Ajustar de 0 a 23 para que al encender, el LED se encienda en la dirección que inclinas la placa.

Para más detalles de funcionamiento, ver siguiente paso.

Paso 4: Cómo Funciona (Opcional)

Pantalla LED Interactiva con Giroscopio, Anillo NeoPixel y Arduino

MPU6050: Giroscopio MEMS (Sistemas Microelectromecánicos). Tiene componente oscilante; por conservación del momento, un objeto vibrando tiende a seguir vibrando en mismo plano, y desviaciones vibracionales derivan cambio de dirección. Incluye microcontrolador propio que calcula roll, pitch, yaw con matemáticas complejas. Datos raw tienen ruido y deriva; usamos librería externa para suavizar y obtener datos limpios.

NeoPixel: LEDs RGB direccionables individualmente, encadenados en tiras/anillos. Trabajan a 5V, contienen electrónica propia: solo alimentar y comunicar por línea de datos (reloj+datos en una línea). Librería Adafruit limpia para interactuar.

Código: En loop(), librería MPU6050_6Axis_MotionApps20 es llamada. Cuando hay datos nuevos del giroscopio, llama redrawLeds(x, y, z) con yaw, pitch, roll (en radianes, convertidos a grados).

En redrawLeds():

Matemáticas: Imagen adjunta muestra anillo LED y función trigonométrica para determinar ángulo.

Código

Código Arduino

Repositorio GitHub

Esquemáticos

sketch_gMlSrk3rCX.fzz (archivo Fritzing)

Proceso de manufactura

  1. Construye un Juego Giroscópico en Tiempo Real con Arduino Nano y Sensor MPU-6050
  2. Construye un Reloj de Pared Elegante con Anillo Neopixel 60 LEDs Adafruit y Arduino
  3. Sensor K30 CO₂: Monitorización en tiempo real de la calidad del aire interior
  4. Facilitar la comunicación sordo‑ciego usando 1Sheeld y Arduino
  5. Mando USB para juegos DIY con Arduino – Construye tu propio gamepad de alto rendimiento
  6. Alcancía Inteligente: Controla un Aceptador de Monedas con Arduino Nano
  7. Pixie: Reloj de pulsera NeoPixel basado en Arduino – Elegante reloj LED DIY
  8. Controla un LED por Bluetooth con Arduino – Guía DIY paso a paso
  9. Integración del sensor de huella capacitivo DFRobot (ID809) con Arduino o ESP8266
  10. Dominando reconocimiento y síntesis de voz en Arduino Due
  11. Medición Precisa de Radiación Solar con Arduino UNO y Shield Ethernet