Wiznet makers

Lihan__

Published July 06, 2026 ©

73 UCC

8 WCC

3 VAR

0 Contests

0 Followers

0 Following

Original Link

laser-projector

This project is for a quadruple laser projection controller, aimed at supporting room-scale projections

COMPONENTS
PROJECT DESCRIPTION

Room-Scale Quad Laser Projector — When Four Galvo Heads Dance to the Same Beat, No Wires Attached

#W5500 #UDP #RP2040 #GalvoLaser #RealTimeStreaming #ArtInstallation #MusicSync #WIZnet-Pico-SDK #DualCore #MulticastControl

📚 Context: Personal art/entertainment installation — a room-scale interactive laser show system, built and iterated across three build generations (2023 → 2025). ✅ Implementation status: Full hardware (custom KiCad PCB, BOM-verified) + full firmware (RP2040 + W5500) + full server software (Python control station with audio/BLE/DMX integration) all present in-repo and consistent with each other.


01 — What is this project?

Most DIY laser shows on GitHub stop at "one MCU drives one galvo pair." This project goes further: it's a four-head, room-scale laser installation where every head is an independent network node, and a single Python "control station" chореographs all of them in real time — synced to music, to a hand-held motion wand, to DMX/sACN lighting cues, or to generative visual algorithms (spirographs, audio-reactive patterns, even a two-player Pong game rendered in laser light).

The project has visibly evolved through three hardware generations:

  • 2023 — an Arduino-class MCU driving 4 lasers over a CAN bus. No networking; everything wired point-to-point.
  • 2024 — a full redesign: each laser head becomes its own RP2040 + W5500 board, receiving its frame data over standard Ethernet UDP from a Raspberry Pi running the Python server. A SuperCollider synthesizer patch was added for audio-reactive shows.
  • 2025 — same hardware, refined server software (bug fixes across song handling, wand tracking, and the Sierpinski/spirograph generators).

The result is a laser installation that behaves less like a single gadget and more like a small distributed real-time rendering cluster, with WIZnet's Ethernet offload doing the unglamorous but critical job of getting frame data to four independent heads without jitter.


02 — Why Ethernet over Wi-Fi or a wired protocol?

🔷 Room-scale = physically separated heads

Four laser projectors, mounted around a room, all need to receive synchronized frame data. Running four Wi-Fi radios in the same room with tight-timing laser data is an invitation to jitter and packet loss from RF contention. A wired star topology from a central Raspberry Pi avoids that problem entirely.

🔷 Deterministic, low-jitter delivery

Laser vector graphics are extremely sensitive to timing — a delayed point doesn't just look wrong, it visibly distorts the image or "wobbles" the beam. Standard Ethernet with a dedicated hardware TCP/IP stack per node keeps that jitter bounded in a way a shared Wi-Fi channel across four receivers cannot.

🔷 Simplicity of the star topology

One Raspberry Pi source, four independent Ethernet-connected sinks — no mesh, no pairing, no discovery protocol. The Pi simply targets each head at a fixed IP (10.0.0.10, .11, .12, .13) and streams.


03 — System architecture

Each head is board-strapped with a 3-bit GPIO ID (pins 6/7/8, pulled up) that auto-derives its IP address (10.0.0.10 + board_id) and MAC address suffix — so all four boards run identical firmware, differentiated only by a jumper.


04 — Why WIZnet W5500? ⭐

🔷 Dedicated core, dedicated job — no stack overhead competing with real-time rendering

The RP2040 is a dual-core MCU, and this project puts that architecture to direct use: core1 does nothing but service the W5500 (getSn_SR, getSn_RX_RSR, recvfrom), while core0 runs a tight 150 µs loop driving the DAC and PWM outputs for the actual laser beam. Because the W5500 handles the TCP/IP stack entirely in hardware, core1's job reduces to a handful of register polls and a recvfrom() call — there is no software network stack competing for the same core cycles that need to stay free for beam-steering timing. On a bare RP2040 without hardware offload, that separation would be much harder to guarantee.

🔷 Socket mode used: UDP (Sn_MR_UDP)

