Stonelamp with Wemos D1 mini and 5050 NeoPixel

This is a small project for a mood lamp in a glass vase with 4 x 15 5050 Neopixels. The Neopixel strips are mounted on a 1cm x 1cm x 20cm hollow aluminium profile inside the vase and connected accordingly. I drilled a hole into the vase’s bottom for the three cables 5V, GND, and DI leading to the Wemos D1 mini which is buried in the wooden socket of the lamp. Blynk is used to control the different patterns, speed and brightness as well as on/off the light. There are 12 patterns you may chose from. Program updates can be sent through the wireless network using OTA.

  • Blynk server 0.23.5 on Orange Pi
  • Blynk library 0.4.6
  • Android phone

Here are a screen shot of the Blynk project, some videos and the code running on the Wemos. Hope you enjoy.

Activity 10: Fire

Activity 4: rainbowCycle

Activity 7: TwinkleRandom

    /*
      Neopixel stonelamp by Markus Rohner
      Version 1.0     23. 3. 2017

      Funtion: 12 activities
      
    Aknowledgements:
      1. Adafruit Neopixel library: http://learn.adafruit.com/adafruit-neopixel-uberguide/neomatrix-library
      2. Arduino – LEDStrip effects for NeoPixel and FastLED: https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
      
    Pin assignments:
     * Wemos
    D2 to DI 5050 RGB LED string 

    Blynk Virtual Pins:
    V0: ON OFF Button 
    V1: Activity slider
    V2: Terminal
    V8: Blink button
    V10: Brightness slider
    V11: Speed slider
    V12: Colour select
    V13: ON OFF LED
    V14: UP LED

    Bill of material:
      -Wemos D1 mini
      -Adafruit Neopixelstring 60 LEDs
      -1000uF capacitor 
      -5V 4A Power Supply

    */


    #include <ESP8266WiFi.h>
    #include <ESP8266mDNS.h>
    #include <WiFiUdp.h>
    #include <ArduinoOTA.h>

    // Set ESP8266 Serial object
    #include <ESP8266WiFi.h>
    #include <BlynkSimpleEsp8266.h>
    #include <SimpleTimer.h>
    SimpleTimer timer;

    // Blynk
    //#define BLYNK_DEBUG
    //#define BLYNK_PRINT Serial
    int ONOFF_LED = V13;
    int UP_LED = V14;
    long int last_UP_change = millis();
    bool runn = 1;
    WidgetTerminal terminal(V2);

    // RGB Lights
    #include <Adafruit_NeoPixel.h>
    #define NUM_LEDS 60
    const int NUM_LEDS4 = NUM_LEDS/4;
    #define PIN D2
    //const int long red = 16711680;
    //const int long green = 65280;
    const int long blue = 255;
    int brightness = 155;
    int standard_speed = 50;
    int current_activity = 0;
    int this_activity = 0;
    long current_color = blue;
    bool lamp_on = false;
    bool blinkon = false;

    Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);


    // Wireless settings
    const char AUTH[] = "*******************";
    const char SSID[] = "********"; 
    const char PASSWORD[] = "*************";

    // Timing
    volatile int WDTCount = 0;


    void setup() {
     Serial.begin(115200);
     Serial.println(F("setup start"));
     
    //Blynk
     WiFi.mode(WIFI_STA);
     Blynk.begin(AUTH, SSID, PASSWORD,"192.168.178.36",8442);
       while (Blynk.connect() == false) {  // Wait until connected
         if ((millis() - last_UP_change) > 30000) { // 30s before reset
           Serial.println(F("resetting"));
           terminal.println(F("resetting"));
           terminal.flush();
           ESP.restart();
        }
      }
     wait(500);
     
    // Init Neopixels
      strip.begin();
      all_lights(0);


    //OTA
      // Port defaults to 8266
      // ArduinoOTA.setPort(8266);
      // Hostname defaults to esp8266-[ChipID]
      ArduinoOTA.setHostname("D1-Stonelamp");
      // No authentication by default
      ArduinoOTA.setPassword((const char *)"***");
      ArduinoOTA.onStart([]() {
        Serial.println("Start");
      });
      ArduinoOTA.onEnd([]() {
        Serial.println("\nEnd");
      });
      ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
        Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
      });
      ArduinoOTA.onError([](ota_error_t error) {
        Serial.printf("Error[%u]: ", error);
        if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
        else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
        else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
        else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
        else if (error == OTA_END_ERROR) Serial.println("End Failed");
      });
      ArduinoOTA.begin();

      Serial.println(F("Entering loop"));
      wait(3000);
      timer.setInterval(2003L, blinkonoff);
      //timer.setInterval(1000L, ISRwatchdog);
      printStatus();
      Serial.println();
      Blynk.virtualWrite(ONOFF_LED,0); 
      Blynk.virtualWrite(UP_LED,0); 
    }


    void loop() {
      Blynk.run();
      if(!Blynk.connected()) {
        Serial.println(F("Resetting in loop"));
        ESP.restart();
      }
      WDTCount = 0;
      timer.run();
      ArduinoOTA.handle();
      activity(current_activity);
    }

     
    void activity(int activity_button) {
      if (lamp_on) {
        this_activity = activity_button;
        strip.setBrightness(brightness);
        switch (activity_button) {
          case 0:  // no activity
            all_lights(current_color);
            if (blinkon) {
              wait(standard_speed*2);
              strip.setBrightness(0);
              strip.show();
              wait(standard_speed*2);
              strip.setBrightness(brightness);
             }
          break;
          case 1:  // colorWipe
          colorWipe(0); 
          colorWipe(current_color); 
        break;
        case 2:  // theaterChase
          theaterChase(strip.Color(random(255), random(255), random(255)));
        break;
        case 3:  // rainbow
          rainbow();
        break;
        case 4:  // rainbowCycle
          rainbowCycle();
        break;
        case 5:  // theaterChaseRainbow
          theaterChaseRainbow();
        break;
        case 6:  // CylonBounce
          CylonBounce(splitColor (current_color,'r'), splitColor (current_color,'g'), splitColor (current_color,'b'), 3);
        break;
        case 7:  // TwinkleRandom
          TwinkleRandom(20,false);
        break;
        case 8:  // Sparkle
          Sparkle(random(255), random(255), random(255));
         break;
        case 9:  // RunningLights
          RunningLights(splitColor (current_color,'r'), splitColor (current_color,'g'), splitColor (current_color,'b'));
        break;
        case 10:  // Fire
          Fire(55,120);// was 55,120
        break;
        case 11:  // fade
          FadeInOut(splitColor (current_color,'r'), splitColor (current_color,'g'), splitColor (current_color,'b'));
        break;
        case 12:  // rotate
          rotate();
        break; 
       }
     }
     else {
      strip.setBrightness(0);
      strip.show();
     }
    }


    // Fill the dots one after the other with a color (1)
    void colorWipe(uint32_t c) {
        for (int i = 0; i < NUM_LEDS4; i++) {
          if (!lamp_on || this_activity != current_activity) break;
          for (int j = 0; j < 4; j++) {
          strip.setPixelColor(i+j*NUM_LEDS4,c);
          }
          strip.show();
          wait(standard_speed/3);
       }
    }


    //Theatre-style crawling lights. (2)
    void theaterChase(uint32_t c) {
      for (int j = 0; j < 10; j++) { //do 10 cycles of chasing
        if (!lamp_on || this_activity != current_activity) break;
        for (int q = 0; q < 3; q++) {
          if (!lamp_on || this_activity != current_activity) break;
          for (int i = 0; i < NUM_LEDS4; i = i + 3) {
            if (!lamp_on || this_activity != current_activity) break;
            for (int m = 0; m < 4; m++) {
            strip.setPixelColor(i + q + m*NUM_LEDS4, c);  //turn every third pixel on
            }
          }
          strip.show();
          wait(standard_speed*3);
          for (int i = 0; i < NUM_LEDS; i = i + 3) {
            if (!lamp_on || this_activity != current_activity) break;
            for (int m = 0; m < 4; m++) {
            strip.setPixelColor(i + q + m*NUM_LEDS4, 0);      //turn every third pixel off
            }
          }
        }
      }
    }


    // (3)
    void rainbow() {
      uint16_t i, j;
      for (j = 0; j < 256; j+=2) {
        if (!lamp_on || this_activity != current_activity) break;
        for (i = 0; i < NUM_LEDS4; i++) {
          if (!lamp_on || this_activity != current_activity) break;
          for (int m = 0; m < 4; m++) {
            strip.setPixelColor(i + m*NUM_LEDS4,Wheel((i + j) & 255));
            strip.show();
            wait(standard_speed/5);
          }
         }
       }
    }


    // Slightly different, this makes the rainbow equally distributed throughout (4)
    void rainbowCycle() {
      uint16_t i, j;
      for (j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel
        if (!lamp_on || this_activity != current_activity) break;
        for (i = 0; i < NUM_LEDS4; i++) {
          if (!lamp_on || this_activity != current_activity) break;
          for (int m = 0; m < 4; m++) {
            strip.setPixelColor(i + m*NUM_LEDS4, Wheel(((i * 256 / NUM_LEDS4) + j) & 255));
           }
         }
        strip.show();
        wait(standard_speed/2);
      }
    }


    //Theatre-style crawling lights with rainbow effect (5)
    void theaterChaseRainbow() {
      for (int j = 0; j < 256; j+=2) {   // cycle all 256 colors in the wheel
        if (!lamp_on || this_activity != current_activity) break;
        for (int q = 0; q < 3; q++) {
          if (!lamp_on || this_activity != current_activity) break;
          for (int i = 0; i < NUM_LEDS4; i = i + 3) {
            if (!lamp_on || this_activity != current_activity) break;
            for (int m = 0; m < 4; m++) {
            strip.setPixelColor(i + q + m*NUM_LEDS4, Wheel( (i + j) % 255)); //turn every third pixel on
            }
          }
          strip.show();
          wait(standard_speed*3);
          for (int i = 0; i < NUM_LEDS4; i = i + 3) {
            if (!lamp_on || this_activity != current_activity) break;
            for (int m = 0; m < 4; m++) {
            strip.setPixelColor(i + q + m*NUM_LEDS4, 0);      //turn every third pixel off
            }
          }
        }
      }
    }


    // (6)
    void CylonBounce(byte red, byte green, byte blue, int EyeSize){
      for(int i = 0; i < NUM_LEDS4-EyeSize-2; i++) {
        if (!lamp_on || this_activity != current_activity) break;
        all_lights(0);
         for (int m = 0; m < 4; m++) {
           setPixel(i+ m*NUM_LEDS4, red/10, green/10, blue/10);
         }
        for(int j = 1; j <= EyeSize; j++) {
          if (!lamp_on || this_activity != current_activity) break;
           for (int m = 0; m < 4; m++) {
             setPixel(i + j + m*NUM_LEDS4, red, green, blue); 
           }
        }
          for (int m = 0; m < 4; m++) {
            setPixel(i + EyeSize + 1 + m*NUM_LEDS4, red/10, green/10, blue/10);
          }
        strip.show();
        wait(standard_speed/2);
      }
      wait(standard_speed);

      for(int i = NUM_LEDS4-EyeSize-2; i > 0; i--) {
        if (!lamp_on || this_activity != current_activity) break;
        all_lights(0);
        for (int m = 0; m < 4; m++) {
          setPixel(i + m*NUM_LEDS4, red/10, green/10, blue/10);
        }
        for(int j = 1; j <= EyeSize; j++) {
          if (!lamp_on || this_activity != current_activity) break;
          for (int m = 0; m < 4; m++) {
            setPixel(i + j + m*NUM_LEDS4, red, green, blue); 
          }
        }
        for (int m = 0; m < 4; m++) {
          setPixel(i +EyeSize + 1 + m*NUM_LEDS4, red/10, green/10, blue/10);
        }
        strip.show();
        wait(standard_speed/2);
      }
      wait(standard_speed);
    }


    // (7)
    void TwinkleRandom(int Count,boolean OnlyOne) {
      all_lights(0);
       for (int i=0; i<Count; i++) {
         if (!lamp_on || this_activity != current_activity) break;
         setPixel(random(NUM_LEDS),random(0,255),random(0,255),random(0,255));
         strip.show();
         wait(standard_speed);
         if(OnlyOne) { 
           all_lights(0); 
         }
       }
       wait(standard_speed/2);
    }


    // (8)
    void Sparkle(byte red, byte green, byte blue) {
      all_lights(0);
      int Pixel = random(NUM_LEDS);
      setPixel(Pixel,red,green,blue);
      strip.show();
      wait(standard_speed);
      setPixel(Pixel,0,0,0);
    }


    // (9)
    void RunningLights(byte red, byte green, byte blue) {
      int Position=0;
      for(int i=0; i<NUM_LEDS4*2; i++)  {
        if (!lamp_on || this_activity != current_activity) break;
          Position++; // = 0; //Position + Rate;
          for(int i=0; i<NUM_LEDS4; i++) {
            if (!lamp_on || this_activity != current_activity) break;
              for (int m = 0; m < 4; m++) {
                if (!lamp_on || this_activity != current_activity) break;
                setPixel(i + m*NUM_LEDS4,((sin(i+Position) * 127 + 128)/255)*red,
                       ((sin(i+Position) * 127 + 128)/255)*green,
                       ((sin(i+Position) * 127 + 128)/255)*blue);
            }
          }
          strip.show();
          wait(standard_speed*2);
      }
    }


    // (10)
    void Fire(int Cooling, int Sparking) {
      static byte heat[NUM_LEDS];
      int cooldown;
      // Step 1.  Cool down every cell a little
      for (int m = 0; m < 4; m++) {
        for( int i = 0; i < NUM_LEDS4; i++) {
          cooldown = random(0, ((Cooling * 10) / NUM_LEDS4) + 2);
          if(cooldown>heat[i + m*NUM_LEDS4]) {
            heat[i + m*NUM_LEDS4]=0;
         } else {
            heat[i + m*NUM_LEDS4]=heat[i + m*NUM_LEDS4]-cooldown;
          }
        }
      }
      // Step 2.  Heat from each cell drifts 'up' and diffuses a little
      for (int m = 0; m < 4; m++) {
        for( int k = NUM_LEDS4 - 1; k >= 2; k--) {
          if (!lamp_on || this_activity != current_activity) break;
          heat[k + m*NUM_LEDS4] = (heat[k + m*NUM_LEDS4 - 1] + heat[k + m*NUM_LEDS4 - 2] + heat[k + m*NUM_LEDS4 - 2]) / 3;
        }
      }
      // Step 3.  Randomly ignite new 'sparks' near the bottom
      for (int m = 0; m < 4; m++) {
        if( random(255) < Sparking ) {
          int y = random(3); //was 7
          heat[y + m*NUM_LEDS4] = heat[y + m*NUM_LEDS4] + random(160,255);
        }
      }
      // Step 4.  Convert heat to LED colors
      for( int j = 0; j < NUM_LEDS; j++) {
        if (!lamp_on || this_activity != current_activity) break;
        setPixelHeatColor(j, heat[j]);
      }
      strip.show();
      wait(standard_speed);
    }


    void setPixelHeatColor (int Pixel, byte temperature) {
      // Scale 'heat' down from 0-255 to 0-191
      byte t192 = round((temperature/255.0)*191);
      // calculate ramp up from
      byte heatramp = t192 & 0x3F; // 0..63
      heatramp <<= 2; // scale up to 0..252
      // figure out which third of the spectrum we're in:
      if( t192 > 0x80) {                     // hottest
        setPixel(Pixel, 255, 255, heatramp);
      } else if( t192 > 0x40 ) {             // middle
        setPixel(Pixel, 255, heatramp, 0);
      } else {                               // coolest
        setPixel(Pixel, heatramp, 0, 0);
      }
    }


    //(11)
    void FadeInOut(byte red, byte green, byte blue){
      float r, g, b;
          
      for(int k = 20; k < 256; k=k+1) {
        if (!lamp_on || this_activity != current_activity) break; 
        r = (k/256.0)*red;
        g = (k/256.0)*green;
        b = (k/256.0)*blue;
        all_lights(r,g,b);
        wait(standard_speed/6);
      }
         
      for(int k = 255; k >= 20; k=k-2) {
        if (!lamp_on || this_activity != current_activity) break;
        r = (k/256.0)*red;
        g = (k/256.0)*green;
        b = (k/256.0)*blue;
        all_lights(r,g,b);
        wait(standard_speed/6);
      }
    }


    //Rotate (12)
    void rotate() {
      all_lights(0);
      for (int m = 0; m < 4; m++) {
        for (int i = m*NUM_LEDS4; i < (m+1)*NUM_LEDS4; i++) {
          if (!lamp_on || this_activity != current_activity) break;
            strip.setPixelColor(i,current_color);
           }
          strip.show();
          wait(standard_speed*2);
        for (int i = m*NUM_LEDS4; i < (m+1)*NUM_LEDS4; i++) {
          if (!lamp_on || this_activity != current_activity) break;
            strip.setPixelColor(i,0);
           }
          strip.show();
      }
    }


    void all_lights(int g, int r, int b) {
      wait(1);
        for (int x = 0; x < NUM_LEDS; x++) {
          strip.setPixelColor(x, g, r, b);
        }
        strip.show();
    }


    void all_lights(int color) {
      wait(1);
        for (int x = 0; x < NUM_LEDS; x++) {
          strip.setPixelColor(x,color);
        }
        strip.show();
        }


    // Input a value 0 to 255 to get a color value.
    // The colours are a transition r - g - b - back to r.
    uint32_t Wheel(byte WheelPos) {
      WheelPos = 255 - WheelPos;
      if (WheelPos < 85) {
        return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
      } else if (WheelPos < 170) {
        WheelPos -= 85;
        return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
      } else {
        WheelPos -= 170;
        return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
      }
    }


    /**
       splitColor() - Receive a uint32_t value, and spread into bits.
    */
    byte splitColor ( uint32_t c, char value )
    {
      switch ( value ) {
        case 'r': return (uint8_t)(c >> 16);
        case 'g': return (uint8_t)(c >>  8);
        case 'b': return (uint8_t)(c >>  0);
        default:  return 0;
      }
    }


    void printStatus() {
      Serial.print(F(" ON: "));
      Serial.print(lamp_on);
      Serial.print(F(" Blink: "));
      Serial.print(blinkon);
      Serial.print(F(" Activity: "));
      Serial.print(current_activity);
      Serial.print(F(" Color: "));
      Serial.print(current_color);
      Serial.print(F(" Brightness: "));
      Serial.print(brightness);
      Serial.print(F(" Speed: "));
      Serial.println(standard_speed);
      terminal.print(F(" ON:"));
      terminal.print(lamp_on);
      terminal.print(F(" Blk:"));
      terminal.print(blinkon);
      terminal.print(F(" Act:"));
      terminal.print(current_activity);
      terminal.print(F(" Col:"));
      terminal.print(current_color);
      terminal.print(F(" Bright:"));
      terminal.print(brightness);
      terminal.print(F(" Spd:"));
      terminal.println(standard_speed);
      terminal.flush();
    }


    void wait (int ms) {
      long current_time = millis();
      long end_time = current_time + ms; 
      while (current_time < end_time) {
        if (!lamp_on || this_activity != current_activity) break;
        current_time = millis();
      }
      Blynk.run();
      timer.run();
    }


    void blinkonoff(){
     // Turn runn LED on/off
       Blynk.virtualWrite(UP_LED,runn * 255);  // turn Up off
       runn = !runn;
       last_UP_change = millis();  
       WDTCount = 0;
    }

    BLYNK_WRITE(V0) { //ON Off
        if (param.asInt()) lamp_on = 1;
        else {
          all_lights(0);
          lamp_on = 0;
        }
        Blynk.virtualWrite(ONOFF_LED,lamp_on * 255);  // turn Up off
        printStatus();
    }

    BLYNK_WRITE(V1) { //Activity slider
       current_activity = param.asInt();
       printStatus();
    }
      
    BLYNK_WRITE(V8) { //Blink
      if (param.asInt()) blinkon = true;
      else blinkon = false;
      printStatus();
    }

    BLYNK_WRITE(V10) { // Brightness slider
        brightness = param.asInt();
        strip.setBrightness(brightness);
        strip.show();
      printStatus();
    }

    BLYNK_WRITE(V11) { // Speed
      standard_speed = param.asInt();
      printStatus();
    }

    BLYNK_WRITE(V12) { //RGB light
      current_color = param[2].asInt() + 256*param[1].asInt() + 256*256*param[0].asInt();
      printStatus();  
    }


    void ISRwatchdog() {
      WDTCount++;
      if (WDTCount == 5) {
        Serial.println(F("WDT reset"));
        terminal.println(F("WDT reset"));
        terminal.flush();
        ESP.reset();
      }
    }


    void setPixel(int Pixel, byte red, byte green, byte blue) {
       strip.setPixelColor(Pixel, strip.Color(red, green, blue));
    }
