Zum Inhalt

dmx_dimmer_panel.tc

dmx_dimmer_panel.tc — minimal DMX512 test panel.

Source on GitHub

// dmx_dimmer_panel.tc — minimal DMX512 test panel.
//
// /tc_ui page: a TX-pin pulldown (TinyC's built-in free-GPIO
// selector), a DMX-channel number input and a value slider.
// Picking a pin re-inits the DMX UART at runtime; the value is
// pushed once per second (firmware also auto-refreshes the DMX
// frame ~20 Hz and runs a 30 s watchdog → 0).
//
// Hardware: an auto-direction RS485 transceiver on the chosen TX
// pin (no DE pin needed). DMX is TX-only.
//
// Note: "@getfreepins" lists only GPIOs Tasmota currently has free
// (the bound var holds the real GPIO number, or -1 = None).
//
// The default txpin below (17) is valid on classic ESP32/S3 but is a
// flash pin on the ESP32-C3 (GPIO11-17 = SPI flash). Driving RMT onto a
// flash pin crashes the chip immediately. So before every (re)init we
// gate on pinFree(txpin) — a soft check (returns 1=free, 0=forbidden:
// out-of-range / flash / claimed by a peripheral) that does NOT halt the
// VM. A forbidden default just logs a hint and waits for the user to pick
// a free pin from the pulldown, instead of taking the slot down on boot.

int txpin = 17;   // DMX TX GPIO — set via the @getfreepins pulldown
int chan  = 1;    // DMX channel  (webNumber 1..16)
int val   = 0;    // DMX value    (webSlider 0..255)
int curtx = -2;   // last-initialised pin (-2 = not yet)
int dmxok = 0;    // 1 once dmxInit() succeeded on curtx

void main() {
  webPageLabel(0, "DMX");   // adds a "DMX" button on the Tasmota main page
}

// Rendered on the /tc_ui page (every 2 s + on widget change).
void WebUI() {
  webPulldown(txpin, "DMX TX pin", "@getfreepins");
  webNumber(chan, 1, 16,  "DMX Channel");
  webSlider(val,  0, 255, "DMX Value");
}

void EverySecond() {
  if (txpin != curtx) {                 // pin changed → (re)init
    curtx = txpin;
    dmxok = 0;
    if (txpin >= 0) {
      if (pinFree(txpin) == 0) {        // forbidden on this CPU (flash/range/claimed)
        log("DMX: TX pin not allowed on this CPU — pick a free pin");
      } else if (dmxInit(txpin) == 0) {
        log("DMX init failed");
      } else {
        dmxok = 1;
      }
    }
  }
  if (dmxok) { dmxWrite(chan, val); }   // push + feed watchdog (only when initialised)
}