The firmware opens socket 0 in UDP mode with SF_IO_NONBLOCK:

 
c
sockfd = socket(0, Sn_MR_UDP, 8090, SF_IO_NONBLOCK); ... size = getSn_RX_RSR(sockfd); size = recvfrom(sockfd, recv_buf, size, dest_ip, &dest_port);

UDP is the correct choice here, not TCP: laser frame data is a continuous real-time stream where a dropped frame should be silently skipped, not retransmitted. TCP's retransmission and head-of-line blocking would actively hurt a system where "just draw the next frame" is always the right behavior. A one-byte sequence counter in the packet lets the firmware detect and discard out-of-order or dropped packets without any handshake overhead.

🔷 Built on WIZnet's own reference port

The SPI glue code (w5x00_spi.c/h) carries the WIZnet Co.,Ltd copyright header and matches WIZnet's official ioLibrary_Driver RP2040 port — the project correctly reused the vendor reference implementation rather than reinventing SPI/CS handling, which is exactly the kind of integration WIZnet's ports are meant to enable.

🔷 Verified in a real, physical multi-head deployment

This isn't a single-board demo — it's four physically distinct, independently-addressed W5500 boards deployed simultaneously in one room, each fed from the same source stream, with a custom KiCad-designed carrier board (combo_laser_driver) putting the W5500 directly next to the RP2040 and DAC on a single PCB (BOM-confirmed: W5500 LQFP-48, RP2040 QFN-56, MCP4922 DAC, W25Q128JVS flash).


05 — Key components

🌐 WIZnet W5500 — UDP socket mode, hardware-offloaded frame receiver

Bare W5500 (LQFP-48) on a custom PCB, one per laser head, each running the identical firmware image and differentiated only by a GPIO strap. Handles all Ethernet/IP/UDP processing in hardware so the RP2040's second core is free for microsecond-precision beam control.

🎛️ RP2040 (dual-core)

  • Core0: 150 µs main loop — reads points from a lock-free queue, writes PWM (RGB laser intensity) and drives the DAC (galvo X/Y position), with a 3-second no-signal timeout that blanks the beam for safety.
  • Core1: dedicated W5500 UDP receive loop, unpacking 6-byte point records (12-bit X, 12-bit Y, 8-bit R/G/B) from each incoming packet into the shared queue.

🎯 MCP4922 — dual 12-bit SPI DAC

Drives the X/Y galvanometer mirrors that steer the laser beam — the same vector-scanning principle used in commercial ILDA laser projectors.

💡 Direct RGB laser diode driving

Red/Green/Blue diodes driven directly via PWM (documented operating points: Red 3.3 V/46 mA, Green 7.2 V/27 mA, Blue 7.2 V/44 mA) rather than through a separate laser projector engine.

🖥️ Python control station (Raspberry Pi)

app.py (pygame GUI) orchestrates laser_server.py, which streams UDP frames to all four heads at a fixed ~25.8 ms cadence. Multiple generative and interactive modes are implemented: audio visualization, parametric equations, spirographs, a laser Pong game, drum-triggered graphics, BLE-wand-driven freehand drawing (using quaternion IMU tracking via pyquaternion), and a calibration mode. sacn_handler.py additionally drives sACN/DMX-based ambient lighting in sync with the laser show.


06 — Application scenarios

01. Music-synced laser installations — the audio-visualization and drum-graphics generators make this directly usable for live performance or exhibit spaces without further development.

02. Interactive art exhibits — the BLE motion wand mode lets a visitor "draw" in the air with the laser responding to their hand motion in real time, a pattern reusable for any hands-on installation.

03. Multi-node real-time UDP streaming reference — the core1/core0 split and the custom lightweight framing protocol (sequence byte + fixed-size point records) is a clean reference for anyone building a low-latency, hardware-offloaded UDP sink on RP2040 + W5500.

04. Scalable venue lighting — the board-strap addressing scheme (GPIO-derived IP/MAC) means adding a 5th, 6th, or Nth head is a matter of flashing identical firmware and setting a jumper — a pattern applicable well beyond laser shows, to any array of identical Ethernet-addressed peripheral nodes.


