ND Pico2DMX System

Bộ chuyển đổi Art-Net và sACN sang 4 cổng DMX, hỗ trợ Ethernet, Wi-Fi và giao diện quản lý qua web.

Mac / Window / Linux
PLATFORM
$50
COST TO MAKE
1.0.0
VERSION
C++
BUILT WITH

TỔNG QUAN

Từ một Ý TƯỞNG NHỎ đến một DMX Node có thể vận hành thực tế

ND Pico2DMX Node bắt đầu từ một nhu cầu khá đơn giản: tôi muốn tự làm một thiết bị có thể nhận tín hiệu lighting qua network và chuyển chúng thành DMX, đủ nhỏ gọn để mang theo, đủ ổn định để sử dụng trong công việc, và quan trọng nhất là tôi có thể hiểu cũng như kiểm soát toàn bộ cách nó vận hành.

Ban đầu, mục tiêu của tôi không phải tạo ra một sản phẩm quá phức tạp. Tôi chỉ muốn giải quyết một vấn đề thực tế trong workflow của mình. Nhưng càng làm, tôi càng nhận ra rằng khoảng cách giữa một prototype “chạy được” và một thiết bị mà mình cảm thấy yên tâm khi cắm vào hệ thống thật là rất lớn.

 

Và phần lớn thời gian của project này thực ra được dành để thu hẹp khoảng cách đó.

Phiên bản đầu tiên RP2040 - W5500 và rất nhiều dây

Những prototype đầu tiên của tôi được xây dựng xung quanh RP2040 (Raspberry Pico 1)  kết hợp với một module Ethernet W5500 riêng biệt.

Về mặt ý tưởng, nó hoàn toàn hợp lý. RP2040 xử lý logic và DMX, W5500 đảm nhiệm Ethernet. Tôi có thể nhận Art-Net từ network, xử lý dữ liệu rồi đưa tín hiệu ra các cổng DMX.

Nó hoạt động.

Nhưng khi prototype bắt đầu lớn hơn, một vấn đề rất đời thường xuất hiện: có quá nhiều dây.

Giữa board RP2040, W5500, nguồn, các đường SPI, module RS485 và những kết nối khác, chiếc prototype bắt đầu giống một hệ thống thử nghiệm trên bàn hơn là nền tảng của một thiết bị mà tôi muốn đóng thành sản phẩm.

Điều đó không chỉ ảnh hưởng đến thẩm mỹ.

 

Mỗi dây nối thêm là một điểm có khả năng tiếp xúc không tốt. Mỗi module rời là thêm một connector, thêm một vị trí phải kiểm tra khi hệ thống có vấn đề. Và khi đang phát triển firmware, việc phải liên tục tự hỏi lỗi đến từ code hay từ một jumper wire nào đó thực sự làm quá trình debug chậm đi rất nhiều.

 

Đó là lúc tôi quyết định thay đổi nền tảng phần cứng.

Chuyển sang Pico 2 + W5500 của Waveshare

Thay vì tiếp tục tối ưu prototype RP2040 cũ, tôi chuyển sang Waveshare W5500-EVB-Pico2 – một board kết hợp RP2350 và Ethernet W5500 trong một thiết kế gọn hơn rất nhiều.

 

Đây là một thay đổi mà tôi cảm thấy đúng gần như ngay lập tức.

 

Ethernet không còn là một module rời treo bên ngoài. Số lượng dây giảm đáng kể, hệ thống gọn hơn, việc kiểm tra phần cứng cũng dễ hơn và quan trọng hơn, tôi có một nền tảng tốt hơn để phát triển thiết bị lâu dài.

 

Việc chuyển từ RP2040 lên RP2350 cũng không chỉ để giải quyết chuyện dây nối. Tôi muốn thiết kế này có khoảng trống để phát triển.

 

Phiên bản hiện tại sử dụng 4 DMX output độc lập, nhưng ngay từ khi thiết kế lại, tôi đã nghĩ đến khả năng mở rộng lên 8 universe DMX trong tương lai. Pico 2 cho tôi thêm tài nguyên xử lý và một nền tảng phù hợp hơn để tiếp tục phát triển mà không phải thay toàn bộ kiến trúc chỉ sau một phiên bản.

 

