Skip to content

ledbar.tc

LEDBAR — WS2812 position indicator with IR lamp control

Source on GitHub

// LEDBAR — WS2812 position indicator with IR lamp control
// Translated from Scripter ws2812script.txt
//
// Left half: red stripes, right half: green stripes
// Blue marker shows 'ledbar' value (-5000..+5000) as position
// 'elamp' toggles IR lamp on/off via NEC protocol

// UDP shared variables (auto-updated from other device)
global float ledbar;
global float elamp;

// LED strip pixel buffer (heap-allocated, ESP8266 has only 64 global slots)
int leds[65];    // > 64 → auto heap; only [0..59] used
char buf[16];

// Stripe colors (dim to save power)
int colr1 = 0x050000;   // dark red
int colr2 = 0x050100;   // dark red + tiny green
int colg1 = 0x000300;   // dark green
int colg2 = 0x020300;   // dark green + tiny red
int blue  = 64;          // 0x000040 — blue marker

// Configuration
int pixels = 60;
int steps  = 10;
int divn;
int maxval =  5000;
int minval = -5000;

// Fill strip with alternating color stripes
void prep() {
    int ind = 0;
    int tog = 0;
    for (int i = 0; i < pixels; i++) {
        ind++;
        if (ind > divn) {
            ind = 1;
            tog = tog ^ 1;
        }
        if (i < pixels / 2) {
            if (tog) {
                leds[i] = colr1;
            } else {
                leds[i] = colr2;
            }
        } else {
            if (tog) {
                leds[i] = colg1;
            } else {
                leds[i] = colg2;
            }
        }
    }
}

int main() {
    divn = pixels / steps;
    prep();
    setPixels(leds, pixels, 0);
    return 0;
}

void WebCall() {
    char buf[64];
    sprintf(buf, "{s}ledbar{m}%f{e}", ledbar);
    webSend(buf);
}

void UdpCall() {
    // elamp is auto-updated from UDP; react to changes here
    if (elamp > 0.0) {
        tasmCmd("IRsend {\"Protocol\":\"NEC\",\"Bits\":32,\"Data\":0x00F7E01F}", buf);
    } else {
        tasmCmd("IRsend {\"Protocol\":\"NEC\",\"Bits\":32,\"Data\":0x00F740BF}", buf);
    }
}

void EverySecond() {
    // ledbar and elamp are auto-updated from UDP packets

    // Clamp to range
    if (ledbar < (float)minval) { ledbar = (float)minval; }
    if (ledbar > (float)maxval) { ledbar = (float)maxval; }

    // Map ledbar (-5000..+5000) to pixel position (0..59)
    // Center = pixel 29/30, negative = left, positive = right
    int half = pixels / 2;
    int pos;
    float fpos = (ledbar / (float)maxval) * (float)half;

    if (ledbar > 0.0) {
        pos = (int)fpos + half;
        if (pos > pixels - 1) { pos = pixels - 1; }
    } else {
        pos = (int)fpos + half;
        if (pos < 0) { pos = 0; }
    }

    // Fill base stripe pattern
    prep();

    // Overlay blue position marker
    if (ledbar == 0.0) {
        leds[pos] = blue;
        if (pos > 0) { leds[pos - 1] = blue; }
    } else {
        leds[pos] = blue;
    }

    // Update strip only when power is off (manual LED control)
    if (tasm_power == 0) {
        setPixels(leds, pixels, 0);
    }
}