산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

NeoPixel 링과 Arduino로 만드는 인터랙티브 자이로스코프 LED 디스플레이

부품 및 소모품

SparkFun Arduino Pro Mini 328 - 5V/16MHz × 1개
Adafruit NeoPixel 링: WS2812 5050 RGB LED (24개) × 1개
SparkFun IMU 브레이크아웃 - MPU-9250 (MPU6050 호환) × 1개
브레드보드 (범용) × 1개
수-수 점퍼 와이어 × 1세트
수-암 점퍼 와이어 × 1세트
4x AA 배터리 홀더 + 배터리 × 1개

프로젝트 소개

이 튜토리얼에서는 MPU6050 자이로스코프, NeoPixel 링, Arduino를 사용해 기울기 각도에 해당하는 LED를 점등하는 장치를 만듭니다.

브레드보드에서 조립하는 간단하고 재미있는 프로젝트입니다. 단계를 따라하면 영상에서 본 장치를 만들 수 있습니다. 자이로스코프와 NeoPixel 링 학습에 좋은 튜토리얼입니다.

다른 튜토리얼에 대한 관심을 보고 이 튜토리얼을 만들게 되었습니다. 단순 LED를 NeoPixel 링으로 대체했는데, Adafruit 라이브러리로 더 간단하게 제어할 수 있고 시각적으로 훨씬 화려합니다.

이 부품들이 굴러다닌다면 이를 활용하는 좋은 방법입니다. 장치 제작 과정을 단계별로 안내하고 마지막 단계에서 작동 원리를 설명하겠습니다.

1단계: 필요한 것들

NeoPixel 링과 Arduino로 만드는 인터랙티브 자이로스코프 LED 디스플레이

부품

  1. Arduino Pro Mini 328P
  2. 브레드보드
  3. MPU6050 자이로스코프
  4. 24 NeoPixel LED 링
  5. 4x AA 배터리 팩 + 배터리 4개
  6. U자형 점퍼 케이블 (선택사항). 브레드보드에서 깔끔하고 LED가 잘 보이게 하려 사용. 이베이에서 140개 약 $4. 없으면 듀퐁 와이어로 대체 가능.

도구:

  1. Arduino Pro Mini 프로그래밍용 USB-시리얼 FTDI 어댑터 FT232RL
  2. Arduino IDE

기술:

  1. 납땜
  2. 기본 Arduino 프로그래밍

2단계: 조립

NeoPixel 링과 Arduino로 만드는 인터랙티브 자이로스코프 LED 디스플레이
NeoPixel 링과 Arduino로 만드는 인터랙티브 자이로스코프 LED 디스플레이

Fritzing 회로도(.fzz)와 사진을 첨부해 연결을 쉽게 시각화했습니다.

  1. NeoPixel 링 뒷면에 수컷 핀 3개 납땜 (사진 참조): 양극, 접지, 데이터 입력 핀
  2. 4x 배터리 홀더를 브레드보드에 연결할 수 있게 듀퐁 와이어 2개를 단자에 납땜
  3. 브레드보드 준비: NeoPixel 링, 마이크로컨트롤러, 자이로스코프를 사진처럼 배치. 모든 음극선(마이크로컨트롤러, NeoPixel, 자이로), 모든 양극선, 데이터선(SDA/SCL: 마이크로컨트롤러↔자이로, D6: 마이크로컨트롤러→NeoPixel) 연결. 전원 투입 전 모든 연결 재확인. 선택사항: 덕트 테이프로 배터리 팩을 브레드보드 뒤에 고정해 휴대성 확보.

3단계: 코드 및 캘리브레이션

먼저 두 라이브러리 다운로드 및 설치:

  1. Adafruit NeoPixel 라이브러리 (NeoPixel 제어용)
  2. MPU6050 라이브러리 (자이로스코프용)

이 두 라이브러리가 무거운 작업을 처리해줍니다! NeoPixel 상세 정보는 여기 참조.

그 다음 내 라이브러리를 여기서 다운로드하거나 아래에서 복사:

#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_GRB + 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("Program started");
  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 fromLedPosition, int toLedPosition, int fromAngle, int toAngle) {
  double angle = (atan((double)abs(x) / (double)abs(y)) * 4068) / 71;
  int ledNr = map(angle, fromAngle, toAngle, fromLedPosition, toLedPosition);
  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 position) {
  if (NUM_LEDS > position + LED_OFFSET) return position + LED_OFFSET;
  return position + 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;
  mpu.initialize();
  Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
  Serial.println(F("Initializing DMP..."));
  devStatus = mpu.dmpInitialize();
  mpu.setXGyroOffset(220);
  mpu.setYGyroOffset(76);
  mpu.setZGyroOffset(-85);
  mpz.setZAccelOffset(1788);
  if (devStatus != 0) { Serial.print(F("DMP Initialization failed (code ")); Serial.println(devStatus); return false; }
  mpu.setDMPEnabled(true);
  Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
  attachInterrupt(0, dmpDataReady, RISING);
  mpuIntStatus = mpu.getIntStatus();
  Serial.println(F("DMP ready! Waiting for first interrupt..."));
  packetSize = mpz.dmpGetFIFOPacketSize();
  return true;
}
void dmpDataReady() { mpuInterrupt = true; }

코드 업로드:

FTDI 어댑터로 Arduino에 코드 업로드.

전원 연결 (배터리)

캘리브레이션:

가장 중요한 건 "LED_OFFSET" 상수 캘리브레이션입니다. 예제에서는 12입니다. 보드 전원 켠 후 보드를 기울인 방향으로 LED가 점등하도록 0~23 사이에서 조정하세요.

작동 원리 상세 알고 싶으면 다음 단계 참조

4단계: 작동 원리 (선택사항)

NeoPixel 링과 Arduino로 만드는 인터랙티브 자이로스코프 LED 디스플레이

첫째, MPU6050 자이로스코프에 대해. 이는 MEMS 자이로스코프입니다(MEMS = 미세전자기계시스템).

모든 MEMS 자이로스코프는 가속도와 방향 변화를 감지할 수 있는 진동 구성 요소를 가집니다. 운동 보존 법칙에 따라 진동하는 물체는 같은 평면에서 계속 진동하려 하고, 진동 편차로 방향 변화를 유도할 수 있습니다.

자이로에는 자체 마이크로컨트롤러가 있어 롤, 피치, 요를 복잡한 수학으로 계산합니다.

하지만 자이로 원시 데이터는 노이즈와 드리프트가 있어, 외부 라이브러리로 깔끔한 사용 가능 데이터로 다듬었습니다.

NeoPixel은 개별 어드레싱 가능한 RGB LED가 밴드/링 형태로 체인된 것입니다. 5V로 작동하며 자체 회로를 내장해 전원만 공급하고 데이터 라인으로 통신하면 됩니다(클럭과 데이터가 단일 라인에 포함). Adafruit가 NeoPixel 링용 깔끔한 라이브러리를 제공합니다.

코드

loop() 함수 내부에서 MPU6050_6Axis_MotionApps20 라이브러리 호출. 라이브러리에 자이로스코프 새 데이터가 있으면 redrawLeds(x, y, z)를 요/피치/롤 3개 인자로 호출.

redrawLeds 내부:

수학

LED 링과 각도 결정을 위한 삼각함수를 그린 그림 첨부.

코드

Arduino 코드

https://github.com/danionescu0/arduino/tree/master/projects/neopixel_ring_gyroscope

회로도

sketch_gMlSrk3rCX.fzz

제조공정

  1. 아두이노 나노와 MPU-6050으로 실시간 자이로스코프 게임 만들기
  2. 아다프루트 60-LED 네오픽셀 링 4개로 스타일리시 벽시계 만들기
  3. K30 CO2 센서: 실시간 실내 공기질 모니터링
  4. 1Sheeld와 아두이노로 시각/청각 장애인 간 소통 돕기
  5. DIY 아두이노 USB 게임 컨트롤러 - 나만의 고성능 게임패드 만들기
  6. 스마트 저금통 만들기: 아두이노 나노로 동전 인식기 제어하기
  7. Pixie: 아두이노 기반 네오픽셀 손목시계 – 세련된 DIY LED 타임피스
  8. 아두이노 블루투스로 LED 제어하기 - HC-05 & MIT App Inventor 입문 가이드
  9. DFRobot 정전식 지문 인식 센서 아두이노/ESP8266 연동 가이드
  10. 아두이노 Due에서 음성 인식 및 합성 마스터하기