Skip to content

Commit

Permalink
Changed _modes[] to a static array. Tweaked RUNNING_COLOR effect. (#232)
Browse files Browse the repository at this point in the history
* made _modes[] a static array

* fixed typo

* fixed the modes being out of order

* updated documentation

* changed RUNNING_COLOR mode to use color[1] instead of WHITE for the background color

* updated change log

Co-authored-by: Keith Lord <[email protected]>
  • Loading branch information
moose4lord and Keith Lord authored Jun 15, 2020
1 parent fc571c4 commit 41936b8
Show file tree
Hide file tree
Showing 8 changed files with 193 additions and 81 deletions.
13 changes: 5 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Note, some effects make use of more then one color (up to three) and are program
// divide the string of LEDs into two independent segments
uint32_t colors[] = {RED, GREEN};
ws2812fx.setSegment(0, 0, (LED_COUNT/2)-1, FX_MODE_BLINK, colors, 1000, false);
ws2812fx.setSegment(1, LED_COUNT/2, LED_COUNT-1, FX_MODE_BLINK, (const uint32_t[]) {ORANGE, PURPLE}, 1000, false);
ws2812fx.setSegment(1, LED_COUNT/2, LED_COUNT-1, FX_MODE_BLINK, COLORS(ORANGE, PURPLE), 1000, false);
```
Expand Down Expand Up @@ -124,13 +124,10 @@ Effects
50. **Fire Flicker (intense)** - Fire flickering effect. More range of color.
51. **Circus Combustus** - Alternating white/red/black pixels running.
52. **Halloween** - Alternating orange/purple pixels running.
53. **Bicolor Chase** - Two LEDs running on a background color (set three colors).
54. **Tricolor Chase** - Alternating three color pixels running (set three colors).
55. **ICU** - Two eyes looking around.
56. **Custom** - Up to four user created custom effects.
57. **Custom**
58. **Custom**
59. **Custom**
53. **Bicolor Chase** - Two LEDs running on a background color.
54. **Tricolor Chase** - Alternating three color pixels running.
55. thru 62. **Custom** - Up to eight user created custom effects.
Projects using WS2812FX
-----------------------
Expand Down
80 changes: 80 additions & 0 deletions examples/ws2812fx_virtual_strip/ws2812fx_virtual_strip.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
Demo sketch which shows how to configure WS2812FX such that two physical
stips of LEDs, driven by two separate GPIO pins, get their pixel data
from one virtual strip. One effect can be spread across two strips.
LICENSE
The MIT License (MIT)
Copyright (c) 2020 Keith Lord
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
CHANGELOG
2020-05-29 initial version
*/

#include <WS2812FX.h>

#define LED_PIN_V1 10 // virtual digital pin used to drive the virtual LED strip
#define LED_PIN_P1 10 // physical digital pin used to drive the first physical LED strip
#define LED_PIN_P2 11 // physical digital pin used to drive the second physical LED strip
#define LED_COUNT_P1 30 // number of LEDs on the first physical strip
#define LED_COUNT_P2 30 // number of LEDs on the second physical strip

// create an instance of one virtual strip and two physical strips.
// the physical strips are only initialized with a count of one LED, since
// these strips will ultimately use the pixel data of the virtual strip.
// (Note the instances are created with support of only one segment and one
// segment_runtime, just so the sketch fits in an Arduino's limited SRAM.)
WS2812FX ws2812fx_v1 = WS2812FX(LED_COUNT_P1 + LED_COUNT_P2, LED_PIN_V1, NEO_GRB + NEO_KHZ800, 1, 1);
WS2812FX ws2812fx_p1 = WS2812FX(1, LED_PIN_P1, NEO_GRB + NEO_KHZ800, 1, 1);
WS2812FX ws2812fx_p2 = WS2812FX(1, LED_PIN_P2, NEO_GRB + NEO_KHZ800, 1, 1);

void setup() {
// initialize the virtual strip as you would any normal ws2812fx instance
ws2812fx_v1.init();
ws2812fx_v1.setBrightness(255);
ws2812fx_v1.setSegment(0, 0, ws2812fx_v1.getLength()-1, FX_MODE_COMET, RED, 2000, NO_OPTIONS);
ws2812fx_v1.start();

// init the physical strip's GPIOs and reassign their pixel data
// pointer to use the virtual strip's pixel data.
ws2812fx_p1.init();
ws2812fx_p1.setPixels(LED_COUNT_P1, ws2812fx_v1.getPixels());
ws2812fx_p2.init();
ws2812fx_p2.setPixels(LED_COUNT_P2, ws2812fx_v1.getPixels() + (LED_COUNT_P1 * ws2812fx_v1.getNumBytesPerPixel()));

// config a custom show() function for the virtual strip, so pixel
// data gets sent to the physical strips's LEDs instead
ws2812fx_v1.setCustomShow(myCustomShow);
}

void loop() {
// update the virtual strip's pixel data by calling service() as you normally would
ws2812fx_v1.service();
}

// update the physical strips's LEDs
void myCustomShow(void) {
ws2812fx_p1.show();
ws2812fx_p2.show();
}
14 changes: 14 additions & 0 deletions extras/WS2812FX Users Guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,20 @@ show() function.
```c++
ws2812fx.setCustomShow(myCustomShow);
```

***

## Segment management

As of v1.3.0 WS2812FX provides more fine grained management of segments by
introducing the idea of idle segments. Segments can be created
in an "idle" state using the setIdleSegment() function. These segments are
initially inactive and can be activated at a later time by using the
addActiveSegment() or swapActiveSegment() functions. Active segments can be
returned to the idle state by using the removeActiveSegment() function. In this
way you can create a bunch of segments, and then pick and choose which segments
are active at runtime. See the **ws2812fx_segment_sequence** example sketch.

***

## One More Thing
Expand Down
21 changes: 20 additions & 1 deletion extras/WS2812FX change log.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
WS2182FX Change Log


v1.3.1 changes 6/2/2020
------------------------

1) Changed _modes[] to a static array. Saves a bunch of flash
and SRAM memory when instantiating more than one WS2812FX object.

2) Added ws2812fx_virtual_strip example sketch to demonstrate how to
use setPixels() to manage the Adafruit_NeoPixel pixel data.

3) Changed RUNNING_COLOR effect so that the background color is
set to colors[1] instead of hardcoded to WHITE. The default
background color will be BLACK now. Set color[1]=WHITE if
you want the old behavior.

4) Updated the README.md file.


v1.3.0 changes 5/11/2020
------------------------

Expand Down Expand Up @@ -40,6 +57,8 @@ v1.3.0 changes 5/11/2020
9) Substantial refactoring of the segment code to use global variables
instead of macros, which makes sketches significantly smaller.

10) added setPixels() function to allow users to manually manage the
underlying Adafruit_NeoPixel pixel data.


v1.2.4 changes 5/8/2020
Expand Down Expand Up @@ -230,7 +249,7 @@ v1.1.4 changes 12/1/2018

1) Refactored the custom effect code to make it more flexible. You
can now dynamically assign custom effects to any one of the
four _mode 'slots' by using the setCustomMode(index, name, *p)
four _modes[] 'slots' by using the setCustomMode(index, name, *p)
function.

2) Fixed a bug in the DualLarson custom effect that caused it to
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"name": "Harm Aldick",
"url": "https://github.com/kitesurfer1404/WS2812FX"
},
"version": "1.3.0",
"version": "1.3.1",
"downloadUrl": "https://github.com/kitesurfer1404/WS2812FX/archive/master.zip",
"export": {
"include": "WS2812FX-master"
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=WS2812FX
version=1.3.0
version=1.3.1
author=Harm Aldick
maintainer=Harm Aldick
sentence=WS2812 FX Library for Arduino and ESP microprocessors.
Expand Down
6 changes: 3 additions & 3 deletions src/WS2812FX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ void WS2812FX::init() {

// void WS2812FX::timer() {
// for (int j=0; j < 1000; j++) {
// uint16_t delay = (this->*_mode[_seg->mode])();
// uint16_t delay = (this->*_modes[_seg->mode])();
// }
// }

Expand All @@ -78,7 +78,7 @@ void WS2812FX::service() {
if(now > _seg_rt->next_time || _triggered) {
SET_FRAME;
doShow = true;
uint16_t delay = (this->*_mode[_seg->mode])();
uint16_t delay = (this->*_modes[_seg->mode])();
_seg_rt->next_time = now + max(delay, SPEED_MIN);
_seg_rt->counter_mode_call++;
}
Expand Down Expand Up @@ -1377,7 +1377,7 @@ uint16_t WS2812FX::running(uint32_t color1, uint32_t color2) {
* Alternating color/white pixels running.
*/
uint16_t WS2812FX::mode_running_color(void) {
return running(_seg->colors[0], WHITE);
return running(_seg->colors[0], _seg->colors[1]);
}


Expand Down
136 changes: 69 additions & 67 deletions src/WS2812FX.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,9 @@ static const __FlashStringHelper* _names[] = {

class WS2812FX : public Adafruit_NeoPixel {

typedef uint16_t (WS2812FX::*mode_ptr)(void);

public:
typedef uint16_t (WS2812FX::*mode_ptr)(void);

// segment parameters
typedef struct Segment { // 20 bytes
uint16_t start;
Expand All @@ -349,69 +349,6 @@ typedef uint16_t (WS2812FX::*mode_ptr)(void);
uint8_t max_num_segments=MAX_NUM_SEGMENTS,
uint8_t max_num_active_segments=MAX_NUM_ACTIVE_SEGMENTS)
: Adafruit_NeoPixel(num_leds, pin, type) {
_mode[FX_MODE_STATIC] = &WS2812FX::mode_static;
_mode[FX_MODE_BLINK] = &WS2812FX::mode_blink;
_mode[FX_MODE_COLOR_WIPE] = &WS2812FX::mode_color_wipe;
_mode[FX_MODE_COLOR_WIPE_INV] = &WS2812FX::mode_color_wipe_inv;
_mode[FX_MODE_COLOR_WIPE_REV] = &WS2812FX::mode_color_wipe_rev;
_mode[FX_MODE_COLOR_WIPE_REV_INV] = &WS2812FX::mode_color_wipe_rev_inv;
_mode[FX_MODE_COLOR_WIPE_RANDOM] = &WS2812FX::mode_color_wipe_random;
_mode[FX_MODE_RANDOM_COLOR] = &WS2812FX::mode_random_color;
_mode[FX_MODE_SINGLE_DYNAMIC] = &WS2812FX::mode_single_dynamic;
_mode[FX_MODE_MULTI_DYNAMIC] = &WS2812FX::mode_multi_dynamic;
_mode[FX_MODE_RAINBOW] = &WS2812FX::mode_rainbow;
_mode[FX_MODE_RAINBOW_CYCLE] = &WS2812FX::mode_rainbow_cycle;
_mode[FX_MODE_SCAN] = &WS2812FX::mode_scan;
_mode[FX_MODE_DUAL_SCAN] = &WS2812FX::mode_dual_scan;
_mode[FX_MODE_FADE] = &WS2812FX::mode_fade;
_mode[FX_MODE_THEATER_CHASE] = &WS2812FX::mode_theater_chase;
_mode[FX_MODE_THEATER_CHASE_RAINBOW] = &WS2812FX::mode_theater_chase_rainbow;
_mode[FX_MODE_TWINKLE] = &WS2812FX::mode_twinkle;
_mode[FX_MODE_TWINKLE_RANDOM] = &WS2812FX::mode_twinkle_random;
_mode[FX_MODE_TWINKLE_FADE] = &WS2812FX::mode_twinkle_fade;
_mode[FX_MODE_TWINKLE_FADE_RANDOM] = &WS2812FX::mode_twinkle_fade_random;
_mode[FX_MODE_SPARKLE] = &WS2812FX::mode_sparkle;
_mode[FX_MODE_FLASH_SPARKLE] = &WS2812FX::mode_flash_sparkle;
_mode[FX_MODE_HYPER_SPARKLE] = &WS2812FX::mode_hyper_sparkle;
_mode[FX_MODE_STROBE] = &WS2812FX::mode_strobe;
_mode[FX_MODE_STROBE_RAINBOW] = &WS2812FX::mode_strobe_rainbow;
_mode[FX_MODE_MULTI_STROBE] = &WS2812FX::mode_multi_strobe;
_mode[FX_MODE_BLINK_RAINBOW] = &WS2812FX::mode_blink_rainbow;
_mode[FX_MODE_CHASE_WHITE] = &WS2812FX::mode_chase_white;
_mode[FX_MODE_CHASE_COLOR] = &WS2812FX::mode_chase_color;
_mode[FX_MODE_CHASE_RANDOM] = &WS2812FX::mode_chase_random;
_mode[FX_MODE_CHASE_RAINBOW] = &WS2812FX::mode_chase_rainbow;
_mode[FX_MODE_CHASE_FLASH] = &WS2812FX::mode_chase_flash;
_mode[FX_MODE_CHASE_FLASH_RANDOM] = &WS2812FX::mode_chase_flash_random;
_mode[FX_MODE_CHASE_RAINBOW_WHITE] = &WS2812FX::mode_chase_rainbow_white;
_mode[FX_MODE_CHASE_BLACKOUT] = &WS2812FX::mode_chase_blackout;
_mode[FX_MODE_CHASE_BLACKOUT_RAINBOW] = &WS2812FX::mode_chase_blackout_rainbow;
_mode[FX_MODE_COLOR_SWEEP_RANDOM] = &WS2812FX::mode_color_sweep_random;
_mode[FX_MODE_RUNNING_COLOR] = &WS2812FX::mode_running_color;
_mode[FX_MODE_RUNNING_RED_BLUE] = &WS2812FX::mode_running_red_blue;
_mode[FX_MODE_RUNNING_RANDOM] = &WS2812FX::mode_running_random;
_mode[FX_MODE_LARSON_SCANNER] = &WS2812FX::mode_larson_scanner;
_mode[FX_MODE_COMET] = &WS2812FX::mode_comet;
_mode[FX_MODE_FIREWORKS] = &WS2812FX::mode_fireworks;
_mode[FX_MODE_FIREWORKS_RANDOM] = &WS2812FX::mode_fireworks_random;
_mode[FX_MODE_MERRY_CHRISTMAS] = &WS2812FX::mode_merry_christmas;
_mode[FX_MODE_FIRE_FLICKER] = &WS2812FX::mode_fire_flicker;
_mode[FX_MODE_FIRE_FLICKER_SOFT] = &WS2812FX::mode_fire_flicker_soft;
_mode[FX_MODE_FIRE_FLICKER_INTENSE] = &WS2812FX::mode_fire_flicker_intense;
_mode[FX_MODE_CIRCUS_COMBUSTUS] = &WS2812FX::mode_circus_combustus;
_mode[FX_MODE_HALLOWEEN] = &WS2812FX::mode_halloween;
_mode[FX_MODE_BICOLOR_CHASE] = &WS2812FX::mode_bicolor_chase;
_mode[FX_MODE_TRICOLOR_CHASE] = &WS2812FX::mode_tricolor_chase;
_mode[FX_MODE_BREATH] = &WS2812FX::mode_breath;
_mode[FX_MODE_RUNNING_LIGHTS] = &WS2812FX::mode_running_lights;
_mode[FX_MODE_CUSTOM_0] = &WS2812FX::mode_custom_0;
_mode[FX_MODE_CUSTOM_1] = &WS2812FX::mode_custom_1;
_mode[FX_MODE_CUSTOM_2] = &WS2812FX::mode_custom_2;
_mode[FX_MODE_CUSTOM_3] = &WS2812FX::mode_custom_3;
_mode[FX_MODE_CUSTOM_4] = &WS2812FX::mode_custom_4;
_mode[FX_MODE_CUSTOM_5] = &WS2812FX::mode_custom_5;
_mode[FX_MODE_CUSTOM_6] = &WS2812FX::mode_custom_6;
_mode[FX_MODE_CUSTOM_7] = &WS2812FX::mode_custom_7;

brightness = DEFAULT_BRIGHTNESS + 1; // Adafruit_NeoPixel internally offsets brightness by 1
_running = false;
Expand Down Expand Up @@ -637,8 +574,6 @@ typedef uint16_t (WS2812FX::*mode_ptr)(void);
_running,
_triggered;

mode_ptr _mode[MODE_COUNT]; // array of mode function pointers (4 bytes per element)

segment* _segments; // array of segments (20 bytes per element)
segment_runtime* _segment_runtimes; // array of segment runtimes (16 bytes per element)
uint8_t* _active_segments; // array of active segments (1 bytes per element)
Expand All @@ -653,4 +588,71 @@ typedef uint16_t (WS2812FX::*mode_ptr)(void);
uint16_t _seg_len; // num LEDs in the currently active segment
};

// define static array of member function pointers.
// function pointers MUST be in the same order as the corresponding name in the _name array.
static WS2812FX::mode_ptr _modes[MODE_COUNT] = {
&WS2812FX::mode_static,
&WS2812FX::mode_blink,
&WS2812FX::mode_breath,
&WS2812FX::mode_color_wipe,
&WS2812FX::mode_color_wipe_inv,
&WS2812FX::mode_color_wipe_rev,
&WS2812FX::mode_color_wipe_rev_inv,
&WS2812FX::mode_color_wipe_random,
&WS2812FX::mode_random_color,
&WS2812FX::mode_single_dynamic,
&WS2812FX::mode_multi_dynamic,
&WS2812FX::mode_rainbow,
&WS2812FX::mode_rainbow_cycle,
&WS2812FX::mode_scan,
&WS2812FX::mode_dual_scan,
&WS2812FX::mode_fade,
&WS2812FX::mode_theater_chase,
&WS2812FX::mode_theater_chase_rainbow,
&WS2812FX::mode_running_lights,
&WS2812FX::mode_twinkle,
&WS2812FX::mode_twinkle_random,
&WS2812FX::mode_twinkle_fade,
&WS2812FX::mode_twinkle_fade_random,
&WS2812FX::mode_sparkle,
&WS2812FX::mode_flash_sparkle,
&WS2812FX::mode_hyper_sparkle,
&WS2812FX::mode_strobe,
&WS2812FX::mode_strobe_rainbow,
&WS2812FX::mode_multi_strobe,
&WS2812FX::mode_blink_rainbow,
&WS2812FX::mode_chase_white,
&WS2812FX::mode_chase_color,
&WS2812FX::mode_chase_random,
&WS2812FX::mode_chase_rainbow,
&WS2812FX::mode_chase_flash,
&WS2812FX::mode_chase_flash_random,
&WS2812FX::mode_chase_rainbow_white,
&WS2812FX::mode_chase_blackout,
&WS2812FX::mode_chase_blackout_rainbow,
&WS2812FX::mode_color_sweep_random,
&WS2812FX::mode_running_color,
&WS2812FX::mode_running_red_blue,
&WS2812FX::mode_running_random,
&WS2812FX::mode_larson_scanner,
&WS2812FX::mode_comet,
&WS2812FX::mode_fireworks,
&WS2812FX::mode_fireworks_random,
&WS2812FX::mode_merry_christmas,
&WS2812FX::mode_fire_flicker,
&WS2812FX::mode_fire_flicker_soft,
&WS2812FX::mode_fire_flicker_intense,
&WS2812FX::mode_circus_combustus,
&WS2812FX::mode_halloween,
&WS2812FX::mode_bicolor_chase,
&WS2812FX::mode_tricolor_chase,
&WS2812FX::mode_custom_0,
&WS2812FX::mode_custom_1,
&WS2812FX::mode_custom_2,
&WS2812FX::mode_custom_3,
&WS2812FX::mode_custom_4,
&WS2812FX::mode_custom_5,
&WS2812FX::mode_custom_6,
&WS2812FX::mode_custom_7
};
#endif

0 comments on commit 41936b8

Please sign in to comment.