메뉴 전체보기

회원메뉴

프리즘캐스트: 맞춤형 앰비라이트 백라이트 > 게시판

본문 바로가기

쇼핑몰 검색

NO. 3443
제목 : 프리즘캐스트: 맞춤형 앰비라이트 백라이트
2026-09-28 10:33

소개: 프리즘캐스트: 맞춤형 앰비라이트 백라이트


소개: 프리즘캐스트: 맞춤형 앰비라이트 백라이트


소개: 프리즘캐스트: 맞춤형 앰비라이트 백라이트


소개: 프리즘캐스트: 맞춤형 앰비라이트 백라이트


안녕하세요! 저는 Ayushmaan Bhardwaj이며, 전자기기 제작, 제품 디자인, 아이디어를 기능성 장치로 전환하는 것을 좋아하는 전기 및 전자 공학 (EEE) 학생입니다.

제가 항상 제 설정에서 원했던 것은 디스플레이 동기화 RGB 모니터 백라이트였습니다. 이미 WLED, Hyperion, Prismatik와 같은 멋진 프로젝트들이 있지만, 저는 다른 무언가를 원했습니다. 각 솔루션은 고유의 장점이 있었지만, 제가 생각한 것과는 잘 맞지 않는 한계도 있었습니다.

그래서 기존 프로젝트를 수정하는 대신, 모든 것을 완전히 처음부터 만들기로 결정했습니다—펌웨어, 브라우저 대시보드, 장치 UI에서 3D 프린트 인클로저와 하드웨어까지 말이죠.

그 결과는 PrismCast입니다.

주요 기능은 브라우저 기반 디스플레이 동기화로, 사용자 정의 웹 앱이 화면을 캡처하고 가장자리 주변의 색상을 샘플링하여 무선으로 ESP32에 스트리밍합니다. 이 ESP32는 모니터 뒤의 WS2812B LED 스트립을 구동합니다. 전용 데스크탑 소프트웨어는 필요하지 않습니다.

PrismCast가 디스플레이 동기화가 실행되지 않을 때도 유용하도록, 2.4인치 TFT 디스플레이와 세 개의 기계식 스위치가 있는 독립형 컨트롤러도 설계했습니다. 이 장치는 조명 모드, 밝기, 색상과 같은 일상적인 설정에 빠르게 접근할 수 있도록 하며, 미래적인 책상 시계 역할도 합니다.

더 많은 제어를 원하는 사용자들을 위해, 웹 대시보드는 디스플레이 동기화, LED별 편집, 모니터 레이아웃 구성, 사용자 정의 색상 제어, 프리셋 등 고급 기능을 잠금 해제합니다.

이 Instructable에서는 제가 인클로저를 설계하고, 전자 기기를 조립하고, 펌웨어를 작성하고, 웹 대시보드를 구축하고, 모든 것을 최종 프로젝트로 통합하는 방법을 보여드리겠습니다. 빌드를 즐기시길 바랍니다!




STEP 1. 준비물


준비물


필요한 재료:

  1. ESP32 WROOM 개발 보드
  2. 2 × 1미터 WS2812B 주소 지정 가능 LED 스트립, 60 LEDs/m
  3. 2.4인치 ILI9341 320 × 240 SPI TFT 디스플레이
  4. 3 × Cherry MX Red 기계식 키보드 스위치
  5. HW-688 DC-DC 벅 컨버터
  6. 74AHCT125 로직 레벨 시프터
  7. 330옴 저항
  8. 1000µF 커패시터
  9. 100nF 커패시터
  10. 전선
  11. 커넥터
  12. 퍼프보드 / 일반 프로토타입 재료




STEP 2. 개념


Fusion 360을 열기 전이나 단일 와이어를 납땜하기 전, 나는 PrismCast가 실제로 무엇이 되기를 원하는지에 대해 생각하는 시간을 가졌습니다. 나는 단순한 RGB 모니터 백라이트가 되기를 원하지 않았습니다. 매일 사용하기 재미있는 완전한 책상 액세서리처럼 느껴지기를 원했습니다.

이미 WLED, Hyperion, Prismatik와 같은 환상적인 프로젝트들이 있으며, 이들은 정말 잘 작동합니다. 하지만 이들을 탐색하면서, 각 프로젝트마다 내가 좋아하는 기능과 다르게 작동했으면 하는 몇 가지가 있다는 것을 깨달았습니다. 기존 프로젝트를 수정하는 대신, 나는 전체 시스템을 처음부터 구축하는 것에 도전했습니다. 이는 나만의 펌웨어를 작성하고, 맞춤형 웹 대시보드를 설계하며, 장치 인터페이스를 만들고, 심지어 인클로저를 직접 설계하고 인쇄하는 것을 의미했습니다.

PrismCast의 가장 큰 특징은 브라우저 기반 디스플레이 동기화입니다. 맞춤형 웹 앱이 화면을 캡처하고, 가장자리 주변의 색상을 감지하여 무선으로 ESP32에 전송하며, 이는 모니터 뒤의 LED를 실시간으로 업데이트합니다. 모든 것이 브라우저를 통해 실행되기 때문에, 전용 데스크탑 소프트웨어를 설치할 필요가 없습니다.

나는 또한 디스플레이 동기화가 실행되지 않을 때도 프로젝트가 유용하게 유지되기를 원했습니다. 그래서 컨트롤러에는 자체 2.4인치 TFT 디스플레이와 세 개의 기계식 스위치가 있어 브라우저에 손을 뻗지 않고도 조명 모드, 밝기 및 색상을 쉽게 변경할 수 있습니다. 더 많은 제어가 필요할 때, 웹 대시보드는 LED별 편집, 모니터 레이아웃 구성, 맞춤형 색상 제어, 프리셋 관리와 같은 고급 기능을 제공합니다.

