Blue Mood Blobs Effect - Wanna make it in C on ESP32

  • Hello!


    I love the effect Blue Mood Blobs and I'd like to have this effect on ESP32 connected to a led strip. ESP32 uses C language and I got the blobs effect code from Hyperion and I am converting to C. I am using an emulator to code and test it with an Arduino (www.tinkercad.com) - See imagem attached.
    After long work I could convert the code but it's not working properly, current it just light the "blobs" in red only, but it is rolling through the strip, but only in red color, I believe something I converted wrong.
    Is anyone up to help me to figure out how to make it working correctly?
    The code is below.


    Here is the original code of the effect on Hyperion: https://github.com/hyperion-pr…ter/effects/mood-blobs.py
    -------


    #include <Adafruit_NeoPixel.h>
    #include <stdio.h>
    #include <stdbool.h>
    #include <math.h>


    #define PIN 11
    #define NUMPIXELS 60


    Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);


    float rotationTime = 20;
    float hueChange = 60;
    float baseColorRangeLeft = 0; // Degree
    float baseColorRangeRight = 360; // Degree
    float baseColorChangeRate = 10; // Seconds for one Degree
    float baseColorChangeIncreaseValue;
    float hue;
    float sleepTime;
    float amplitudePhaseIncrement;
    float amplitudePhase;
    float baseHSVValue;
    float amplitude;
    float baseHsv[3];
    float rgb[3];


    int color[3] = {0,0,255};
    int blobs = int(5);
    int colorData[NUMPIXELS][3];
    int colorDataIncrement;
    int colors[NUMPIXELS][3];
    int baseColorChangeStepCount;
    float numberOfRotates;


    bool colorRandom = false;
    bool reverse = false;
    bool baseColorChange = false;
    bool fullColorWheelAvailable;
    bool rotateColors;


    void setColorLED();
    float *rgb_to_hsv(float r, float g, float b);
    float * hsv_to_rgb(float H, float S, float V);



    void setup() {
    // Get the parameters
    pixels.begin();

    // switch baseColor change off if left and right are too close together to see a difference in color
    if ((baseColorRangeRight > baseColorRangeLeft && (baseColorRangeRight - baseColorRangeLeft) < 10) || (baseColorRangeLeft > baseColorRangeRight && ((baseColorRangeRight + 360) - baseColorRangeLeft) < 10)) {
    baseColorChange = false;
    }


    // 360 -> 1
    fullColorWheelAvailable = fmod(baseColorRangeRight, 360) == fmod(baseColorRangeLeft, 360);
    baseColorChangeIncreaseValue = 1 / 360; // 1 degree
    hueChange /= 360.0;
    baseColorRangeLeft = (baseColorRangeLeft / 360.0);
    baseColorRangeRight = (baseColorRangeRight / 360.0);


    // Check parameters
    rotationTime = max(0.1, rotationTime);
    hueChange = max(0.0, min(abs(hueChange), .5));
    blobs = max(1, blobs);
    baseColorChangeRate = max(0, baseColorChangeRate); // > 0


    // Calculate the color data
    rgb_to_hsv(color[0]/255, color[1]/255, color[2]/255, baseHsv);
    if (colorRandom) {
    baseHsv[0] = random();
    baseHsv[1] = baseHsv[1];
    baseHsv[2] = baseHsv[2];
    }


    //colorData = bytearray();
    // for i in range(hyperion.ledCount):
    for (int i = 0; i < NUMPIXELS; i++) {
    hue = fmodf((baseHsv[0] + hueChange * sin(2 * M_PI * i / NUMPIXELS)),1);
    hsv_to_rgb(hue, baseHsv[1], baseHsv[2], rgb);
    colorData[0] = rgb[0]*255;
    colorData[1] = rgb[1]*255;
    colorData[2] = rgb[2]*255;
    }
    // Calculate the increments
    sleepTime = 0.1;
    amplitudePhaseIncrement = blobs * M_PI * sleepTime / rotationTime;
    colorDataIncrement = 3;
    baseColorChangeRate /= sleepTime;


    // Switch direction if needed
    if (reverse) {
    amplitudePhaseIncrement = -amplitudePhaseIncrement;
    colorDataIncrement = -colorDataIncrement;
    }


    // create a Array for the colors
    for (int i = 0; i < NUMPIXELS; i++) {
    colors[0] = 0;
    colors[1] = 0;
    colors[2] = 0;
    }


    // Start the write data loop
    amplitudePhase = 0.0;
    rotateColors = false;
    baseColorChangeStepCount = 0;
    baseHSVValue = baseHsv[0];
    numberOfRotates = 0;


    }

    void loop() {

    // move the basecolor
    if (baseColorChange) {
    // every baseColorChangeRate seconds
    if (baseColorChangeStepCount >= baseColorChangeRate) {
    baseColorChangeStepCount = 0;
    // cyclic increment when the full colorwheel is available, move up and down otherwise
    if (fullColorWheelAvailable) {
    baseHSVValue = fmod((baseHSVValue + baseColorChangeIncreaseValue), baseColorRangeRight);
    } else {
    // switch increment direction if baseHSV <= left or baseHSV >= right
    if (baseColorChangeIncreaseValue < 0 && baseHSVValue > baseColorRangeLeft && (baseHSVValue + baseColorChangeIncreaseValue) <= baseColorRangeLeft) {
    baseColorChangeIncreaseValue = abs(baseColorChangeIncreaseValue);
    } else {
    if (baseColorChangeIncreaseValue > 0 && baseHSVValue < baseColorRangeRight && (baseHSVValue + baseColorChangeIncreaseValue) >= baseColorRangeRight) {
    baseColorChangeIncreaseValue = -abs(baseColorChangeIncreaseValue);
    }
    }
    baseHSVValue = fmod((baseHSVValue + baseColorChangeIncreaseValue), 1);
    }
    // update color values
    //colorData = bytearray();
    for (int i = 0; i < NUMPIXELS; i++) {
    hue = fmod((baseHSVValue + hueChange * sin(2*M_PI * i / NUMPIXELS)), 1);
    hsv_to_rgb(hue, baseHsv[1], baseHsv[2], rgb);
    colorData[0] = rgb[0] * 255;
    colorData
    [1] = rgb[1] * 255;
    colorData[i][2] = rgb[2] * 255;
    }
    // set correct rotation after reinitialisation of the array
    //colorData = colorData[-colorDataIncrement*numberOfRotates:] + colorData[:-colorDataIncrement*numberOfRotates];
    //colorData = colorData[-colorDataIncrement*numberOfRotates] + colorData[-colorDataIncrement*numberOfRotates];
    }
    baseColorChangeStepCount += 1;
    }
    // Calculate new colors
    for (int i = 0; i < NUMPIXELS; i++) {
    amplitude = max(0.0, sin(-amplitudePhase + 2*M_PI * blobs * i / NUMPIXELS));
    colors[i][0] = int(colorData[i][0] * amplitude);
    colors[i][1] = int(colorData[i][1] * amplitude);
    colors[i][2] = int(colorData[i][2] * amplitude);
    }
    // set colors
    setColorLED();
    pixels.show();
    // increment the phase
    amplitudePhase = fmod((amplitudePhase + amplitudePhaseIncrement), (2*M_PI));


    if (rotateColors) {
    //colorData = colorData[-colorDataIncrement:] + colorData[:-colorDataIncrement]; //// NEED TO CHANGE, BUT I DIDN'T UNDERSTAND THIS LINE
    numberOfRotates = fmod((numberOfRotates + 1), NUMPIXELS);
    }
    rotateColors = not rotateColors;
    baseColorChange = not baseColorChange;
    // sleep for a while
    delay(sleepTime);
    }


    void setColorLED() {
    for (int i = 0; i < NUMPIXELS; i++) {
    pixels.setPixelColor(i, pixels.Color(colors[i][0], colors[i][1], colors[i][2]));
    }
    return;
    }


    void rgb_to_hsv(float r, float g, float b, float *base) {
    float min, max, delta;


    float hsv[3];
    float h, s, v;

    min = r < g ? r : g;
    min = min < b ? min : b;


    max = r > g ? r : g;
    max = max > b ? max : b;


    v = max; // v
    delta = max - min;
    if (delta < 0.00001)
    {
    s = 0;
    h = 0; // undefined, maybe nan?
    base[0] = h;
    base[1] = s;
    base[2] = v;
    //return hsv;
    }
    if( max > 0.0 ) { // NOTE: if Max is == 0, this divide would cause a crash
    s = (delta / max); // s
    } else {
    // if max is 0, then r = g = b = 0
    // s = 0, h is undefined
    s = 0.0;
    h = NAN; // its now undefined
    base[0] = h;
    base[1] = s;
    base[2] = v;
    //return hsv;
    }
    if( r >= max ) // > is bogus, just keeps compilor happy
    h = ( g - b ) / delta; // between yellow & magenta
    else
    if( g >= max )
    h = 2.0 + ( b - r ) / delta; // between cyan & yellow
    else
    h = 4.0 + ( r - g ) / delta; // between magenta & cyan


    h *= 60.0; // degrees


    if( h < 0.0 )
    h += 360.0;


    base[0] = h;
    base[1] = s;
    base[2] = v;
    //return hsv;
    return;
    }



    void hsv_to_rgb(float H, float S, float V, float *base) {
    float hh, p, q, t, ff;
    float i;
    float Rs, Gs, Bs;
    float nRgb[3];


    if(S <= 0.0) { // < is bogus, just shuts up warnings
    Rs = V;
    Gs = V;
    Bs = V;
    base[0] = Rs;
    base[1] = Gs;
    base[2] = Bs;
    return;
    }
    hh = H;
    if(hh >= 360.0) hh = 0.0;
    hh /= 60.0;
    i = (float)hh;
    ff = hh - i;
    p = V * (1.0 - S);
    q = V * (1.0 - (S * ff));
    t = V * (1.0 - (S * (1.0 - ff)));


    switch((int)i) {
    case 0:
    Rs = V;
    Gs = t;
    Bs = p;
    break;
    case 1:
    Rs = q;
    Gs = V;
    Bs = p;
    break;
    case 2:
    Rs = p;
    Gs = V;
    Bs = t;
    break;


    case 3:
    Rs = p;
    Gs = q;
    Bs = V;
    break;
    case 4:
    Rs = t;
    Gs = p;
    Bs = V;
    break;
    case 5:
    default:
    Rs = V;
    Gs = p;
    Bs = q;
    break;
    }

    base[0] = Rs;
    base[1] = Gs;
    base[2] = Bs;

    return;
    }
    [/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][i][i][i][i][i][i][i][i][i][i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][i][i][i][i][i][i][i][i][i][i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i]

  • you can use also micropython on esp32


    Nice! I just had a look at it. I didn't know it is possible. I am just worried if I can later be able to back to the original firmware, but I will check it out.


    By the way, is there a code for the function below? I could not find it on github. For the C I have to adapt..
    hyperion.setColor(colors)


    Thanks a lot TPmodding!!!!

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!