kitesurfer1404 / WS2812FX

WS2812 FX Library for Arduino and ESP8266
MIT License
1.6k stars 347 forks source link

Using 3 strips 300 leds wirh ws2812fx #198

Closed johndlcg closed 4 years ago

johndlcg commented 5 years ago

Hi there,

im new to this world, i just found this library very usefull and easy to use, until now i have manage to turn 400 leds with the library, i was wondering if there's a way that i can manage to turn on 900 leds.

im using the auto mode cycle and want to know if there a possibility to make the modes to change after they complete the number of leds os the strips, not using the timer.

i need help to accomplish this, im not a programmer.

thanks in advanced for your reply and help

moose4lord commented 5 years ago

The library supports 900 LEDs, but with that many you need to pay particular attention to the power supply requirements and the voltage drop that occurs when an LED strip is so long. Make sure you read Adrafruit's Uber Guide.

I'm not sure what you mean by "after they complete the number of leds [on] the strips." Some of the modes do not depend on the number of LEDs (like Blink, for example), so how would you time those mode changes?

johndlcg commented 5 years ago

thanks For the fast reply, If I put more than 400 leds they won’t lit, I have a power supply connected on the middle of two strips and the one to turn on the first one and the arduino nano.

What I mean about completing the number of led is that With timing working a mode could get until a quarter of the entire strip and change mode, I would like the mode to start and when it get to the last led on the strip then change.

Don’t know if I explain my self. I’m sorry if there are mistakes on my writing, but English is not my nature language, I speak Spanish.

moose4lord commented 5 years ago

The Arduino Nano has a very small amount of SRAM memory (only 2kB), so you would not be able to use that board with 900 LEDs. Each LED requires at least 3 bytes of memory, so 900 LEDs x 3 bytes = 2700 bytes. You might want to look into using an Arduino Mega processor, which has 8kB of memory, or an ESP8266 board, which has 32kB of memory.

To synchronize changing modes with the number of LEDs you could use the isFrame() function. isFrame() returns true whenever the LEDs are updated with new information, effectively marking a single animation frame. You can use this to count the number of animation frames. A crude approach would be something like this in your loop() function:

void loop() {
  static int frameCount = 0;
  now = millis();

  ws2812fx.service();

  if(ws2812fx.isFrame()) { // increment the animation frame count
    frameCount++;
  }

  // if the timer has expired and the frame count indicates we're at the
  // end of an animation cycle, then change the mode
  if(now - last_change > TIMER_MS && frameCount == LED_COUNT) {
    ws2812fx.setMode((ws2812fx.getMode() + 1) % ws2812fx.getModeCount());
    last_change = now;
  }

  // if we're at the end of an animation cycle, reset the frame count
  if(frameCount == LED_COUNT) {
    frameCount = 0;
  }
}
johndlcg commented 5 years ago

Thank you for the information, I will give it a try with arduino uno that I have in hand, if doesn’t work I will try to get the mega.

I’ll keep you up to date on the progress.

johndlcg commented 4 years ago

Hello again, thanks for the code it does the trick, i just make it print the frame count and in some mode it repeates the secuense in others dont, but i notice that it will depends on the value of TIMER_MS.

i use my generic UNO for the test but still not getting more than 400 leds to tunr on, i just bought these modules: 1 https://www.ebay.com/itm/New-NodeMCU-Lua-ESP8266-ESP-12E-cp2102-Arduino-compatible-wifi-development-board/382593145644?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2057872.m2749.l2649

2 https://www.ebay.com/itm/2PCS-NodeMcu-Lua-ESP8266-ESP12E-CH340G-WIFI-Internet-Development-Board/382553530067?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2057872.m2749.l2649

3 https://www.ebay.com/itm/2X-ESP8266-Serial-WIFI-Wireless-Transceiver-Module-Send-Receive-AP-STA-ESP-01-US/382619187384?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2057872.m2749.l2649

which of them you recommend me to use for my project???

due to the currently amount of leds that i have (836 leds) wich is the best power source i will need to run this??

i was planning to supply power every 209 leds on the entire strip, is this ok?? im learning to use the custom modes to see if i could incorporate some fastled effects, is this possible?

thanks for all the help

moose4lord commented 4 years ago

I have had no trouble using the NodeMCU boards that are in your list. They are reliable and easy to use.

As for power supply, you should probably take some current measurements on the particular LED strips that you're using, and buy a power supply that can handle the load. If you're using 5V WS2812 LEDs, Adafruit has some power supply guidelines in their UberGuide. Be aware if you're planning to drive the LEDs at full intensity, you'll need a beefy power supply, at least 250 Watts. That's a lot. Again Adafruit has some words of wisdom here.

I have never driven so many LEDs, so I can't comment on your power injection scheme. Seems like a good place to start though. Let us know how it works for you.

There is a demo sketch in the WS2812FX/examples folder, ws2812fx_custom_FastLED, that shows a technique for integrating FastLED effects into your project. That might help you with your custom effects.

johndlcg commented 4 years ago

hello, i just saw the custom effects example but i got stuck, dont know how to add them to the sketch i was able to get the name of the mode int the auto mode, in the list of names it shows me 4 custom effects, 0-3 how can i add custom effects on those options, because when it get to those modes it just keeps some lights on until the four custom effects ends the get to the static and restart.

or how can i discompose the auto mode to use the most of the modes and add the custom modes from the library and some from fastled.

sorry for been a PITA and thanks for all the help.

moose4lord commented 4 years ago

I refactored the auto_mode_cycle example sketch to include a FastLED custom effect and one of the prebuilt custom effects. This should get you going.

#include "FastLED.h" // be sure to install and include the FastLED lib
#include <WS2812FX.h>

// include the pre-built custom effect
#include "custom/DualLarson.h"

#define NUM_LEDS 144
#define LED_PIN 4

