Add ArtNetDMX Pico W firmware with dual DMX and docs.
Art-Net to two RS-485 outputs over Wi-Fi (AP or STA with SoftAP fallback), web UI, mDNS, and QLC+/ArtPoll notes for unicast on STA. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+89
@@ -0,0 +1,89 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "pico/stdlib.h"
|
||||
#include "pico/stdio_usb.h"
|
||||
#include "pico/cyw43_arch.h"
|
||||
#include "hardware/pio.h"
|
||||
|
||||
#include "board.h"
|
||||
#include "config.h"
|
||||
#include "channels.h"
|
||||
#include "dmx_out.h"
|
||||
#include "artnet.h"
|
||||
#include "wifi_mgr.h"
|
||||
#include "http_server.h"
|
||||
|
||||
static dmx_out_t g_dmx[BOARD_NUM_UNIVERSES];
|
||||
static uint8_t g_frames[BOARD_NUM_UNIVERSES][BOARD_DMX_FRAME_LEN];
|
||||
|
||||
static bool dmx_timer_cb(repeating_timer_t *rt) {
|
||||
(void)rt;
|
||||
for (unsigned u = 0; u < BOARD_NUM_UNIVERSES; u++) {
|
||||
if (dmx_out_busy(&g_dmx[u])) {
|
||||
continue;
|
||||
}
|
||||
channels_build_frame(u, g_frames[u]);
|
||||
dmx_out_write(&g_dmx[u], g_frames[u], BOARD_DMX_FRAME_LEN);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
stdio_init_all();
|
||||
/* Give USB CDC a moment so early boot logs are visible after flash/reboot. */
|
||||
for (int i = 0; i < 40 && !stdio_usb_connected(); i++) {
|
||||
sleep_ms(50);
|
||||
}
|
||||
sleep_ms(200);
|
||||
printf("\nArtNetDMX starting\n");
|
||||
fflush(stdout);
|
||||
|
||||
config_init();
|
||||
channels_init();
|
||||
|
||||
if (!dmx_out_init(&g_dmx[0], BOARD_DMX_A_PIN, pio0)) {
|
||||
printf("DMX A init failed\n");
|
||||
}
|
||||
if (!dmx_out_init(&g_dmx[1], BOARD_DMX_B_PIN, pio1)) {
|
||||
printf("DMX B init failed\n");
|
||||
}
|
||||
|
||||
if (!wifi_mgr_start(config_get())) {
|
||||
printf("WiFi start failed\n");
|
||||
while (true) {
|
||||
tight_loop_contents();
|
||||
}
|
||||
}
|
||||
|
||||
if (!http_server_start()) {
|
||||
printf("HTTP start failed\n");
|
||||
}
|
||||
if (!artnet_start()) {
|
||||
printf("Art-Net start failed\n");
|
||||
}
|
||||
|
||||
static repeating_timer_t dmx_timer;
|
||||
if (!add_repeating_timer_ms(-BOARD_DMX_PERIOD_MS, dmx_timer_cb, NULL, &dmx_timer)) {
|
||||
printf("DMX timer failed\n");
|
||||
} else {
|
||||
printf("DMX output at %d Hz\n", BOARD_DMX_HZ);
|
||||
}
|
||||
|
||||
printf("Ready — mode=%s primary=%s mDNS http://%s/\n",
|
||||
wifi_mode_name(wifi_mgr_active_mode()),
|
||||
wifi_mgr_ip_str(),
|
||||
wifi_mgr_mdns_name());
|
||||
if (wifi_mgr_ap_up()) {
|
||||
printf("SoftAP http://%s/ (ssid ArtNetDMX)\n", wifi_mgr_ap_ip_str());
|
||||
} else {
|
||||
printf("Joining STA (SoftAP starts only if join fails)...\n");
|
||||
}
|
||||
|
||||
while (true) {
|
||||
wifi_mgr_poll();
|
||||
artnet_poll();
|
||||
tight_loop_contents();
|
||||
sleep_ms(10);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user