특징

  1. 브라우저 기반 디스플레이 동기화
  2. 전용 데스크탑 소프트웨어 필요 없음
  3. 완전히 처음부터 구축됨
  4. 맞춤형 ESP32 펌웨어
  5. 2.4인치 TFT 디스플레이가 있는 독립형 컨트롤러
  6. 빠른 제어를 위한 세 개의 기계식 스위치
  7. 여러 가지 내장 조명 효과
  8. 고급 브라우저 대시보드
  9. LED별 맞춤화
  10. 다양한 모니터 크기 및 레이아웃 지원
  11. 맞춤형 3D 인쇄 인클로저
  12. 미래적인 책상 시계 인터페이스

개념이 확정되었으니, 이제 모든 것을 통합할 인클로저 설계를 시작할 때가 되었습니다.




STEP 3. 인클로저 설계하기


인클로저 설계하기


인클로저 설계하기


인클로저 설계하기


인클로저 설계하기


PrismCast는 제 책상 위에 놓이도록 설계되었기 때문에, 전형적인 DIY 전자 프로젝트보다 현대적인 책상 액세서리처럼 보이기를 원했습니다. 영감을 찾던 중 HiDock을 발견했고, 각진 앞면의 깔끔하고 미니멀한 디자인이 마음에 들었습니다. 이를 영감으로 삼아, 제가 사용하고 있는 하드웨어에 맞춰 Fusion 360에서 완전히 맞춤형 인클로저를 설계했습니다.

인클로저는 세 개의 개별 부품으로 구성되어 있습니다: 상단 하우징, 하단 커버, 그리고 전용 디스플레이 장착판입니다. TFT를 별도의 판에 장착함으로써 조립이 훨씬 쉬워졌고, 디스플레이가 앞쪽 개구부와 완벽하게 정렬되도록 보장했습니다.

앞면에는 왼쪽에 2.4인치 TFT 디스플레이가 있고, 오른쪽에는 세 개의 기계식 스위치가 있으며, 내부 레이아웃은 ESP32와 나머지 전자 장치를 깔끔하게 수용할 수 있도록 설계되었습니다.

치수와 내부 여유 공간을 미세 조정하기 위해 몇 번의 반복 작업을 거친 후, 최종 디자인에 만족했습니다.




STEP 4. 3D 프린팅


3D 프린팅


3D 프린팅


3D 프린팅


3D 프린팅


디자인이 완료되었으므로 PrismCast를 실제로 구현할 시간입니다.

인클로저는 제 Anycubic Kobra S1에서 인쇄되었습니다. 본체는 Blue Sparkle PLA를 사용하였고, 디스플레이 장착판은 Black Rapid PLA로 인쇄하여 장치 전면에 깔끔한 대비를 주었습니다.

인클로저는 세 개의 개별 부품—상단 하우징, 하단 커버, 디스플레이 장착판—으로 구성되어 있으므로, 각 부품을 개별적으로 인쇄한 후 지지대를 정리하고 하드웨어를 테스트 장착했습니다.

전자 부품으로 넘어가기 전에 TFT 디스플레이, 기계식 스위치, 및 기타 구성 요소가 올바르게 맞는지 확인했습니다. 다행히 모든 것이 완벽하게 정렬되어 최종 조립이 훨씬 쉬워졌습니다.

프린터: Anycubic Kobra S1

재료:

  1. Blue Sparkle PLA (상단 하우징 및 하단 커버)
  2. Black Rapid PLA (디스플레이 장착)

슬라이서: Anycubic Slicer Next (또는 실제로 그곳에서 슬라이스한 경우 Bambu Studio)




STEP 5. 전자기기 제작하기


전자기기 제작하기


모든 3D 프린트 부품이 준비되었으므로, 이제 PrismCast를 구동하는 전자 장치를 조립할 시간입니다. 이곳에서 프로젝트가 실제로 하나로 모이기 시작했으며, 각 개별 구성 요소가 인클로저 안에 제자리를 찾았습니다.

프로젝트가 여러 개의 서로 다른 모듈로 구성되어 있기 때문에, 모든 것을 한 번에 연결하는 대신 하나씩 조립하고 테스트하기로 결정했습니다. 이렇게 하면 디버깅이 훨씬 쉬워졌고, 다음 단계로 넘어가기 전에 각 부품이 올바르게 작동하는지 확인하는 데 도움이 되었습니다.

정리를 위해 이 단계를 다음 섹션으로 나누었습니다:

  1. 디스플레이 연결 – 2.4인치 ILI9341 TFT 디스플레이 연결 및 장착.
  2. 기계 스위치 – 내비게이션에 사용되는 세 개의 Cherry MX 스위치 배선.
  3. 전원 분배 – 전원 공급 장치, 로직 레벨 시프터, 커패시터 및 공통 접지 연결.
  4. LED 설치 – WS2812B LED 스트립 설치, 전원 주입 및 확산기.
  5. 최종 조립 – 모든 구성 요소를 인클로저 안에 장착하고 배선 완료.

디스플레이 연결부터 시작해 봅시다.




STEP 6. 디스플레이 연결


디스플레이 연결


디스플레이 연결


디스플레이 연결


디스플레이에는 2.4인치 ILI9341 TFT 디스플레이를 SPI 인터페이스와 함께 사용했습니다. 크기, 해상도 및 성능 간의 균형이 잘 맞아 시계, 메뉴 및 장치 상태를 표시하는 데 이상적입니다.

디스플레이는 전용 디스플레이 장착판에 장착되어 있어 인클로저의 전면 개구부와 완벽하게 정렬되며 조립이 훨씬 쉬워집니다.