#define TIMER_MS 5000

WS2812FX ws2812fx = WS2812FX(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);

// declare global parameters used by Fire2012
bool gReverseDirection = false;

unsigned long last_change = 0;
unsigned long now = 0;

void setup() {
  Serial.begin(115200);

  ws2812fx.init();
  ws2812fx.setBrightness(255);
  ws2812fx.setSpeed(1000);
  uint32_t colors[] = {RED, GREEN, BLUE}; // some default colors
  ws2812fx.setColors(0, colors);
  ws2812fx.setMode(FX_MODE_STATIC);
  ws2812fx.start();

  // setup custom effects
  uint8_t fire2012Mode  = ws2812fx.setCustomMode(F("Fire 2012"), fire2012CustomEffect);
  uint8_t dualLarsonMode  = ws2812fx.setCustomMode(F("Dual Larson"), dualLarson);
}

void loop() {
  now = millis();

  ws2812fx.service();

  if(now - last_change > TIMER_MS) {
    ws2812fx.setMode((ws2812fx.getMode() + 1) % ws2812fx.getModeCount());
    Serial.print("Mode: "); Serial.println(ws2812fx.getModeName(ws2812fx.getMode()));
    last_change = now;
  }
}

// create a custom effect function which runs the FastLED Fire2012 algorithm
uint16_t fire2012CustomEffect() {
  Fire2012(); // call the FastLED function

  // return the animation speed based on the ws2812fx speed setting
  return (ws2812fx.getSpeed() / NUM_LEDS);
}

/*
 * paste in the Fire2012 code with a small edit at the end which uses the
 * setPixelColor() function to copy the color data to the ws2812fx instance. 
*/

// Fire2012 by Mark Kriegsman, July 2012
// as part of "Five Elements" shown here: http://youtu.be/knWiGsmgycY
//// 
// This basic one-dimensional 'fire' simulation works roughly as follows:
// There's a underlying array of 'heat' cells, that model the temperature
// at each point along the line.  Every cycle through the simulation, 
// four steps are performed:
//  1) All cells cool down a little bit, losing heat to the air
//  2) The heat from each cell drifts 'up' and diffuses a little
//  3) Sometimes randomly new 'sparks' of heat are added at the bottom
//  4) The heat from each cell is rendered as a color into the leds array
//     The heat-to-color mapping uses a black-body radiation approximation.
//
// Temperature is in arbitrary units from 0 (cold black) to 255 (white hot).
//
// This simulation scales it self a bit depending on NUM_LEDS; it should look
// "OK" on anywhere from 20 to 100 LEDs without too much tweaking. 
//
// I recommend running this simulation at anywhere from 30-100 frames per second,
// meaning an interframe delay of about 10-35 milliseconds.
//
// Looks best on a high-density LED setup (60+ pixels/meter).
//
//
// There are two main parameters you can play with to control the look and
// feel of your fire: COOLING (used in step 1 above), and SPARKING (used
// in step 3 above).
//
// COOLING: How much does the air cool as it rises?
// Less cooling = taller flames.  More cooling = shorter flames.
// Default 50, suggested range 20-100 
#define COOLING  55

// SPARKING: What chance (out of 255) is there that a new spark will be lit?
// Higher chance = more roaring fire.  Lower chance = more flickery fire.
// Default 120, suggested range 50-200.
#define SPARKING 120

void Fire2012()
{
// Array of temperature readings at each simulation cell
  static byte heat[NUM_LEDS];

  // Step 1.  Cool down every cell a little
    for( int i = 0; i < NUM_LEDS; i++) {
      heat[i] = qsub8( heat[i],  random8(0, ((COOLING * 10) / NUM_LEDS) + 2));
    }

    // Step 2.  Heat from each cell drifts 'up' and diffuses a little
    for( int k= NUM_LEDS - 1; k >= 2; k--) {
      heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
    }

    // Step 3.  Randomly ignite new 'sparks' of heat near the bottom
    if( random8() < SPARKING ) {
      int y = random8(7);
      heat[y] = qadd8( heat[y], random8(160,255) );
    }

    // Step 4.  Map from heat cells to LED colors
    for( int j = 0; j < NUM_LEDS; j++) {
      CRGB color = HeatColor( heat[j]);
      int pixelnumber;
      if( gReverseDirection ) {
        pixelnumber = (NUM_LEDS-1) - j;
      } else {
        pixelnumber = j;
      }

// **** modified for use with WS2812FX ****
//    leds[pixelnumber] = color;
      ws2812fx.setPixelColor(pixelnumber, color.red, color.green, color.blue);
// **** modified for use with WS2812FX ****

    }
}
johndlcg commented 4 years ago

Thanks very much, for sure it is biiiig kick-off. one more question, can this be ramdom colors: uint32_t colors[] = {RED, GREEN, BLUE}; // some default colors ws2812fx.setColors(0, colors);

thanks in advanced

moose4lord commented 4 years ago

You can generate a pseudo-random color with this:

uint32_t color1 = ws2812fx.color_wheel(random(256));

But it will be the same "random" color whenever you restart the microprocessor, so not really random. That might be good enough for you. If not, see the Arduino random() function description here.

johndlcg commented 4 years ago

thanks for the reply, for now i will leave it as your refactored sketch it is doing just what i need. i try to add more custom effects to it, but it only use the Fire2012 from Fastled the first 3 that i add from your custom effects 2, asume that is because the auto mode just use 4 custom effects.

I just received my ESP8266 Module and load the 800+ leds to it and it didnt tell me anything about memory, i havent try it with all the leds yet cause no power supply yet, im waiting for it to arrive.

now with this done and working, how could i use the MClightning with this refactored sketch.

i've been reading and watching videos but still confuse, my ESP ony shows OTA not SPIFFS i have load all the libraries needed to use MClightning but i havent get to it yet.

