Adafruit_NeoPixel 라이브러리의 대표적인 예제인 strandtest.ino를 살펴보고 있습니다. 이번 포스팅에서는 예제에 있는 다양한 연출 함수들을 상세히 살펴보도록 하겠습니다.
Adafruit NeoPixel에 대한 소개와 라이브러리, 예제 소개 등은 아래의 포스트를 확인해 주세요.
네오픽셀 사용의 핵심적인 내용을 알고 싶다면 아래의 포스트를 확인해 주세요.
// 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문을 반복합니다.
// 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 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씩 바꿔가며 이어나갑니다.
※ 네오픽셀을 원형으로 만들면 무지개빛이 빙글빙글 돌아가는 연출이 됩니다.
// 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를 제어할 수 있다는 것입니다.
위에 소개해 드린 연출 효과를 활용하여 무드등을 만들 수도 있고, 배터리량이나 점수 등을 표현하는 게이지로 만들어 보는 것도 좋을 것 같습니다.
그럼 이상으로 네오픽셀 포스팅을 마치도록 하겠습니다. 감사합니다.
끝.
아두이노 라이브러리의 예제 파일 활용 방법 (feat. LiquidCrystal.h) (0) | 2022.07.14 |
---|---|
개발 중에 잘 되던 동작이 안될 때 어떻게 하시나요? (1) | 2022.07.13 |
[네오픽셀] 아두이노 Adafruit NeoPixel 예제 파일 분석 (2/3) (0) | 2022.07.11 |
[네오픽셀] 아두이노 Adafruit NeoPixel 예제 파일 분석 (1/3) (0) | 2022.07.11 |