TFT는 다음 연결을 사용하여 ESP32와 SPI로 통신합니다:

  1. VCC → 3.3V
  2. GND → GND
  3. CS → GPIO 5
  4. RESET → GPIO 4
  5. DC → GPIO 2
  6. MOSI → GPIO 23
  7. MISO → GPIO 19 S
  8. CK → GPIO 18
  9. LED → 3.3V

모든 연결이 완료되면, 나머지 전자 장치로 넘어가기 전에 간단한 그래픽 테스트 스케치를 사용하여 디스플레이를 테스트했습니다.




STEP 7. 기계식 스위치 연결


기계식 스위치 연결


기계식 스위치 연결


웹 대시보드에 의존하지 않고 PrismCast를 쉽게 사용할 수 있도록 세 개의 Cherry MX Red 기계식 스위치를 추가했습니다. 이 스위치는 메뉴를 탐색하고, 옵션을 선택하며, 장치에서 직접 설정을 빠르게 조정하는 데 사용됩니다.

각 스위치는 GPIO 핀과 GND 사이에 연결되어 있으며, ESP32의 내부 INPUT_PULLUP 저항기가 사용됩니다. 이렇게 하면 외부 풀업 저항기가 필요 없어 배선이 간단해집니다.

연결:

  1. NEXT → GPIO 32
  2. SELECT → GPIO 33
  3. BACK → GPIO 25

스위치를 배선한 후, 각 버튼 누름이 올바르게 감지되는지 확인하기 위해 간단한 테스트 스케치를 업로드한 다음 다음 섹션으로 넘어갔습니다.




STEP 8. LED 스트립 설치하기


LED 스트립 설치하기


LED 스트립 설치하기


LED 스트립 설치하기


LED 스트립 설치하기


LED 스트립 설치하기


백라이트를 위해 두 개의 1미터 WS2812B LED 스트립을 사용했으며, 미터당 60개의 LED가 있어 총 120개의 개별 주소 지정 가능한 LED가 됩니다.

스트립은 3D 프린터로 제작한 확산기를 사용하여 모니터 뒷면에 장착되었으며, 이는 빛을 더 고르게 퍼뜨리고 벽에 훨씬 부드러운 빛을 만들어 줍니다. 스트립을 설치하는 동안, LED가 펌웨어에서 예상하는 레이아웃과 일치하도록 올바른 데이터 방향을 따르도록 했습니다.

스트립이 설치된 후, 74AHCT125 로직 레벨 시프터를 통해 ESP32에 연결하고 최종 조립을 진행하기 전에 간단한 테스트 스케치를 사용하여 모든 LED를 테스트했습니다.

포함할 이미지

  1. WS2812B LED 스트립
  2. LED 스트립 설치
  3. 3D 프린터로 제작한 확산기
  4. 전원이 켜진 LED





STEP 9. 전력 분배


전력 분배


PrismCast에 전원을 공급하기 위해 HW-688 DC-DC 벅 컨버터를 사용했습니다. 이 장치는 ESP32와 WS2812B LED 스트립 모두에 안정적인 5V 전원을 제공합니다.

LED 스트립은 5V에서 작동하고 ESP32는 3.3V 로직을 출력하므로, ESP32와 LED 간의 신뢰할 수 있는 통신을 보장하기 위해 74AHCT125 로직 레벨 시프터를 추가했습니다.

배선에서 가장 중요한 부분 중 하나는 모든 구성 요소가 공통 접지를 공유하는 것이었습니다. ESP32, TFT 디스플레이, LED 스트립, 벅 컨버터 및 스위치가 모두 함께 연결되어 시스템 전반에 걸쳐 안정적인 작동을 보장합니다.

전원 연결이 완료되면 출력 전압을 확인하고 LED 설치로 넘어가기 전에 각 구성 요소를 개별적으로 테스트했습니다.

포함할 이미지

  1. HW-688 벅 컨버터
  2. 전원 배선
  3. 로직 레벨 시프터
  4. 완전한 전원 분배





STEP 10. 최종 조립


최종 조립


최종 조립


최종 조립


모든 개별 구성 요소가 테스트된 후, 드디어 모든 것을 인클로저 안에 조립할 시간이었다.

먼저 TFT 디스플레이를 디스플레이 장착판에 고정한 다음, 기계식 스위치와 ESP32를 설치했다. 인클로저 안에 배선을 깔끔하게 정리한 후, 나머지 구성 요소를 연결하고 모든 것이 예상대로 작동하는지 최종 점검을 수행했다.

인클로저가 닫히자, PrismCast는 개별 부품의 집합이 아닌 완성된 제품처럼 보이기 시작했다.

하드웨어가 완성되었으므로, 다음 단계는 디스플레이를 구동하고, LED를 제어하며, 사용자 입력을 처리하고, 웹 대시보드와 통신하는 펌웨어를 작성하여 생명을 불어넣는 것이었다.

포함할 이미지

  1. 인클로저 안에 장착된 구성 요소
  2. 내부 배선
  3. 닫기 전의 인클로저
  4. 완전히 조립된 컨트롤러




STEP 11. 하드웨어 테스트


최종 펌웨어로 넘어가기 전에 모든 구성 요소가 제대로 작동하는지 확인하기 위해 간단한 하드웨어 테스트 스케치를 작성했습니다.

테스트 프로그램은 TFT 디스플레이, 기계식 스위치, WS2812B LED 스트립, Wi-Fi의 기본 기능을 확인하여 모든 모듈이 메인 펌웨어에 통합되기 전에 예상대로 작동하는지 확인했습니다.

이 간단한 단계는 배선이나 하드웨어 문제를 조기에 발견하는 데 도움이 되었고, 나머지 개발 프로세스를 훨씬 더 원활하게 만들었습니다.

포함할 이미지

  1. 하드웨어 테스트 실행
  2. TFT 디스플레이 테스트
  3. LED 테스트
  4. 버튼 테스트