i would like to be able to use all the effects from the sketch you made for me and have the possibility to select a mode or use the static colors as shown in the video of MCLightning.

thanks and sorry for the long reading.

moose4lord commented 4 years ago

McLighting is a reasonably complex application and, since you've just started using WS2812 LEDs, I think modifying it is a little beyond your abilities at the moment.

If you're just looking for a web interface to control your setup, you should probably start with one of the web example sketches included with WS2812FX. The esp8266_webinterface example sketch is similar to McLighting and supports the 4 custom effects. You'd still need to incorporate the custom effect code, similar to what I did in the refactored auto_mode_cycle example sketch above.

The ws2812fx_segments_web example sketch is a little more sophisticated, but it supports partitioning your LEDs into segments and WS2812FX's advanced controls (like multiple colors, reverse, gamma correction, fade rate and size). Adding code for custom effects would have to be done here too.

johndlcg commented 4 years ago

Hello again, i just manage to get mclightning working, but as you said, it is a bit complex, anyway with this web interface when i put it in auto it just shows me 3 modes not the 59 that are list in the web page. i didnt know that you have a web interface in the library, so i will see what i can do with it now.

thanks for replying

johndlcg commented 4 years ago

Hi Keith, i manage to transfer the refactored sketch to the ws2812fx webinterface dont know why if i use my test strip with 11 leds it works like a charm, but when i use it on my long strip with the 800+ it just blinks different colors, but dont do what it should.

what should i do in this case.

moose4lord commented 4 years ago

For your 800+ LED strip setup, do you have a 1000uF capacitor between the LED power and ground wires, and a 100-500 ohm resistor in series with the data pin as mentioned in the Adafruit UberGuide here? It might be good to set the default brightness to 32 just to make it easier for your power supply to drive so many LEDs.

#define DEFAULT_BRIGHTNESS 32

Also, what happens if you connect your 11 LED test strip, but set LED_COUNT = 900? You of course won't see 900 LEDs blinking, but the 11 LEDs on the strip should work fine.

johndlcg commented 4 years ago

No i have not capacitor/resistor, i will today, but still havent get the 60amps power supply, im using a computer power supply 27 amps at the end and a 2.5 amps in the begining of the strip/esp8266 i just try and it still work with the 800+ on the 11 test strip.

i found out in the webpage is that the speed restart if you continue to press the speed button to get the slowest. how can i fix this? and there is a variation on the speed, you get faster speed in less [+] button press than on the contrary and the opposite on brightness.

moose4lord commented 4 years ago

The speed button is working as intended. Pressing the [-] button slows down the animation, while pressing [+] speeds it up, which seems intuitive to me. The speed numbers displayed in the Serial Monitor may be confusing you, since the library's speed parameter is inverted (smaller speed numbers yield faster animation). The speed parameter should probably be called "delay", but it's called "speed" for historical reasons.

tobi01001 commented 4 years ago

Hi,

800 leds is quite a massive task to be written out especially with bit banging... 1 led needs about 30us to be written. With 800 you need 30us*800 =24 ms (+some negligible 50us).

So you will hardly get 40 fps without time required to calculate the frame. And the worst thing is that the controller is more or less blocked during that time.

One thing to release resources for frame calculation and other tasks is using a DMA method to write the leds (for the drawback of memory consumption - which is usually no problem on a esp8266).

AFAIK there is an example using neopixelbus. This should ease things.

Another option (if performance and fps is key) would be parallel output with an esp32.

I am happy with writing the leds with DMA as I use 300 (297) leds at max.

For the power supply: 1000uf capacitor and a very good ground connection... I supplied my 300 leds application from both sides which works fine but with 800 I would supply every 150 to 200 leds (there is recommendation in the adafruit guide).

And don't forget to take care of the cable size. If you drive them at full white with full brightness they will draw a lot (around 40 amps or more depending on the led type) and for this you would need at least 16mm2 cable diameter.... If not even more...

Regards.

johndlcg notifications@github.com schrieb am Fr., 22. Nov. 2019, 21:38:

No i have not capacitor/resistor, i will today, but still havent get the 60amps power supply, im using a computer power supply 27 amps at the end and a 2.5 amps in the begining of the strip/esp8266 i just try and it still work with the 800+ on the 11 test strip.

i found out in the webpage is that the speed restart if you continue to press the speed button to get the slowest. how can i fix this? and there is a variation on the speed, you get faster speed in less [+] button press than on the contrary and the opposite on brightness.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/kitesurfer1404/WS2812FX/issues/198?email_source=notifications&email_token=AAIIPSEJCMYFD3665ZFYDWTQVA7ODA5CNFSM4JK4CUH2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEE6ZWPY#issuecomment-557685567, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIIPSASUXMYMVHV3FRD3I3QVA7ODANCNFSM4JK4CUHQ .

johndlcg commented 4 years ago

Hi Keith sorry if you get me wrong on what i said in the last message, the web interface more intuitive cannot be, and like you said it is working as intended, what i notice is that when you keep pressing the [-] button the speed restart to fast again. and that you have to press more times to slow down than to speed up and same with the brightness. i add the capacitor and the resistor to the strip, but the problem for all the leds to power on was that the ground was not joint to the same power supply after i put it togeter it start working.

dont know why when i press the bicolor and tricolor chase starts running but in one default/selected color.

johndlcg commented 4 years ago

hi tobi, im not a programmer, dont know how to implemet the fps/dma in the sketch, i have to thanks Keith for giving me the modifications to the code and guidance to accomplish what i was looking for.

fot the wire, im using #12 wire and im leaving a power input on every 100 leds of the strips, keith lead me to the adaruit recommendation for the wiring and components to use on the project.

any guidance on changing the code to get FPS and DMA working wikk preciated.

thanks

mindforger commented 4 years ago

