공작소굴

 Adafruit_NeoPixel 라이브러리의 대표적인 예제인 strandtest.ino를 살펴보고 있습니다. 이번 포스팅에서는 예제에 있는 다양한 연출 함수들을 상세히 살펴보도록 하겠습니다. 

strandtest.ino

 

1. 네오픽셀 소개 및 strandtest.ino 프로그램 소개 주석

Adafruit NeoPixel에 대한 소개와 라이브러리, 예제 소개 등은 아래의 포스트를 확인해 주세요.

 

[네오픽셀] 아두이노 Adafruit NeoPixel 예제 파일 분석 (1/3)

 Adafruit 사의 네오픽셀(Neopixel)은 컬러 LED와 제어칩을 하나의 모듈로 만든 태로 1개의 신호만으로 밝기와 색상을 바꿀 수 있으며, 이론상 무한대의 네오픽셀 연결해 움직이는 무지개, 사운드

mechacave.tistory.com

 

2. 전처리 및 setup(), loop()

네오픽셀 사용의 핵심적인 내용을 알고 싶다면 아래의 포스트를 확인해 주세요.

 

[네오픽셀] 아두이노 Adafruit NeoPixel 예제 파일 분석 (2/3)

아두이노에서 네오픽셀을 사용할 때 유용하게 쓰이는 Adafruit_NeoPixel 라이브러리의 대표적인 예제인 strandtest.ino를 살펴보고 있습니다. strandtest.ino 1. 네오픽셀 소개 및 strandtest.ino 프로그램 소개..

mechacave.tistory.com

 

3. 네오픽셀 연출 함수 상세보기

 

colorWipe() 함수

// Fill strip pixels one after another with a color. Strip is NOT cleared
// first; anything there will be covered pixel by pixel. Pass in color
// (as a single 'packed' 32-bit value, which you can get by calling
// strip.Color(red, green, blue) as shown in the loop() function above),
// and a delay time (in milliseconds) between pixels.

01: void colorWipe(uint32_t color, int wait) {
02:   for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
03:     strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
04:     strip.show();                          //  Update strip to match
05:     delay(wait);                           //  Pause for a moment
06:   }
07: }
// 선택한 컬로로 픽셀을 하나 하나 차례로 채워나갑니다.
// 다른 색이 켜져 있었다면 그 색을 덮고 새로운 색으로 바뀝니다.
// 컬러 색상은 strip.Color(red, green, blue) 함수를 사용하여 얻어지는 32bit 값을 사용합니다.

01 : 인자값은 색상딜레이입니다.
02 : 0번 LED 부터 strip.numPixels() 로 얻어지는 제어하려는 네오픽셀의 개수 만큼 반복합니다.
03 : strip.setPixelColor(i, color) 함수로 i번째 픽셀 색상을 color값으로 정합니다.
   ▶ 바로 해당 픽셀의 빛이 바뀌지 않습니다. 단지 해당 픽셀의 색상 정보를 바꿀 뿐입니다.
04 : strip.show() 함수로 모든 픽셀들이 각각의 색상값을 나타내도록 합니다.
  ▶ i 값이 증가하면서 다음 픽셀도 원하는 color값으로 바꾸고, strip.show()를 통해 나타냅니다.
  ▶ 픽셀 하나만을 켜거나 끌 수 없습니다.
05 : 딜레이값 만큼 기다렸다가 다음 픽셀의 색을 지정하기 위해 for문을 반복합니다.

 

 


 

theaterChase() 함수

// Theater-marquee-style chasing lights. Pass in a color (32-bit value,
// a la strip.Color(r,g,b) as mentioned above), and a delay time (in ms)
// between frames.