11 Likes

Beautiful fire effect.

That is really beautiful! If you add some sticks and a bigger jar you can simulate a forest/nature thing. Maybe fill some “old” wood with glowy resin which would light along, I think I’ve seen someone on Instructables do that with wooden shelves. Mix resin and some color glow dust so it lights up and/or reflects too. Awesome!! I’ll definitely build something similar for my new house :slight_smile:

Wonderful effects! What material did you use to diffuse the light at the top of the vase?
Thanks for sharing!

@mrohner did you use a clear vase or a difused one?
Thanks!

Hi, I used a piece of what we call “baking paper” but I guess it would also work with “wax paper” or a piece of
parchment.

Hi, It was a clear vase and on top inside the vase a piece of “baking paper”

Ok, thanks! It looks really great.

3 posts were split to a new topic: Blynk app says “device is offline”

I love this project. How did you wire up the wemos d1 mini to the neopixels. My understanding is that the wemos is 3.3V and the neopixel is 5V. Also, how was power management for the number of LEDs?

Thanks,
Chris.

The Wemos is 3.3v, as is the digital signal it sends to the LED strips, but the strips can easily read that signal.

However, they require their own separate 5v supply (just share the ground between all power sources) and enough current (Amps) to handle the total number of LEDs… which can vary depending on colour, intensity and number of LEDs… check with the suppliers for those requirements and then add in a little extra as a buffer… you can never have too many amps available :wink:

EDIT - I guess I should expand a bit on my explanation… the ESP chipset runs on 3.3v as does the GPIO, but many ESP development boards will be powered by 5v from the USB connector… they actually have their own 3.3v regulator on them in order to accommodate that.

So generally in this use case the ESP dev board gets powered by the same 5v power supply that runs the LED strips.

Google NeoPixel and you will see many explanations on how they are wired up to Arduinos and ESPs.

for example, I have made my own power distribution boards for the Wemos D1 Mini to take a 5v PSU and run both the Wemos and RGB strips from it.

Thanks. I’ll look it up.

My main issue is having 2 power sources. I’d like to take the raw 5v from the wemos (i.e., the 5V coming into the wemos from the USB micro socket) and feed that to the neopixels. There’s a cap pad on the PCB, but I think it will slide off if I try to solder a wire on it. IOW, I’m trying to make a variant of the lamp but I don’t want a separate power source, or another 5V regulator circuit. Too messy.

I’m trying to use a capacitive touch switch to turn it off and on, but I suspect it’s acting finicky because of the power loss from the strand of 25 neopixels. I’m looking at debounce tricks on an interruptAttach.

I love the project. Well done. And thanks for sharing, Chris.

I did exactly what Gunnar suggests. One 5V 4A Power supply for LEDs and Wemos.