STEP 12. 소프트웨어 개발하기


소프트웨어 개발하기


소프트웨어 개발하기


PrismCast의 주요 목표 중 하나는 기존 소프트웨어에 의존하는 대신 완전한 생태계를 구축하는 것이었습니다. WLED, Hyperion, 또는 Prismatik와 같은 솔루션을 사용하는 대신, 저는 전체 소프트웨어 스택을 처음부터 개발했습니다. 이를 통해 하드웨어, 사용자 인터페이스 및 전반적인 경험에 대한 완전한 제어를 가질 수 있었습니다.

소프트웨어는 Wi-Fi를 통해 함께 작동하는 세 가지 주요 부분으로 나뉩니다.

ESP32 펌웨어는 TFT 디스플레이, 조명 효과, 버튼 입력, 시계 인터페이스를 제어하고 브라우저와 통신합니다.

브라우저 대시보드는 HTML, CSS 및 JavaScript를 사용하여 구축된 맞춤형 웹 애플리케이션입니다. 이 애플리케이션은 디스플레이 동기화, LED별 편집, 조명 모드 및 장치 구성을 포함한 고급 제어 기능을 제공합니다.

통신 계층은 WebSockets를 사용하여 양쪽을 연결합니다. 밝기, 색상 및 조명 모드와 같은 설정은 JSON 메시지로 교환되며, 고속 디스플레이 동기화는 성능 향상을 위해 압축된 이진 패킷을 사용하여 전송됩니다.

아래 다이어그램은 이러한 다양한 부분이 서로 어떻게 상호작용하는지를 보여줍니다.

중요한 설계 결정 중 하나는 ESP32를 단일 진실의 출처로 유지하는 것이었습니다. 설정이 물리적 버튼을 사용하여 변경되든 웹 대시보드를 통해 변경되든, ESP32는 먼저 내부 상태를 업데이트한 다음 그 정보를 브라우저와 동기화합니다. 이렇게 하면 두 인터페이스가 완벽하게 동기화되고 서로 간의 충돌을 피할 수 있습니다.

소프트웨어를 이해하기 쉽게 만들기 위해 이 섹션을 다음과 같은 부분으로 나누었습니다:

  1. 펌웨어 아키텍처
  2. 장치 사용자 인터페이스
  3. 조명 엔진
  4. 브라우저 대시보드
  5. 통신 프로토콜
  6. 시스템 아키텍처

이제 펌웨어가 어떻게 구조화되어 있는지, 시스템의 다양한 부분을 어떻게 관리하는지 살펴보겠습니다.




STEP 13. ESP32 펌웨어


ESP32 펌웨어


ESP32는 PrismCast의 핵심입니다. TFT 디스플레이를 제어하고, 사용자 인터페이스를 렌더링하며, WS2812B LED 스트립을 구동하고, 기계 스위치를 읽고, WebSockets를 사용하여 브라우저 대시보드와 통신합니다. 모든 것이 단일 장치에서 실행되어 전체 시스템의 중앙 컨트롤러 역할을 합니다.

프로젝트를 체계적으로 유지하기 위해 Arduino 프레임워크와 그래픽, 네트워킹, JSON 파싱 및 LED 제어를 처리하는 몇 가지 오픈 소스 라이브러리를 사용했습니다.


#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <NeoPixelBus.h>
#include <WiFi.h>
#include <WebSocketsServer.h>
#include <ArduinoJson.h>

펌웨어는 모든 하드웨어 연결을 정의하고 디스플레이, LED 및 WebSocket 서버를 제어하는 데 필요한 객체를 생성하는 것으로 시작합니다.


#define TFT_CS 5
#define TFT_DC 2
#define TFT_RST 4

#define LED_PIN 27
#define NUM_LEDS 120

#define SW_NEXT 32
#define SW_SELECT 33
#define SW_BACK 25

#define WS_PORT 81

Adafruit_ILI9341 tft(TFT_CS, TFT_DC, TFT_RST);
NeoPixelBus<NeoGrbFeature,
NeoEsp32Rmt0Ws2812xMethod>
strip(NUM_LEDS, LED_PIN);

WebSocketsServer webSocket(WS_PORT);

PrismCast는 각기 다른 색상 테마와 애니메이션을 가진 여러 조명 모드를 지원합니다. 현재 모드는 enum으로 저장되어 있어 펌웨어 전반에 걸쳐 효과를 쉽게 전환할 수 있습니다.


enum Mode {
M_SOLID,
M_BREATHE,
M_WAVE,
M_COMET,
M_PULSE,
M_COUNT
};

Mode gMode = M_WAVE;

브라우저와의 통신은 ESP32에서 직접 실행되는 WebSocket 서버를 사용하여 처리됩니다. 펌웨어는 두 가지 유형의 데이터를 수신합니다: JSON 메시지는 밝기 및 조명 모드와 같은 설정을 위한 것이고, 바이너리 패킷은 고속 디스플레이 동기화를 위한 것입니다.


void onWsEvent(uint8_t id,
WStype_t type,
uint8_t* payload,
size_t len)
{
switch(type)
{
case WStype_CONNECTED:
broadcastState();
break;

case WStype_BIN:
// 라이브 디스플레이 동기화
break;

case WStype_TEXT:
// JSON 설정
break;
}
}

디스플레이 동기화가 활성화되면 브라우저는 RGB 값의 연속 스트림을 전송합니다. ESP32는 이러한 값을 LED 버퍼에 직접 복사하고 즉시 스트립을 업데이트하여 지연 시간을 극도로 낮게 유지합니다.


uint16_t n = len / 3;

for (int i = 0; i < n; i++) {
strip.SetPixelColor(
i,
RgbColor(
payload[i * 3],
payload[i * 3 + 1],
payload[i * 3 + 2]
)
);
}