01: void theaterChase(uint32_t color, int wait) {
02:  for(int a=0; a<10; a++) {  // Repeat 10 times...
03:   for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
04:     strip.clear();         //   Set all pixels in RAM to 0 (off)
05:     // 'c' counts up from 'b' to end of strip in steps of 3...
06:     for(int c=b; c<strip.numPixels(); c += 3) {
07:       strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
08:     }
09:     strip.show(); // Update strip with new contents
10:     delay(wait);  // Pause for a moment
11:   }
12:  } 
13: }
// 지정된 색상의 빛이 지나가는 효과입니다. (strip.Color(r,g,b))
// 각 프레임간 속도를 지정해 줍니다. (ms)

01 : 인자값 (컬러값, 딜레이)
02 : a 값을 0부터 9까지 증가시켜가며 10번 반복합니다.
03 : b 값은 0, 1, 2 가 됩니다. (최대값 3)
04 : strip.clear() 함수로 네오픽셀 스트립을 모두 끕니다 // 네오픽셀의 색상정보가 들어가는 RAM 값을 0으로 함
06 : c 값은 b부터 3씩 더해가며 전체 픽셀 개수 까지 증가합니다.
07 : c번째 네오픽셀에 색상 정보를 넣고
09 : 네오픽셀을 켭니다.
10 : 딜레이만큼 기다린 뒤 03번으로 돌아갑니다.
   
   ▶ 만약, 픽셀개수가 24개 라면
   b=0 일 때 네오픽셀이 꺼진 뒤 c = 0,3,6,9,12,15,18,21 로 바뀌며 해당 네오픽셀만 켭니다.
   b=1 일 때 네오픽셀이 꺼졌다가 c = 1,4,7,10,16,19,22 로 방금 전 켜졌던 네오픽셀의 다음 칸이 켜지게 됩니다.
   b=2 일 때 네오픽셀이 꺼졌다가 c = 2,5,8,11,17,20,23다음 칸 네오픽셀이 켜지게 됩니다.
   이 과정을 a 번 반복되게 됩니다.

이 때, b의 최대값과 c의 증가값은 같아야 하고, 그 값은 동시에 켜지는 네오픽셀간의 간격이 됩니다.

 

 


 

rainbow() 함수

// Rainbow cycle along whole strip. Pass delay time (in ms) between frames.
01: void rainbow(int wait) {
  // Hue of first pixel runs 5 complete loops through the color wheel.
  // Color wheel has a range of 65536 but it's OK if we roll over, so
  // just count from 0 to 5*65536. Adding 256 to firstPixelHue each time
  // means we'll make 5*65536/256 = 1280 passes through this outer loop:
02: 	for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
03:     	for(int i=0; i<strip.numPixels(); i++) { 
		// For each pixel in strip...
		// Offset pixel hue by an amount to make one full revolution of the
		// color wheel (range of 65536) along the length of the strip
		// (strip.numPixels() steps):
            
04:      	int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());

		// strip.ColorHSV() can take 1 or 3 arguments: a hue (0 to 65535) or
		// optionally add saturation and value (brightness) (each 0 to 255).
		// Here we're using just the single-argument hue variant. The result
		// is passed through strip.gamma32() to provide 'truer' colors
		// before assigning to each pixel:
            
05:      	strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
06:		}
07:   	strip.show(); // Update strip with new contents
08:    	delay(wait);  // Pause for a moment
09: 	}	
10: }
// 전체 네오픽셀 스트립을 따라 레인보우 색상 사이클이 흘러갑니다.
// 프레임간 주어진 시간만큼 딜레이가 생깁니다.

01 : 인자값 (딜레이)

// 첫 번째 픽셀의 색조(Hue)는 전체 네오픽셀 스트립을 5번 회전하게 됩니다.
   ▶ 무지개 색상을 이끌고 네오픽셀을 5바퀴 돈다고 생각하면 됩니다. 

// 색상환의 범위는 65566입니다. 5회전을 하기 위해서는 0~65565 까지를 5번 반복해도 되지만,
// 65536이 되면 롤오버 되어 0이 되는 것과 마찬가지이므로,
// 0에서 부터 5*65536까지 반복하는 것으로 줄여서 사용합니다.