Thay vì hỏi “phần cứng này có đủ cho phiên bản hiện tại không?”, tôi bắt đầu hỏi:

 

“Nếu sau này tôi muốn làm gấp đôi những gì đang làm hôm nay thì sao?”

 

Câu hỏi đó ảnh hưởng khá nhiều đến những quyết định tiếp theo của project.

Không chỉ Ethernet tôi vẫn muốn Wi-Fi

Ethernet rất phù hợp với một lighting node. Nó ổn định, dễ dự đoán và trong môi trường production, wired network luôn là thứ tôi muốn có. Nhưng tôi cũng không muốn thiết bị bị phụ thuộc hoàn toàn vào dây mạng.

Vì vậy ESP32-C5 được thêm vào hệ thống để đảm nhiệm Wi-Fi. Nó có thể tạo Access Point riêng hoặc kết nối vào một Wi-Fi network có sẵn, đồng thời nhận Art-Net/sACN qua wireless.

Từ đây, project bắt đầu có hai bộ xử lý làm việc cùng nhau. RP2350 là bộ điều khiển chính. Nó quản lý Ethernet, trạng thái hệ thống và các DMX output. ESP32-C5 phụ trách phần Wi-Fi và đóng vai trò gateway cho dữ liệu đi vào từ wireless network.

Nghe thì khá đơn giản, nhưng đây cũng là nơi tôi gặp một trong những bài học lớn nhất của project.

Có những giải pháp "chạy được" nhưng không phải giải pháp đúng

Ban đầu, giao tiếp giữa RP2350 và ESP32-C5 được thử bằng UART. Với những packet nhỏ và các bài test cơ bản, nó hoạt động. Ở tốc độ thấp, hai MCU có thể nói chuyện với nhau bình thường. Nhưng DMX không phải là một vài byte trạng thái thỉnh thoảng mới gửi. Khi bắt đầu nghĩ đến nhiều universe chạy liên tục, bandwidth trở thành vấn đề thực sự. Tăng baud rate lại làm kết nối kém ổn định hơn.

 

Đây là một thời điểm khá quan trọng trong project, bởi lựa chọn dễ nhất lúc đó là tiếp tục cố “sửa UART”. Thay vào đó, tôi quyết định dừng lại. UART đã chứng minh rằng đường kết nối vật lý hoạt động. Nhưng nó không phải transport phù hợp với lượng dữ liệu mà thiết bị cần xử lý.

 

Vì vậy toàn bộ interprocessor transport được chuyển sang SPI. Đó là một trong những nguyên tắc mà tôi giữ xuyên suốt quá trình phát triển:

 

Không phải thứ gì có thể làm cho chạy được cũng nên trở thành kiến trúc production.

 

Đôi khi giải pháp tốt nhất cho một bug không phải là thêm một workaround, mà là thừa nhận rằng lựa chọn ban đầu không còn phù hợp nữa.

Và rồi SPI cũng không hoạt động

Tất nhiên, chuyển sang SPI không có nghĩa mọi thứ lập tức trở nên hoàn hảo.

Có một giai đoạn SPI hoạt động rất kỳ lạ. Firmware nhìn có vẻ hợp lý, pin mapping được kiểm tra, mode và clock cũng được kiểm tra đi kiểm tra lại. Nhưng dữ liệu nhận được vẫn sai.

Đây chính xác là loại lỗi rất dễ khiến mình bắt đầu sửa mọi thứ cùng lúc.

Đổi pin.

Đổi clock.

Đổi protocol.

Đổi parser.

Đổi timing.

Nhưng càng thay nhiều thứ cùng lúc thì càng khó biết điều gì thực sự gây ra vấn đề.

Cuối cùng, nguyên nhân lại nằm ở thứ đơn giản nhất: physical interconnect.

Sau khi wiring được làm lại đầy đủ, bao gồm cả ground, cùng firmware đó, cùng pin đó, cùng SPI mode và cùng clock đó bắt đầu chạy ổn định.

Đó là một bài học tôi nhớ khá rõ từ project này: khi debug một hệ thống embedded, đừng mặc định rằng firmware luôn có lỗi chỉ vì lỗi đang xuất hiện trên màn hình serial.