Conclusion

Four independently-addressed W5500 nodes, one Raspberry Pi source, and a beam-steering loop that never has to think about the network — this project shows what "hardware offload" buys you when microseconds actually matter.

  • ✅ Custom KiCad PCB with W5500 + RP2040 + MCP4922 co-located, BOM-verified
  • ✅ Clean UDP socket-mode usage matching the real-time, loss-tolerant nature of laser streaming
  • ✅ Dual-core RP2040 architecture that isolates network I/O from beam-timing-critical code
  • ✅ Built on WIZnet's official ioLibrary RP2040 SPI port rather than a from-scratch driver
  • ✅ Three build generations of iteration, from wired CAN bus to a networked multi-head system
  • ✅ A full accompanying server ecosystem: audio reactivity, BLE wand tracking, sACN lighting sync, generative visual modes
  • ✅ Auto-addressing via GPIO strap — a reusable pattern for any identical multi-node deployment

07 — Similar Projects on WIZnet Makers

OpenLaserDAC — An open-source ESP32-S3 laser DAC firmware implementing the Ether Dream protocol over W5500 Ethernet (with WiFi fallback), driving an 8-channel DAC80508 for a single laser head. It targets compatibility with existing laser-show software (MadMapper, Liberation, any Ether Dream client) and adds a web UI with OTA firmware updates.

 Room-Scale Quad Laser ProjectorOpenLaserDAC
MCURP2040 (dual-core)ESP32-S3 (dual-core)
WIZnet chipW5500 (bare chip, custom carrier PCB)W5500 (SPI, interrupt-driven)
Socket modeUDP (Sn_MR_UDP), custom framingTCP (Ether Dream, port 7765) + UDP broadcast discovery (port 7654)
Position DACMCP4922 (12-bit, 2-channel)DAC80508 (16-bit, 8-channel)
Head count4, independently addressed1
Client compatibilityCustom Python server onlyStandard Ether Dream ecosystem (MadMapper, Liberation, etc.)
Extra featuresBLE motion wand, sACN/DMX sync, audio-reactive & generative visual modesWeb dashboard, OTA updates, WiFi fallback
Deployment modelFixed multi-node installationSingle, software-agnostic laser head

Insight: the two projects sit at opposite ends of the same design space. The quad projector optimizes for a closed, purpose-built installation — custom protocol, custom server, multiple synchronized heads, rich interactive/generative content built in. OpenLaserDAC optimizes for interoperability — standard Ether Dream protocol means it drops into any existing laser-show software stack with zero custom server work, at the cost of being a single head with no built-in show logic of its own. Both independently chose the W5500 for the same underlying reason: a laser head is a latency-sensitive embedded target where a software network stack would compete with real-time DAC timing, and both land on UDP-based real-time delivery for the actual laser point stream (Ether Dream itself uses UDP for point-streaming, with TCP reserved for control/handshake). Together they sketch a natural roadmap: a future head design could adopt Ether Dream compatibility (from OpenLaserDAC) while keeping the multi-head synchronization and rich show content (from the quad projector).


Q&A

Q. Why UDP instead of TCP, given TCP's reliability guarantees? A. Laser frame data is inherently disposable — a lost frame should be skipped, not retransmitted, since retransmission would arrive after its display window has passed. UDP's fire-and-forget model plus a simple sequence-number check for drop detection is the right fit; TCP's retransmission and ordering guarantees would only add latency without adding value here.

Q. Could this run on the W6100 or W5500-based module boards instead of a bare chip on a custom PCB? A. Functionally yes — the socket API used (socket(), getSn_RX_RSR(), recvfrom()) is identical across WIZnet's W5x00 family. The custom PCB choice here looks driven by wanting the W5500 co-located with the RP2040 and DAC on one board rather than by any W5500-specific requirement.

Q. How does the 3-second timeout affect safety? A. If core0 stops receiving valid points from the queue for 3 seconds (LASER_TIMEOUT), it forces the laser output to zero — a reasonable fail-safe against a network hiccup leaving a beam parked (and potentially hazardous) at a fixed point.


