[37호]카멜레온 DIY LED 이야기③
카멜레온 DIY LED 이야기 3
카멜레온 DIY LED를 위한 아두이노 라이브러리
글 | 신상석 ssshin@jcnet.co.kr
디바이스마트 매거진 독자 여러분, 안녕하세요. 앞으로 5회에 걸쳐 [카멜레온 DIY LED 이야기]를 진행할 신상석입니다. 이 이야기는 WS2812B라는 컬러 LED를 기반으로 제작된 [카멜레온 DIY LED] 시리즈를 이용하여 생활에 필요한 다양한 형상을 꾸며보고 이것을 다양한 컬러로 디스플레이 해보는 내용입니다. 앞으로 진행할 내용에 대하여 간단히 알아보면 다음과 같습니다. (약간 변경될 수도 있습니다.) 앞으로 즐겁고 유익한 강의가 될 수 있도록 많은 격려와 성원 부탁드립니다. |
디바이스마트매거진 독자 여러분, 안녕하세요. 반갑습니다.
[카멜레온 DIY LED 이야기] 세번째 시간이 돌아왔습니다.지난 시간에는 카멜레온 DIY LED를 구성하고 있는 WS2812B의 동작 원리를 알아보았고 이를 기반으로 JLED-BAR-1(막대 모양 카멜레온 DIY LED 1개 모듈)로 무지개색을 표현해 보았으며, JLED-RING-12(원형의 카멜레온 DIY LED 12개 모듈)을 이용하여 알록달록 동그란 12색상환을 만들어 보았습니다. 기본 개념과 원리를 이해하고 실행해 보았으므로 이제부터는 어떤 모양, 어떤 컬러, 어떤 동작도 조금씩만 응용하면 모두 다 만들 수 있는 기초 능력은 갖추었지만, 그렇다고 해도 내가 원하는 형태로 바로 동작시킬 수 있다는 뜻은 아닙니다. 바둑에 비유하자면, 바둑을 배우는 것은 쉽지만 고수가 되는 것은 매우 많은 공부와 훈련, 실전을 필요로 하기 때문입니다. 지금 현재 상태는 이제 막 18급을 넘어선 상태라고나 할까요?
한편, 지난번에 (기억이 나실 지 모르겠지만…) WS2812B가 인식하는 ‘0’과 ‘1’을 생성하기 위하여 정의한 ‘CODE0’와 ‘CODE1’ 마크로 선언은 개념적으로 실행해 본다는 의미에서 불명확한 타이밍을 기반으로 정의하여 사용하였으므로 이 부분도 오늘은 해결을 하고 넘어가야 하겠습니다.
자, 그럼 천천히 라이브러리 이야기를 시작해 보겠습니다. 출발~
WS2812B를 위한 라이브러리가 있을까?
C 언어를 처음 배울 때, C 언어의 사용법을 아주 간단하면서도 빠르게 이해시키기 위하여 가장 많이 사용하는 방법 중의 하나는 “Hello, World!”와 같은 문장을 C로 프로그램하고 이를 실행시켜 실제로 이 문장이 디스플레이되는 것을 보여주는 것입니다. 복잡한 설명 보다는 일단 아주 간단한 예를 보여주면 이해가 빠르고 흥미가 생기기 때문이지요.
그 때를 회상하며 한 번 다시 보겠습니다.
————————————————
#include <stdio.h>
int main()
{ printf(“Hello, World!\n”); }
————————————————
그렇다면, 혹시 printf( ) 함수처럼, “WS2812B를 기반으로 하는 컬러 LED의 색상을 누구나 쉽게 지정할 수 있도록 하는 함수를 어떤 고수가 라이브러리로 만들어놓지는 않았을까?” 하는 의문이 들만도 합니다.
과연 그럴까요. 예, 과연 그렇습니다. “YES!”입니다.
우리보다 먼저 이런 형태의 컬러 LED를 접한 선배들이 당연히 만들어 놓았습니다. 이렇게 제공된 라이브러리의 종류는 꽤 되지만 이들 중 우리가 주목할 만한 것은 Adafruit_NeoPixel 과 FastLED입니다.
Adafruit_NeoPixel은 WS2812B를 기반으로 한 NeoPixel 제품(BAR, RING, MATRIX 등)을 생산 판매하고 있는 Adafruit 사에서 제공하는 라이브러리로, 조금은 단순하지만 <LED에 색 지정하기>와 <LED에 데이터 전송하기>의 기본 라이브러리 외에 <한 개씩 색칠하기>, <무지개색 만들기>, <영화관 효과 만들기> 등의 응용 함수를 제공합니다.
FastLED는 Adafruit_NeoPixcel 보다는 조금 더 다양한 라이브러리를 제공하는데, 위에서 언급한 라이브러리나 예제에 더하여, <좌우로 이동하기> <번지는 느낌의 색상 만들기> 등의 기능도 더 제공하며, 적용할 수 있는 컬러LED도 우리가 사용하는 WS2812B 외에 LPD8806, APA102 등 거의 모든 컬러 LED로도 확장되는 장점이 있습니다. FastLED는 또한, 아두이노 외에 ESP9266, Teensy3 등의 플랫폼에서도 사용이 가능하도록 만들어진, 응용 범위가 조금 넓은 전문화된 라이브러리라고 하겠습니다.
오늘 이야기에서는 일단 간단한 라이브러리인 Adafruit_NeoPixel 라이브러리를 이용해보는 것으로 하고 진행해 보겠습니다. (FastLED의 이용은 다음 기회에~)
Adafruits_NeoPixel 라이브러리 설치
위에서도 언급했듯이 라이브러리를 사용하려면 이 라이브러리를 사용할 수 있는 환경을 만들어 주어야 합니다. NeoPixel 라이브러리를 사용하기 위한 설치 방법을 순서대로 나타내면 아래와 같습니다.
1. Github의 Adafruit_NeoPixel 프로젝트를 찾아갑니다. URL은 https://github.com/adafruit/Adafruit_NeoPixel 입니다. 아래의 화면이 나오면 화면 중간 오른쪽의 녹색으로 표시된 [Clones or download]를 클릭하고 새로 나타난 창에서 [Download ZIP]을 선택하여 적당한 디렉토리에 “Adafruit_NeoPixel-master.zip” 파일을 저장합니다.
2. “Adafruit_NeoPixel-master.zip” 파일의 압축을 풉니다. “Adafruit_NeoPixel-master” 디렉토리가 생성됩니다.
3. “Adafruit_NeoPixel-master” 디렉토리를 통째로 아두이노 스케치의 라이브러리인 [\My Doucument \Arduino\library] 디렉토리 아래에 복사합니다. [\My Doucument \Arduino\library\Adafruit_NeoPixel-master] 형태로 보여져야 합니다.
4. 아두이노를 실행합니다. 스케치 화면에서 [파일] ▶ [예제] ▶ {Adafruit_NeoPixel-master} ▶ [simple]를 클릭합니다. 아래와 같이 프로그램이 올라오면 설치가 잘 된 것입니다.
Adafruit NeoPixel 라이브러리 기본 함수
이제 설치가 되었으니 Adafruit_NeoPixel 라이브러리를 사용할 수 있는 환경은 갖추어졌습니다. 그렇다면 실제로 어떤 라이브러리가 어떤 형태로 제공되는지만 알면 되겠네요. 그런데 여기서 잠깐! 돌발 퀴즈!
“세부적인 함수를 사용하기 전에 가장 먼저 결정하고 선언해 놓아야 할 변수가 있는데, 이것은 무엇일까요?” “무엇이 결정되어야만 함수가 동작할 수 있을까요?”
1분 동안만 잠시 각자 생각해 보겠습니다.
흐음. 예, 상당수의 분들은 이미 예상하셨겠지만, Adafruit_NeoPixel 라이브러리 입장에서는 반드시 3가지가 미리 결정되어져야만 하는데, 그것은 첫째, 사용할 LED의 개수이고, 둘째, 데이터 입력으로 사용할 제어기(아두이노)의 출력핀 번호, 마지막으로 셋째, 사용할 LED의 타입(WS2811, WS2812)입니다.
이것이 결정되었다면, Adafruit_NeoPixel 라이브러리는 아래 그림과 같이 원하는 크기(3 X LED 개수)의 버퍼를 준비하고 여기에 어떤 한 순간에 보여지기를 원하는 컬러 값으로 R(Red), G(Green), B(Blue) 값을 저장해 놓은 다음 이것을 데이터출력핀을 통하여 순서대로 끊김없이 카멜레온 DIY LED에게 전송하는 방식을 사용하는 것입니다. (주의 : 예전에 잠깐 이야기했듯이, 데이터의 모양은 RGB 형태이지만 실제 전송될 때는 WS2812B 특성에 맞추어 GRB 순으로 전송됨)
Leds[N]
이렇게 하면 어떤 한 순간 전제 LED의 컬러가 결정되어지므로, 이러한 동작을 시간 간격을 두고 반복적으로 실행하면 움직이는 컬러 LED의 형상을 만들 수 있습니다.
개념적인 설명이 되었으므로, 이제 프로그램을 직접 작성해 보면서 Adafruit_NeoPixel의 기본 함수를 살펴 보겠습니다.
JLED-BAR-10(카멜레온 DIY LED 10개 모듈)을 사용하여 모든 LED를 녹색(Green)으로 유지하는 프로그램을 한 번 작성해 보겠습니다. 아두이노 UNO의 6번핀을 출력핀으로 사용하는 경우 프로그램의 앞 부분은 아래와 같이 되겠습니다.
————————————————-
#include <Adafruit_NeoPixel.h> // Adafruit_NeoPixel 라이브러리 include, 필수 선언!!!
#define PIN 6/ // 결정하여야 할 변수 1 → 데이터 출력핀 번호
#define NUMPIXELS 10 // 결정하여야 할 변수 2 → LED 개수
————————————————-
JLED-BAR-10의 입력쪽으로 3개의 신호 GND, DIN, VCC(+5V)가 아두이노와 연결되어 있는 것을 확인할 수 있습니다.
이제 Adafruit_NeoPixel 클래스로 pixels을 아래와 같이 선언합니다.
————————————————-
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
// pixels는 Adafrut_NeoPixel 구조체의 형태를 가짐
// LED의 개수는 10(NUMPIXELS)이며,
// WS2812B 타입(NEO_GRB + NEO_KHZ800)임
————————————————-
————————————————-
class Adafruit_NeoPixel {
public:
Adafruit_NeoPixel(uint16_t n, uint8_t p=6, uint8_t t=NEO_GRB + NEO_KHZ800);
// n : LED 개수
// p : 출력핀 번호 = 6
// t : 타입 = NEO_GRB (GRB 순서로 데이터를 전송) + NEO_KHZ800 (800KHZ 타입)
// 결국, WS2812B를 사용한다는 의미
~Adafruit_NeoPixel();
void
begin(void), // 시작 함수
show(void), // 데이터 전송 함수, 따로 설명
setPin(uint8_t p), // 출력핀 셋업 함수
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b), // n번째 LED를 r, g, b 값으로 설정하는 함수
setPixelColor(uint16_t n, uint32_t c), // n번째 LED를 c 값(32비트)으로 설정하는 함수
setBrightness(uint8_t), // 밝기 세팅 함수
clear(); // LED OFF 함수
uint8_t
*getPixels(void) const,
getBrightness(void) const;
uint16_t
numPixels(void) const; // 선언된 LED 개수를 추출하는 함수
static uint32_t
Color(uint8_t r, uint8_t g, uint8_t b);
uint32_t
getPixelColor(uint16_t n) const;
inline bool
canShow(void) { return (micros() – endTime) >= 50L; }
};
————————————————
pixels 클래스가 생성되었으므로 setup() 프로그램을 통하여 멤버 함수인 begin()을 콜하여 초기화를 실행합니다.
————————————————-
void setup() {
pixels.begin(); // Adafruit_Neopixel 라이브러리 초기화
}
————————————————-
이제 이를 이용하여 녹색으로 10개 LED를 1초 간격으로 껐다 켰다 깜빡이도록(blink) 프로그램 해보겠습니다.
————————————————-
void loop() {
for(int i=0; i<NUMPIXELS; i++) // 전체 LED에 대하여
pixels.setPixelColor(i, pixels.Color(0,150,0)); // Green 컬러(중간 밝기) 준비.
pixels.show(); // 데이터 전송
delay(1000); // 1초 동안 디스플레이
for(int i=0; i<NUMPIXELS; i++) // 전체 LED에 대하여
pixels.setPixelColor(i, pixels.Color(0,0,0)); // Black 컬러(LED OFF) 준비.
pixels.show(); // 데이터 전송
delay(1000); // 1초 동안 디스플레이
}
————————————————-
————————————————-
#include <Adafruit_NeoPixel.h> // Adafruit_NeoPixel 라이브러리 include, 필수 선언!!!
#define PIN 6 // 결정하여야 할 변수 → 데이터 출력핀 번호
#define NUMPIXELS 10 // 결정하여야 할 변수 → LED 개수
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
// pixels 는 Adafrut_NeoPixel 구조체의 형태를 가짐
// LED의 개수는 10(NUMPIXELS)이며,
// WS2812B 타입(NEO_GRB + NEO_KHZ800)임
void setup() {
pixels.begin(); // Adafruit_Neopixel 라이브러리 초기화
}
void loop() {
for(int i=0; i<NUMPIXELS; i++) // 전체 LED에 대하여
pixels.setPixelColor(i, pixels.Color(0,150,0)); // Green 컬러(중간 밝기) 준비.
pixels.show(); // 데이터 전송
delay(1000); // 1초 동안 디스플레이
for(int i=0; i<NUMPIXELS; i++) // 전체 LED에 대하여
pixels.setPixelColor(i, pixels.Color(0,0,0)); // Black 컬러(LED OFF) 준비.
pixels.show(); // 데이터 전송
delay(1000); // 1초 동안 디스플레이
}
————————————————-
오오~! 성공입니다. 제가 좋아하는 은은한 녹색 LED가 깜빡깜빡 하네요. 기분 UP! 갑자기 히말라야 등정이 생각나는데, 이 정도면 4000m 고지에 베이스캠프 설치는 성공한 정도로 느껴집니다.
JLED-RING-12로 12색상환 표현하기
실력이 얼마나 늘었는지는 예전과 비교해 보면 금방 알 수 있습니다. 지난번 이야기에서 마지막으로 다루었던 작품, JLED-RING-12로 12색상환 표현하기 과제를 라이브러리를 이용하여 한 번 구현해 보겠습니다.
조금 전에 배운 라이브러리를 이용해서 (1) 어레이로 준비한 12가지 색상을, (2) 순서대로 데이터로 세팅한 후, (3) 이것을 JLED-RING-12로 전송하면 되겠습니다. 12가지 색상값은 지난번에 제시한 표와 동일한 값을 사용하겠습니다.
색상 | 빨강 | 다홍 | 주황 | 귤색 | 노랑 | 연두 |
데이터 | 0xff0000 | 0xdc143c | 0xff7f00 | 0xf89b00 | 0xffd400 | 0x66cc00 |
색상 | 녹색 | 청록 | 파랑 | 남색 | 보라 | 자주 |
데이터 | 0x00ff00 | 0×005666 | 0x0000ff | 0x080b54 | 0xee82ee | 0×800080 |
위에서 언급한 기본 라이브러리를 이용하면 다양한 응용 프로그램을 작성할 수 있는데, 이것에 대한 예제는 Adafruit_NeoPixel의 “strandtest” 프로그램에 잘 나타나 있습니다. 우리가 사용할 수 있는 프로그램을 하나씩 살펴봅시다.
어려울 것이 없어 설명없이 바로 스케치 진행합니다. 라이브러리를 사용하니까 정말 간단하네요.
————————————————-
#include <Adafruit_NeoPixel.h> // Adafruit_NeoPixel 라이브러리 include, 필수 선언!!!
#define PIN 6 // 결정하여야 할 변수 → 데이터 출력핀 번호
#define NUMPIXELS 12 // 결정하여야 할 변수 → LED 개수
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
// pixels 는 Adafrut_NeoPixel 구조체의 형태를 가짐
// LED의 개수는 12(NUMPIXELS)이며,
// WS2812B 타입(NEO_GRB + NEO_KHZ800)임
void setup() {
pixels.begin(); // Adafruit_Neopixel 라이브러리 초기화
}
void loop() {
unsigned long data[12] = {0xff0000, 0xdc143c, 0xff7f00, 0xf89b00, 0xffd400, 0x66cc00, 0x00ff00, 0×005666, 0x0000ff, 0x080b54, 0xee82ee, 0×800080}; // 12개 색상 준비
for(int i=0; i<NUMPIXELS; i++) // 전체 LED에 대하여
pixels.setPixelColor(i,data[i]); // 12색상 데이터값 세팅
pixels.show(); // 데이터 전송
}
————————————————-
다양한 응용 프로그램
위에서 언급한 기본 라이브러리를 이용하면 다양한 응용 프로그램을 작성할 수 있는데, 이것에 대한 예제는 Adafruit_NeoPixel의 “strandtest” 프로그램에 잘 나타나 있습니다. 우리가 사용할 수 있는 프로그램을 하나씩 살펴봅시다.
응용 함수 | 설명 |
void colorWipe (uint32_t c, uint8_t wait) |
LED를 하나씩 순서대로 동일한 컬러로 채우는 함수 - c : 채우고자 하는 컬러 - wait : 하나씩 채우는데 걸리는 간격 (ms) |
void rainbow(uint8_t wait) | 전체 LED의 컬러를 무지개처럼 다양한 컬러로 변화시키는 함수 - wait : 컬러를 바꾸는 간격(ms) |
void rainbowCycle (uint8_t wait) |
LED의 컬러를 무지개처럼 다양한 컬러로 서로 다르게 세팅하고 이것을 돌아가면서 변화시키는 함수 - wait : 컬러를 바꾸는 간격(ms) |
void theaterChase (uint32_t c, uint8_t wait) |
LED의 컬러를 동일한 컬러로 N개씩 건너서 세팅하되, 이것도 돌아가면서 LED에 할당하게 함으로써 번쩍번쩍하는 사이키 조명의 느낌을 만드는 함수 - c : 채우고자 하는 컬러 - wait : 변화하는 간격 (ms) |
void theaterChaseRainbow (uint8_t wait) |
LED의 컬러를 다양한 컬러로 3개씩 건너서 세팅하되, 이것도 돌아가면서 LED에 할당하게 함으로써 번쩍번쩍하는 사이키 조명의 느낌을 만드는 함수 - wait : 변화하는 간격 (ms) |
uint32_t Wheel (byte WheelPos) |
0~255까지의 값을 전달하면 R과 G, G와 B, B와 R 값으로만 구성된 4 바이트 컬러값을 리턴하는 함수. 임의의 고르게 분포된 컬러값을 생성하기 위하여 사용 - WheelPos : 0~255 사이의 값 |
예를 들어 “colorWipe(0x00ff0000, 10)” 이렇게 사용하면 모든 LED의 컬러를 빨강색(Red, 0x00ff0000, (X)(R)(G)(B) 순)으로 세팅하되 처음부터 1개씩 10ms의 간격으로 하나씩 증가하는 방식으로 적용됩니다.
이러한 함수를 모두 사용하여 작성한 strandtest( ) 예제 프로그램 전체를 나타내면 아래와 같습니다.
개별 함수의 동작을 이해하려면 약간의 시간과 노력이 필요하나, 하나씩 차근차근 생각해 보면 이해가 될 수 있는 부분이므로 여러분 모두가 짬을 내서 찬찬히 공부해 보시기 바랍니다. 이용에만 관심있는 분들은 굳이 개별 함수의 내부의 프로그램 동작을 이해하지 않고 그냥 기능적으로만 이해한 다음, 그냥 함수를 불러다 쓰기만 해도 괜찮겠습니다.
—————————————————-
#include <Adafruit_NeoPixel.h>
#define PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(45, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
strip.begin();
strip.show(); // Initialize all pixels to ‘off’
}
void loop() {
// Some example procedures showing how to display to the pixels:
colorWipe(strip.Color(255, 0, 0), 50); // Red
colorWipe(strip.Color(0, 255, 0), 50); // Green
colorWipe(strip.Color(0, 0, 255), 50); // Blue
// Send a theater pixel chase in…
theaterChase(strip.Color(127, 127, 127), 50); // White
theaterChase(strip.Color(127, 0, 0), 50); // Red
theaterChase(strip.Color( 0, 0, 127), 50); // Blue
rainbow(20);
rainbowCycle(20);
theaterChaseRainbow(50);
}
// Fill the dots one after the other with a color
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 rainbow(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 255));
}
strip.show();
delay(wait);
}
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}
//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
for (int j=0; j<10; j++) { //do 10 cycles of chasing
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, c); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r – g – b – back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 – WheelPos;
if(WheelPos < 85) {
return strip.Color(255 – WheelPos * 3, 0, WheelPos * 3);
} else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 – WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 – WheelPos * 3, 0);
}
}
—————————————————-
이제 이 프로그램을 아래와 같이 JLED-BAR-10, JLED-STAR-10, JLED-RING-12, JLED-SNOW-13의 4가지 카멜레온 DIY LED를 순서대로 연결한 [3단 아이스크림] 형상(LED 총 45개)에 적용하여 업로드하고 실행하여 보겠습니다.
wheel( ) 함수는 다른 함수를 사용할 때 내부에서 사용되는 함수이므로 이것을 제외하고 나머지 5가지 함수는 눈으로 그 기능을 바로 확인할 수 있습니다. 아래에 결과 사진을 제시하였습니다.
<colorWipe( ) 함수> 실행 결과
<rainbow( ) 함수> 실행 결과
<rainbowCycle( ) 함수> 실행 결과
<theaterChase( ) 함수> 실행 결과
<theaterChaseCycle( ) 함수> 실행 결과
당연한 이야기지만 다행히도(?) 모든 함수가 다 잘 동작하는 것 같죠?굿~입니다. 이제 히말라야 등정에서 6,000m 정도 위치에 제1캠프를 설치한 정도는 되지 않았을라나요? 여기서 더 나아간다면 이제부터는 조금씩은 자신의 루트를 개척하면서 가야하는 경우가 생길 수 있겠습니다. 물론 잘 찾아보면 아직도 많은 선배들이 닦아 놓은 훌륭한 루트가 중간 중간 많이 있긴 하겠습니다.
카멜레온 DIY LED를 위한 아두이노 라이브러리를 설명한다고 하면서 Adafruit_NeoPixcel 라이브러리만 설명하였는데… 사실 카멜레온 DIY LED제품이나 NeoPixel 제품은 형태만 다를뿐 WS2812B를 한 줄로 연결한 동일한 형태를 가지고 있기 때문에 라이브러리는 동일하게 사용 가능합니다. 그래도 카멜레온 DIY LED만을 위한 따로 제공하는 라이브러리가 몇 개는 있어야 한다구요? 예. 그러면 오늘은 일단 이 정도에서 마무리하고, 다음 시간 [다양한 형상의 카멜레온 DIY LED]를 만나보면서 좀 더 다이나믹한 응용 함수도 함께 소개하는 시간을 갖도록 하겠습니다.
다음 회에 환한 얼굴로 또 만나겠습니다. 안녕히 계십시오. 야옹~