strip.Show();

메인 루프는 디스플레이, 버튼, 조명 효과 및 WebSocket 서버를 차단하지 않고 지속적으로 업데이트하여 장치의 모든 부분이 반응성을 유지할 수 있도록 합니다.


void loop() {

webSocket.loop();

handleButtons();

updateClock();

updateEffects();

drawUI();
}

버튼 처리:

세 개의 Cherry MX 스위치는 모든 일반 컨트롤에 빠르게 접근할 수 있도록 합니다. 사용자는 메뉴를 탐색하고, 옵션을 선택하며, 브라우저 대시보드 없이 홈 화면으로 돌아갈 수 있습니다.

if(nextButton.pressed())
nextMenu();

if(selectButton.pressed())
selectItem();

if(backButton.held())
openTimeSettings





STEP 14. 장치 인터페이스 설계


장치 인터페이스 설계


장치 인터페이스 설계


PrismCast의 주요 목표 중 하나는 단순한 RGB 컨트롤러가 아닌 전용 데스크탑 가젯처럼 느껴지게 하는 것이었습니다. 간단한 설정 화면 대신, 세 개의 기계식 스위치만으로 제어할 수 있는 완전한 사용자 인터페이스를 설계했습니다.

기본 화면은 사용자 정의로 그려진 세그먼트 숫자, 현재 날짜, 초 진행 바 및 활성 조명 모드가 있는 미래적인 디지털 시계입니다. 버튼이 눌릴 때마다 인터페이스는 부드럽게 메뉴로 전환되며, 사용자는 모드, 색상, 밝기 및 기타 설정을 변경할 수 있습니다.


void drawHomeScreen() {

drawClock();

drawDate();

drawModeChip();

drawProgressBar();

drawStatusBar();

}

메뉴 시스템은 세 개의 Cherry MX 스위치에 의해 완전히 구동됩니다. 각 버튼은 전용 목적이 있어 터치스크린 없이도 탐색이 간단합니다.


switch(uiState){

case UI_HOME:
drawHome();
break;

case UI_MENU:
drawMenu();
break;

case UI_COLOR:
drawColorPicker();
break;

case UI_TIME:
drawTimeSettings();
break;
}

버튼 처리는 이벤트 기반으로, 펌웨어가 짧은 눌림과 긴 눌림을 감지하면서 인터페이스를 반응형으로 유지할 수 있게 합니다.


if(btnNext.pressed()){

nextMenu();

}

if(btnSelect.pressed()){

selectOption();

}

if(btnBack.longPressed()){

openTimeSettings();

}

성능을 개선하기 위해 디스플레이는 매 프레임마다 다시 그려지지 않습니다. 시계 숫자나 메뉴 선택과 같이 변경되는 인터페이스의 부분만 업데이트됩니다. 이는 SPI 트래픽을 크게 줄이고 LED가 업데이트되는 동안에도 애니메이션을 부드럽게 유지합니다.


if(lastMinute != currentMinute){

drawClock();

lastMinute = currentMinute;

}

본문이 길어 아래 덧글 1개로 계속됩니다.


원문: https://www.instructables.com/PrismCast-a-Custom-Built-Ambilight-Backlight/

좋아요 0
게시판

본문 계속 1/1




STEP 15. 조명 엔진 구축하기


조명 엔진 구축하기


조명 엔진은 PrismCast에서 표시되는 모든 효과를 생성하는 역할을 합니다. Solid, Wave, Breathe와 같은 내장 애니메이션과 함께, 브라우저가 실시간으로 ESP32에 RGB 값을 스트리밍하는 Display Sync도 지원합니다.

현재 효과는 간단한 상태 기계를 사용하여 선택됩니다.


switch (gMode) {

case M_SOLID:
renderSolid();
break;

case M_BREATHE:
renderBreathe();
break;

case M_WAVE:
renderWave();
break;

case M_SYNC:
renderSync();
break;
}

단색

단색 모드는 선택한 색상으로 전체 스트립을 채웁니다.


void renderSolid() {

for(int i = 0; i < NUM_LEDS; i++) {

strip.SetPixelColor(i, currentColor);

}

strip.Show();
}


파도 애니메이션

파도 효과는 스트립을 가로질러 색조를 지속적으로 이동시켜 움직이는 무지개를 생성합니다.


for(int i = 0; i < NUM_LEDS; i++) {

float hue = phase + (i * hueStep);

strip.SetPixelColor(
i,
HslColor(hue, 1.0f, 0.5f)
);
}

phase += animationSpeed;

strip.Show();


호흡 효과

호흡 효과는 사인파를 사용하여 선택한 색상을 부드럽게 서서히 나타나고 사라지게 합니다.


float level =
(sin(millis() * 0.002f) + 1.0f) * 0.5f;

RgbColor c(

baseColor.R * level,

baseColor.G * level,

baseColor.B * level

);

fillStrip(c);

strip.Show();


디스플레이 동기화

디스플레이 동기화는 PrismCast의 주요 기능입니다. ESP32에서 색상을 생성하는 대신, 브라우저는 화면을 캡처하고, 가장자리 색상을 샘플링하며, 이진 WebSocket 패킷을 사용하여 컨트롤러에 전체 RGB 프레임을 전송합니다.


case WStype_BIN:

renderSyncFrame(payload);

lastSync = millis();

break;

각 LED는 빨간색, 초록색 및 파란색 값을 나타내는 세 바이트를 수신합니다.


for(uint16_t i = 0; i < NUM_LEDS; i++) {

strip.SetPixelColor(

i,

RgbColor(

payload[i * 3],

payload[i * 3 + 1],

payload[i * 3 + 2]

)

);

}

strip.Show();

밝기 조절

각 효과에 대해 밝기를 별도로 구현하는 대신, PrismCast는 LED를 업데이트하기 전에 전역 밝기 값을 적용합니다.