Đôi khi code đã đúng từ trước.

DMX phải được chứng minh bằng ánh sáng thật

Một nguyên tắc khác mà tôi đặt ra là tôi không muốn gọi DMX output là “working” chỉ vì đồng hồ đo điện hay console nói rằng nó đang chạy.

Cuối cùng, DMX tồn tại để điều khiển đèn thật.

Vì vậy output được test xuyên suốt cả chain thực tế: từ node, qua RS485/DMX, qua wireless DMX/CRMX và cuối cùng đến fixture thật.

Trong quá trình đó tôi sử dụng Godox TimoLink TRX và Aputure MC Pro để kiểm tra tín hiệu trong một workflow gần với cách tôi thực sự sử dụng thiết bị.

Khi ánh sáng phản ứng đúng với FULL, BLACKOUT và dữ liệu network thực tế, lúc đó tôi mới coi đường DMX đó là đã được chứng minh.

Phiên bản hiện tại có 4 DMX output độc lập, mỗi output có engine riêng. Đây cũng là nền móng cho hướng 8-output mà tôi muốn phát triển sau này.

Một bug tưởng là DMX, nhưng thực ra lại nằm ở… dashboard

Có lẽ một trong những phần thú vị nhất của quá trình phát triển là nhiều bug không nằm ở nơi mà biểu hiện của nó khiến mình nghĩ tới.

Có lúc dashboard báo Core1 ngừng hoạt động và toàn bộ DMX FPS rơi về 0.

Phản xạ đầu tiên rất dễ là nghi ngờ PIO, DMX timing hoặc multicore synchronization.

Nhưng sau khi đi từng lớp một, vấn đề lớn lại được tìm thấy ở phần HTTP/dashboard.

Một số buffer khá lớn đang được tạo cục bộ trong các function. Trên một hệ thống embedded với stack hạn chế, điều đó có thể làm tràn stack và ghi đè lên vùng bộ nhớ liên quan đến core còn lại.

Kết quả nhìn từ bên ngoài giống như “DMX engine bị treo”.

Nhưng DMX engine không phải thủ phạm.

Các buffer được chuyển sang vùng nhớ tĩnh và stack usage giảm mạnh. Core1 và bốn DMX output sau đó hoạt động ổn định trở lại.

Điều thú vị là bản sửa đó lại tạo ra một bug HTTP mới vì một đoạn kiểm tra kích thước buffer vẫn đang sử dụng logic cũ.

Và thế là tôi sửa tiếp.

Không phải bằng cách rewrite toàn bộ dashboard, mà bằng một thay đổi nhỏ, có giới hạn và có thể kiểm chứng.

Đây dần trở thành cách project được phát triển: thay đổi càng ít thứ cùng lúc càng tốt, sau đó kiểm tra lại toàn bộ những phần quan trọng.

Dashboard cũng phải dành cho người sử dụng, không phải chỉ dành cho người viết firmware

Ở những phiên bản đầu, dashboard chứa khá nhiều thông tin kỹ thuật.

Điều đó rất hữu ích trong quá trình development, nhưng tôi dần nhận ra một thiết bị production không nên bắt người vận hành phải hiểu những thứ như core diagnostics, SPI internals hay các giá trị debug chỉ để biết hệ thống có đang ổn hay không.

Vì vậy dashboard được chỉnh lại theo hướng đơn giản hơn.

Người dùng cần biết network có kết nối không, Wi-Fi đang ở trạng thái nào, các DMX output có hoạt động không, firmware đang chạy phiên bản nào và khi update firmware thì cần làm gì.

Những thông tin kỹ thuật sâu hơn vẫn tồn tại trong API để phục vụ troubleshooting, nhưng không cần xuất hiện trước mặt người dùng mọi lúc.

Tôi rất thích sự thay đổi này, vì nó đánh dấu lúc project bắt đầu chuyển từ “một thiết bị tôi đang debug” sang “một thiết bị mà người khác cũng có thể sử dụng.”

Firmware update: một hành trình nhỏ khác

OTA update cũng mất nhiều thời gian hơn tôi dự tính.