Original Link: https://github.com/adeboni/laser-projector



룸스케일 4채널 레이저 프로젝터 — 4개의 갈보 헤드가 선 하나 없이 같은 박자에 맞춰 춤춘다

#W5500 #UDP #RP2040 #갈보레이저 #실시간스트리밍 #아트설치물 #음악동기화 #WIZnet-Pico-SDK #듀얼코어 #멀티캐스트제어

📚 컨텍스트: 개인 아트/엔터테인먼트 설치 프로젝트 — 룸스케일 인터랙티브 레이저쇼 시스템으로, 2023년부터 2025년까지 세 세대에 걸쳐 반복 개발됨. ✅ 구현 상태: 하드웨어(KiCad 커스텀 PCB, BOM 검증 완료) + 펌웨어(RP2040 + W5500) + 서버 소프트웨어(오디오/BLE/DMX 통합 파이썬 제어 스테이션) 전체가 저장소에 존재하며 서로 정합성이 맞음.


01 — 이 프로젝트는 무엇인가?

GitHub의 웬만한 DIY 레이저쇼는 "MCU 하나가 갈보 한 쌍을 구동한다"에서 멈춘다. 이 프로젝트는 한 단계 더 나아가 4개의 독립된 네트워크 노드로 구성된 룸스케일 레이저 설치물을 만들었다. 하나의 파이썬 "제어 스테이션"이 음악, 손에 든 모션 완드, DMX/sACN 조명 큐, 또는 생성형 비주얼 알고리즘(스피로그래프, 오디오 반응 패턴, 심지어 레이저로 렌더링한 2인용 퐁 게임까지)에 맞춰 네 대를 동시에 지휘한다.

이 프로젝트는 세 세대의 하드웨어 진화를 거친 흔적이 뚜렷하다:

  • 2023년 — Arduino급 MCU 하나가 CAN 버스로 4개의 레이저를 구동. 네트워크 없이 전부 점대점 배선.
  • 2024년 — 전면 재설계: 각 레이저 헤드가 독립된 RP2040 + W5500 보드가 되어, 라즈베리파이에서 돌아가는 파이썬 서버로부터 표준 이더넷 UDP로 프레임 데이터를 받음. 오디오 반응형 쇼를 위한 SuperCollider 신디사이저 패치도 추가됨.
  • 2025년 — 하드웨어는 동일, 서버 소프트웨어만 다듬음(곡 처리, 완드 트래킹, 시에르핀스키/스피로그래프 생성기 버그 수정).

결과물은 단일 기기라기보다 작은 규모의 분산 실시간 렌더링 클러스터에 가깝고, WIZnet의 이더넷 오프로드가 눈에 띄진 않지만 결정적인 역할 — 4개의 독립 헤드에 지터 없이 프레임 데이터를 전달하는 일 — 을 맡고 있다.


02 — 왜 Wi-Fi나 유선 프로토콜이 아니라 이더넷인가?

🔷 룸스케일 = 물리적으로 분산된 헤드

룸 곳곳에 설치된 4대의 레이저 프로젝터가 동기화된 프레임 데이터를 받아야 한다. 타이밍이 촘촘한 레이저 데이터를 위해 한 방에서 4개의 Wi-Fi 라디오를 동시에 돌리는 건 RF 간섭으로 인한 지터와 패킷 손실을 자초하는 일이다. 중앙 라즈베리파이에서 뻗어나오는 유선 스타 토폴로지는 이 문제를 애초에 피해간다.

🔷 결정론적, 저지터 전달

레이저 벡터 그래픽은 타이밍에 극도로 민감하다 — 포인트 하나가 지연되면 단순히 이상해 보이는 게 아니라 이미지가 눈에 띄게 일그러지거나 빔이 "흔들린다." 노드마다 전용 하드웨어 TCP/IP 스택을 갖춘 표준 이더넷은, 4개 수신단이 공유하는 Wi-Fi 채널로는 불가능한 방식으로 그 지터를 억제한다.

🔷 스타 토폴로지의 단순함

