와이파이로 네오픽셀 LED 스트립 제어: 안드로이드 앱 연동 ESP8266 프로젝트
부품 및 소모품
| 부품 |
수량 |
| ElectroPeak ESP8266 시리얼 와이파이 Witty Cloud 보드 |
1 |
| 네오픽셀 스마트 LED 스트립 (60LED/m) |
3 |
| ElectroPeak 로직 레벨 컨버터 |
1 |
| ElectroPeak 21cm 40핀 수-암 점퍼 와이어 |
1 |
| PVC 파이프 60cm, 2인치 |
1 |
| 트레이싱 페이퍼 |
1 |
| 유리 실린더 |
1 |
| 5V 전원 공급장치 (최소 9A) |
1 |
| Arduino Nano R3 |
1 |
필요한 도구 및 기계
앱 및 온라인 서비스
프로젝트 소개
ElectroPeak 공식 웹사이트에서 이 튜토리얼과 다른 멋진 튜토리얼을 볼 수 있습니다.
와이파이 무선 제어로 멋진 불꽃 시뮬레이션 효과를 만듭니다. 안드로이드 스마트폰용 모바일 앱(깔끔한 인터페이스)이 준비되어 있어 설치 후 바로 가지고 놀 수 있습니다! 아두이노와 ESP8266으로 불꽃을 제어합니다. 이 프로젝트를 마치면 다음을 배우게 됩니다:
- 네오픽셀 작동 원리
- ESP8266 프로그래밍 및 와이파이로 변수 제어
- 네오픽셀로 멋진 불꽃 효과 만들기
네오픽셀 소개
개별 주소 지정 가능한 LED, 흔히 네오픽셀이라 불리는 이들은 꽤 오래전부터 존재했습니다. 일반 RGB LED와 비슷하지만 이름 그대로 각 LED의 색상을 개별적으로 제어할 수 있어 무한히 멋진 패턴과 애니메이션을 만들 수 있습니다. WS2812B의 경우 전원 2선, 데이터 1선 총 3선만 필요합니다. 즉, 아두이노 핀 1개만으로 수많은 LED를 제어할 수 있습니다!
이 프로젝트에서는 스마트 LED로 불꽃 효과를 만듭니다. LED 제어에는 훌륭한 FastLED 라이브러리를 사용합니다. Mark Kriegsman이 작성한 라이브러리 예제인 Fire2012 스케치를 사용합니다. 30개 LED씩 6개 스트립(총 180개 LED)을 사용하며, 이를 PVC 파이프에 붙이고 유리 실린더(보통 꽃병으로 쓰임) 안에 넣습니다. LED 빛이 연속적으로 보이게 하려면 확산이 필요한데, 트레이싱 페이퍼를 사용해 빛을 통과시키면서 확산시킵니다.
제작 과정
- 적절한 유리 실린더를 구합니다(길이 60cm, 지름 12cm).
- 내부 길이를 재고 PVC 파이프를 잘라 실린더 안에 맞춥니다(내부 길이 59cm면 파이프도 59cm). 지름 4cm 파이프가 적당합니다.
- LED 스트립을 6등분합니다. 여기서는 60LED/m 밀도 스트립을 사용하며(더 높은 밀도면 더 좋은 효과), 50cm 길이 6개가 필요해 총 3미터입니다. PVC 파이프 둘레에 6개 스트립을 균등 간격으로 붙입니다.
- LED 스트립 연결: 스트립에 직접 와이어를 납땜하거나 핀 헤더를 먼저 납땜 후 브레드보드 와이어로 연결합니다.
- 파이프를 실린더 중앙에 고정: 폼으로 실린더 내부 지름과 같은 외경, 파이프 외경과 같은 내경의 원을 잘라 양쪽에 끼웁니다.
코드
Arduino IDE로 코딩하고 ESP8266에 업로드합니다. SPIFFS에 컨트롤러 소프트웨어 파일을 올리려면 3MB SPIFFS가 있는 ESP8266 보드가 필요합니다. SPIFFS(Serial Peripheral Interface Flash File System)에 파일을 업로드하면 브라우저(폰이나 노트북)에서 ESP 주소(기본 192.168.4.1)로 접속해 앱 설치 없이 컨트롤러 인터페이스를 사용할 수 있습니다. 아이폰/아이패드 사용자는 이 방법이 유일한 선택지입니다.
다음 스케치를 ESP 보드에 업로드하세요. FastLED 라이브러리가 필요하니 Arduino IDE에 추가하세요(여기서 다운로드). 불꽃 시뮬레이션 코드는 Mark Kriegsman의 Fire2012 예제를 기반으로 하며, 여기서는 가변 개수 스트립을 사용하도록 수정했습니다. 스트립/LED가 많을수록 효과가 더 좋습니다.
불꽃 시뮬레이션 로직은 예제 파일에 명확히 설명되어 있습니다. 작동 원리를 알고 싶다면 예제 소스 코드를 읽어보세요.
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include "FastLED.h"
#include "EEPROM.h"
#include "FS.h" // SPIFFS용
#define DATA_PIN 5
#define LED_TYPE WS2811
#define COLOR_ORDER GRB
#define NUM_LEDS 30
#define NUM_STRIPS 6
#define CHIPSET WS2812B
// EEPROM 저장 주소
#define cs0Adr 0
#define cs1Adr 3
#define cs2Adr 6
#define cs3Adr 9
#define BriAdr 15
#define FpsAdr 16
#define SparkingAdr 17
#define CoolingAdr 18
#define EEPROMCheckAdr 20
CRGB leds[NUM_STRIPS * NUM_LEDS];
String inData;
uint8_t FPS = 100;
uint8_t SPARKING = 150;
uint8_t COOLING = 90;
uint8_t BRIGHTNESS = 100;
uint8_t csRGB[4][3] = {{0,0,0}, {255,0,0}, {255,127,0}, {255,255,255}};
unsigned long previousMillis = 0;
bool change = false;
unsigned long changeMillis = 0;
bool initSetup = true;
CRGBPalette16 gPal;
ESP8266WebServer server(80);
void setup() {
EEPROM.begin(200);
cWiFi();
setupFastLED();
loadConfig();
gPal = CRGBPalette16(
CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]),
CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]),
CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]),
CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2])
);
}
inline void setupFastLED() {
delay(1000);
FastLED.addLeds<CHIPSET, DATA_PIN, COLOR_ORDER>(leds, NUM_STRIPS * NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
}
void loop() {
server.handleClient();
if (change) {
if (millis() - changeMillis > 60000) {
change = false;
saveToEEPROM();
}
}
fire();
FastLED.show();
FastLED.delay(1000 / FPS);
}
// Fire2012 팔레트 버전 (스트립별)
void Fire2012WithPalette(int stripNo) {
static byte heat[NUM_STRIPS][NUM_LEDS];
// 1. 모든 셀 약간 식히기
for(int i=0; i<NUM_LEDS; i++) {
heat[stripNo][i] = qsub8(heat[stripNo][i], random8(0, ((COOLING * 10) / NUM_LEDS) + 2));
}
// 2. 열이 위로 퍼지며 확산
for(int k=NUM_LEDS-1; k>=2; k--) {
heat[stripNo][k] = (heat[stripNo][k-1] + heat[stripNo][k-2] + heat[stripNo][k-2]) / 3;
}
// 3. 바닥 근처에 무작위 불씨 생성
if(random8() < SPARKING) {
int y = random8(5);
heat[stripNo][y] = qadd8(heat[stripNo][y], random8(160,200));
}
// 4. 열 값을 LED 색상으로 매핑
for(int j=0; j<NUM_LEDS; j++) {
byte colorindex = scale8(heat[stripNo][j], 240);
CRGB color = ColorFromPalette(gPal, colorindex);
leds[j+stripNo*NUM_LEDS] = color;
}
}
void fire() {
for(int i=0; i<NUM_STRIPS; i++) Fire2012WithPalette(i);
}
// ... (웹 서버 핸들러, EEPROM 저장/로드, 와이파이 설정 등 생략)
SPIFFS 업로드 방법
- 스케치 폴더 안에 "data" 폴더를 만들고 업로드할 파일들을 넣습니다.
- Arduino ESP8266 Filesystem Uploader 플러그인을 설치합니다(GitHub 페이지 참고).
- 툴 메뉴에서 "ESP8266 Sketch Data Upload"를 선택합니다. 업로드 속도를 921600으로 설정하면 더 빠릅니다.
작동 원리
ESP8266에 업로드된 스케치가 웹 서버를 생성하고, 앱에서 보낸 요청에 응답합니다. 앱은 단순히 ESP8266에 GET 요청을 보냅니다. 색상 팔레트 데이터, Sparking, Cooling 등 파라미터가 GET 요청의 인자로 전송됩니다.
예: 밝기 설정 요청 - https://192.168.4.1/conf?brightness=224
안드로이드 앱
Phonegap으로 제작되었습니다. 웹 기술(HTML, CSS, JavaScript)로 크로스 플랫폼 모바일 앱을 만들 수 있습니다. 소스 코드는 해당 페이지에서 확인 가능합니다.