Mục tiêu là sau khi thiết bị đã được lắp đặt, tôi không muốn mỗi lần update firmware lại phải tháo nó ra và cắm USB.

RP2350 vì vậy được bổ sung khả năng update firmware qua Ethernet dashboard. ESP32-C5 cũng có workflow update riêng.

Nhưng lần OTA đầu tiên thất bại.

Rồi lần tiếp theo cũng thất bại.

Có lần dashboard chỉ trả về Not found. Có lần firmware từ chối update dù request nhìn hoàn toàn hợp lệ. Có lần browser báo mất kết nối nhưng nguyên nhân thực sự lại nằm ở cách backend đọc confirmation header.

Mỗi lần như vậy, điều quan trọng nhất là không đoán.

Tôi kiểm tra request thực tế, trạng thái OTA, kích thước image, flash layout, header parser và từng điều kiện trước khi firmware bắt đầu ghi dữ liệu.

Cuối cùng, một lỗi rất nhỏ được tìm thấy: độ dài của tên HTTP header bị tính lệch đúng một ký tự.

Một ký tự.

Nhưng nó đủ để toàn bộ OTA pipeline thất bại.

Sau khi sửa và kiểm tra lại, firmware đã có thể update từ phiên bản F4 lên F5 hoàn toàn qua Ethernet dashboard. Sau reboot, Ethernet, SPI, Core1 và cả bốn DMX output vẫn hoạt động bình thường, và các bài test FULL → BLACKOUT → NETWORK đều vượt qua.

Đó là thời điểm tôi cảm thấy OTA thực sự “đã xong”.

Không phải khi code compile.

Mà là khi thiết bị tự update, khởi động lại và tiếp tục điều khiển ánh sáng như trước

“Stable” không có nghĩa là “không còn bug”

Một điều project này thay đổi trong cách tôi nhìn về firmware là định nghĩa của chữ stable.

Stable không có nghĩa là tôi tin rằng code không còn bug.

Stable nghĩa là có một phiên bản mà tôi biết chính xác nó đã được kiểm tra những gì, trên phần cứng nào, với wiring nào và trong điều kiện nào.

Với ND Pico2DMX Node, baseline hiện tại là RP2350 V3.6F5 kết hợp với ESP32-C5 V3.6A.

Từ thời điểm baseline này được xác nhận, tôi cố tình không “cleanup code cho đẹp”, không thay đổi timing vì cảm giác nó có thể tốt hơn và không refactor những phần đã được chứng minh chỉ vì có một cách viết khác hay hơn.

Một hệ thống production đôi khi cần sự kỷ luật để không sửa những thứ đang hoạt động.

Điều tôi thích nhất ở project này

Có lẽ điều tôi thích nhất ở ND Pico2DMX Node không phải là một feature cụ thể.

Nó là cách project được hình thành.

Rất nhiều thứ đã không hoạt động ngay lần đầu. UART không trở thành transport cuối cùng. SPI từng khiến tôi nghi ngờ firmware trong khi lỗi nằm ở wiring. Một bug dashboard có thể làm DMX core ngừng chạy. Một ký tự trong HTTP parser có thể chặn toàn bộ OTA.

Nhưng mỗi vấn đề đều khiến kiến trúc rõ ràng hơn một chút.

Tôi cố gắng không giải quyết lỗi bằng cách thay năm thứ cùng lúc. Thay vào đó là đo, xác nhận, cô lập vấn đề, thay đổi ít nhất có thể rồi kiểm tra lại trên phần cứng thật.

Có những phiên bản nhìn trên giấy rất ổn nhưng vẫn chưa được coi là hoàn thành, đơn giản vì tôi chưa thấy fixture thật phản ứng đúng.

Có những đoạn code có thể được refactor đẹp hơn, nhưng được giữ nguyên vì chúng đã trở thành một phần của baseline đã được chứng minh.

Và cũng có những lúc giải pháp tốt nhất là bỏ một hướng đã tốn khá nhiều công sức như UART để chọn kiến trúc phù hợp hơn.

Đây vẫn chưa phải điểm kết thúc

ND Pico2DMX Node hiện đã có một nền tảng mà tôi cảm thấy đủ chắc chắn để gọi là v1.0.0.