brightness = constrain(

brightness,

0,

255

);

strip.SetBrightness(

brightness

);

LED 업데이트

애니메이션 프레임이 생성되면, 전체 LED 버퍼가 스트립으로 전송됩니다.


strip.Show();

NeoPixelBus를 사용하면 ESP32가 RMT 주변 장치를 사용할 수 있어 Wi-Fi 통신을 처리하는 동안에도 신뢰할 수 있는 LED 업데이트가 가능합니다.

주 애니메이션 루프

활성 조명 모드는 메인 루프 내에서 지속적으로 업데이트되며, 디스플레이, 버튼 및 WebSocket 서버는 계속 실행됩니다.


void loop() {

webSocket.loop();

handleButtons();

updateEffects();

drawUI();

}

이 비차단 방식은 모든 120개의 LED를 실시간으로 부드럽게 업데이트하면서 인터페이스를 반응성 있게 유지합니다.




STEP 16. 웹 대시보드 구축하기


웹 대시보드 구축하기


컨트롤러는 일상적인 사용에 완벽하지만, 고급 사용자 지정을 위한 훨씬 더 강력한 인터페이스가 필요했습니다. 데스크탑 애플리케이션을 만드는 대신, HTML, CSS, JavaScript를 사용하여 브라우저 기반 대시보드를 만들었고, 이를 통해 PrismCast를 모든 현대 브라우저에서 직접 제어할 수 있게 되었습니다.

대시보드는 둥근 패널, 미세한 투명도, 부드러운 애니메이션을 갖춘 서리 낀 유리 (글래스모피즘) 디자인을 따르며, 장치의 전체 미학과 잘 어울립니다.


<div class="glass-panel">

<div class="hero"></div>

<div class="controls"></div>

<div class="settings"></div>

</div>


.glass-panel{

backdrop-filter:blur(24px);

background:rgba(255,255,255,.08);

border-radius:20px;

}


장치 연결

개발 중에 항상 하드웨어가 연결되어 있지는 않았기 때문에, 데모 모드와 실시간 장치 모드를 모두 구현했습니다. 이를 통해 ESP32 펌웨어가 완성되기 전에도 거의 전체 대시보드를 구축하고 테스트할 수 있었습니다.


const device =

demoMode

? new MockDevice()

: new LiveDevice(deviceIP);

await device.connect();


socket = new WebSocket(

"ws://" + ip + ":81/"

);

socket.onopen=()=>{

console.log("연결됨");

};


디스플레이 구성

모든 모니터의 크기가 다르기 때문에, 대시보드는 사용자가 모니터 크기와 3면 또는 4면 모두에 LED가 설치되어 있는지를 선택할 수 있게 합니다. 이러한 설정을 기반으로 PrismCast는 필요한 LED 수를 자동으로 계산하고 올바른 LED 레이아웃을 생성합니다.


const layout =

computeLayout({

inches:27,

sides:4,

density:60

});


updateLEDCount(

layout.totalLEDs

);

drawLayout(layout);


조명 제어

대시보드는 모든 조명 모드에 대한 빠른 접근과 함께 밝기, 애니메이션 속도 및 색상 제어를 제공합니다.


device.setState({

mode,

brightness,

speed,

solidColor

});


modeButtons.forEach(btn=>{

btn.onclick=()=>{

setMode(btn.dataset.mode);

};

});


색상 선택기

서드파티 라이브러리를 사용하는 대신, RGB 슬라이더와 HEX 값과 동기화된 사용자 정의 HSV 색상 선택기를 만들었습니다.


picker.onChange(color=>{

state.color=color;

sendState();

});


hexInput.oninput=()=>{

updateColor(

hexInput.value

);

};


사용자 정의 LED 편집기

제가 가장 좋아하는 기능 중 하나는 사용자 정의 LED 편집기입니다. LED를 직선으로 표시하는 대신, 모니터의 윤곽을 따라 배치되어 최종 설치를 시각화하기가 훨씬 더 쉽습니다.

사용자는 개별 LED를 칠하고, 패턴을 미러링하고, 섹션을 채우고, 스트립을 지우거나, 현재 디스플레이 동기화 프레임을 캡처하여 추가 편집을 할 수 있습니다.


paintLED(

ledIndex,

currentColor

);


mirrorPattern();

fillStrip();

clearStrip();

snapshotLive();


프리셋 및 실시간 미리보기

조명 프로필은 로컬에 저장되어 서로 다른 설정 간에 빠르게 전환할 수 있습니다. 대시보드에는 LED가 모니터 주위에 어떻게 보일지를 실시간으로 업데이트하는 실시간 모니터 미리보기도 포함되어 있습니다.


localStorage.setItem(

"preset",

JSON.stringify(state)

);


renderMonitor();

renderGlow();

renderLEDs();

requestAnimationFrame(

renderFrame

);




STEP 17. 디스플레이 동기화


PrismCast의 가장 큰 목표 중 하나는 Hyperion, Prismatik 또는 WLED와 같은 기존 소프트웨어에 의존하지 않고 디스플레이 동기화 시스템을 만드는 것이었습니다. 대신, 최신 브라우저 API와 사용자 정의 통신 프로토콜을 사용하여 전체 파이프라인을 처음부터 끝까지 구축했습니다.

브라우저는 먼저 Screen Capture API를 사용하여 선택한 모니터를 캡처합니다. 이 기능은 사용자 권한이 필요하므로 대시보드는 로컬에서 실행되며 사용자가 동기화해야 할 디스플레이를 선택하도록 요청합니다.


const stream =
await navigator.mediaDevices
.getDisplayMedia({

video:{

frameRate:30

}

});

const video =
document.createElement("video");

video.srcObject = stream;