라즈베리파이 소스 하나, 이더넷으로 연결된 독립 싱크 4개 — 메시도, 페어링도, 디스커버리 프로토콜도 필요 없다. 파이는 각 헤드를 고정 IP(10.0.0.10, .11, .12, .13)로 지정해 그냥 스트리밍한다.


03 — 시스템 아키텍처

각 헤드는 GPIO 3비트 ID(6/7/8번 핀, 풀업)로 보드를 스트랩해서 IP 주소(10.0.0.10 + board_id)와 MAC 주소 뒷자리를 자동으로 결정한다 — 그래서 4개 보드 모두 동일한 펌웨어를 돌리고 점퍼 하나로만 구분된다.


04 — 왜 WIZnet W5500인가? ⭐

🔷 전용 코어, 전용 임무 — 실시간 렌더링과 경쟁하지 않는 네트워크 스택

RP2040은 듀얼코어 MCU이고, 이 프로젝트는 그 구조를 정확히 활용한다. core1은 오직 W5500 서비스만 담당하고(getSn_SR, getSn_RX_RSR, recvfrom), core0은 150µs 주기의 타이트한 루프로 DAC와 PWM 출력을 구동해 실제 레이저 빔을 제어한다. W5500이 TCP/IP 스택 전체를 하드웨어로 처리하기 때문에, core1의 일은 레지스터 폴링 몇 번과 recvfrom() 호출로 줄어든다 — 빔 조향 타이밍을 위해 비워둬야 할 코어 사이클을 놓고 경쟁하는 소프트웨어 네트워크 스택이 없다. 하드웨어 오프로드가 없는 순정 RP2040이었다면 이런 분리를 보장하기가 훨씬 어려웠을 것이다.

🔷 사용 모드: UDP (Sn_MR_UDP)

펌웨어는 소켓 0번을 UDP 모드, SF_IO_NONBLOCK으로 연다:

sockfd = socket(0, Sn_MR_UDP, 8090, SF_IO_NONBLOCK); ... size = getSn_RX_RSR(sockfd); size = recvfrom(sockfd, recv_buf, size, dest_ip, &dest_port);

여기서 UDP는 TCP가 아니라 정확한 선택이다. 레이저 프레임 데이터는 연속적인 실시간 스트림이고, 프레임 하나가 손실되면 재전송할 게 아니라 조용히 건너뛰어야 한다. TCP의 재전송과 헤드오브라인 블로킹은 "그냥 다음 프레임을 그려라"가 항상 정답인 시스템에서 오히려 해가 된다. 패킷에 담긴 1바이트 시퀀스 카운터 덕분에 핸드셰이크 오버헤드 없이 순서가 어긋나거나 누락된 패킷을 감지해 버릴 수 있다.

🔷 WIZnet 공식 레퍼런스 포트 위에 구축

SPI 글루 코드(w5x00_spi.c/h)에는 WIZnet Co.,Ltd 저작권 헤더가 붙어있고 WIZnet 공식 ioLibrary_Driver의 RP2040 포트와 일치한다 — SPI/CS 처리를 처음부터 새로 짜는 대신 벤더 레퍼런스 구현을 그대로 재사용했는데, 이건 WIZnet 포트가 목표로 하는 정확한 통합 방식이다.

🔷 실제 물리적 멀티헤드 배포에서 검증됨

단일 보드 데모가 아니라, 한 방에 동시에 배치된 4개의 물리적으로 독립된, 각기 다른 주소를 가진 W5500 보드다. 모두 같은 소스 스트림을 받고, 커스텀 KiCad 설계 캐리어 보드(combo_laser_driver)는 W5500을 RP2040·DAC와 한 PCB에 나란히 배치했다(BOM 확인: W5500 LQFP-48, RP2040 QFN-56, MCP4922 DAC, W25Q128JVS 플래시).


05 — 핵심 구성요소

🌐 WIZnet W5500 — UDP 소켓 모드, 하드웨어 오프로드 프레임 수신기