I tried abusing an SPI peripheral once on an atmega, creating the bit pattern by using a faster spi clock to use 3 bits per byte in spi for each ws2812 bit, but that made it kind of worse, because it took more time to convert the RGB data into an fitting spi bytestream than bitbanging it out. Only thing i can imagine, since the esp clocks way faster would be to dma timer values into an pwm peripheral, but this would mean at least 1 whole byte per RGB bit in memory. I know the raspberry pi ws2812 libs do it that way, since memory is by far no issue there.

johndlcg commented 4 years ago

Hi Keith

im trying to add custom effects from fastled "Demo Reel" in the code but i get it ro show the name in the monitor, but not the modes on the strips, here the code im using.

#include "FastLED.h" // be sure to install and include the FastLED lib
#include <WS2812FX.h>
FASTLED_USING_NAMESPACE

#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
#warning "Requires FastLED 3.1 or later; check github for latest code."
#endif

#define NUM_LEDS 11
#define LED_PIN 3
CRGB leds[NUM_LEDS];

#define TIMER_MS 5000
#define FRAMES_PER_SECOND  120
WS2812FX ws2812fx = WS2812FX(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);

// declare global parameters used by Fire2012
bool gReverseDirection = false;

unsigned long last_change = 0;
unsigned long now = 0;

void setup() {
  Serial.begin(115200);
  ws2812fx.init();
  ws2812fx.setBrightness(32);
  ws2812fx.setSpeed(2000);
  uint32_t colors[] = {RED, GREEN, BLUE}; // some default colors
  ws2812fx.setColors(0, colors);
  ws2812fx.setMode(FX_MODE_TRICOLOR_CHASE);
  ws2812fx.start();

  uint8_t RainbowMode  = ws2812fx.setCustomMode(F("Rainbow"), rainbowCustomEffect);
  uint8_t RainbowWithGlitterMode  = ws2812fx.setCustomMode(F("Rainbow With Glitter"), rainbowWithGlitterCustomEffect);
  uint8_t ConfettiMode  = ws2812fx.setCustomMode(F("Confetti"), confettiCustomEffect);
  uint8_t JuggleMode  = ws2812fx.setCustomMode(F("Juggle"), juggleCustomEffect);      
}
uint8_t gHue = 0; // rotating "base color" used by many of the patterns

void loop() {
  static int frameCount = 0;
  now = millis();

  ws2812fx.service();

    if(ws2812fx.isFrame()) { // increment the animation frame count
    frameCount++;
    Serial.println(frameCount);
    //Serial.println(TIMER_MS);
  }

  if(now - last_change > TIMER_MS && frameCount == NUM_LEDS) {
    ws2812fx.setMode((ws2812fx.getMode() + 1) % ws2812fx.getModeCount());
    Serial.print("Mode: "); Serial.println(ws2812fx.getModeName(ws2812fx.getMode()));
    last_change = now;
  }
     //if we're at the end of an animation cycle, reset the frame count
   if(frameCount == NUM_LEDS) {
     frameCount = 0;
  }
}
//FastLED.delay(1000/FRAMES_PER_SECOND);
//EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow

// create a custom effect function which runs the FastLED Fire2012 algorithm
/*uint16_t fire2012CustomEffect() {
  Fire2012(); // call the FastLED function

  // return the animation speed based on the ws2812fx speed setting
  return (ws2812fx.getSpeed() / NUM_LEDS);
}*/

uint16_t rainbowCustomEffect() {
  Rainbow(); // call the FastLED function

  // return the animation speed based on the ws2812fx speed setting
  return (ws2812fx.getSpeed() / NUM_LEDS);
}

uint16_t rainbowWithGlitterCustomEffect() {
  RainbowWithGlitter(); // call the FastLED function

  // return the animation speed based on the ws2812fx speed setting
  return (ws2812fx.getSpeed() / NUM_LEDS);
}

uint16_t confettiCustomEffect() {
  Confetti(); // call the FastLED function

  // return the animation speed based on the ws2812fx speed setting
  return (ws2812fx.getSpeed() / NUM_LEDS);
}

uint16_t juggleCustomEffect() {
  Juggle(); // call the FastLED function

  // return the animation speed based on the ws2812fx speed setting
  return (ws2812fx.getSpeed() / NUM_LEDS);
}

void Rainbow() 
{
  // FastLED's built-in rainbow generator
  fill_rainbow( leds, NUM_LEDS, gHue, 7);
}

void RainbowWithGlitter() 
{
  // built-in FastLED rainbow, plus some random sparkly glitter
  Rainbow();
  addGlitter(80);
}

void addGlitter( fract8 chanceOfGlitter) 
{
  if( random8() < chanceOfGlitter) {
    leds[ random16(NUM_LEDS) ] += CRGB::White;
  }
}

void Confetti() 
{
  // random colored speckles that blink in and fade smoothly
  fadeToBlackBy( leds, NUM_LEDS, 10);
  int pos = random16(NUM_LEDS);
  leds[pos] += CHSV( gHue + random8(64), 200, 255);
}

void Juggle() {
  // eight colored dots, weaving in and out of sync with each other
  fadeToBlackBy( leds, NUM_LEDS, 20);
  byte dothue = 0;
  for( int i = 0; i < 8; i++) {
    leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255);
    dothue += 32;
  }
}

this is the demo reel 100 code from where i took the parts added to your code. i was trying to follow the guide from fire2012.

#include <FastLED.h>

FASTLED_USING_NAMESPACE

// FastLED "100-lines-of-code" demo reel, showing just a few 
// of the kinds of animation patterns you can quickly and easily 
// compose using FastLED.  
//
// This example also shows one easy way to define multiple 
// animations patterns and have them automatically rotate.
//
// -Mark Kriegsman, December 2014

#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
#warning "Requires FastLED 3.1 or later; check github for latest code."
#endif

