아두이노

아두이노 IR신호를 이용해서 네오픽셀 LED제어하기(Neopixel led)(2)

난쏘공돌이 2021. 9. 2. 01:21

2021.09.02 - [IoT프로젝트] - 내방을 리모컨을 사용해 RGB 감성으로 꾸며보자! (1/2)

 

내방을 리모컨을 사용해 RGB 감성으로 꾸며보자! (1/2)

※최종코드는 다음 포스팅에 있습니다! 방청소를 하면서 책상을 좀 꾸며볼까 하는 생각을 하게 되었다. 이전에 2021.01.05 - [라즈베리파이 프로젝트] - 라즈베리파이로 네오픽셀 led제어하기 (WS2812B

nan-sso-gong.tistory.com

해당글의 2번째글입니다!

 

이전글에서 우리는 IR신호까지 받아왔습니다 이제 그 신호를 기반으로 제어를 해줄건데요!

 

3. 아두이노에 led연결하기

먼저 led스트립에 고정을 위해서 벨크로를 부착했습니다

led의 연결은 vin은 5v로 , gnd는 gnd로 , din은 D7번에 연결해주시면 되겠습니다.

 

이제 실제로 led를 켜봐야겠죠

#include <Adafruit_NeoPixel.h> // Neopixel을 사용하기 위해서 라이브러리를 불러옵니다.
#include <IRremote.h>

#define PIN 7                             // 디지털 입력 핀 설정
#define NUMPIXELS 30              // Neopixel LED 소자 수 (LED가 24개라면 , 24로 작성)
#define BRIGHTNESS 230       // 밝기 설정 0(어둡게) ~ 255(밝게) 까지 임의로 설정 가능

#define bt1 0xFF30CF
#define bt2 0xFF18E7
#define bt3 0xFF7A85
#define bt4 0xFF10EF
#define bt5 0xFF38C7
#define bt6 0xFF5AA5
#define bt7 0xFF42BD
#define bt8 0xFF4AB5
#define bt9 0xFF52AD


Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

#define IRRECV_PIN 2 // IR 수신 핀 할당

// IR 수신 클래스 객체 생성
IRrecv irrecv(IRRECV_PIN);
// IR 수신하여 복조된 데이터 클래서 객체 생성(수신된 데이터의 저장소)
decode_results results;
// decodeType 출력을 편하게 하기위한 문자열 배열
String decodeType[19] = {
  "UNKNOWN", // decodeType : -1
  "UNUSED", // decodeType : 0
  "RC5",
  "RC6",
  "NEC",
  "SONY",
  "PANASONIC",
  "JVC",
  "SAMSUNG",
  "WHYNTER",
  "AIWA_RC_T501",
  "LG",
  "SANYO",
  "MITSUBISHI",
  "DISH",
  "SHARP",
  "DENON",
  "PRONTO",
  "LEGO_PF",
};

void setup() {
  Serial.begin(9600);
  strip.setBrightness(BRIGHTNESS);    //  BRIGHTNESS 만큼 밝기 설정
  strip.begin();                                        //  Neopixel 제어를 시작
  strip.show();                                        //  Neopixel 동작 초기화 합니다

  delay(500);
  Serial.println(F("IR Recv Program Start..."));
  irrecv.enableIRIn(); // IR 리시버 동작 시작
  attachInterrupt(0,swap,RISING);


}

void loop() {

  if (irrecv.decode(&results)) {
    // DecodeType, Data, Bit 수를 출력
    Serial.println(F("========================================"));
    Serial.print(F("Decode Type        : "));
    Serial.println(decodeType[results.decode_type + 1]);
    Serial.print(F("Received Data      : 0x"));
    Serial.println(results.value, HEX);
    Serial.print(F("Received Data Bits : "));
    Serial.println(results.bits);
    irrecv.resume(); // 다음신호를 받을 수 있도록 준비
  }


  //  colorWipe 함수를 적용하면 모든 LED를 동일한 색상으로 적용합니다.
  if (results.value == bt1) {
    colorWipe(strip.Color(255, 0, 0), 100); //  strip 색상을 ( 255 (Red) , 0 (Green) , 0 (Blue) , 마지막 100은 딜레이 타임으로
  }

  if (results.value == bt2) {
    colorWipe(strip.Color(0, 255, 0), 100); //  strip 색상을 ( 0 (Red) , 255 (Green) , 0 (Blue) , 100)
  }
  
  if (results.value == bt3) {
    colorWipe(strip.Color(207, 255, 229), 100); //  strip 색상을 ( 0 (Red) , 255 (Green) , 0 (Blue) , 100)
  }

  if (results.value == bt4) {
    theaterChase(strip.Color(  0,   0, 127), 50); // Blue, half brightness
  }
  if (results.value == bt5) {
    rainbow(10);
  }
  if (results.value == bt6) {
    theaterChaseRainbow(50);
  }

  if (results.value == bt7) {
    theaterChase(strip.Color(  0,   0, 127), 50); // Blue, half brightness
  }
  if (results.value == bt8) {
    rainbow(30);
  }
  if (results.value == bt9) {
    colorWipe(strip.Color(0, 0, 0), 100); //  strip 색상을 ( 255 (Red) , 0 (Green) , 0 (Blue) , 마지막 100은 딜레이 타임으로
  }


}
void colorWipe(uint32_t c, uint8_t wait) { 

  for (uint16_t i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);

  }
}

void theaterChase(uint32_t color, int wait) {
  for (int a = 0; a < 10; a++) { // Repeat 10 times...
    for (int b = 0; b < 3; b++) { //  'b' counts from 0 to 2...
      strip.clear();         //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in steps of 3...
      for (int c = b; c < strip.numPixels(); c += 3) {
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      strip.show(); // Update strip with new contents
      delay(wait);  // Pause for a moment
    }
  }
}

void rainbow(int wait) {
  for (long firstPixelHue = 0; firstPixelHue < 5 * 65536; firstPixelHue += 256) {
    for (int i = 0; i < strip.numPixels(); i++) {
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show();
    delay(wait);
  }
}

void theaterChaseRainbow(int wait) {
  int firstPixelHue = 0;
  for (int a = 0; a < 30; a++) {
    for (int b = 0; b < 3; b++) {
      strip.clear();
      for (int c = b; c < strip.numPixels(); c += 3) {
        int hue = firstPixelHue + c * 65536L / strip.numPixels();
        uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue -> RGB
        strip.setPixelColor(c, color);
      }
      strip.show();
      delay(wait);
      firstPixelHue += 65536 / 90;
    }
  }
}

void swap(){
  if (irrecv.decode(&results)) {
    // DecodeType, Data, Bit 수를 출력
    Serial.println(F("========================================"));
    Serial.print(F("Decode Type        : "));
    Serial.println(decodeType[results.decode_type + 1]);
    Serial.print(F("Received Data      : 0x"));
    Serial.println(results.value, HEX);
    Serial.print(F("Received Data Bits : "));
    Serial.println(results.bits);
    irrecv.resume(); // 다음신호를 받을 수 있도록 준비
  }   
}

해당코드를 실행하게 되면 저는 9개의 키매핑에대해 패턴을 다르게 지정했습니다

이걸 따라하시는 분들은 저기 #define 부분에 여러분의 리모컨 신호를 넣으시면 됩니다.

 

특별하게 이번코드에서는 IR신호에 즉각적으로 반응할수 있도록 인터럽트 코드를 추가하였습니다

 

다 따라오셨다면 이런 책상을 만나실수 있어요 ㅎㅎ

이제는 보드와 배선정리만 하면 깔끔하겠네요!