커스텀 PCB 위의 베어 W5500(LQFP-48), 레이저 헤드마다 한 개씩, 동일한 펌웨어 이미지를 돌리며 GPIO 스트랩만으로 구분된다. 이더넷/IP/UDP 처리 전체를 하드웨어에서 담당해 RP2040의 두 번째 코어를 마이크로초 단위 빔 제어에 온전히 비워준다.

🎛️ RP2040 (듀얼코어)

  • Core0: 150µs 메인 루프 — 락프리 큐에서 포인트를 읽어 PWM(RGB 레이저 세기)을 쓰고 DAC(갈보 X/Y 위치)를 구동하며, 신호 없음 3초 타임아웃 시 안전을 위해 빔을 꺼버림.
  • Core1: W5500 UDP 수신 전용 루프. 들어오는 패킷마다 6바이트 포인트 레코드(12비트 X, 12비트 Y, 8비트 R/G/B)를 풀어서 공유 큐에 넣음.

🎯 MCP4922 — 듀얼 12비트 SPI DAC

X/Y 갈바노미터 미러를 구동해 레이저 빔을 조향한다 — 상용 ILDA 레이저 프로젝터와 동일한 벡터 스캐닝 원리.

💡 RGB 레이저 다이오드 직접 구동

별도의 레이저 프로젝터 엔진 없이 R/G/B 다이오드를 PWM으로 직접 구동한다(동작점 문서화됨: 빨강 3.3V/46mA, 녹색 7.2V/27mA, 파랑 7.2V/44mA).

🖥️ 파이썬 제어 스테이션 (라즈베리파이)

app.py(pygame GUI)가 laser_server.py를 지휘하며, 약 25.8ms 주기로 4개 헤드 전체에 UDP 프레임을 스트리밍한다. 오디오 시각화, 파라메트릭 방정식, 스피로그래프, 레이저 퐁 게임, 드럼 트리거 그래픽, BLE 완드 기반 자유 드로잉(pyquaternion으로 쿼터니언 IMU 트래킹), 캘리브레이션 모드까지 다양한 생성형·인터랙티브 모드가 구현돼 있다. sacn_handler.py는 sACN/DMX 기반 주변 조명을 레이저쇼와 동기화해 추가로 구동한다.


06 — 응용 시나리오

01. 음악 동기화 레이저 설치물 — 오디오 비주얼라이저와 드럼 그래픽 생성기가 있어 별도 개발 없이 라이브 공연이나 전시 공간에 바로 쓸 수 있다.

02. 인터랙티브 아트 전시 — BLE 모션 완드 모드는 방문객이 허공에 "그림을 그리면" 레이저가 손동작에 실시간으로 반응하게 해준다. 어떤 체험형 설치물에도 재사용 가능한 패턴이다.

03. 멀티노드 실시간 UDP 스트리밍 레퍼런스 — core1/core0 분리 구조와 자체 경량 프레이밍 프로토콜(시퀀스 바이트 + 고정 크기 포인트 레코드)은 RP2040 + W5500으로 저지연 하드웨어 오프로드 UDP 싱크를 만들려는 누구에게나 깔끔한 참고 사례다.

04. 확장 가능한 공연장 조명 — GPIO 스트랩 기반 자동 주소지정 방식 덕분에 5번째, 6번째, N번째 헤드를 추가하는 건 동일 펌웨어를 플래시하고 점퍼 하나 세팅하는 문제로 줄어든다 — 레이저쇼를 넘어 동일한 이더넷 주소지정 주변장치 배열이라면 어디에든 적용 가능한 패턴이다.


Conclusion