Nó có Ethernet, Wi-Fi, Art-Net, sACN, 4 DMX output độc lập, dashboard quản lý, firmware update và một kiến trúc hai MCU được thiết kế để mỗi phần làm đúng công việc của mình.

Nhưng từ đầu tôi đã không thiết kế nó chỉ cho bốn output.

Việc chuyển sang Pico 2 cho tôi thêm không gian để nghĩ tới phiên bản 8 universe, những hardware revision gọn hơn và nhiều khả năng khác mà tôi chưa muốn đưa vào v1.0.0 chỉ để có thêm feature.

Tôi muốn phát triển chúng theo đúng cách mà phiên bản hiện tại đã được xây dựng:

làm từng phần, hiểu tại sao nó hoạt động, test trên hardware thật, và chỉ gọi nó là hoàn thành khi tôi thực sự tin tưởng nó.

ND Pico2DMX Node bắt đầu từ vài board mạch, một đống jumper wire và ý tưởng rằng “chắc mình có thể tự làm cái này”.

Sau khá nhiều lần build, flash, test, fail, debug, nối lại dây, sửa một dòng code rồi test lại từ đầu, nó đã trở thành một thiết bị mà tôi thực sự muốn đặt trong DOP Kit của mình.

Với tôi, đó mới là phần thú vị nhất của việc tự xây dựng một thứ gì đó.

Các Câu Hỏi Thường Gặp

Giải đáp nhanh các câu hỏi thường gặp về ND Pico2DMX Node

Hiện tại, ND Pico2DMX Node trước hết là một dự án cá nhân và open-source được tôi xây dựng từ nhu cầu sử dụng thực tế trong công việc điều khiển ánh sáng. Mục tiêu của tôi không chỉ là làm một prototype có thể xuất DMX, mà là phát triển một hệ thống đủ ổn định, dễ vận hành và có cấu trúc rõ ràng để có thể tiếp tục phát triển lâu dài. Phiên bản v1.0.0 hiện tại có 4 DMX output, Ethernet, Wi-Fi, Art-Net, sACN, dashboard quản lý và khả năng cập nhật firmware. Kiến trúc cũng đã được chuẩn bị với định hướng mở rộng lên 8 universe trong tương lai.

Có. Một trong những lý do tôi public project là để những người có cùng sở thích về lighting, embedded system, lập trình nhúng hoặc DIY hardware có thể tìm hiểu, tự build và phát triển nó theo nhu cầu của mình. Chẳng hạn, mapping GPIO cho các DMX output có thể được điều chỉnh khi làm custom hardware, miễn là người build hiểu những tài nguyên phần cứng đang được sử dụng và kiểm tra lại thiết kế của mình cẩn thận.

Tuy nhiên, tôi luôn phân biệt khá rõ giữa cấu hình đã được kiểm chứng trên phần cứng của tôi và những custom build khác. Firmware chính thức được giữ ở một baseline đã qua test thực tế; việc thay đổi hardware, pin mapping hay mở rộng thêm output nên được xem là một nhánh phát triển mới và cần được kiểm tra lại thay vì mặc định rằng nó sẽ hoạt động giống hệt bản reference.

Có. ND Pico2DMX Node được phát hành theo GNU General Public License v3.0 (GPLv3). Điều này cho phép bạn sử dụng, nghiên cứu, chỉnh sửa và phân phối lại phần mềm theo các điều khoản của GPLv3.

Nếu bạn phân phối một phiên bản đã chỉnh sửa hoặc một sản phẩm có chứa phần mềm thuộc phạm vi GPL của dự án, bạn cần tuân thủ các nghĩa vụ tương ứng của GPLv3, bao gồm việc cung cấp source code liên quan theo các điều khoản của giấy phép và giữ lại các thông báo bản quyền/license cần thiết. Một số thư viện hoặc thành phần bên thứ ba được sử dụng trong project có thể có license riêng và các license đó vẫn cần được tôn trọng.

Nói đơn giản hơn: bạn hoàn toàn có thể học từ nó, build nó, thay đổi nó và tạo ra phiên bản của riêng mình, chỉ cần giữ đúng tinh thần và các điều khoản của open-source license mà project sử dụng.

Back To Top