#define DATA_PIN    3
//#define CLK_PIN   4
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
#define NUM_LEDS    64
CRGB leds[NUM_LEDS];

#define BRIGHTNESS          96
#define FRAMES_PER_SECOND  120

void setup() {
  delay(3000); // 3 second delay for recovery

  // tell FastLED about the LED strip configuration
  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  //FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);

  // set master brightness control
  FastLED.setBrightness(BRIGHTNESS);
}

// List of patterns to cycle through.  Each is defined as a separate function below.
typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = { rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm };

uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current
uint8_t gHue = 0; // rotating "base color" used by many of the patterns

void loop()
{
  // Call the current pattern function once, updating the 'leds' array
  gPatterns[gCurrentPatternNumber]();

  // send the 'leds' array out to the actual LED strip
  FastLED.show();  
  // insert a delay to keep the framerate modest
  FastLED.delay(1000/FRAMES_PER_SECOND); 

  // do some periodic updates
  EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow
  EVERY_N_SECONDS( 10 ) { nextPattern(); } // change patterns periodically
}

#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))

void nextPattern()
{
  // add one to the current pattern number, and wrap around at the end
  gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);
}

void rainbow() 
{
  // FastLED's built-in rainbow generator
  fill_rainbow( leds, NUM_LEDS, gHue, 7);
}

void rainbowWithGlitter() 
{
  // built-in FastLED rainbow, plus some random sparkly glitter
  rainbow();
  addGlitter(80);
}

void addGlitter( fract8 chanceOfGlitter) 
{
  if( random8() < chanceOfGlitter) {
    leds[ random16(NUM_LEDS) ] += CRGB::White;
  }
}

void confetti() 
{
  // random colored speckles that blink in and fade smoothly
  fadeToBlackBy( leds, NUM_LEDS, 10);
  int pos = random16(NUM_LEDS);
  leds[pos] += CHSV( gHue + random8(64), 200, 255);
}

void sinelon()
{
  // a colored dot sweeping back and forth, with fading trails
  fadeToBlackBy( leds, NUM_LEDS, 20);
  int pos = beatsin16( 13, 0, NUM_LEDS-1 );
  leds[pos] += CHSV( gHue, 255, 192);
}

void bpm()
{
  // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
  uint8_t BeatsPerMinute = 62;
  CRGBPalette16 palette = PartyColors_p;
  uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
  for( int i = 0; i < NUM_LEDS; i++) { //9948
    leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10));
  }
}

void juggle() {
  // eight colored dots, weaving in and out of sync with each other
  fadeToBlackBy( leds, NUM_LEDS, 20);
  byte dothue = 0;
  for( int i = 0; i < 8; i++) {
    leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255);
    dothue += 32;
  }
}

thank you very much

moose4lord commented 4 years ago

John, in your code you have an array of FastLED pixel data: CRGB leds[NUM_LEDS]; and a ws2812fx object: WS2812FX ws2812fx = WS2812FX(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800); , but no connection between the two.

The FastLED functions will manipulate the leds[] array, but you need a means to copy that pixel data to the ws2812fx object. Adding a memmove statement will do that:

void Rainbow() { // FastLED's built-in rainbow generator
    fill_rainbow( leds, NUM_LEDS, gHue, 7);
    memmove( ws2812fx.getPixels(), leds, ws2812fx.getNumBytes() );
}
johndlcg commented 4 years ago

hi Keith,

it just lit the leds steady gradient but no rainbow running, and it doesnt change to the other effects im trying to use.

to use the modes from the automode i have to declare each mode independently right? how could i play them automatically as they does in the automode.

so that way i can add more effects from fastled and from the custom you have

another thing is that as we have made the change to wait for the entire frames, and some of the effects last too long to change like blink, that you have to wait until it blnks 800+ times to go to the next mode, and maybe separatly you could change the time.

moose4lord commented 4 years ago

The code snippet I showed was only for the Rainbow effect. You need to add the memmove() statement to the RainbowWithGlitter(), Confetti() and Juggle() functions as well, in order to get those effects to work.

The automode cycles all effects, including the 56 builtin effects and the 4 optional custom effects. You have to setup each custom effect you want to use, but remember there are only four "slots" for custom effects. If you want to use more than four, you'll need to figure out a way to dynamically change them.

You're right, the code that changes effects when "frameCount == NUM_LEDS" does not work well for effects like Blink. I can't think of an easy way to fix that.

johndlcg commented 4 years ago

Hi Keith,

i found in one of your posts a WS2812FX_Noise sketch, and i was wondering how it would look like, i loaded into a nano/esp8266 but it only fills blue, what could be wrong.

this is the link to your sketch. https://github.com/kitesurfer1404/WS2812FX/files/1781284/ws2812fx_noise.zip

thanks

moose4lord commented 4 years ago

For some reason there's no setMode() function call in the sketch. Add it before calling the start() function.

  ws2812fx.setCustomMode(myCustomEffect);
  ws2812fx.setMode(FX_MODE_CUSTOM);  // add this
  ws2812fx.start();
johndlcg commented 4 years ago

hi, Keith thanks for the fix , it is a really nice noise effect, i will try to use it in the sketch:

i still trying to run almost all the effects from auto_mode, just defined every mode individually. i could see that in this part, is where you change the effect:

 ws2812fx.setMode((ws2812fx.getMode() + 1)

can you please if you can take a look to this and tell me if it could possiibly work! it is telling me that gHue and gPatterns are not declared but they are, i got stuck,

#include "FastLED.h" // be sure to install and include the FastLED lib
//Start*********************************************************************************
FASTLED_USING_NAMESPACE
//End*********************************************************************************
#include <WS2812FX.h>

// include the pre-built custom effect
#include "custom/DualLarson.h"
//#include "custom/MultiComet.h"
//#include "custom/RainbowLarson.h"
#include "custom/RandomChase.h"
#include "custom/TriFade.h"
//Start********************************************************************************
// Define the default effect
//#define FX_MODE_STATIC 0 // No blinking. Just plain old static light.
//#define FX_MODE_BLINK 1 // Normal blinking. 50% on/off time.
//#define FX_MODE_BREATH 2 // Does the "standby//breathing" of well known i//Devices. Fixed Speed.
#define FX_MODE_COLOR_WIPE 3 // Lights all LEDs after each other up. Then turns them in that order off. Repeat.
#define FX_MODE_COLOR_WIPE_INV 4 // Same as Color Wipe, except swaps on/off colors.
#define FX_MODE_COLOR_WIPE_REV 5 // Lights all LEDs after each other up. Then turns them in reverse order off. Repeat.
#define FX_MODE_COLOR_WIPE_REV_INV 6 // Same as Color Wipe Reverse, except swaps on/off colors.
#define FX_MODE_COLOR_WIPE_RANDOM 7 // Turns all LEDs after each other to a random color. Then starts over with another color.
#define FX_MODE_RANDOM_COLOR 8 // Lights all LEDs in one random color up. Then switches them to the next random color.
#define FX_MODE_SINGLE_DYNAMIC 9 // Lights every LED in a random color. Changes one random LED after the other to a random color.
#define FX_MODE_MULTI_DYNAMIC 10 // Lights every LED in a random color. Changes all LED at the same time to new random colors.
#define FX_MODE_RAINBOW 11 // Cycles all LEDs at once through a rainbow.
#define FX_MODE_RAINBOW_CYCLE 12 // Cycles a rainbow over the entire string of LEDs.
#define FX_MODE_SCAN 13 // Runs a single pixel back and forth.
#define FX_MODE_DUAL_SCAN 14 // Runs two pixel back and forth in opposite directions.
#define FX_MODE_FADE 15 // Fades the LEDs on and (almost) off again.
#define FX_MODE_THEATER_CHASE 16 // Theatre//style crawling lights. Inspired by the Adafruit examples.
#define FX_MODE_THEATER_CHASE_RAINBOW 17 // Theatre//style crawling lights with rainbow effect. Inspired by the Adafruit examples.
#define FX_MODE_RUNNING_LIGHTS 18 // Running lights effect with smooth sine transition.
#define FX_MODE_TWINKLE 19 // Blink several LEDs on, reset, repeat.
#define FX_MODE_TWINKLE_RANDOM 20// Blink several LEDs in random colors on, reset, repeat.
#define FX_MODE_TWINKLE_FADE 21 // Blink several LEDs on, fading out.
#define FX_MODE_TWINKLE_FADE_RANDOM 22 // Blink several LEDs in random colors on, fading out.
#define FX_MODE_SPARKLE 23 // Blinks one LED at a time.
#define FX_MODE_FLASH_SPARKLE 24 // Lights all LEDs in the selected color. Flashes single white pixels randomly.
#define FX_MODE_HYPER_SPARKLE 25 // Like flash sparkle. With more flash.
//#define FX_MODE_STROBE 26 // Classic Strobe effect.
//#define FX_MODE_STROBE_RAINBOW 27 // Classic Strobe effect. Cycling through the rainbow.
//#define FX_MODE_MULTI_STROBE 28 // Strobe effect with different strobe count and pause, controlled by speed setting.
#define FX_MODE_BLINK_RAINBOW 29 // Classic Blink effect. Cycling through the rainbow.
#define FX_MODE_CHASE_WHITE 30 // Color running on white.
#define FX_MODE_CHASE_COLOR 31 // White running on color.
#define FX_MODE_CHASE_RANDOM 32 // White running followed by random color.
#define FX_MODE_CHASE_RAINBOW 33 // White running on rainbow.
#define FX_MODE_CHASE_FLASH 34 // White flashes running on color.
#define FX_MODE_CHASE_FLASH_RANDOM 35 // White flashes running, followed by random color.
#define FX_MODE_CHASE_RAINBOW_WHITE 36 // Rainbow running on white.
#define FX_MODE_CHASE_BLACKOUT 37 // Black running on color.
#define FX_MODE_CHASE_BLACKOUT_RAINBOW 38 // Black running on rainbow.
#define FX_MODE_COLOR_SWEEP_RANDOM 39 // Random color introduced alternating from start and end of strip.
#define FX_MODE_RUNNING_COLOR 40 // Alternating color/white pixels running.
#define FX_MODE_RUNNING_RED_BLUE 41 // Alternating red/blue pixels running.
#define FX_MODE_RUNNING_RANDOM 42 // Random colored pixels running.
#define FX_MODE_LARSON_SCANNER 43 // K.I.T.T.
#define FX_MODE_COMET 44 // Firing comets from one end.
#define FX_MODE_FIREWORKS 45 // Firework sparks.
#define FX_MODE_FIREWORKS_RANDOM 46 // Random colored firework sparks.
#define FX_MODE_MERRY_CHRISTMAS 47 // Alternating green/red pixels running.
#define FX_MODE_FIRE_FLICKER 48 // Fire flickering effect. Like in harsh wind.
#define FX_MODE_FIRE_FLICKER_SOFT 49 // Fire flickering effect. Runs slower/softer.
#define FX_MODE_FIRE_FLICKER_INTENSE 50 // Fire flickering effect. More range of color.
#define FX_MODE_CIRCUS_COMBUSTUS 51 // Alternating white/red/black pixels running.
#define FX_MODE_HALLOWEEN 52 // Alternating orange/purple pixels running.
#define FX_MODE_BICOLOR_CHASE 53 // Two LEDs running on a background color (set three colors).
#define FX_MODE_TRICOLOR_CHASE 54 // Alternating three color pixels running (set three colors).
#define FX_MODE_ICU 55 // Two eyes looking around.
#define FX_MODE_CUSTOM_0 56 // Fire 2012
#define FX_MODE_CUSTOM_1 57 // Dual Larson
#define FX_MODE_CUSTOM_2 58 // Multi Comet
#define FX_MODE_CUSTOM_3 59 // Rainbow Larson
#define rainbow 60
#define rainbowWithGlitter 61
#define confetti 62
#define sinelon 63
#define juggle 64
#define bpm 65
//End********************************************************************************

#define NUM_LEDS 11
#define LED_PIN 3 // port 14 = D5 ESP8266

//Start*********************************************************************************
CRGB leds[NUM_LEDS];
//End*********************************************************************************

#define TIMER_MS 5000

WS2812FX ws2812fx = WS2812FX(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);

// declare global parameters used by Fire2012
bool gReverseDirection = false;

unsigned long last_change = 0;
unsigned long now = 0;

void setup() {
  Serial.begin(115200);
  ws2812fx.init();
  ws2812fx.setBrightness(32);
  ws2812fx.setSpeed(2000);
  uint32_t colors[] = {RED, GREEN, BLUE}; // some default colors
  ws2812fx.setColors(0, colors);
  ws2812fx.setMode(FX_MODE_ICU);
  ws2812fx.start();

//Start*********************************************************************************
// List of patterns to cycle through.  Each is defined as a separate function below.
typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = { 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,52,52,53,54,55,56,57,58,58,rainbow,rainbowWithGlitter,confetti,sinelon,juggle,bpm};
SimplePatternList gPatterns = { 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,52,52,53,54,55,56,57,58,58,60,61,62,63,64,65};

uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current
uint8_t gHue = 0; // rotating "base color" used by many of the patterns
//End*********************************************************************************

  // setup custom effects
  uint8_t fire2012Mode  = ws2812fx.setCustomMode(F("Fire 2012"), fire2012CustomEffect);
  uint8_t dualLarsonMode  = ws2812fx.setCustomMode(F("Dual Larson"), dualLarson);
//  uint8_t multiCometMode  = ws2812fx.setCustomMode(F("Multi Comet"), multiComet);
//  uint8_t rainbowLarsonMode  = ws2812fx.setCustomMode(F("Rainbow Larson"), rainbowLarson);
  uint8_t randomChaseMode  = ws2812fx.setCustomMode(F("Random Chase"), randomChase);
  uint8_t triFadeMode  = ws2812fx.setCustomMode(F("Tri Fade"), triFade);
}

void loop() {
  static int frameCount = 0;
  now = millis();

//Start*********************************************************************************
 // Call the current pattern function once, updating the 'leds' array
  gPatterns[gCurrentPatternNumber]();
//End*********************************************************************************

  ws2812fx.service();

    if(ws2812fx.isFrame()) { // increment the animation frame count
    frameCount++;
    //Serial.println(frameCount);
    //Serial.println(TIMER_MS);
  }

  if(now - last_change > TIMER_MS && frameCount == NUM_LEDS) {
    ws2812fx.setMode((ws2812fx.getMode(nextPattern)) % ws2812fx.getModeCount());
    Serial.print("Mode Name: "); Serial.println(ws2812fx.getModeName(ws2812fx.getMode()));
    Serial.print("Mode Number: "); Serial.println(ws2812fx.getMode());
    last_change = now;
  }
     //if we're at the end of an animation cycle, reset the frame count
   if(frameCount == NUM_LEDS) {
     frameCount = 0;
  }
}

//Start*********************************************************************************
EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0])) 