독립적으로 주소가 지정된 W5500 노드 4개, 라즈베리파이 소스 하나, 그리고 네트워크를 신경 쓸 필요가 전혀 없는 빔 조향 루프 — 이 프로젝트는 마이크로초가 진짜로 중요할 때 "하드웨어 오프로드"가 무엇을 사줄 수 있는지 보여준다.

  • ✅ W5500 + RP2040 + MCP4922를 한 보드에 배치한 커스텀 KiCad PCB, BOM 검증 완료
  • ✅ 레이저 스트리밍의 실시간·손실허용 특성에 정확히 맞는 깔끔한 UDP 소켓 모드 사용
  • ✅ 네트워크 I/O와 빔 타이밍 크리티컬 코드를 분리하는 듀얼코어 RP2040 아키텍처
  • ✅ 처음부터 짠 드라이버가 아니라 WIZnet 공식 ioLibrary RP2040 SPI 포트 위에 구축
  • ✅ 유선 CAN 버스에서 네트워크형 멀티헤드 시스템까지, 세 세대에 걸친 반복 개발
  • ✅ 오디오 반응, BLE 완드 트래킹, sACN 조명 동기화, 생성형 비주얼 모드까지 갖춘 풀 서버 생태계
  • ✅ GPIO 스트랩 기반 자동 주소지정 — 동일 구성 멀티노드 배포라면 어디에든 재사용 가능한 패턴

07 — WIZnet Makers 내 유사 프로젝트

OpenLaserDAC — Ether Dream 프로토콜을 W5500 이더넷(WiFi 폴백 포함)으로 구현한 오픈소스 ESP32-S3 레이저 DAC 펌웨어. 8채널 DAC80508로 단일 레이저 헤드를 구동한다. 기존 레이저쇼 소프트웨어(MadMapper, Liberation, 모든 Ether Dream 클라이언트)와의 호환성을 목표로 하며, OTA 펌웨어 업데이트가 되는 웹 UI도 갖췄다.

 룸스케일 쿼드 레이저 프로젝터OpenLaserDAC
MCURP2040 (듀얼코어)ESP32-S3 (듀얼코어)
WIZnet 칩W5500 (베어칩, 커스텀 캐리어 PCB)W5500 (SPI, 인터럽트 구동)
소켓 모드UDP (Sn_MR_UDP), 자체 프레이밍TCP (Ether Dream, 포트 7765) + UDP 브로드캐스트 디스커버리 (포트 7654)
위치제어 DACMCP4922 (12비트, 2채널)DAC80508 (16비트, 8채널)
헤드 개수4개, 독립 주소지정1개
클라이언트 호환성자체 파이썬 서버 전용표준 Ether Dream 생태계(MadMapper, Liberation 등)
추가 기능BLE 모션 완드, sACN/DMX 동기화, 오디오반응·생성형 비주얼 모드웹 대시보드, OTA 업데이트, WiFi 폴백
배포 모델고정 멀티노드 설치물소프트웨어 무관 단일 레이저 헤드

Q&A

Q. TCP의 신뢰성 보장이 있는데 왜 UDP를 썼나? A. 레이저 프레임 데이터는 본질적으로 "버려도 되는" 데이터다 — 손실된 프레임은 재전송할 게 아니라 건너뛰어야 한다. 재전송이 도착할 즈음이면 이미 그 프레임을 표시할 타이밍은 지나가 있기 때문이다. UDP의 발사 후 망각(fire-and-forget) 방식에 손실 감지를 위한 간단한 시퀀스 넘버 체크를 더한 조합이 정확히 맞는 선택이고, TCP의 재전송·순서보장은 여기선 지연만 늘릴 뿐 얻는 게 없다.

Q. 커스텀 PCB의 베어칩 대신 W6100이나 W5500 모듈 보드로도 돌아갈까? A. 기능적으로는 그렇다 — 사용된 소켓 API(socket(), getSn_RX_RSR(), recvfrom())는 WIZnet W5x00 계열 전체에서 동일하다. 이 프로젝트가 커스텀 PCB를 택한 이유는 W5500 자체의 특수 요구사항이라기보다 RP2040·DAC와 한 보드에 나란히 배치하고 싶었던 설계 의도로 보인다.

Q. 3초 타임아웃은 안전성 측면에서 어떤 역할을 하나? A. core0이 3초간(LASER_TIMEOUT) 큐에서 유효한 포인트를 받지 못하면 레이저 출력을 강제로 0으로 만든다 — 네트워크 문제로 빔이 한 점에 고정된 채(위험할 수 있는 상태로) 방치되는 걸 막는 합리적인 안전장치다.

Documents
Comments Write