프레임 캡처

캡처된 모든 프레임은 숨겨진 캔버스에 그려집니다. 전체 이미지를 처리하는 대신, PrismCast는 LED가 설치된 디스플레이의 가장자리 주변의 작은 영역만 샘플링합니다.


ctx.drawImage(

video,

0,

0,

canvas.width,

canvas.height

);


const frame =

ctx.getImageData(

0,

0,

canvas.width,

canvas.height

);


LED 존 생성

고정 샘플링 위치를 사용하는 대신, 대시보드는 선택한 모니터 크기와 LED가 3면 또는 4면에 설치되어 있는지에 따라 자동으로 LED 존을 생성합니다.

24인치 모니터에서 27인치 모니터로 변경하면 펌웨어 설정을 변경하지 않고도 LED의 수와 위치가 즉시 재계산됩니다.


const layout =

computeLayout({

inches:27,

sides:4,

density:60

});

const zones =

buildZones(layout);


ledCount =

layout.totalLEDs;

renderPreview();


색상 샘플링

샘플링 영역이 생성되면, PrismCast는 모든 LED 위치에 대한 평균 색상을 계산합니다.


for(const zone of zones){

colors.push(

sampleZone(

frame,

zone

)

);

}

이것은 스트립의 모든 LED에 대한 하나의 RGB 값을 포함하는 배열을 생성합니다.


시간적 스무딩

원시 화면 캡처는 장면이 빠르게 변경될 때 깜박일 수 있습니다. 애니메이션을 더 부드럽게 만들기 위해, PrismCast는 이전 프레임과 현재 프레임을 ESP32로 전송하기 전에 혼합합니다.


color.r =

lerp(

previous.r,

current.r,

0.35

);

color.g =

lerp(

previous.g,

current.g,

0.35

);

color.b =

lerp(

previous.b,

current.b,

0.35

);

이 작은 양의 보간은 훨씬 더 부드러운 조명을 생성하면서도 여전히 반응성을 유지합니다.

감마 보정

LED는 밝기에 선형적으로 반응하지 않으므로, PrismCast는 최종 프레임을 전송하기 전에 감마 보정을 적용합니다.


function gamma(v){

return Math.pow(

v/255,

2.2

)*255;

}

이것은 특히 어두운 장면에서 색상 정확도를 향상시킵니다.

이진 웹소켓 스트리밍

각 프레임에 대해 JSON을 전송하는 대신, 대시보드는 RGB 값을 이진 버퍼에 패킹한 후 ESP32로 전송합니다.


const packet =

new Uint8Array(

ledCount*3

);

packet[i*3+0]=r;

packet[i*3+1]=g;

packet[i*3+2]=b;

socket.send(packet);

바이너리 패킷은 JSON보다 훨씬 작고 처리 속도가 훨씬 빠릅니다.

ESP32에서의 렌더링

패킷을 수신한 후, ESP32는 LED 스트립을 업데이트하기 전에 모든 RGB 값을 LED 버퍼에 직접 복사합니다.


for(int i=0;i<NUM_LEDS;i++){

strip.SetPixelColor(

i,

RgbColor(

payload[i*3],

payload[i*3+1],

payload[i*3+2]

)

);

}

strip.Show();





STEP 18. 통신 프로토콜


통신 프로토콜


PrismCast는 WebSockets를 사용하여 브라우저 대시보드와 ESP32 간의 실시간 통신을 수행합니다. 전통적인 HTTP 요청과 달리, WebSockets는 지속적인 연결을 유지하여 두 장치가 매우 낮은 지연 시간으로 즉시 데이터를 교환할 수 있도록 합니다.


WebSocketsServer webSocket(81);

webSocket.begin();

webSocket.onEvent(webSocketEvent);

모든 데이터가 동일한 형식으로 전송되는 것은 아닙니다. 조명 모드, 밝기, 색상 및 디스플레이 설정과 같은 구성 변경 사항은 JSON 패킷으로 전송되며, 이는 읽기 쉽고 가끔만 업데이트되기 때문입니다.


socket.send(JSON.stringify({

mode: state.mode,

brightness: state.brightness,

color: state.solidColor,

layout: state.layout

}));

ESP32에서는 수신된 JSON 패킷이 파싱되어 현재 장치 상태에 적용됩니다.


StaticJsonDocument<256> doc;

deserializeJson(doc, payload);

state.mode = doc["mode"];

state.brightness = doc["brightness"];

디스플레이 동기화를 위해 JSON은 매초 수백 개의 RGB 값을 전송해야 하므로 불필요한 오버헤드를 발생시킵니다. 대신, PrismCast는 각 LED가 빨강, 초록, 파랑 값에 해당하는 세 바이트로 표현되는 압축된 이진 패킷을 전송합니다.


const packet = new Uint8Array(

ledCount * 3

);

socket.send(packet);

ESP32는 이진 패킷을 자동으로 감지하고 수신된 RGB 값을 LED 버퍼에 직접 복사한 후 스트립을 업데이트합니다.


case WStype_BIN:

renderSyncFrame(

payload,

length

);

break;

설정에 대한 JSON과 실시간 동기화를 위한 이진 패킷의 조합은 통신을 효율적이고 유지 관리하기 쉽게 유지하면서 부드러운 실시간 성능을 제공합니다.

브라우저 대시보드
│
┌────────────┴────────────┐
▼ ▼
JSON 명령어 이진 프레임
│ │
└────────────┬────────────┘
▼
웹소켓 서버
│
▼
ESP32 펌웨어
┌────────┴────────┐
▼ ▼
설정 업데이트 LED 업데이트

이 통신 시스템은 물리적 컨트롤러와 브라우저 대시보드가 동기화된 상태를 유지할 수 있도록 하여, 모든 변경 사항이 시스템 전체에 즉시 반영되도록 보장합니다.