02 : 첫 번째 네오픽셀의 색조는 firstPixelHue 값에 256씩 더해 가며 변화시킵니다.
   ▶ 전체적으로 따지면, 네오픽셀은 무지개가 5번 회전하는 동안 (5*65536) / 256 = 1280번 색상이 바뀌게 됩니다.

03 : 제어할 네오픽셀의 개수만큼 반복하며 픽셀들의 색조를 정합니다.

// Heu가 가질 수 있는 전체 범위 65565을 전체 픽셀 개수(strip.numPixels())로 나눈 값을
// 픽셀 순서(i)에 맞게 배정합니다.
04 : 해당 픽셀에 적용할 pixelHue값을 계산합니다.

// strip.ColorHSV() 함수는1개 또는 3개의 인수를 취할 수 있습니다
// 색조(0 ~ 65535) 또는 선택적으로 채도와 밝기를 추가할 수 있습니다. (각각 0에서 255까지)
// 여기에서는 색조에 한해서만 변형합니다.
// 색조의 변화를 '실제' 색상으로 바꾸기 위해 strip.gamma32()함수를 사용합니다.

05 : 이렇게 정해진 색상값을 해당 픽셀에 부여합니다.

07 : 모든 픽셀에 색상이 정해지면, 한꺼번에 출력(strip.show())합니다.
08 : 정해진 딜레이(50ms) 이후에 Hue값을 256씩 바꿔가며 이어나갑니다.

 

 

※ 네오픽셀을 원형으로 만들면 무지개빛이 빙글빙글 돌아가는 연출이 됩니다.


 

theaterChaseRainboe() 함수

// Rainbow-enhanced theater marquee. Pass delay time (in ms) between frames.
// 레인보우 색상이 적용된 따라잡기 효과입니다.

void theaterChaseRainbow(int wait) {

  // 레인보우와 마찬가지로 첫번째 픽셀의 Hue값을 조절합니다.
  int firstPixelHue = 0;     // First pixel starts at red (hue 0)

  // 30번을 반복합니다.
  for(int a=0; a<30; a++) {  // Repeat 30 times...
  
    // theaterChase 와 마찬가지로 3칸마다 따라가도록 합니다.
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
    
      strip.clear();         //   Set all pixels in RAM to 0 (off)
      
      // 3칸씩 띄어가며 색을 입혀줍니다.
      // 'c' counts up from 'b' to end of strip in increments of 3...      
      for(int c=b; c<strip.numPixels(); c += 3) {
      
        // hue of pixel 'c' is offset by an amount to make one full
        // revolution of the color wheel (range 65536) along the length
        // of the strip (strip.numPixels() steps):
        
        // 픽셀 위치에 알맞은 hue값을 계산합니다.
        int hue   = firstPixelHue + c * 65536L / strip.numPixels();
        
        // hue값을 rgb로 바꿉니다.
        uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue -> RGB
        
        // rgb값을 픽셀에 넣습니다.
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'        
      }
      
      strip.show();                // Update strip with new contents
      delay(wait);                 // Pause for a moment
      
      // 90프레임에 걸쳐 회전하도록 첫 번째 hue값을 조정합니다.
      firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
    }
  }
}

 

 


마무리

 이번 포스트까지 3개의 포스트에 걸쳐 NeoPixel의 기본적인 예제인 strandtest.ino 를 분석해 보았습니다. 

 

 네오픽셀의 장점은 1개의 디지털 신호만으로 여러개의 LED를 제어할 수 있다는 것입니다.

 위에 소개해 드린 연출 효과를 활용하여 무드등을 만들 수도 있고, 배터리량이나 점수 등을 표현하는 게이지로 만들어 보는 것도 좋을 것 같습니다.

 

 그럼 이상으로 네오픽셀 포스팅을 마치도록 하겠습니다. 감사합니다.

 끝.

공유하기

facebook twitter kakaoTalk kakaostory naver band