This was simply amazing :slight_smile:
Because of this project i’ve bought some 5050 led strip (15) with 144leds/meter
So i have 15 leds wired to one esp-01 i’ve had around. Modified the #define NUM_LEDS 60 to #define NUM_LEDS 144 (i was asuming this is how many are per meter) and also: const int NUM_LEDS4 = NUM_LEDS/4; in const int NUM_LEDS4 = 15;

Surprisingly enough everything works perfect except for the scene 12 but i think i know why :slight_smile:

If i have to use 4 strips instead on one(like you did), how are the Data pins connected? In series? meaning DO of strip1 to DI of strip2 and so on, right?

THANK YOU!!!

This will be total number of LEDS… this is how the library determines “end stops” of your strip for patterns etc.

I can’t speak for the OP, but I have a setup with two identical lench strips acting as one (as far as the controller is concerned) by simply hooking both data pins to the same GPIO pin. (and of course that doubles the current required for the PSU)

I guess you can run separate patterns on separate strips (each data pin connected to their own GPIO) but how to code that…? I don’t know.

Thank you gunner. Then what is NUM_LEDS4 declared as NUM_LEDS/4 on the original sketch? this is the number/strip? meaning 15 on his case?

Considering the pattern12 that is circle from my understanding, it means that his 4 strips should be lit in sequence to be able to simulate a circular light motion. Which means that his 4 strips are treated individualy, not in parallel (all 4 as one).

