Wi-Fi 스마트 전구 속 금서 도서관
1 week ago
16
- Banned Book Library는 Wi-Fi 스마트 전구를 공개 액세스 포인트와 웹 서버로 바꿔, 전구가 켜져 있는 동안 주변 기기에서 전자책에 접근하게 하는 디지털 데드드롭 프로젝트임
- 하드웨어는 ESP32C3 4MB 기반 Tasmota 사전 설치 전구에서 시작했으며, 작은 플래시 용량 때문에 펌웨어·웹사이트·책 파일을 모두 담는 저장 공간 조정이 핵심 제약이 됨
- microSD 추가는 실제 전구 내부 납땜과 보드 탈거가 어렵고 안전하게 재조립하기 힘들어 포기됐으며, 대신 파티션 테이블을 수정해 파일 저장 공간을 320KB에서 2MB로 늘림
- Arduino만으로는 보호된 플래시 영역에 접근하지 못해 ESP-IDF와 Arduino as a Component를 사용했으며, 별도 safeboot 펌웨어와 ElegantOTA로 업데이트 경로를 구성함
- 최종 웹 앱은 책 목록, 관리자 패널, 복원 기능, 캡티브 포털을 갖추며, 4MB 한계 때문에 전구 하나가 많은 책보다 선택된 몇 권을 담는 개인적 라이브러리에 가까워짐
개요
- Wi-Fi 스마트 전구를 개조해 열린 Wi-Fi 액세스 포인트와 금서 웹 서버를 제공하는 아이디어에서 프로젝트가 시작됨
- 전구가 켜져 있으면 주변 사용자는 Wi-Fi가 있는 전자기기로 전구에 저장된 자료에 접근할 수 있음
- 전구 형태라 눈에 잘 띄지 않고, 가격도 비교적 낮아 동네 곳곳에 남겨두는 디지털 데드드롭으로 구상됨
- 아이디어는 Ben Brown의 단편 Library에서 영향을 받았으며, 그 이야기 속 “도서관”은 창작물, 사용 설명서, 3D 모델 등 인터넷에서 사라지면 안 되는 자료를 보관하는 디지털 아카이브 역할을 함
- 몇 달 전 실제 작업이 시작됐고 결과물이 Banned Book Library로 공개됨
하드웨어
- 지역 DEFCON 모임에서 아이디어를 공유한 뒤 Tasmota를 검토하게 됨
- Tasmota는 여러 스마트 기기에 설치해 HomeAssistant 같은 홈 자동화 시스템과 통합할 수 있는 오픈소스 펌웨어임
- 주요 목적은 클라우드 서비스에 의존하지 않고 기기를 로컬에서 제어하게 하는 것임
- 많은 스마트 기기는 시간이 지나 바뀌거나 사라질 수 있는 클라우드 서비스에 의존하며, Tasmota는 이를 내부 호스팅으로 대체할 수 있음
- Tasmota를 직접 수정하지는 않았지만, Tasmota가 사전 설치된 Wi-Fi 전구 판매처를 찾게 됨
- 제품 페이지에는 전구가 ESP32C3 4MB를 사용한다고 적혀 있었음
- LED 제어용 GPIO 핀도 공개돼 있었고, 이후 작업에 도움이 됨
- 핀 매핑은 R=GPIO6, G=GPIO7, B=GPIO5, CW=GPIO3, WW=GPIO4였음
- Tasmota에는 OTA 펌웨어 업데이트 기능이 있어 전구를 뜯지 않고 커스텀 펌웨어를 올릴 수 있을 가능성이 있었음
- 가장 큰 문제는 4MB 플래시였으며, 이 안에 펌웨어, 웹사이트, 책 파일을 모두 넣어야 했음
- 실험 중 하나를 망가뜨릴 가능성을 고려해 전구 두 개를 구매함
분해
- 전구 상단의 흰색 플라스틱 확산부는 칼날로 둘레를 두 번 절개한 뒤 비틀어 분리함
- 내부에는 LED가 올라간 원형 자식 보드가 있었고, 아래쪽 보드와 여섯 개 핀으로 연결돼 있었음
- 가운데 구멍으로 메인 보드 일부가 올라와 있었으며, 이 부분은 ESP32 안테나였음
- 전구 하우징과 자식 보드는 알루미늄으로 돼 있어 Wi-Fi 신호 확보를 고려한 설계로 보였음
- 자식 보드를 떼어내자 내부의 ESP32C3와 전원 변환·LED 구동용으로 보이는 부품들이 보였음
- ESP32에는 노출된 핀이 여럿 있었고, microSD 카드 리더를 붙일 수 있을 가능성이 있어 보였음
- 전구 안쪽으로 납땜 인두를 넣을 수 없어 메인 보드를 꺼내야 했고, 고무 같은 포팅 컴파운드를 칼과 드라이버로 파내야 했음
- 메인 보드 탈거는 매우 번거롭고 재설치 후 안전성을 신뢰하기 어려워, 실제 데드드롭 설치 과정의 필수 단계로 삼기에는 부적합했음
- 분해된 전구는 개발 플랫폼으로 활용됐고, 직렬 프로그래밍을 위해 VCC, GND, TX, RX, IO9에 선을 납땜함
- AliExpress의 동일 모듈 사진에서 핀 라벨을 확인해 VCC, GND, TX, RX 위치를 파악함
- GND는 납땜이 쉬운 금속 실드에 연결함
- 다운로드 모드 진입에는 IO9를 접지한 상태로 부팅하는 방식이 쓰임
- esptool로 전체 펌웨어를 덤프했고, 몇 분 뒤 tasmota_original_firmware.bin을 확보함
초기 실험
-
Hello World
- 처음에는 Tasmota 소스 코드를 수정해 Banned Book Library로 만들려 했지만, 펌웨어가 예상보다 복잡하고 여러 아키텍처와 기기를 지원해 범위가 컸음
- 프로젝트 목적상 불필요한 기능을 줄이고 저장 공간을 확보하고 싶어 Tasmota 수정은 포기함
- ESP32를 Arduino로 프로그래밍할 수 있다는 점을 확인하고 Arduino IDE를 설정함
- 기본 Hello World 프로그램을 올려 직렬 포트로 메시지를 보내게 했고, 전구에 직접 커스텀 펌웨어를 쓸 수 있음을 확인함
-
웹 서버
- 다음 단계는 열린 Wi-Fi 액세스 포인트와 웹 서버를 구성하는 것이었음
- ESP32 웹 서버 튜토리얼을 참고했지만 LED 제어는 당시 목적이 아니어서 수정함
- 이후 Async Web Server로 전환해 관련 튜토리얼을 기반으로 구현을 진행함
-
microSD 카드
- 저장 공간 확장을 위해 Sparkfun microSD 브레이크아웃 보드를 구매함
- ESP32C3 데이터시트를 참고해 SD 카드 리더 배선을 파악함
- 실제 전구 대신 Adafruit ItsyBitsy ESP32를 프로토타입에 사용했는데, 핀 헤더 납땜과 microSD 연결이 훨씬 쉬웠기 때문임
- microSD와 LittleFS를 이용해 웹 서버 파일을 호스팅하는 데는 성공했지만, 실제 전구에 적용하기 어려워 microSD 방식은 포기됨
- 실제 전구의 ESP32C3에 납땜하려면 보드를 하우징에서 꺼내야 했고, 이는 사실상 기기를 망가뜨리는 작업에 가까웠음
- LED 제어 핀 재활용도 시도했지만, 해당 구조에서는 GPIO가 트랜지스터를 켜 회로를 접지로 완성하는 출력 용도로만 쓰일 수 있었음
- ESP32 위에 끼워 핀과 접촉하는 3D 프린트 클램프도 설계했지만, 너무 불안정하고 신뢰성이 낮아 폐기됨
우회 검토
- 더 납땜하기 쉬운 전구가 있는지 확인하기 위해 다른 스마트 전구를 조사함
- 여러 분해 글을 찾았지만 대부분 기존 전구와 비슷한 내부 구조였음
- 일부 전구는 ESP32가 아닌 칩을 사용했지만, 이미 ESP32 프로그래밍을 익혔기 때문에 ESP32 기반 전구로 범위를 좁힘
- 지역 하드웨어 매장에서 산 전구 중 하나는 비슷한 구조였지만 메인 보드를 안전하게 분리하기 어려운 알루미늄 보호부가 있었음
- Philips WiZ는 플라스틱 확산부만 제거하면 ESP32C3-mini-1이 드러나 유망해 보였지만, 필요한 ESP32 핀에 접근할 수 없었음
- 일반 LED 전구에 자체 회로를 넣는 방법도 검토했지만, Tasmota 전구를 플래시하는 것보다 더 복잡하고 특수한 작업이 됨
- 최종적으로 Tasmota 전구를 유지하고 4MB 제한 안에서 해결하기로 함
저장 공간 문제
- ESP32 파티션 테이블은 보통 플래시 오프셋 0x8000에 저장되며, 이 영역을 덤프한 뒤 CSV로 변환해 구조를 확인함
- 기존 파티션은 nvs, otadata, safeboot, app0, spiffs 다섯 개였음
- nvs는 Wi-Fi 네트워크, 비밀번호, LED 색상 같은 설정을 저장하는 비휘발성 저장 공간으로 쓰임
- otadata는 OTA 업데이트와 관련된 영역으로 파악됨
- safeboot는 Tasmota가 메인 펌웨어를 플래시하는 데 쓰는 별도 부팅 펌웨어임
- app0에는 메인 펌웨어가 저장됨
- spiffs는 파일 저장용 작은 파일 시스템 파티션이며, 이 경우 LittleFS도 나타낼 수 있음
- 기존 구성에서는 메인 펌웨어가 거의 3MB, safeboot가 거의 1MB를 차지했고, 파일 저장 공간은 320KB뿐이었음
- 커스텀 펌웨어는 Tasmota보다 단순하므로 app0 크기를 줄이고 spiffs를 늘릴 수 있다고 판단함
- 새 파티션 구성은 spiffs를 0x200000 크기로 잡아 웹 파일과 책을 위한 2MB 저장 공간을 확보함
- 파티션 테이블 수정은 위험하며, 손상되면 기기가 부팅하지 못하고 직렬 프로그래밍으로만 복구할 수 있음
- 테이블 끝에는 MD5 체크섬이 있어 오프셋과 크기만 바꾸는 것으로는 부팅할 수 없음
- 실행 중인 app0 파티션 자체를 옮기면 해당 펌웨어로 다시 부팅할 수 없으므로 app0 시작 위치는 유지해야 했음
- 새 파티션 CSV를 만들고 gen_esp32part.py로 바이너리 테이블을 생성한 뒤, xxd로 C 배열 형태를 만들어 partition.h에 넣음
- 파티션 테이블 MD5가 이미 새 테이블과 같으면 건너뛰고, 다르면 테이블을 지우고 새 테이블을 쓰는 함수를 작성함
- Arduino 환경에서는 보호된 플래시 영역 접근이 막혀 있어 API가 성공을 반환해도 실제 파티션 테이블을 읽거나 쓰지 못했음
ESP-IDF
- 공식 ESP32 프레임워크인 ESP-IDF는 설정과 사용이 더 복잡하지만, 장치와 프레임워크 제어 범위가 더 넓음
- idf.py menuconfig로 프레임워크 설정을 바꿀 수 있으며, 이 메뉴는 Linux 커널의 menuconfig와 비슷한 방식임
- 파티션 테이블을 읽고 쓰려면 SPI_FLASH_DANGEROUS_WRITE_ALLOWED를 Allowed로 설정해야 했음
- SPI_FLASH_DANGEROUS_WRITE_ABORTS도 비활성화해야 파티션 테이블 접근이 가능해졌음
- ESP-IDF를 직접 쓰면 Arduino의 편의 기능을 그대로 쓸 수 없었지만, Arduino as a Component를 추가해 Arduino 기능과 ESP-IDF 제어를 함께 사용할 수 있었음
- ElegantOTA, Async_TCP, AsyncWebServer 같은 라이브러리는 프로젝트의 components 디렉터리나 Arduino 컴포넌트의 libraries 디렉터리에 복제해야 했음
- 일부 CMakeLists.txt도 조정해야 했고, 이 반복 작업을 처리하는 build.sh 스크립트를 저장소에 추가함
- 빌드는 idf.py build로 수행했고, 직렬 플래시는 esptool -p /dev/ttyUSB0 write-flash 0xe0000 build/library.bin으로 진행함
설정 페이지
- 메인 펌웨어 이미지는 중요한 웹 서버 엔드포인트를 포함하지만 실제 라이브러리 코드는 LittleFS 파티션에 별도로 저장됨
- 파일 시스템 이미지는 별도로 플래시해야 하며, 이를 위해 ElegantOTA가 포함됨
- 파일 시스템을 아직 플래시하지 않은 상태로 부팅하면 설정 페이지가 표시됨
- 설정 페이지는 ElegantOTA로 파일 시스템 이미지와 safeboot 펌웨어를 플래시하는 절차를 안내함
Safeboot
- 메인 펌웨어의 OTA 업데이트를 유지하기 위해 처음에는 Tasmota safeboot를 그대로 쓰려 했음
- Tasmota safeboot는 nvs 파티션의 Wi-Fi 설정을 사용해 업데이트를 수행함
- 이 과정에서 Wi-Fi SSID와 비밀번호가 nvs 파티션에 평문으로 저장된다는 점이 문제가 됨
- 전구를 외부에 남겨둘 경우 Wi-Fi 자격 증명이 그대로 남아 있는 것은 좋지 않은 운영 보안 상태임
- 커스텀 펌웨어는 먼저 nvs 파티션을 지우고, 추가로 SPIFFS 파티션도 지움
- nvs의 Wi-Fi 설정이 사라지면 Tasmota safeboot는 네트워크에 연결할 수 없어 기본 펌웨어 업데이트 경로가 끊김
- 이를 해결하기 위해 별도 커스텀 safeboot 펌웨어가 필요해짐
- 최소 웹 서버와 액세스 포인트로 OTA 업데이트를 수행하는 GitHub 예제를 기반으로 safeboot 펌웨어를 만들었음
- 일부 menuconfig 항목을 비활성화해 safeboot 파티션에 들어갈 만큼 이미지를 줄였고, 최종적으로 동작함
- safeboot 파티션 자체에는 비밀번호가 없지만, safeboot로 재부팅하는 관리자 기능은 비밀번호로 보호됨
웹 애플리케이션
-
라이브러리
- 첫 화면은 문이 있는 노란색 선적 컨테이너 이미지를 보여줌
- 이 이미지는 앞서 언급한 Ben Brown의 Library 단편을 참조한 요소임
- 이미지는 저장 공간을 차지하지만 유지됐고, 첫 화면에는 “해커 같은” 느낌을 주기 위한 글리치 효과도 들어감
- 주요 라이브러리 페이지는 직접 HTML과 CSS를 작성하며 구현됨
- 초기 계획은 파일 목록만 있는 기본 HTML 인덱스였지만, 더 보기 좋고 재미있는 형태로 바뀌었음
- 사이트 구조는 비교적 단순함
- 현재 보고 있는 것이 무엇인지 설명하는 섹션이 있음
- 책 섹션에는 제목, 저자, 도전받거나 금지된 이유가 표시됨
- 참고 링크 섹션도 있지만, Banned Book Library 액세스 포인트는 인터넷 연결이 없으므로 접속 중에는 외부 링크가 동작하지 않음
-
관리자
- /admin 경로에는 비밀번호로 보호되는 관리자 패널이 있음
- 관리자 패널은 LED 색온도를 제어할 수 있게 함
- 공공장소에 설치할 때 기존 전구 색과 맞춰 변경 사실을 덜 눈에 띄게 하려는 목적임
- 전구 판매사가 각 LED 색상 제어용 GPIO 핀을 공개했기 때문에 AnalogWrite()로 색상별 강도를 설정할 수 있었음
- 색상 설정은 NVS에 저장되어 다음 부팅 때 같은 색상으로 돌아옴
- 관리자 기능에는 복원 페이지로 이동하는 버튼도 있음
-
복원
- 복원 기능은 파티션 테이블을 어느 정도 되돌리고 safeboot로 부팅하게 함
- 실제로는 커스텀 safeboot 파티션으로 재부팅한 뒤, Banned Book Library 펌웨어 위에 다른 펌웨어를 플래시할 수 있게 함
- 플래시 대상은 새 버전, Tasmota, ESPHome 등일 수 있음
- safeboot 파티션 자체를 복원하는 좋은 방법은 아직 찾지 못함
- Tasmota를 다시 플래시한 뒤 Tasmota 인터페이스에서 “Firmware Upgrade”를 누르면 커스텀 safeboot로 다시 부팅됨
- 이 safeboot는 Tasmota 업데이트에 사용할 수는 있지만, Tasmota의 일반 업그레이드 경험과 매끄럽게 맞지는 않음
- 이 문제 때문에 파티션 복원은 safeboot의 서브타입을 Factory로 완전히 되돌리지 않고 OTA_1로 남김
-
캡티브 포털
- 사용자가 열린 액세스 포인트에 연결한 뒤 인터넷이 없다는 사실만 보고 포기할 수 있어 캡티브 포털이 필요해짐
- 과거 방식은 HTTP 요청을 가로채 포털로 리다이렉트하는 것이었지만, 현재는 대부분의 웹사이트가 HTTPS를 사용해 이 방식이 잘 맞지 않음
- 현대 방식에는 캡티브 포털 사용을 알리는 DHCP 옵션과, 기기별 포털 감지 요청을 처리하는 방식이 있음
- ESP32용 캡티브 포털 예제 코드를 찾아 프로젝트에 일부 사용함
- 해당 코드는 두 가지 작업을 수행함
- DNS 서버가 모든 요청에 ESP32 자신의 IP 주소로 응답함
- Microsoft, Android, iOS, Firefox 등에서 쓰는 특정 HTTP 요청을 잡아 리다이렉트나 응답을 보냄
- 알 수 없는 요청은 server.onNotFound에서 로컬 URL로 리다이렉트되며, 직렬 모니터에는 요청 호스트와 URL이 출력됨
최종 생각
-
크기 제한
- 기기의 전체 저장 공간은 4MB로 제한됨
- 확인한 epub 책 몇 권은 각각 약 350KB였고, 전구 하나에는 이런 책 몇 권만 담을 수 있음
- 처음에는 많은 금서를 제공하는 웹 서버를 상상했기 때문에 이 제한이 실망스러웠음
- 이후에는 제한된 공간 때문에 각 데드드롭이 만든 사람의 선택을 반영한다는 점이 장점으로 받아들여짐
- 만든 사람은 자신에게 중요하거나 다른 사람이 접근해야 한다고 느끼는 책을 골라야 함
- 한 지역에 여러 개가 놓이고 각 전구에 서로 다른 자료가 들어 있다면, 찾아다니며 내용을 발견하는 경험이 더 재미있어질 수 있음
-
향후 아이디어
-
색상 제어
- RGB 색상과 흰색 색온도를 더 세밀하게 제어하는 슬라이더를 추가하고 싶어 함
- 이를 통해 설치 장소의 기존 조명 색상에 더 가깝게 맞출 수 있음
-
메시 네트워킹
- 저장 공간 제한과 관련해 여러 전구가 메시 네트워크를 형성하는 아이디어가 나옴
- 분산 해시 테이블 같은 방식을 사용하면, 서로 범위 안에 있는 기기들의 책을 어느 한 기기에 접속한 사용자에게 제공할 수 있음
- 이 아이디어는 탐구할 가치가 있는 재미있는 방향으로 남음
-
기타
- 스마트 기기를 다른 용도로 재활용하는 아이디어가 여러 개 더 있음
- ESP32 칩은 매우 저렴하면서도 성능이 충분하다고 평가됨
- ESP32 사용법을 익힌 뒤 앞으로 더 많은 ESP32 프로젝트를 만들 가능성이 높아짐
-
Homepage
-
개발자
- Wi-Fi 스마트 전구 속 금서 도서관