void nextPattern()
{
  // add one to the current pattern number, and wrap around at the end
//*  gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);
}

void rainbow() 
{
  // FastLED's built-in rainbow generator
  fill_rainbow( leds, NUM_LEDS, gHue, 7);
  memmove( ws2812fx.getPixels(), leds, ws2812fx.getNumBytes() );
}

void rainbowWithGlitter() 
{
  // built-in FastLED rainbow, plus some random sparkly glitter
  rainbow();
  addGlitter(80);
}

void addGlitter( fract8 chanceOfGlitter) 
{
  if( random8() < chanceOfGlitter) {
    leds[ random16(NUM_LEDS) ] += CRGB::White;
  }
}

void confetti() 
{
  // random colored speckles that blink in and fade smoothly
  fadeToBlackBy( leds, NUM_LEDS, 10);
  memmove( ws2812fx.getPixels(), leds, ws2812fx.getNumBytes() );
  int pos = random16(NUM_LEDS);
  leds[pos] += CHSV( gHue + random8(64), 200, 255);

}

void sinelon()
{
  // a colored dot sweeping back and forth, with fading trails
  fadeToBlackBy( leds, NUM_LEDS, 20);
  memmove( ws2812fx.getPixels(), leds, ws2812fx.getNumBytes() );
  int pos = beatsin16( 13, 0, NUM_LEDS-1 );
  leds[pos] += CHSV( gHue, 255, 192);

}

void bpm()
{
  // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
  uint8_t BeatsPerMinute = 62;
  CRGBPalette16 palette = PartyColors_p;
  uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
  for( int i = 0; i < NUM_LEDS; i++) { //9948
    leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10));
    memmove( ws2812fx.getPixels(), leds, ws2812fx.getNumBytes() );
  }
}

void juggle() {
  // eight colored dots, weaving in and out of sync with each other
  fadeToBlackBy( leds, NUM_LEDS, 20);
  memmove( ws2812fx.getPixels(), leds, ws2812fx.getNumBytes() );
  byte dothue = 0;
  for( int i = 0; i < 8; i++) {
    leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255);
    dothue += 32;
  }
}
//End*********************************************************************************

// create a custom effect function which runs the FastLED Fire2012 algorithm
uint16_t fire2012CustomEffect() {
  Fire2012(); // call the FastLED function

  // return the animation speed based on the ws2812fx speed setting
  return (ws2812fx.getSpeed() / NUM_LEDS);
}