This, or i am totally wrong :)))

I do not have any power issues. I can power 500 leds with ease. I just try to understand better before i buy the next batch of pixels. Also, for this project in particular, a lower density/meter might be better. Mine looks amazing but 15 leds are around 11cm long. Quite condensed :slight_smile:

later edit: Nope. Setting NUM_LEDS to 15 (my number of leds on the strip) makes the script freeze when you set pattern 10 (fire). Back to 144 :slight_smile:

The #define NUM_LEDS 60 is the total or individually addressable LED’s. And because the OP has 4 separate strips, there was probably a need to designate the number of LED’s in each for some pattern calculations… thus the const int NUM_LEDS4 = NUM_LEDS/4; I haven’t dug that deep into the code to be sure of the exact hows and whys.

Again, haven’t dug into the code… but the fire pattern would benefit from having the code split the count into the separate strips… thus having a common base for each “flame” to start from. So yes, changing the total of your LED’s to their actual 15 doesn’t divide equally into 4 and the code probably crashed whilst trying to individually address that last fraction of an LED out of the “separate” strips of 3.750 (or 3.7 in iOS :stuck_out_tongue_winking_eye: )

Tested last night. You are right. That is why the other patterns works :slight_smile:slight_smile:
Now to the actual lamp build…this is going to take much more time as i try to stuff marble rocks inside a log where i will cut a “window” to see the burning rocks inside the log. Hopefully…

1 Like

1 Like

Thank you :slight_smile:
It makes sense. i was sure they were “in series”.