STEP 19. 성능 최적화


ESP32가 디스플레이, LED, 버튼 및 무선 통신을 동시에 처리하기 때문에 모든 것이 반응성을 유지하는 것이 프로젝트의 중요한 부분이었습니다. 이를 달성하기 위해 펌웨어는 블로킹 지연을 피하고 각 모듈을 독립적으로 업데이트하여 부드러운 애니메이션과 반응성 있는 제어를 제공합니다.

updateButtons();
updateClock();
updateEffects();
updateDisplay();
webSocket.loop();

펌웨어가 완성되자 하드웨어가 마침내 작동하기 시작했습니다. 다음 단계는 브라우저 대시보드를 구축하는 것이었으며, 이는 디스플레이 동기화, LED별 편집 및 사용자 정의 모니터 레이아웃을 포함한 PrismCast의 모든 고급 기능을 잠금 해제합니다. 성능 최적화

ESP32가 디스플레이, LED, 버튼 및 무선 통신을 동시에 처리하기 때문에 모든 것이 반응성을 유지하는 것이 프로젝트의 중요한 부분이었습니다. 이를 달성하기 위해 펌웨어는 블로킹 지연을 피하고 각 모듈을 독립적으로 업데이트하여 부드러운 애니메이션과 반응성 있는 제어를 제공합니다.

updateButtons();
updateClock();
updateEffects();
updateDisplay();
webSocket.loop();

펌웨어가 완성되자 하드웨어가 마침내 작동하기 시작했습니다. 다음 단계는 브라우저 대시보드를 구축하는 것이었으며, 이는 디스플레이 동기화, LED별 편집 및 사용자 정의 모니터 레이아웃을 포함한 PrismCast의 모든 고급 기능을 잠금 해제합니다.




STEP 20. 최종 테스트 및 통합


최종 테스트 및 통합


최종 테스트 및 통합


최종 테스트 및 통합


펌웨어가 완성되었으므로 전체 시스템을 테스트할 시간이었다.

최종 펌웨어를 ESP32에 업로드하고 TFT 인터페이스, 버튼 탐색, 조명 효과, 시계, 브라우저 대시보드와의 통신을 포함하여 모든 기능을 마지막으로 확인했다. 모든 것이 제대로 작동하는 것을 확인한 후, 모니터 옆에 컨트롤러를 설치하고 디스플레이 뒤에 LED 스트립을 장착했다.

LED가 화면에 반응하는 모습을 처음 보는 것은 프로젝트에서 가장 만족스러운 순간 중 하나였다. 몇 주간의 설계, 인쇄, 배선 및 프로그래밍 끝에 PrismCast가 마침내 생명을 얻었다.

포함할 이미지

  1. 업로드된 펌웨어
  2. 첫 번째 성공적인 부팅
  3. 모니터 옆의 컨트롤러
  4. 화면에 반응하는 LED





STEP 21. 최종 결과 및 향후 개선 사항


최종 결과 및 향후 개선 사항


최종 결과 및 향후 개선 사항


최종 결과 및 향후 개선 사항


최종 결과 및 향후 개선 사항


프리즘캐스트는 디스플레이 동기화 모니터 백라이트를 위한 간단한 아이디어로 시작했지만, 프로젝트가 끝날 무렵에는 훨씬 더 큰 것으로 성장했습니다. RGB 조명 프로젝트로 시작된 것이 결국 자체 컨트롤러, 맞춤형 펌웨어, 브라우저 대시보드 및 사용자 인터페이스를 갖춘 완전한 책상 동반자로 발전했습니다.

프로젝트에서 제가 가장 좋아하는 부분 중 하나는 상호작용할 수 있는 두 가지 완전히 다른 방법을 제공한다는 점입니다. 일상적인 사용을 위해 물리적 컨트롤러는 몇 번의 버튼 클릭만으로 조명 모드, 밝기 및 색상을 쉽게 변경할 수 있게 해줍니다. 더 고급 사용자 지정을 원할 때마다 브라우저 대시보드는 디스플레이 동기화 및 개별 LED 편집에서 모니터 레이아웃 구성 및 프리셋에 이르기까지 시스템에 대한 완전한 제어를 제공합니다.

모든 것을 처음부터 만드는 것은 확실히 프로젝트에서 가장 도전적인 부분이었지만, 또한 가장 보람 있는 일이었습니다. 기존의 펌웨어나 소프트웨어에 의존하는 대신, 프리즘캐스트의 모든 주요 부분은 이 프로젝트를 위해 특별히 설계되어 하드웨어와 소프트웨어 모두에 대한 완전한 제어를 가능하게 했습니다.

모든 프로젝트와 마찬가지로 항상 개선의 여지가 있습니다. 앞으로는 맞춤형 PCB를 설계하고, 더 정확한 시간 측정을 위한 RTC를 추가하며, 자동 밝기 조정을 위한 주변광 센서를 포함하고, 더 많은 조명 효과와 대시보드 기능을 도입하고 싶습니다.

이 프로젝트가 여러분이 자신만의 무언가를 만드는 데 영감을 주기를 바랍니다. 이 인스트럭터블이 마음에 드셨거나 도움이 되셨다면, 레인보우/RGB 콘테스트에서 여러분의 투표를 정말 감사하겠습니다. 질문이나 제안이 있으시면 언제든지 댓글을 남겨주세요.

읽어주셔서 감사합니다, 그리고 즐거운 제작 되세요!

회사명 공방유니언 주소 각 공방 주소 참조
사업자 등록번호 0000 대표 공방유니언 전화 019-60105846 팩스 0000 이메일 gongbangunion@gmail.com
통신판매업신고번호 0000 개인정보관리책임자 공방유니언
Copyright © 2017 공방유니언. All Rights Reserved.