// I recommend running this simulation at anywhere from 30-100 frames per second,
// meaning an interframe delay of about 10-35 milliseconds.
//
// Looks best on a high-density LED setup (60+ pixels/meter).
//
//
// There are two main parameters you can play with to control the look and
// feel of your fire: COOLING (used in step 1 above), and SPARKING (used
// in step 3 above).
//
// COOLING: How much does the air cool as it rises?
// Less cooling = taller flames.  More cooling = shorter flames.
// Default 50, suggested range 20-100 
#define COOLING  55

// SPARKING: What chance (out of 255) is there that a new spark will be lit?
// Higher chance = more roaring fire.  Lower chance = more flickery fire.
// Default 120, suggested range 50-200.
#define SPARKING 120

void Fire2012()
{
// Array of temperature readings at each simulation cell
  static byte heat[NUM_LEDS];

  // Step 1.  Cool down every cell a little
    for( int i = 0; i < NUM_LEDS; i++) {
      heat[i] = qsub8( heat[i],  random8(0, ((COOLING * 10) / NUM_LEDS) + 2));
    }

    // Step 2.  Heat from each cell drifts 'up' and diffuses a little
    for( int k= NUM_LEDS - 1; k >= 2; k--) {
      heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
    }

    // Step 3.  Randomly ignite new 'sparks' of heat near the bottom
    if( random8() < SPARKING ) {
      int y = random8(7);
      heat[y] = qadd8( heat[y], random8(160,255) );
    }

    // Step 4.  Map from heat cells to LED colors
    for( int j = 0; j < NUM_LEDS; j++) {
      CRGB color = HeatColor( heat[j]);
      int pixelnumber;
      if( gReverseDirection ) {
        pixelnumber = (NUM_LEDS-1) - j;
      } else {
        pixelnumber = j;
      }

// **** modified for use with WS2812FX ****
//    leds[pixelnumber] = color;
      ws2812fx.setPixelColor(pixelnumber, color.red, color.green, color.blue);
// **** modified for use with WS2812FX ****

    }
}

the new addtition to this code are the one with //Start* - //End thanks again for your help

moose4lord commented 4 years ago

Yikes! You've made quite a few changes to the code. Modifying code is a methodical process of change and test, change and test, change and test... You've changed too many things at once and gotten off course.

I see a few problems with your code. You should remove the "#define FXMODE..." statements at the top of your sketch. They are already a part of the WS2812FX.h file, so should not be included in your sketch. The gHue variable should be a global variable, so needs to go outside the setup() function. Move it after the "last_changed" variable at the top of the sketch. Your call to EVERY_N_MILLISECONDS is outside the loop() function. You need to move it back inside the loop() function. You're using gPatterns incorrectly. SimplePatternList is an array of function pointers, not an array of integers. You should remove all that pattern code. If you want to create your own list of effects to cycle through, create an array of modes (integers) and iterate through it, like this:

uint8_t myModes[] = {4,6,8,9,15,22,48}; // global array of effect mode numbers
uint8_t myModeIndex = 0; // global index into the myModes array

// in the loop() function
if(now - last_change > TIMER_MS && frameCount == NUM_LEDS) {
    myModeIndex = (myModeIndex + 1) % sizeof(myModes);
    ws2812fx.setMode(myModes[myModeIndex]);
    Serial.print("Mode Name: "); Serial.println(ws2812fx.getModeName(ws2812fx.getMode()));
    Serial.print("Mode Number: "); Serial.println(ws2812fx.getMode());
    last_change = now;
  }

Also it looks like you're trying to add more than 4 custom effects. WS2812FX does not support more than 4 custom effects. The library is hardcoded with a total of 60 effects (56 built-in effects and 4 user created custom effects).

At this point you may want to toss the code you have now and revert back to an earlier version that was working well. Then make small changes to the code, testing frequently and obsessively, until you've gradually built up the functionality you want. Slow and steady wins the race. :)

johndlcg commented 4 years ago

Hello Keith. You are the men!!!! thanks for the code, this was exactly what i was trying to do with the effects modes, been able to select the effects i want to show.

i was trying to add more effects besides the one from the library, thats why i add the code of demo reel from fastled, as the library is already included in the sketch.

is there a way that i could add fastled effect in addition to the four custom.?

i found an sketch called AllLedsEffectsinOne with 18 effects some of the ones you have in your library https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDEffects here is an effect called meteorrain that i would like to add.

moose4lord commented 4 years ago

You can create custom effects using FastLED to do the "math" (see the ws2812fx_custom_FastLED example sketch), or you can write your own "math" (see the ws2812fx_custom_effect example sketch). You can mix and match techniques too. It's totally up to you on how to manipulate the LED data. Just remember you're limited to four custom effects no matter which technique you use.

The effects on the Tweaking4all web site you mention can't just be plopped into a WS2812FX sketch. The developer assumes his code has complete control of the microprocessor, so it doesn't integrate easily with another effects lib like WS2812FX. However, the MeteorRain effect looks similar to WS2812FX's comet effect with a long fade rate. Maybe this would be close enough:

ws2812fx.setSegment(0, 0, LED_COUNT - 1, FX_MODE_COMET, WHITE, 4000, FADE_GLACIAL);
bangoroo commented 4 years ago

Hey, I use both, WS2812FX and FastLed in my lightProject. I run the code on a esp8266 wit 300 leds and it works fine. I also added some more FastLED effects without using custom_effect from WS2812FX. If you like you can take a look at it on my github

johndlcg commented 4 years ago

Hi bangoroo,

i went to your github, but didnt see any sketch.

bangoroo commented 4 years ago

Hi bangoroo,

i went to your github, but didnt see any sketch.

https://github.com/bangoroo/lightControl/blob/master/src/lightcontrol.cpp thats the link. I use VS Code with platformIO, so it's not a .ino file.