mirror of
https://github.com/bbulkow/FastLED-idf.git
synced 2025-07-30 10:48:06 +02:00
Add the WS2812FX pattern library.
This commit is contained in:
29
README.md
29
README.md
@ -1,4 +1,4 @@
|
|||||||
# FastLED-idf
|
# FastLED-idf & Patterns
|
||||||
|
|
||||||
# TL;DR
|
# TL;DR
|
||||||
|
|
||||||
@ -8,6 +8,8 @@ MASSIVE UPDATE Sept 4, 2020. Even after porting Sam Guyer's branch in July, I st
|
|||||||
had a huge amount of visual artifacts. I've done a huge analysis and have licked the issue to my
|
had a huge amount of visual artifacts. I've done a huge analysis and have licked the issue to my
|
||||||
satisfaction, and can say the system simply doesn't glitch.
|
satisfaction, and can say the system simply doesn't glitch.
|
||||||
|
|
||||||
|
UPDATE 2 Sept 11, 2020. Added the WS2812FX pattern library, see below.
|
||||||
|
|
||||||
There are some new tunables, and if you're also fighting glitches, you need to read `components/FastLED-idf/ESP-IDF.md`.
|
There are some new tunables, and if you're also fighting glitches, you need to read `components/FastLED-idf/ESP-IDF.md`.
|
||||||
|
|
||||||
Note you must use the ESP-IDF environment, and the ESP-IDF build system. That's how the paths and whatnot are created.
|
Note you must use the ESP-IDF environment, and the ESP-IDF build system. That's how the paths and whatnot are created.
|
||||||
@ -45,6 +47,12 @@ changing the duty cycle and brightness, it doesn't control color-controlled LEDs
|
|||||||
|
|
||||||
Thus, we need FastLED
|
Thus, we need FastLED
|
||||||
|
|
||||||
|
# WS8212FX
|
||||||
|
|
||||||
|
Playing around, there are "a lot of nice libraries on FastLED", but each and every one of them
|
||||||
|
requires porting. At least, now there's a single one to start with. See the underlying component,
|
||||||
|
and use it or not. If you don't want it, just don't bring that component over into your project.
|
||||||
|
|
||||||
# TL;DR about this repo
|
# TL;DR about this repo
|
||||||
|
|
||||||
As with any ESP-IDF project, there is a sdkconfig file. It contains things that might
|
As with any ESP-IDF project, there is a sdkconfig file. It contains things that might
|
||||||
@ -57,9 +65,9 @@ contradictory, the one in this repo matches "current" master, with a 4.0, 4.1, a
|
|||||||
If you'd like to test my starting point, copy the correct one over to sdkconfig and
|
If you'd like to test my starting point, copy the correct one over to sdkconfig and
|
||||||
give it a try.
|
give it a try.
|
||||||
|
|
||||||
I've read scary stuff about Rev0 and GPIO. You have to insert a number of NOP statements
|
For master, either use the standard `sdkconfig` or build your own. Remove this one,
|
||||||
between bangs of the pins. If you're using that version, you might want to look carefully
|
and `idf.py menuconfig`, and set whatever paramenters you need. There is
|
||||||
into the issue.
|
nothing in this library that's specific to any particular version.
|
||||||
|
|
||||||
# a note about level shifting
|
# a note about level shifting
|
||||||
|
|
||||||
@ -117,7 +125,7 @@ and the RMT interface doesn't do that. What does do that is the SPI
|
|||||||
interface, and I don't think I've wired that up.
|
interface, and I don't think I've wired that up.
|
||||||
|
|
||||||
There are two hardware SPI ports in the system, so that should be
|
There are two hardware SPI ports in the system, so that should be
|
||||||
able to be enabled. I haven't tried that.
|
able to be enabled. Work to do.
|
||||||
|
|
||||||
Since hardware banging is used ( that's the big ugly warning ),
|
Since hardware banging is used ( that's the big ugly warning ),
|
||||||
these LEDs are very likely far slower, and probably do not respond to parallelism
|
these LEDs are very likely far slower, and probably do not respond to parallelism
|
||||||
@ -226,12 +234,13 @@ In their forums, they said they don't intend to do anything like that.
|
|||||||
|
|
||||||
According to a reddit post, someone named Sam Guyer fixed the issues with FastLED. There are
|
According to a reddit post, someone named Sam Guyer fixed the issues with FastLED. There are
|
||||||
a number of fundamental problems that Sam has been gnawing on, notably the access to flash
|
a number of fundamental problems that Sam has been gnawing on, notably the access to flash
|
||||||
that happens when you 'read files'.
|
that happens when you 'read files'. His fork was my starting point.
|
||||||
|
|
||||||
However, Sam found the truely important thing: that the built-in interrupt handler
|
However, I found that the primarily issue with visual artifacts in RMT had to do with
|
||||||
wasn't working, because the use of templates obscured the IRAM_ATTR attribute. Which
|
the amount of ESP-IDF jitter.
|
||||||
means the "fast interrupt routing" to shovel bits into RMT was running out of executable
|
|
||||||
flash, not out of RAM, so of course it wouldn't keep up.
|
Kudos to Sam for getting the code to a better point, where it was amenable to the optimizations
|
||||||
|
I did.
|
||||||
|
|
||||||
https://github.com/samguyer/FastLED
|
https://github.com/samguyer/FastLED
|
||||||
|
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
#ifndef __INC_LIB8TION_H
|
#ifndef __INC_LIB8TION_H
|
||||||
#define __INC_LIB8TION_H
|
#define __INC_LIB8TION_H
|
||||||
|
|
||||||
|
/* defines get_millis() */
|
||||||
|
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "esp_timer.h"
|
||||||
|
|
||||||
#include "FastLED.h"
|
#include "FastLED.h"
|
||||||
|
|
||||||
#ifndef __INC_LED_SYSDEFS_H
|
#ifndef __INC_LED_SYSDEFS_H
|
||||||
@ -915,16 +920,13 @@ typedef q<uint16_t, 12,4> q124;
|
|||||||
// need to provide a function with this signature:
|
// need to provide a function with this signature:
|
||||||
// uint32_t get_millisecond_timer();
|
// uint32_t get_millisecond_timer();
|
||||||
// that provides similar functionality.
|
// that provides similar functionality.
|
||||||
// You can also force use of the get_millisecond_timer function
|
//
|
||||||
// by #defining USE_GET_MILLISECOND_TIMER.
|
// On ESP-IDF we have esp_timer_get_time which has microseconds.
|
||||||
#if (defined(ARDUINO) || defined(SPARK) || defined(FASTLED_HAS_MILLIS)) && !defined(USE_GET_MILLISECOND_TIMER)
|
// It's a little expensive to get micros and divide, but.... good for now and later we'll
|
||||||
// Forward declaration of Arduino function 'millis'.
|
// fix that uses it
|
||||||
//uint32_t millis();
|
|
||||||
#define GET_MILLIS millis
|
#define GET_MILLIS() (get_millisecond_timer())
|
||||||
#else
|
static inline uint32_t get_millisecond_timer() { return( esp_timer_get_time() / 1000); }
|
||||||
uint32_t get_millisecond_timer();
|
|
||||||
#define GET_MILLIS get_millisecond_timer
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// beat16 generates a 16-bit 'sawtooth' wave at a given BPM,
|
// beat16 generates a 16-bit 'sawtooth' wave at a given BPM,
|
||||||
/// with BPM specified in Q8.8 fixed-point format; e.g.
|
/// with BPM specified in Q8.8 fixed-point format; e.g.
|
||||||
|
14
components/WS2812FX-idf/CMakeLists.txt
Normal file
14
components/WS2812FX-idf/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
set(srcs
|
||||||
|
"FX.cpp"
|
||||||
|
"FX_fcn.cpp"
|
||||||
|
)
|
||||||
|
|
||||||
|
# everything needs the ESP32 flag, not sure why this won't work
|
||||||
|
# going to hack by adding the ESP32 define in the h file
|
||||||
|
#`target_compile_options(${COMPONENT_LIB} PRIVATE "-DESP32")
|
||||||
|
|
||||||
|
idf_component_register(SRCS "${srcs}"
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
REQUIRES FastLED-idf )
|
3722
components/WS2812FX-idf/FX.cpp
Normal file
3722
components/WS2812FX-idf/FX.cpp
Normal file
File diff suppressed because it is too large
Load Diff
746
components/WS2812FX-idf/FX.h
Normal file
746
components/WS2812FX-idf/FX.h
Normal file
@ -0,0 +1,746 @@
|
|||||||
|
/*
|
||||||
|
WS2812FX.h - Library for WS2812 LED effects.
|
||||||
|
Harm Aldick - 2016
|
||||||
|
www.aldick.org
|
||||||
|
LICENSE
|
||||||
|
The MIT License (MIT)
|
||||||
|
Copyright (c) 2016 Harm Aldick
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to dealf
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, 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.
|
||||||
|
|
||||||
|
Modified for WLED
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WS2812FX_h
|
||||||
|
#define WS2812FX_h
|
||||||
|
|
||||||
|
|
||||||
|
#define USE_GET_MILLISECOND_TIMER
|
||||||
|
|
||||||
|
#include "FastLED.h"
|
||||||
|
|
||||||
|
// byte exists as std::byte, but that's not included here
|
||||||
|
typedef uint8_t byte;
|
||||||
|
|
||||||
|
#define DEFAULT_BRIGHTNESS (uint8_t)127
|
||||||
|
#define DEFAULT_MODE (uint8_t)0
|
||||||
|
#define DEFAULT_SPEED (uint8_t)128
|
||||||
|
#define DEFAULT_COLOR (uint32_t)0xFFAA00
|
||||||
|
|
||||||
|
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||||
|
#define MAX(a,b) ((a)>(b)?(a):(b))
|
||||||
|
|
||||||
|
// the arduino 'map' has nothing to do with std::map :-/
|
||||||
|
#define ArduinoMap(v, s1, e1, s2, e2) \
|
||||||
|
( s2 + (e2 - s2) * ((v - s1) / (e1 - s1) ) )
|
||||||
|
#define ArduinoConstrain(amt,low,high) \
|
||||||
|
((amt) < (low) ? (low) : ( (amt)>(high) ? (high) : (amt) ) )
|
||||||
|
#define ArduinoBitRead(value, bit) \
|
||||||
|
(((value) >> (bit)) & 0x01)
|
||||||
|
#define ArduinoBitSet(value, bit) \
|
||||||
|
((value) |= (1UL << (bit)))
|
||||||
|
#define ArduinoBitClear(value, bit) \
|
||||||
|
((value) &= ~(1UL << (bit)))
|
||||||
|
#define ArduinoBitWrite(value, bit, bitvalue) \
|
||||||
|
( bitvalue ? ArduinoBitSet(value, bit) : ArduinoBitClear(value, bit) )
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t getColorCode(const CRGB &c);
|
||||||
|
|
||||||
|
/* Not used in all effects yet */
|
||||||
|
#define FX_FPS 42
|
||||||
|
#define FRAMETIME (1000/FX_FPS)
|
||||||
|
|
||||||
|
/* each segment uses 52 bytes of SRAM memory, so if you're application fails because of
|
||||||
|
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
||||||
|
#define MAX_NUM_SEGMENTS 10
|
||||||
|
|
||||||
|
/* How much data bytes all segments combined may allocate */
|
||||||
|
#ifdef ESP8266
|
||||||
|
#define MAX_SEGMENT_DATA 2048
|
||||||
|
#else
|
||||||
|
#define MAX_SEGMENT_DATA 8192
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LED_SKIP_AMOUNT 1
|
||||||
|
#define MIN_SHOW_DELAY 15
|
||||||
|
|
||||||
|
#define NUM_COLORS 3 /* number of colors per segment */
|
||||||
|
#define SEGMENT _segments[_segment_index]
|
||||||
|
#define SEGCOLOR(x) gamma32(_segments[_segment_index].colors[x])
|
||||||
|
#define SEGENV _segment_runtimes[_segment_index]
|
||||||
|
#define SEGLEN _virtualSegmentLength
|
||||||
|
#define SEGACT SEGMENT.stop
|
||||||
|
#define SPEED_FORMULA_L 5 + (50*(255 - SEGMENT.speed))/SEGLEN
|
||||||
|
#define RESET_RUNTIME memset(_segment_runtimes, 0, sizeof(_segment_runtimes))
|
||||||
|
|
||||||
|
// some common colors
|
||||||
|
#define RED (uint32_t)0xFF0000
|
||||||
|
#define GREEN (uint32_t)0x00FF00
|
||||||
|
#define BLUE (uint32_t)0x0000FF
|
||||||
|
#define WHITE (uint32_t)0xFFFFFF
|
||||||
|
#define BLACK (uint32_t)0x000000
|
||||||
|
#define YELLOW (uint32_t)0xFFFF00
|
||||||
|
#define CYAN (uint32_t)0x00FFFF
|
||||||
|
#define MAGENTA (uint32_t)0xFF00FF
|
||||||
|
#define PURPLE (uint32_t)0x400080
|
||||||
|
#define ORANGE (uint32_t)0xFF3000
|
||||||
|
#define PINK (uint32_t)0xFF1493
|
||||||
|
#define ULTRAWHITE (uint32_t)0xFFFFFFFF
|
||||||
|
|
||||||
|
// options
|
||||||
|
// bit 7: segment is in transition mode
|
||||||
|
// bits 4-6: TBD
|
||||||
|
// bit 3: mirror effect within segment
|
||||||
|
// bit 2: segment is on
|
||||||
|
// bit 1: reverse segment
|
||||||
|
// bit 0: segment is selected
|
||||||
|
#define NO_OPTIONS (uint8_t)0x00
|
||||||
|
#define TRANSITIONAL (uint8_t)0x80
|
||||||
|
#define MIRROR (uint8_t)0x08
|
||||||
|
#define SEGMENT_ON (uint8_t)0x04
|
||||||
|
#define REVERSE (uint8_t)0x02
|
||||||
|
#define SELECTED (uint8_t)0x01
|
||||||
|
#define IS_TRANSITIONAL ((SEGMENT.options & TRANSITIONAL) == TRANSITIONAL)
|
||||||
|
#define IS_MIRROR ((SEGMENT.options & MIRROR ) == MIRROR )
|
||||||
|
#define IS_SEGMENT_ON ((SEGMENT.options & SEGMENT_ON ) == SEGMENT_ON )
|
||||||
|
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
|
||||||
|
#define IS_SELECTED ((SEGMENT.options & SELECTED ) == SELECTED )
|
||||||
|
|
||||||
|
#define MODE_COUNT 113
|
||||||
|
|
||||||
|
#define FX_MODE_STATIC 0
|
||||||
|
#define FX_MODE_BLINK 1
|
||||||
|
#define FX_MODE_BREATH 2
|
||||||
|
#define FX_MODE_COLOR_WIPE 3
|
||||||
|
#define FX_MODE_COLOR_WIPE_RANDOM 4
|
||||||
|
#define FX_MODE_RANDOM_COLOR 5
|
||||||
|
#define FX_MODE_COLOR_SWEEP 6
|
||||||
|
#define FX_MODE_DYNAMIC 7
|
||||||
|
#define FX_MODE_RAINBOW 8
|
||||||
|
#define FX_MODE_RAINBOW_CYCLE 9
|
||||||
|
#define FX_MODE_SCAN 10
|
||||||
|
#define FX_MODE_DUAL_SCAN 11
|
||||||
|
#define FX_MODE_FADE 12
|
||||||
|
#define FX_MODE_THEATER_CHASE 13
|
||||||
|
#define FX_MODE_THEATER_CHASE_RAINBOW 14
|
||||||
|
#define FX_MODE_RUNNING_LIGHTS 15
|
||||||
|
#define FX_MODE_SAW 16
|
||||||
|
#define FX_MODE_TWINKLE 17
|
||||||
|
#define FX_MODE_DISSOLVE 18
|
||||||
|
#define FX_MODE_DISSOLVE_RANDOM 19
|
||||||
|
#define FX_MODE_SPARKLE 20
|
||||||
|
#define FX_MODE_FLASH_SPARKLE 21
|
||||||
|
#define FX_MODE_HYPER_SPARKLE 22
|
||||||
|
#define FX_MODE_STROBE 23
|
||||||
|
#define FX_MODE_STROBE_RAINBOW 24
|
||||||
|
#define FX_MODE_MULTI_STROBE 25
|
||||||
|
#define FX_MODE_BLINK_RAINBOW 26
|
||||||
|
#define FX_MODE_ANDROID 27
|
||||||
|
#define FX_MODE_CHASE_COLOR 28
|
||||||
|
#define FX_MODE_CHASE_RANDOM 29
|
||||||
|
#define FX_MODE_CHASE_RAINBOW 30
|
||||||
|
#define FX_MODE_CHASE_FLASH 31
|
||||||
|
#define FX_MODE_CHASE_FLASH_RANDOM 32
|
||||||
|
#define FX_MODE_CHASE_RAINBOW_WHITE 33
|
||||||
|
#define FX_MODE_COLORFUL 34
|
||||||
|
#define FX_MODE_TRAFFIC_LIGHT 35
|
||||||
|
#define FX_MODE_COLOR_SWEEP_RANDOM 36
|
||||||
|
#define FX_MODE_RUNNING_COLOR 37
|
||||||
|
#define FX_MODE_RUNNING_RED_BLUE 38
|
||||||
|
#define FX_MODE_RUNNING_RANDOM 39
|
||||||
|
#define FX_MODE_LARSON_SCANNER 40
|
||||||
|
#define FX_MODE_COMET 41
|
||||||
|
#define FX_MODE_FIREWORKS 42
|
||||||
|
#define FX_MODE_RAIN 43
|
||||||
|
#define FX_MODE_MERRY_CHRISTMAS 44
|
||||||
|
#define FX_MODE_FIRE_FLICKER 45
|
||||||
|
#define FX_MODE_GRADIENT 46
|
||||||
|
#define FX_MODE_LOADING 47
|
||||||
|
#define FX_MODE_POLICE 48
|
||||||
|
#define FX_MODE_POLICE_ALL 49
|
||||||
|
#define FX_MODE_TWO_DOTS 50
|
||||||
|
#define FX_MODE_TWO_AREAS 51
|
||||||
|
#define FX_MODE_CIRCUS_COMBUSTUS 52
|
||||||
|
#define FX_MODE_HALLOWEEN 53
|
||||||
|
#define FX_MODE_TRICOLOR_CHASE 54
|
||||||
|
#define FX_MODE_TRICOLOR_WIPE 55
|
||||||
|
#define FX_MODE_TRICOLOR_FADE 56
|
||||||
|
#define FX_MODE_LIGHTNING 57
|
||||||
|
#define FX_MODE_ICU 58
|
||||||
|
#define FX_MODE_MULTI_COMET 59
|
||||||
|
#define FX_MODE_DUAL_LARSON_SCANNER 60
|
||||||
|
#define FX_MODE_RANDOM_CHASE 61
|
||||||
|
#define FX_MODE_OSCILLATE 62
|
||||||
|
#define FX_MODE_PRIDE_2015 63
|
||||||
|
#define FX_MODE_JUGGLE 64
|
||||||
|
#define FX_MODE_PALETTE 65
|
||||||
|
#define FX_MODE_FIRE_2012 66
|
||||||
|
#define FX_MODE_COLORWAVES 67
|
||||||
|
#define FX_MODE_BPM 68
|
||||||
|
#define FX_MODE_FILLNOISE8 69
|
||||||
|
#define FX_MODE_NOISE16_1 70
|
||||||
|
#define FX_MODE_NOISE16_2 71
|
||||||
|
#define FX_MODE_NOISE16_3 72
|
||||||
|
#define FX_MODE_NOISE16_4 73
|
||||||
|
#define FX_MODE_COLORTWINKLE 74
|
||||||
|
#define FX_MODE_LAKE 75
|
||||||
|
#define FX_MODE_METEOR 76
|
||||||
|
#define FX_MODE_METEOR_SMOOTH 77
|
||||||
|
#define FX_MODE_RAILWAY 78
|
||||||
|
#define FX_MODE_RIPPLE 79
|
||||||
|
#define FX_MODE_TWINKLEFOX 80
|
||||||
|
#define FX_MODE_TWINKLECAT 81
|
||||||
|
#define FX_MODE_HALLOWEEN_EYES 82
|
||||||
|
#define FX_MODE_STATIC_PATTERN 83
|
||||||
|
#define FX_MODE_TRI_STATIC_PATTERN 84
|
||||||
|
#define FX_MODE_SPOTS 85
|
||||||
|
#define FX_MODE_SPOTS_FADE 86
|
||||||
|
#define FX_MODE_GLITTER 87
|
||||||
|
#define FX_MODE_CANDLE 88
|
||||||
|
#define FX_MODE_STARBURST 89
|
||||||
|
#define FX_MODE_EXPLODING_FIREWORKS 90
|
||||||
|
#define FX_MODE_BOUNCINGBALLS 91
|
||||||
|
#define FX_MODE_SINELON 92
|
||||||
|
#define FX_MODE_SINELON_DUAL 93
|
||||||
|
#define FX_MODE_SINELON_RAINBOW 94
|
||||||
|
#define FX_MODE_POPCORN 95
|
||||||
|
#define FX_MODE_DRIP 96
|
||||||
|
#define FX_MODE_PLASMA 97
|
||||||
|
#define FX_MODE_PERCENT 98
|
||||||
|
#define FX_MODE_RIPPLE_RAINBOW 99
|
||||||
|
#define FX_MODE_HEARTBEAT 100
|
||||||
|
#define FX_MODE_PACIFICA 101
|
||||||
|
#define FX_MODE_CANDLE_MULTI 102
|
||||||
|
#define FX_MODE_SOLID_GLITTER 103
|
||||||
|
#define FX_MODE_SUNRISE 104
|
||||||
|
#define FX_MODE_PHASED 105
|
||||||
|
#define FX_MODE_TWINKLEUP 106
|
||||||
|
#define FX_MODE_NOISEPAL 107
|
||||||
|
#define FX_MODE_SINEWAVE 108
|
||||||
|
#define FX_MODE_PHASEDNOISE 109
|
||||||
|
#define FX_MODE_FLOW 110
|
||||||
|
#define FX_MODE_CHUNCHUN 111
|
||||||
|
#define FX_MODE_DANCING_SHADOWS 112
|
||||||
|
|
||||||
|
class WS2812FX {
|
||||||
|
typedef uint16_t (WS2812FX::*mode_ptr)(void);
|
||||||
|
|
||||||
|
// pre show callback
|
||||||
|
typedef void (*show_callback) (void);
|
||||||
|
|
||||||
|
// segment parameters
|
||||||
|
public:
|
||||||
|
typedef struct Segment { // 24 bytes
|
||||||
|
uint16_t start;
|
||||||
|
uint16_t stop; //segment invalid if stop == 0
|
||||||
|
uint8_t speed;
|
||||||
|
uint8_t intensity;
|
||||||
|
uint8_t palette;
|
||||||
|
uint8_t mode;
|
||||||
|
uint8_t options; //bit pattern: msb first: transitional needspixelstate tbd tbd (paused) on reverse selected
|
||||||
|
uint8_t grouping, spacing;
|
||||||
|
uint8_t opacity;
|
||||||
|
uint32_t colors[NUM_COLORS];
|
||||||
|
void setOption(uint8_t n, bool val)
|
||||||
|
{
|
||||||
|
if (val) {
|
||||||
|
options |= 0x01 << n;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
options &= ~(0x01 << n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool getOption(uint8_t n)
|
||||||
|
{
|
||||||
|
return ((options >> n) & 0x01);
|
||||||
|
}
|
||||||
|
bool isSelected()
|
||||||
|
{
|
||||||
|
return getOption(0);
|
||||||
|
}
|
||||||
|
bool isActive()
|
||||||
|
{
|
||||||
|
return stop > start;
|
||||||
|
}
|
||||||
|
uint16_t length()
|
||||||
|
{
|
||||||
|
return stop - start;
|
||||||
|
}
|
||||||
|
uint16_t groupLength()
|
||||||
|
{
|
||||||
|
return grouping + spacing;
|
||||||
|
}
|
||||||
|
uint16_t virtualLength()
|
||||||
|
{
|
||||||
|
uint16_t groupLen = groupLength();
|
||||||
|
uint16_t vLength = (length() + groupLen - 1) / groupLen;
|
||||||
|
if (options & MIRROR)
|
||||||
|
vLength = (vLength + 1) /2; // divide by 2 if mirror, leave at least a single LED
|
||||||
|
return vLength;
|
||||||
|
}
|
||||||
|
} segment;
|
||||||
|
|
||||||
|
// segment runtime parameters
|
||||||
|
typedef struct Segment_runtime { // 28 bytes
|
||||||
|
unsigned long next_time;
|
||||||
|
uint32_t step;
|
||||||
|
uint32_t call;
|
||||||
|
uint16_t aux0;
|
||||||
|
uint16_t aux1;
|
||||||
|
// what is data? patterns often want a byte of per-pixel data, although they don't need it
|
||||||
|
uint8_t * data = nullptr;
|
||||||
|
bool allocateData(uint16_t len){
|
||||||
|
if (data && _dataLen == len) return true; //already allocated
|
||||||
|
deallocateData();
|
||||||
|
if (WS2812FX::_usedSegmentData + len > MAX_SEGMENT_DATA) return false; //not enough memory
|
||||||
|
data = (uint8_t *) malloc((size_t)len); // don't need nothrow, really
|
||||||
|
if (!data) return false; //allocation failed
|
||||||
|
WS2812FX::_usedSegmentData += len;
|
||||||
|
_dataLen = len;
|
||||||
|
memset(data, 0, len);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void deallocateData(){
|
||||||
|
delete[] data;
|
||||||
|
data = nullptr;
|
||||||
|
WS2812FX::_usedSegmentData -= _dataLen;
|
||||||
|
_dataLen = 0;
|
||||||
|
}
|
||||||
|
void reset(){next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0; deallocateData();}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint16_t _dataLen = 0;
|
||||||
|
} segment_runtime;
|
||||||
|
|
||||||
|
WS2812FX() {
|
||||||
|
//assign each member of the _mode[] array to its respective function reference
|
||||||
|
_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_RANDOM] = &WS2812FX::mode_color_wipe_random;
|
||||||
|
_mode[FX_MODE_RANDOM_COLOR] = &WS2812FX::mode_random_color;
|
||||||
|
_mode[FX_MODE_COLOR_SWEEP] = &WS2812FX::mode_color_sweep;
|
||||||
|
_mode[FX_MODE_DYNAMIC] = &WS2812FX::mode_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_SAW] = &WS2812FX::mode_saw;
|
||||||
|
_mode[FX_MODE_TWINKLE] = &WS2812FX::mode_twinkle;
|
||||||
|
_mode[FX_MODE_DISSOLVE] = &WS2812FX::mode_dissolve;
|
||||||
|
_mode[FX_MODE_DISSOLVE_RANDOM] = &WS2812FX::mode_dissolve_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_ANDROID] = &WS2812FX::mode_android;
|
||||||
|
_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_COLORFUL] = &WS2812FX::mode_colorful;
|
||||||
|
_mode[FX_MODE_TRAFFIC_LIGHT] = &WS2812FX::mode_traffic_light;
|
||||||
|
_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_RAIN] = &WS2812FX::mode_rain;
|
||||||
|
_mode[FX_MODE_MERRY_CHRISTMAS] = &WS2812FX::mode_merry_christmas;
|
||||||
|
_mode[FX_MODE_FIRE_FLICKER] = &WS2812FX::mode_fire_flicker;
|
||||||
|
_mode[FX_MODE_GRADIENT] = &WS2812FX::mode_gradient;
|
||||||
|
_mode[FX_MODE_LOADING] = &WS2812FX::mode_loading;
|
||||||
|
_mode[FX_MODE_POLICE] = &WS2812FX::mode_police;
|
||||||
|
_mode[FX_MODE_POLICE_ALL] = &WS2812FX::mode_police_all;
|
||||||
|
_mode[FX_MODE_TWO_DOTS] = &WS2812FX::mode_two_dots;
|
||||||
|
_mode[FX_MODE_TWO_AREAS] = &WS2812FX::mode_two_areas;
|
||||||
|
_mode[FX_MODE_CIRCUS_COMBUSTUS] = &WS2812FX::mode_circus_combustus;
|
||||||
|
_mode[FX_MODE_HALLOWEEN] = &WS2812FX::mode_halloween;
|
||||||
|
_mode[FX_MODE_TRICOLOR_CHASE] = &WS2812FX::mode_tricolor_chase;
|
||||||
|
_mode[FX_MODE_TRICOLOR_WIPE] = &WS2812FX::mode_tricolor_wipe;
|
||||||
|
_mode[FX_MODE_TRICOLOR_FADE] = &WS2812FX::mode_tricolor_fade;
|
||||||
|
_mode[FX_MODE_BREATH] = &WS2812FX::mode_breath;
|
||||||
|
_mode[FX_MODE_RUNNING_LIGHTS] = &WS2812FX::mode_running_lights;
|
||||||
|
_mode[FX_MODE_LIGHTNING] = &WS2812FX::mode_lightning;
|
||||||
|
_mode[FX_MODE_ICU] = &WS2812FX::mode_icu;
|
||||||
|
_mode[FX_MODE_MULTI_COMET] = &WS2812FX::mode_multi_comet;
|
||||||
|
_mode[FX_MODE_DUAL_LARSON_SCANNER] = &WS2812FX::mode_dual_larson_scanner;
|
||||||
|
_mode[FX_MODE_RANDOM_CHASE] = &WS2812FX::mode_random_chase;
|
||||||
|
_mode[FX_MODE_OSCILLATE] = &WS2812FX::mode_oscillate;
|
||||||
|
_mode[FX_MODE_FIRE_2012] = &WS2812FX::mode_fire_2012;
|
||||||
|
_mode[FX_MODE_PRIDE_2015] = &WS2812FX::mode_pride_2015;
|
||||||
|
_mode[FX_MODE_BPM] = &WS2812FX::mode_bpm;
|
||||||
|
_mode[FX_MODE_JUGGLE] = &WS2812FX::mode_juggle;
|
||||||
|
_mode[FX_MODE_PALETTE] = &WS2812FX::mode_palette;
|
||||||
|
_mode[FX_MODE_COLORWAVES] = &WS2812FX::mode_colorwaves;
|
||||||
|
_mode[FX_MODE_FILLNOISE8] = &WS2812FX::mode_fillnoise8;
|
||||||
|
_mode[FX_MODE_NOISE16_1] = &WS2812FX::mode_noise16_1;
|
||||||
|
_mode[FX_MODE_NOISE16_2] = &WS2812FX::mode_noise16_2;
|
||||||
|
_mode[FX_MODE_NOISE16_3] = &WS2812FX::mode_noise16_3;
|
||||||
|
_mode[FX_MODE_NOISE16_4] = &WS2812FX::mode_noise16_4;
|
||||||
|
_mode[FX_MODE_COLORTWINKLE] = &WS2812FX::mode_colortwinkle;
|
||||||
|
_mode[FX_MODE_LAKE] = &WS2812FX::mode_lake;
|
||||||
|
_mode[FX_MODE_METEOR] = &WS2812FX::mode_meteor;
|
||||||
|
_mode[FX_MODE_METEOR_SMOOTH] = &WS2812FX::mode_meteor_smooth;
|
||||||
|
_mode[FX_MODE_RAILWAY] = &WS2812FX::mode_railway;
|
||||||
|
_mode[FX_MODE_RIPPLE] = &WS2812FX::mode_ripple;
|
||||||
|
_mode[FX_MODE_TWINKLEFOX] = &WS2812FX::mode_twinklefox;
|
||||||
|
_mode[FX_MODE_TWINKLECAT] = &WS2812FX::mode_twinklecat;
|
||||||
|
_mode[FX_MODE_HALLOWEEN_EYES] = &WS2812FX::mode_halloween_eyes;
|
||||||
|
_mode[FX_MODE_STATIC_PATTERN] = &WS2812FX::mode_static_pattern;
|
||||||
|
_mode[FX_MODE_TRI_STATIC_PATTERN] = &WS2812FX::mode_tri_static_pattern;
|
||||||
|
_mode[FX_MODE_SPOTS] = &WS2812FX::mode_spots;
|
||||||
|
_mode[FX_MODE_SPOTS_FADE] = &WS2812FX::mode_spots_fade;
|
||||||
|
_mode[FX_MODE_GLITTER] = &WS2812FX::mode_glitter;
|
||||||
|
_mode[FX_MODE_CANDLE] = &WS2812FX::mode_candle;
|
||||||
|
_mode[FX_MODE_STARBURST] = &WS2812FX::mode_starburst;
|
||||||
|
_mode[FX_MODE_EXPLODING_FIREWORKS] = &WS2812FX::mode_exploding_fireworks;
|
||||||
|
_mode[FX_MODE_BOUNCINGBALLS] = &WS2812FX::mode_bouncing_balls;
|
||||||
|
_mode[FX_MODE_SINELON] = &WS2812FX::mode_sinelon;
|
||||||
|
_mode[FX_MODE_SINELON_DUAL] = &WS2812FX::mode_sinelon_dual;
|
||||||
|
_mode[FX_MODE_SINELON_RAINBOW] = &WS2812FX::mode_sinelon_rainbow;
|
||||||
|
_mode[FX_MODE_POPCORN] = &WS2812FX::mode_popcorn;
|
||||||
|
_mode[FX_MODE_DRIP] = &WS2812FX::mode_drip;
|
||||||
|
_mode[FX_MODE_PLASMA] = &WS2812FX::mode_plasma;
|
||||||
|
_mode[FX_MODE_PERCENT] = &WS2812FX::mode_percent;
|
||||||
|
_mode[FX_MODE_RIPPLE_RAINBOW] = &WS2812FX::mode_ripple_rainbow;
|
||||||
|
_mode[FX_MODE_HEARTBEAT] = &WS2812FX::mode_heartbeat;
|
||||||
|
_mode[FX_MODE_PACIFICA] = &WS2812FX::mode_pacifica;
|
||||||
|
_mode[FX_MODE_CANDLE_MULTI] = &WS2812FX::mode_candle_multi;
|
||||||
|
_mode[FX_MODE_SOLID_GLITTER] = &WS2812FX::mode_solid_glitter;
|
||||||
|
_mode[FX_MODE_SUNRISE] = &WS2812FX::mode_sunrise;
|
||||||
|
_mode[FX_MODE_PHASED] = &WS2812FX::mode_phased;
|
||||||
|
_mode[FX_MODE_TWINKLEUP] = &WS2812FX::mode_twinkleup;
|
||||||
|
_mode[FX_MODE_NOISEPAL] = &WS2812FX::mode_noisepal;
|
||||||
|
_mode[FX_MODE_SINEWAVE] = &WS2812FX::mode_sinewave;
|
||||||
|
_mode[FX_MODE_PHASEDNOISE] = &WS2812FX::mode_phased_noise;
|
||||||
|
_mode[FX_MODE_FLOW] = &WS2812FX::mode_flow;
|
||||||
|
_mode[FX_MODE_CHUNCHUN] = &WS2812FX::mode_chunchun;
|
||||||
|
_mode[FX_MODE_DANCING_SHADOWS] = &WS2812FX::mode_dancing_shadows;
|
||||||
|
|
||||||
|
_brightness = DEFAULT_BRIGHTNESS;
|
||||||
|
currentPalette = CRGBPalette16(CRGB::Black);
|
||||||
|
targetPalette = CloudColors_p;
|
||||||
|
ablMilliampsMax = 850;
|
||||||
|
currentMilliamps = 0;
|
||||||
|
timebase = 0;
|
||||||
|
|
||||||
|
resetSegments();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
init(uint16_t countPixels, CRGB *leds, bool skipFirst),
|
||||||
|
service(void),
|
||||||
|
blur(uint8_t),
|
||||||
|
fill(uint32_t),
|
||||||
|
fade_out(uint8_t r),
|
||||||
|
setMode(uint8_t segid, uint8_t m),
|
||||||
|
setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b),
|
||||||
|
setColor(uint8_t slot, uint32_t c),
|
||||||
|
setBrightness(uint8_t b),
|
||||||
|
setRange(uint16_t i, uint16_t i2, uint32_t col),
|
||||||
|
setShowCallback(show_callback cb),
|
||||||
|
setTransitionMode(bool t),
|
||||||
|
trigger(void),
|
||||||
|
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t grouping = 0, uint8_t spacing = 0),
|
||||||
|
resetSegments(),
|
||||||
|
setPixelColor(uint16_t n, uint32_t c),
|
||||||
|
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b),
|
||||||
|
show(void),
|
||||||
|
setRgbwPwm(void),
|
||||||
|
setPixelSegment(uint8_t n);
|
||||||
|
|
||||||
|
bool
|
||||||
|
reverseMode = false, //is the entire LED strip reversed?
|
||||||
|
gammaCorrectBri = false,
|
||||||
|
gammaCorrectCol = true,
|
||||||
|
applyToAllSelected = true,
|
||||||
|
segmentsAreIdentical(Segment* a, Segment* b),
|
||||||
|
setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p);
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
mainSegment = 0,
|
||||||
|
paletteFade = 0,
|
||||||
|
paletteBlend = 0,
|
||||||
|
colorOrder = 0,
|
||||||
|
milliampsPerLed = 55,
|
||||||
|
getBrightness(void),
|
||||||
|
getMode(void),
|
||||||
|
getSpeed(void),
|
||||||
|
getModeCount(void),
|
||||||
|
getPaletteCount(void),
|
||||||
|
getMaxSegments(void),
|
||||||
|
getFirstSelectedSegment(void),
|
||||||
|
getMainSegmentId(void),
|
||||||
|
gamma8(uint8_t),
|
||||||
|
get_random_wheel_index(uint8_t);
|
||||||
|
|
||||||
|
uint16_t
|
||||||
|
ablMilliampsMax,
|
||||||
|
currentMilliamps,
|
||||||
|
triwave16(uint16_t);
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
now,
|
||||||
|
timebase,
|
||||||
|
color_wheel(uint8_t),
|
||||||
|
color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255),
|
||||||
|
color_blend(uint32_t,uint32_t,uint8_t),
|
||||||
|
gamma32(uint32_t),
|
||||||
|
getLastShow(void),
|
||||||
|
getPixelColor(uint16_t),
|
||||||
|
getColor(void);
|
||||||
|
|
||||||
|
WS2812FX::Segment&
|
||||||
|
getSegment(uint8_t n);
|
||||||
|
|
||||||
|
WS2812FX::Segment_runtime
|
||||||
|
getSegmentRuntime(void);
|
||||||
|
|
||||||
|
WS2812FX::Segment*
|
||||||
|
getSegments(void);
|
||||||
|
|
||||||
|
// builtin modes
|
||||||
|
uint16_t
|
||||||
|
mode_static(void),
|
||||||
|
mode_blink(void),
|
||||||
|
mode_blink_rainbow(void),
|
||||||
|
mode_strobe(void),
|
||||||
|
mode_strobe_rainbow(void),
|
||||||
|
mode_color_wipe(void),
|
||||||
|
mode_color_sweep(void),
|
||||||
|
mode_color_wipe_random(void),
|
||||||
|
mode_color_sweep_random(void),
|
||||||
|
mode_random_color(void),
|
||||||
|
mode_dynamic(void),
|
||||||
|
mode_breath(void),
|
||||||
|
mode_fade(void),
|
||||||
|
mode_scan(void),
|
||||||
|
mode_dual_scan(void),
|
||||||
|
mode_theater_chase(void),
|
||||||
|
mode_theater_chase_rainbow(void),
|
||||||
|
mode_rainbow(void),
|
||||||
|
mode_rainbow_cycle(void),
|
||||||
|
mode_running_lights(void),
|
||||||
|
mode_saw(void),
|
||||||
|
mode_twinkle(void),
|
||||||
|
mode_dissolve(void),
|
||||||
|
mode_dissolve_random(void),
|
||||||
|
mode_sparkle(void),
|
||||||
|
mode_flash_sparkle(void),
|
||||||
|
mode_hyper_sparkle(void),
|
||||||
|
mode_multi_strobe(void),
|
||||||
|
mode_android(void),
|
||||||
|
mode_chase_color(void),
|
||||||
|
mode_chase_random(void),
|
||||||
|
mode_chase_rainbow(void),
|
||||||
|
mode_chase_flash(void),
|
||||||
|
mode_chase_flash_random(void),
|
||||||
|
mode_chase_rainbow_white(void),
|
||||||
|
mode_colorful(void),
|
||||||
|
mode_traffic_light(void),
|
||||||
|
mode_running_color(void),
|
||||||
|
mode_running_red_blue(void),
|
||||||
|
mode_running_random(void),
|
||||||
|
mode_larson_scanner(void),
|
||||||
|
mode_comet(void),
|
||||||
|
mode_fireworks(void),
|
||||||
|
mode_rain(void),
|
||||||
|
mode_merry_christmas(void),
|
||||||
|
mode_halloween(void),
|
||||||
|
mode_fire_flicker(void),
|
||||||
|
mode_gradient(void),
|
||||||
|
mode_loading(void),
|
||||||
|
mode_police(void),
|
||||||
|
mode_police_all(void),
|
||||||
|
mode_two_dots(void),
|
||||||
|
mode_two_areas(void),
|
||||||
|
mode_circus_combustus(void),
|
||||||
|
mode_bicolor_chase(void),
|
||||||
|
mode_tricolor_chase(void),
|
||||||
|
mode_tricolor_wipe(void),
|
||||||
|
mode_tricolor_fade(void),
|
||||||
|
mode_lightning(void),
|
||||||
|
mode_icu(void),
|
||||||
|
mode_multi_comet(void),
|
||||||
|
mode_dual_larson_scanner(void),
|
||||||
|
mode_random_chase(void),
|
||||||
|
mode_oscillate(void),
|
||||||
|
mode_fire_2012(void),
|
||||||
|
mode_pride_2015(void),
|
||||||
|
mode_bpm(void),
|
||||||
|
mode_juggle(void),
|
||||||
|
mode_palette(void),
|
||||||
|
mode_colorwaves(void),
|
||||||
|
mode_fillnoise8(void),
|
||||||
|
mode_noise16_1(void),
|
||||||
|
mode_noise16_2(void),
|
||||||
|
mode_noise16_3(void),
|
||||||
|
mode_noise16_4(void),
|
||||||
|
mode_colortwinkle(void),
|
||||||
|
mode_lake(void),
|
||||||
|
mode_meteor(void),
|
||||||
|
mode_meteor_smooth(void),
|
||||||
|
mode_railway(void),
|
||||||
|
mode_ripple(void),
|
||||||
|
mode_twinklefox(void),
|
||||||
|
mode_twinklecat(void),
|
||||||
|
mode_halloween_eyes(void),
|
||||||
|
mode_static_pattern(void),
|
||||||
|
mode_tri_static_pattern(void),
|
||||||
|
mode_spots(void),
|
||||||
|
mode_spots_fade(void),
|
||||||
|
mode_glitter(void),
|
||||||
|
mode_candle(void),
|
||||||
|
mode_starburst(void),
|
||||||
|
mode_exploding_fireworks(void),
|
||||||
|
mode_bouncing_balls(void),
|
||||||
|
mode_sinelon(void),
|
||||||
|
mode_sinelon_dual(void),
|
||||||
|
mode_sinelon_rainbow(void),
|
||||||
|
mode_popcorn(void),
|
||||||
|
mode_drip(void),
|
||||||
|
mode_plasma(void),
|
||||||
|
mode_percent(void),
|
||||||
|
mode_ripple_rainbow(void),
|
||||||
|
mode_heartbeat(void),
|
||||||
|
mode_pacifica(void),
|
||||||
|
mode_candle_multi(void),
|
||||||
|
mode_solid_glitter(void),
|
||||||
|
mode_sunrise(void),
|
||||||
|
mode_phased(void),
|
||||||
|
mode_twinkleup(void),
|
||||||
|
mode_noisepal(void),
|
||||||
|
mode_sinewave(void),
|
||||||
|
mode_phased_noise(void),
|
||||||
|
mode_flow(void),
|
||||||
|
mode_chunchun(void),
|
||||||
|
mode_dancing_shadows(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
uint32_t crgb_to_col(CRGB fastled);
|
||||||
|
CRGB col_to_crgb(uint32_t);
|
||||||
|
CRGBPalette16 currentPalette;
|
||||||
|
CRGBPalette16 targetPalette;
|
||||||
|
|
||||||
|
CRGB *_leds;
|
||||||
|
uint16_t _length, _lengthRaw, _virtualSegmentLength;
|
||||||
|
uint16_t _rand16seed;
|
||||||
|
uint8_t _brightness;
|
||||||
|
static uint16_t _usedSegmentData;
|
||||||
|
|
||||||
|
void load_gradient_palette(uint8_t);
|
||||||
|
void handle_palette(void);
|
||||||
|
|
||||||
|
bool
|
||||||
|
_skipFirstMode,
|
||||||
|
_triggered;
|
||||||
|
|
||||||
|
mode_ptr _mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element
|
||||||
|
|
||||||
|
show_callback _callback = nullptr;
|
||||||
|
|
||||||
|
// mode helper functions
|
||||||
|
uint16_t
|
||||||
|
blink(uint32_t, uint32_t, bool strobe, bool),
|
||||||
|
candle(bool),
|
||||||
|
color_wipe(bool, bool),
|
||||||
|
scan(bool),
|
||||||
|
theater_chase(uint32_t, uint32_t, bool),
|
||||||
|
running_base(bool),
|
||||||
|
larson_scanner(bool),
|
||||||
|
sinelon_base(bool,bool),
|
||||||
|
dissolve(uint32_t),
|
||||||
|
chase(uint32_t, uint32_t, uint32_t, bool),
|
||||||
|
gradient_base(bool),
|
||||||
|
ripple_base(bool),
|
||||||
|
police_base(uint32_t, uint32_t, bool),
|
||||||
|
running(uint32_t, uint32_t),
|
||||||
|
tricolor_chase(uint32_t, uint32_t),
|
||||||
|
twinklefox_base(bool),
|
||||||
|
spots_base(uint16_t),
|
||||||
|
phased_base(uint8_t);
|
||||||
|
|
||||||
|
CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat);
|
||||||
|
CRGB pacifica_one_layer(uint16_t i, CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff);
|
||||||
|
|
||||||
|
void blendPixelColor(uint16_t n, uint32_t color, uint8_t blend);
|
||||||
|
|
||||||
|
uint32_t _lastPaletteChange = 0;
|
||||||
|
uint32_t _lastShow = 0;
|
||||||
|
|
||||||
|
uint8_t _segment_index = 0;
|
||||||
|
uint8_t _segment_index_palette_last = 99;
|
||||||
|
segment _segments[MAX_NUM_SEGMENTS] = {
|
||||||
|
// SRAM footprint: 24 bytes per element
|
||||||
|
// start, stop, speed, intensity, palette, mode, options, grouping, spacing, opacity (unused), color[]
|
||||||
|
{ 0, 7, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}}
|
||||||
|
};
|
||||||
|
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 28 bytes per element
|
||||||
|
friend class Segment_runtime;
|
||||||
|
|
||||||
|
uint16_t realPixelIndex(uint16_t i);
|
||||||
|
};
|
||||||
|
|
||||||
|
//10 names per line
|
||||||
|
const char JSON_mode_names[] = R"=====([
|
||||||
|
"Solid","Blink","Breathe","Wipe","Wipe Random","Random Colors","Sweep","Dynamic","Colorloop","Rainbow",
|
||||||
|
"Scan","Scan Dual","Fade","Theater","Theater Rainbow","Running","Saw","Twinkle","Dissolve","Dissolve Rnd",
|
||||||
|
"Sparkle","Sparkle Dark","Sparkle+","Strobe","Strobe Rainbow","Strobe Mega","Blink Rainbow","Android","Chase","Chase Random",
|
||||||
|
"Chase Rainbow","Chase Flash","Chase Flash Rnd","Rainbow Runner","Colorful","Traffic Light","Sweep Random","Running 2","Red & Blue","Stream",
|
||||||
|
"Scanner","Lighthouse","Fireworks","Rain","Merry Christmas","Fire Flicker","Gradient","Loading","Police","Police All",
|
||||||
|
"Two Dots","Two Areas","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet",
|
||||||
|
"Scanner Dual","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise",
|
||||||
|
"Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Meteor Smooth","Railway","Ripple",
|
||||||
|
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle","Fireworks Starburst",
|
||||||
|
"Fireworks 1D","Bouncing Balls","Sinelon","Sinelon Dual","Sinelon Rainbow","Popcorn","Drip","Plasma","Percent","Ripple Rainbow",
|
||||||
|
"Heartbeat","Pacifica","Candle Multi", "Solid Glitter","Sunrise","Phased","Twinkleup","Noise Pal", "Sine","Phased Noise",
|
||||||
|
"Flow","Chunchun","Dancing Shadows"
|
||||||
|
])=====";
|
||||||
|
|
||||||
|
|
||||||
|
const char JSON_palette_names[] = R"=====([
|
||||||
|
"Default","* Random Cycle","* Color 1","* Colors 1&2","* Color Gradient","* Colors Only","Party","Cloud","Lava","Ocean",
|
||||||
|
"Forest","Rainbow","Rainbow Bands","Sunset","Rivendell","Breeze","Red & Blue","Yellowout","Analogous","Splash",
|
||||||
|
"Pastel","Sunset 2","Beech","Vintage","Departure","Landscape","Beach","Sherbet","Hult","Hult 64",
|
||||||
|
"Drywet","Jul","Grintage","Rewhi","Tertiary","Fire","Icefire","Cyane","Light Pink","Autumn",
|
||||||
|
"Magenta","Magred","Yelmag","Yelblu","Orange & Teal","Tiamat","April Night","Orangery","C9","Sakura",
|
||||||
|
"Aurora","Atlantica"
|
||||||
|
])=====";
|
||||||
|
|
||||||
|
//Segment option byte bits
|
||||||
|
#define SEG_OPTION_SELECTED 0
|
||||||
|
#define SEG_OPTION_REVERSED 1
|
||||||
|
#define SEG_OPTION_ON 2
|
||||||
|
#define SEG_OPTION_MIRROR 3 //Indicates that the effect will be mirrored within the segment
|
||||||
|
#define SEG_OPTION_NONUNITY 4 //Indicates that the effect does not use FRAMETIME or needs getPixelColor
|
||||||
|
#define SEG_OPTION_FREEZE 5 //Segment contents will not be refreshed
|
||||||
|
#define SEG_OPTION_TRANSITIONAL 7
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
899
components/WS2812FX-idf/FX_fcn.cpp
Normal file
899
components/WS2812FX-idf/FX_fcn.cpp
Normal file
@ -0,0 +1,899 @@
|
|||||||
|
/*
|
||||||
|
WS2812FX_fcn.cpp contains all utility functions
|
||||||
|
Harm Aldick - 2016
|
||||||
|
www.aldick.org
|
||||||
|
LICENSE
|
||||||
|
The MIT License (MIT)
|
||||||
|
Copyright (c) 2016 Harm Aldick
|
||||||
|
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, sublicense, 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.
|
||||||
|
|
||||||
|
Modified heavily for WLED
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "FX.h"
|
||||||
|
#include "palettes.h"
|
||||||
|
|
||||||
|
//enable custom per-LED mapping. This can allow for better effects on matrices or special displays
|
||||||
|
//#define WLED_CUSTOM_LED_MAPPING
|
||||||
|
|
||||||
|
#ifdef WLED_CUSTOM_LED_MAPPING
|
||||||
|
//this is just an example (30 LEDs). It will first set all even, then all uneven LEDs.
|
||||||
|
const uint16_t customMappingTable[] = {
|
||||||
|
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28,
|
||||||
|
1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29};
|
||||||
|
|
||||||
|
//another example. Switches direction every 5 LEDs.
|
||||||
|
/*const uint16_t customMappingTable[] = {
|
||||||
|
0, 1, 2, 3, 4, 9, 8, 7, 6, 5, 10, 11, 12, 13, 14,
|
||||||
|
19, 18, 17, 16, 15, 20, 21, 22, 23, 24, 29, 28, 27, 26, 25};*/
|
||||||
|
|
||||||
|
const uint16_t customMappingSize = sizeof(customMappingTable)/sizeof(uint16_t); //30 in example
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void WS2812FX::init( uint16_t countPixels, CRGB *leds, bool skipFirst)
|
||||||
|
{
|
||||||
|
if ( countPixels == _length && _skipFirstMode == skipFirst) return;
|
||||||
|
RESET_RUNTIME;
|
||||||
|
_length = countPixels;
|
||||||
|
_leds = leds;
|
||||||
|
_skipFirstMode = skipFirst;
|
||||||
|
|
||||||
|
_lengthRaw = _length;
|
||||||
|
if (_skipFirstMode) {
|
||||||
|
_lengthRaw += LED_SKIP_AMOUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
_segments[0].start = 0;
|
||||||
|
_segments[0].stop = _length;
|
||||||
|
|
||||||
|
setBrightness(_brightness);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WS2812FX::service() {
|
||||||
|
uint32_t nowUp = millis(); // Be aware, millis() rolls over every 49 days
|
||||||
|
now = nowUp + timebase;
|
||||||
|
if (nowUp - _lastShow < MIN_SHOW_DELAY) return;
|
||||||
|
bool doShow = false;
|
||||||
|
|
||||||
|
for(uint8_t i=0; i < MAX_NUM_SEGMENTS; i++)
|
||||||
|
{
|
||||||
|
_segment_index = i;
|
||||||
|
if (SEGMENT.isActive())
|
||||||
|
{
|
||||||
|
if(nowUp > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0)) //last is temporary
|
||||||
|
{
|
||||||
|
if (SEGMENT.grouping == 0) SEGMENT.grouping = 1; //sanity check
|
||||||
|
doShow = true;
|
||||||
|
uint16_t delay = FRAMETIME;
|
||||||
|
|
||||||
|
if (!SEGMENT.getOption(SEG_OPTION_FREEZE)) { //only run effect function if not frozen
|
||||||
|
_virtualSegmentLength = SEGMENT.virtualLength();
|
||||||
|
handle_palette();
|
||||||
|
delay = (this->*_mode[SEGMENT.mode])(); //effect function
|
||||||
|
if (SEGMENT.mode != FX_MODE_HALLOWEEN_EYES) SEGENV.call++;
|
||||||
|
}
|
||||||
|
|
||||||
|
SEGENV.next_time = nowUp + delay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_virtualSegmentLength = 0;
|
||||||
|
if(doShow) {
|
||||||
|
yield();
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
_triggered = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
|
||||||
|
uint8_t r = (c >> 16);
|
||||||
|
uint8_t g = (c >> 8);
|
||||||
|
uint8_t b = c ;
|
||||||
|
setPixelColor(n, r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define REV(i) (_length - 1 - (i))
|
||||||
|
|
||||||
|
//used to map from segment index to physical pixel, taking into account grouping, offsets, reverse and mirroring
|
||||||
|
uint16_t WS2812FX::realPixelIndex(uint16_t i) {
|
||||||
|
int16_t iGroup = i * SEGMENT.groupLength();
|
||||||
|
|
||||||
|
/* reverse just an individual segment */
|
||||||
|
int16_t realIndex = iGroup;
|
||||||
|
if (IS_REVERSE) {
|
||||||
|
if (IS_MIRROR) {
|
||||||
|
realIndex = (SEGMENT.length() -1) / 2 - iGroup; //only need to index half the pixels
|
||||||
|
} else {
|
||||||
|
realIndex = SEGMENT.length() - iGroup - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
realIndex += SEGMENT.start;
|
||||||
|
/* Reverse the whole string */
|
||||||
|
if (reverseMode) realIndex = REV(realIndex);
|
||||||
|
|
||||||
|
return realIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WS2812FX::setPixelColor(uint16_t i, uint8_t r, uint8_t g, uint8_t b)
|
||||||
|
{
|
||||||
|
|
||||||
|
// create a color
|
||||||
|
CRGB col(r, g, b);
|
||||||
|
|
||||||
|
uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0;
|
||||||
|
if (SEGLEN) {//from segment
|
||||||
|
|
||||||
|
//color_blend(getpixel, col, SEGMENT.opacity); (pseudocode for future blending of segments)
|
||||||
|
if (IS_SEGMENT_ON)
|
||||||
|
{
|
||||||
|
// fixme: there's a specific multiply operator we should use
|
||||||
|
if (SEGMENT.opacity < 255) {
|
||||||
|
col.r = scale8(col.r, SEGMENT.opacity);
|
||||||
|
col.g = scale8(col.g, SEGMENT.opacity);
|
||||||
|
col.b = scale8(col.b, SEGMENT.opacity);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
col = BLACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set all the pixels in the group, ensuring _skipFirstMode is honored */
|
||||||
|
bool reversed = reverseMode ^ IS_REVERSE;
|
||||||
|
uint16_t realIndex = realPixelIndex(i);
|
||||||
|
|
||||||
|
for (uint16_t j = 0; j < SEGMENT.grouping; j++) {
|
||||||
|
int16_t indexSet = realIndex + (reversed ? -j : j);
|
||||||
|
int16_t indexSetRev = indexSet;
|
||||||
|
if (reverseMode) indexSetRev = REV(indexSet);
|
||||||
|
#ifdef WLED_CUSTOM_LED_MAPPING
|
||||||
|
if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet];
|
||||||
|
#endif
|
||||||
|
if (indexSetRev >= SEGMENT.start && indexSetRev < SEGMENT.stop) {
|
||||||
|
_leds[indexSet+skip] = col;
|
||||||
|
if (IS_MIRROR) { //set the corresponding mirrored pixel
|
||||||
|
if (reverseMode) {
|
||||||
|
_leds[REV(SEGMENT.start) - indexSet + skip + REV(SEGMENT.stop) + 1] = col;
|
||||||
|
} else {
|
||||||
|
_leds[SEGMENT.stop - indexSet + skip + SEGMENT.start - 1] = col;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { //live data, etc.
|
||||||
|
|
||||||
|
if (reverseMode) i = REV(i);
|
||||||
|
|
||||||
|
#ifdef WLED_CUSTOM_LED_MAPPING
|
||||||
|
if (i < customMappingSize) i = customMappingTable[i];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_leds[i + skip] = col;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skip && i == 0) {
|
||||||
|
for (uint16_t j = 0; j < skip; j++) {
|
||||||
|
_leds[j].r = 0; _leds[j].g = 0; _leds[j].b = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//DISCLAIMER
|
||||||
|
//The following function attemps to calculate the current LED power usage,
|
||||||
|
//and will limit the brightness to stay below a set amperage threshold.
|
||||||
|
//It is NOT a measurement and NOT guaranteed to stay within the ablMilliampsMax margin.
|
||||||
|
//Stay safe with high amperage and have a reasonable safety margin!
|
||||||
|
//I am NOT to be held liable for burned down garages!
|
||||||
|
|
||||||
|
//fine tune power estimation constants for your setup
|
||||||
|
#define MA_FOR_ESP 100 //how much mA does the ESP use (Wemos D1 about 80mA, ESP32 about 120mA)
|
||||||
|
//you can set it to 0 if the ESP is powered by USB and the LEDs by external
|
||||||
|
|
||||||
|
void WS2812FX::show(void) {
|
||||||
|
if (_callback) _callback();
|
||||||
|
|
||||||
|
//power limit calculation
|
||||||
|
//each LED can draw up 195075 "power units" (approx. 53mA)
|
||||||
|
//one PU is the power it takes to have 1 channel 1 step brighter per brightness step
|
||||||
|
//so A=2,R=255,G=0,B=0 would use 510 PU per LED (1mA is about 3700 PU)
|
||||||
|
bool useWackyWS2815PowerModel = false;
|
||||||
|
uint8_t actualMilliampsPerLed = milliampsPerLed;
|
||||||
|
|
||||||
|
if(milliampsPerLed == 255) {
|
||||||
|
useWackyWS2815PowerModel = true;
|
||||||
|
actualMilliampsPerLed = 12; // from testing an actual strip
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ablMilliampsMax > 149 && actualMilliampsPerLed > 0) //0 mA per LED and too low numbers turn off calculation
|
||||||
|
{
|
||||||
|
uint32_t puPerMilliamp = 195075 / actualMilliampsPerLed;
|
||||||
|
uint32_t powerBudget = (ablMilliampsMax - MA_FOR_ESP) * puPerMilliamp; //100mA for ESP power
|
||||||
|
if (powerBudget > puPerMilliamp * _length) //each LED uses about 1mA in standby, exclude that from power budget
|
||||||
|
{
|
||||||
|
powerBudget -= puPerMilliamp * _length;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
powerBudget = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t powerSum = 0;
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < _length; i++) //sum up the usage of each LED
|
||||||
|
{
|
||||||
|
CRGB c = _leds[i];
|
||||||
|
|
||||||
|
if(useWackyWS2815PowerModel)
|
||||||
|
{
|
||||||
|
// ignore white component on WS2815 power calculation
|
||||||
|
powerSum += (MAX(MAX(c.r,c.g),c.b)) * 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
powerSum += (c.r + c.g + c.b) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t powerSum0 = powerSum;
|
||||||
|
powerSum *= _brightness;
|
||||||
|
|
||||||
|
if (powerSum > powerBudget) //scale brightness down to stay in current limit
|
||||||
|
{
|
||||||
|
float scale = (float)powerBudget / (float)powerSum;
|
||||||
|
uint16_t scaleI = scale * 255;
|
||||||
|
uint8_t scaleB = (scaleI > 255) ? 255 : scaleI;
|
||||||
|
uint8_t newBri = scale8(_brightness, scaleB);
|
||||||
|
FastLED.setBrightness(newBri);
|
||||||
|
currentMilliamps = (powerSum0 * newBri) / puPerMilliamp;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
currentMilliamps = powerSum / puPerMilliamp;
|
||||||
|
FastLED.setBrightness(_brightness);
|
||||||
|
}
|
||||||
|
currentMilliamps += MA_FOR_ESP; //add power of ESP back to estimate
|
||||||
|
currentMilliamps += _length; //add standby power back to estimate
|
||||||
|
} else {
|
||||||
|
currentMilliamps = 0;
|
||||||
|
FastLED.setBrightness(_brightness);
|
||||||
|
}
|
||||||
|
|
||||||
|
FastLED.show();
|
||||||
|
_lastShow = millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WS2812FX::trigger() {
|
||||||
|
_triggered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WS2812FX::setMode(uint8_t segid, uint8_t m) {
|
||||||
|
if (segid >= MAX_NUM_SEGMENTS) return;
|
||||||
|
|
||||||
|
if (m >= MODE_COUNT) m = MODE_COUNT - 1;
|
||||||
|
|
||||||
|
if (_segments[segid].mode != m)
|
||||||
|
{
|
||||||
|
_segment_runtimes[segid].reset();
|
||||||
|
_segments[segid].mode = m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t WS2812FX::getModeCount()
|
||||||
|
{
|
||||||
|
return MODE_COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t WS2812FX::getPaletteCount()
|
||||||
|
{
|
||||||
|
return 13 + GRADIENT_PALETTE_COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO transitions
|
||||||
|
|
||||||
|
|
||||||
|
bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t in, uint8_t p) {
|
||||||
|
uint8_t mainSeg = getMainSegmentId();
|
||||||
|
Segment& seg = _segments[getMainSegmentId()];
|
||||||
|
uint8_t modePrev = seg.mode, speedPrev = seg.speed, intensityPrev = seg.intensity, palettePrev = seg.palette;
|
||||||
|
|
||||||
|
bool applied = false;
|
||||||
|
|
||||||
|
if (applyToAllSelected)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||||
|
{
|
||||||
|
if (_segments[i].isSelected())
|
||||||
|
{
|
||||||
|
_segments[i].speed = s;
|
||||||
|
_segments[i].intensity = in;
|
||||||
|
_segments[i].palette = p;
|
||||||
|
setMode(i, m);
|
||||||
|
applied = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!applyToAllSelected || !applied) {
|
||||||
|
seg.speed = s;
|
||||||
|
seg.intensity = in;
|
||||||
|
seg.palette = p;
|
||||||
|
setMode(mainSegment, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seg.mode != modePrev || seg.speed != speedPrev || seg.intensity != intensityPrev || seg.palette != palettePrev) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WS2812FX::setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b) {
|
||||||
|
setColor(slot, ((uint32_t)r << 16) | ((uint32_t)g << 8) | b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WS2812FX::setColor(uint8_t slot, uint32_t c) {
|
||||||
|
if (slot >= NUM_COLORS) return;
|
||||||
|
|
||||||
|
bool applied = false;
|
||||||
|
|
||||||
|
if (applyToAllSelected) {
|
||||||
|
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||||
|
{
|
||||||
|
if (_segments[i].isSelected()) _segments[i].colors[slot] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!applyToAllSelected || !applied) {
|
||||||
|
_segments[getMainSegmentId()].colors[slot] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WS2812FX::setBrightness(uint8_t b) {
|
||||||
|
if (_brightness == b) return;
|
||||||
|
_brightness = (gammaCorrectBri) ? gamma8(b) : b;
|
||||||
|
_segment_index = 0;
|
||||||
|
if (b == 0) { //unfreeze all segments on power off
|
||||||
|
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||||
|
{
|
||||||
|
_segments[i].setOption(SEG_OPTION_FREEZE, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (SEGENV.next_time > millis() + 22 && millis() - _lastShow > MIN_SHOW_DELAY) show();//apply brightness change immediately if no refresh soon
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t WS2812FX::getMode(void) {
|
||||||
|
return _segments[getMainSegmentId()].mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t WS2812FX::getSpeed(void) {
|
||||||
|
return _segments[getMainSegmentId()].speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t WS2812FX::getBrightness(void) {
|
||||||
|
return _brightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t WS2812FX::getMaxSegments(void) {
|
||||||
|
return MAX_NUM_SEGMENTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*uint8_t WS2812FX::getFirstSelectedSegment(void)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||||
|
{
|
||||||
|
if (_segments[i].isActive() && _segments[i].isSelected()) return i;
|
||||||
|
}
|
||||||
|
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) //if none selected, get first active
|
||||||
|
{
|
||||||
|
if (_segments[i].isActive()) return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
uint8_t WS2812FX::getMainSegmentId(void) {
|
||||||
|
if (mainSegment >= MAX_NUM_SEGMENTS) return 0;
|
||||||
|
if (_segments[mainSegment].isActive()) return mainSegment;
|
||||||
|
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) //get first active
|
||||||
|
{
|
||||||
|
if (_segments[i].isActive()) return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t WS2812FX::getColor(void) {
|
||||||
|
return _segments[getMainSegmentId()].colors[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t WS2812FX::getPixelColor(uint16_t i)
|
||||||
|
{
|
||||||
|
i = realPixelIndex(i);
|
||||||
|
|
||||||
|
#ifdef WLED_CUSTOM_LED_MAPPING
|
||||||
|
if (i < customMappingSize) i = customMappingTable[i];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (_skipFirstMode) i += LED_SKIP_AMOUNT;
|
||||||
|
|
||||||
|
if (i >= _lengthRaw) return 0;
|
||||||
|
|
||||||
|
return( (_leds[i].r << 24) | (_leds[i].g << 16) | _leds[i].b );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
WS2812FX::Segment& WS2812FX::getSegment(uint8_t id) {
|
||||||
|
if (id >= MAX_NUM_SEGMENTS) return _segments[0];
|
||||||
|
return _segments[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
WS2812FX::Segment_runtime WS2812FX::getSegmentRuntime(void) {
|
||||||
|
return SEGENV;
|
||||||
|
}
|
||||||
|
|
||||||
|
WS2812FX::Segment* WS2812FX::getSegments(void) {
|
||||||
|
return _segments;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t WS2812FX::getLastShow(void) {
|
||||||
|
return _lastShow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** n: which segment
|
||||||
|
** CRGB - beginning of the RGB array
|
||||||
|
** --- wtf: what exactly do i1 and i2 mean, if start and stop are already set?
|
||||||
|
*/
|
||||||
|
|
||||||
|
void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, uint8_t spacing) {
|
||||||
|
if (n >= MAX_NUM_SEGMENTS) return;
|
||||||
|
Segment& seg = _segments[n];
|
||||||
|
|
||||||
|
//return if neither bounds nor grouping have changed
|
||||||
|
if (seg.start == i1 && seg.stop == i2 && (!grouping || (seg.grouping == grouping && seg.spacing == spacing))) return;
|
||||||
|
|
||||||
|
if (seg.stop) setRange(seg.start, seg.stop -1, 0); //turn old segment range off
|
||||||
|
if (i2 <= i1) //disable segment
|
||||||
|
{
|
||||||
|
seg.stop = 0;
|
||||||
|
if (n == mainSegment) //if main segment is deleted, set first active as main segment
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||||
|
{
|
||||||
|
if (_segments[i].isActive()) {
|
||||||
|
mainSegment = i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mainSegment = 0; //should not happen (always at least one active segment)
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (i1 < _length) seg.start = i1;
|
||||||
|
seg.stop = i2;
|
||||||
|
if (i2 > _length) seg.stop = _length;
|
||||||
|
if (grouping) {
|
||||||
|
seg.grouping = grouping;
|
||||||
|
seg.spacing = spacing;
|
||||||
|
}
|
||||||
|
_segment_runtimes[n].reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WS2812FX::resetSegments() {
|
||||||
|
mainSegment = 0;
|
||||||
|
memset(_segments, 0, sizeof(_segments));
|
||||||
|
//memset(_segment_runtimes, 0, sizeof(_segment_runtimes));
|
||||||
|
_segment_index = 0;
|
||||||
|
_segments[0].mode = DEFAULT_MODE;
|
||||||
|
_segments[0].colors[0] = DEFAULT_COLOR;
|
||||||
|
_segments[0].start = 0;
|
||||||
|
_segments[0].speed = DEFAULT_SPEED;
|
||||||
|
_segments[0].stop = _length;
|
||||||
|
_segments[0].grouping = 1;
|
||||||
|
_segments[0].setOption(SEG_OPTION_SELECTED, 1);
|
||||||
|
_segments[0].setOption(SEG_OPTION_ON, 1);
|
||||||
|
_segments[0].opacity = 255;
|
||||||
|
|
||||||
|
for (uint16_t i = 1; i < MAX_NUM_SEGMENTS; i++)
|
||||||
|
{
|
||||||
|
_segments[i].colors[0] = color_wheel(i*51);
|
||||||
|
_segments[i].grouping = 1;
|
||||||
|
_segments[i].setOption(SEG_OPTION_ON, 1);
|
||||||
|
_segments[i].opacity = 255;
|
||||||
|
_segment_runtimes[i].reset();
|
||||||
|
}
|
||||||
|
_segment_runtimes[0].reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
//After this function is called, setPixelColor() will use that segment (offsets, grouping, ... will apply)
|
||||||
|
void WS2812FX::setPixelSegment(uint8_t n)
|
||||||
|
{
|
||||||
|
if (n < MAX_NUM_SEGMENTS) {
|
||||||
|
_segment_index = n;
|
||||||
|
_virtualSegmentLength = SEGMENT.length();
|
||||||
|
} else {
|
||||||
|
_segment_index = 0;
|
||||||
|
_virtualSegmentLength = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WS2812FX::setRange(uint16_t i, uint16_t i2, uint32_t col)
|
||||||
|
{
|
||||||
|
if (i2 >= i)
|
||||||
|
{
|
||||||
|
for (uint16_t x = i; x <= i2; x++) setPixelColor(x, col);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
for (uint16_t x = i2; x <= i; x++) setPixelColor(x, col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WS2812FX::setShowCallback(show_callback cb)
|
||||||
|
{
|
||||||
|
_callback = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WS2812FX::setTransitionMode(bool t)
|
||||||
|
{
|
||||||
|
unsigned long waitMax = millis() + 20; //refresh after 20 ms if transition enabled
|
||||||
|
for (uint16_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||||
|
{
|
||||||
|
_segment_index = i;
|
||||||
|
SEGMENT.setOption(SEG_OPTION_TRANSITIONAL, t);
|
||||||
|
|
||||||
|
if (t && SEGMENT.mode == FX_MODE_STATIC && SEGENV.next_time > waitMax) SEGENV.next_time = waitMax;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* color blend function - returns color code
|
||||||
|
*/
|
||||||
|
uint32_t WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint8_t blend) {
|
||||||
|
if(blend == 0) return color1;
|
||||||
|
if(blend == 255) return color2;
|
||||||
|
|
||||||
|
uint32_t w1 = (color1 >> 24) & 0xff;
|
||||||
|
uint32_t r1 = (color1 >> 16) & 0xff;
|
||||||
|
uint32_t g1 = (color1 >> 8) & 0xff;
|
||||||
|
uint32_t b1 = color1 & 0xff;
|
||||||
|
|
||||||
|
uint32_t w2 = (color2 >> 24) & 0xff;
|
||||||
|
uint32_t r2 = (color2 >> 16) & 0xff;
|
||||||
|
uint32_t g2 = (color2 >> 8) & 0xff;
|
||||||
|
uint32_t b2 = color2 & 0xff;
|
||||||
|
|
||||||
|
uint32_t w3 = ((w2 * blend) + (w1 * (255 - blend))) >> 8;
|
||||||
|
uint32_t r3 = ((r2 * blend) + (r1 * (255 - blend))) >> 8;
|
||||||
|
uint32_t g3 = ((g2 * blend) + (g1 * (255 - blend))) >> 8;
|
||||||
|
uint32_t b3 = ((b2 * blend) + (b1 * (255 - blend))) >> 8;
|
||||||
|
|
||||||
|
return ((w3 << 24) | (r3 << 16) | (g3 << 8) | (b3));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fills segment with color
|
||||||
|
*/
|
||||||
|
void WS2812FX::fill(uint32_t c) {
|
||||||
|
for(uint16_t i = 0; i < SEGLEN; i++) {
|
||||||
|
setPixelColor(i, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Blends the specified color with the existing pixel color.
|
||||||
|
*/
|
||||||
|
void WS2812FX::blendPixelColor(uint16_t n, uint32_t color, uint8_t blend)
|
||||||
|
{
|
||||||
|
setPixelColor(n, color_blend(getPixelColor(n), color, blend));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fade out function, higher rate = quicker fade
|
||||||
|
*/
|
||||||
|
void WS2812FX::fade_out(uint8_t rate) {
|
||||||
|
rate = (255-rate) >> 1;
|
||||||
|
float mappedRate = float(rate) +1.1;
|
||||||
|
|
||||||
|
uint32_t color = SEGCOLOR(1); // target color
|
||||||
|
int w2 = (color >> 24) & 0xff;
|
||||||
|
int r2 = (color >> 16) & 0xff;
|
||||||
|
int g2 = (color >> 8) & 0xff;
|
||||||
|
int b2 = color & 0xff;
|
||||||
|
|
||||||
|
for(uint16_t i = 0; i < SEGLEN; i++) {
|
||||||
|
color = getPixelColor(i);
|
||||||
|
int w1 = (color >> 24) & 0xff;
|
||||||
|
int r1 = (color >> 16) & 0xff;
|
||||||
|
int g1 = (color >> 8) & 0xff;
|
||||||
|
int b1 = color & 0xff;
|
||||||
|
|
||||||
|
int wdelta = (w2 - w1) / mappedRate;
|
||||||
|
int rdelta = (r2 - r1) / mappedRate;
|
||||||
|
int gdelta = (g2 - g1) / mappedRate;
|
||||||
|
int bdelta = (b2 - b1) / mappedRate;
|
||||||
|
|
||||||
|
// if fade isn't complete, make sure delta is at least 1 (fixes rounding issues)
|
||||||
|
wdelta += (w2 == w1) ? 0 : (w2 > w1) ? 1 : -1;
|
||||||
|
rdelta += (r2 == r1) ? 0 : (r2 > r1) ? 1 : -1;
|
||||||
|
gdelta += (g2 == g1) ? 0 : (g2 > g1) ? 1 : -1;
|
||||||
|
bdelta += (b2 == b1) ? 0 : (b2 > b1) ? 1 : -1;
|
||||||
|
|
||||||
|
setPixelColor(i, r1 + rdelta, g1 + gdelta, b1 + bdelta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* blurs segment content, source: FastLED colorutils.cpp
|
||||||
|
*/
|
||||||
|
void WS2812FX::blur(uint8_t blur_amount)
|
||||||
|
{
|
||||||
|
uint8_t keep = 255 - blur_amount;
|
||||||
|
uint8_t seep = blur_amount >> 1;
|
||||||
|
CRGB carryover = CRGB::Black;
|
||||||
|
for(uint16_t i = 0; i < SEGLEN; i++)
|
||||||
|
{
|
||||||
|
CRGB cur = col_to_crgb(getPixelColor(i));
|
||||||
|
CRGB part = cur;
|
||||||
|
part.nscale8(seep);
|
||||||
|
cur.nscale8(keep);
|
||||||
|
cur += carryover;
|
||||||
|
if(i > 0) {
|
||||||
|
uint32_t c = getPixelColor(i-1);
|
||||||
|
uint8_t r = (c >> 16 & 0xFF);
|
||||||
|
uint8_t g = (c >> 8 & 0xFF);
|
||||||
|
uint8_t b = (c & 0xFF);
|
||||||
|
setPixelColor(i-1, qadd8(r, part.red), qadd8(g, part.green), qadd8(b, part.blue));
|
||||||
|
}
|
||||||
|
setPixelColor(i,cur.red, cur.green, cur.blue);
|
||||||
|
carryover = part;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t WS2812FX::triwave16(uint16_t in)
|
||||||
|
{
|
||||||
|
if (in < 0x8000) return in *2;
|
||||||
|
return 0xFFFF - (in - 0x8000)*2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Put a value 0 to 255 in to get a color value.
|
||||||
|
* The colours are a transition r -> g -> b -> back to r
|
||||||
|
* Inspired by the Adafruit examples.
|
||||||
|
* In FastLED terms, the return value is a 'colorCode' and can be used with 'setColorCode'
|
||||||
|
*/
|
||||||
|
uint32_t WS2812FX::color_wheel(uint8_t pos) {
|
||||||
|
if (SEGMENT.palette) return color_from_palette(pos, false, true, 0);
|
||||||
|
pos = 255 - pos;
|
||||||
|
if(pos < 85) {
|
||||||
|
return ((uint32_t)(255 - pos * 3) << 16) | ((uint32_t)(0) << 8) | (pos * 3);
|
||||||
|
} else if(pos < 170) {
|
||||||
|
pos -= 85;
|
||||||
|
return ((uint32_t)(0) << 16) | ((uint32_t)(pos * 3) << 8) | (255 - pos * 3);
|
||||||
|
} else {
|
||||||
|
pos -= 170;
|
||||||
|
return ((uint32_t)(pos * 3) << 16) | ((uint32_t)(255 - pos * 3) << 8) | (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a new, random wheel index with a minimum distance of 42 from pos.
|
||||||
|
*/
|
||||||
|
uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) {
|
||||||
|
uint8_t r = 0, x = 0, y = 0, d = 0;
|
||||||
|
|
||||||
|
while(d < 42) {
|
||||||
|
r = random8();
|
||||||
|
x = abs(pos - r);
|
||||||
|
y = 255 - x;
|
||||||
|
d = MIN(x, y);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t WS2812FX::crgb_to_col(CRGB fastled)
|
||||||
|
{
|
||||||
|
return (((uint32_t)fastled.red << 16) | ((uint32_t)fastled.green << 8) | fastled.blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CRGB WS2812FX::col_to_crgb(uint32_t color)
|
||||||
|
{
|
||||||
|
CRGB fastled_col;
|
||||||
|
fastled_col.red = (color >> 16 & 0xFF);
|
||||||
|
fastled_col.green = (color >> 8 & 0xFF);
|
||||||
|
fastled_col.blue = (color & 0xFF);
|
||||||
|
return fastled_col;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WS2812FX::load_gradient_palette(uint8_t index)
|
||||||
|
{
|
||||||
|
uint8_t i = ArduinoConstrain(index, 0, GRADIENT_PALETTE_COUNT -1);
|
||||||
|
uint8_t tcp[72]; //support gradient palettes with up to 18 entries
|
||||||
|
memcpy(tcp, &(gGradientPalettes[i]), 72);
|
||||||
|
targetPalette.loadDynamicGradientPalette(tcp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FastLED palette modes helper function. Limitation: Due to memory reasons, multiple active segments with FastLED will disable the Palette transitions
|
||||||
|
*/
|
||||||
|
void WS2812FX::handle_palette(void)
|
||||||
|
{
|
||||||
|
bool singleSegmentMode = (_segment_index == _segment_index_palette_last);
|
||||||
|
_segment_index_palette_last = _segment_index;
|
||||||
|
|
||||||
|
uint8_t paletteIndex = SEGMENT.palette;
|
||||||
|
if (paletteIndex == 0) //default palette. Differs depending on effect
|
||||||
|
{
|
||||||
|
switch (SEGMENT.mode)
|
||||||
|
{
|
||||||
|
case FX_MODE_FIRE_2012 : paletteIndex = 35; break; //heat palette
|
||||||
|
case FX_MODE_COLORWAVES : paletteIndex = 26; break; //landscape 33
|
||||||
|
case FX_MODE_FILLNOISE8 : paletteIndex = 9; break; //ocean colors
|
||||||
|
case FX_MODE_NOISE16_1 : paletteIndex = 20; break; //Drywet
|
||||||
|
case FX_MODE_NOISE16_2 : paletteIndex = 43; break; //Blue cyan yellow
|
||||||
|
case FX_MODE_NOISE16_3 : paletteIndex = 35; break; //heat palette
|
||||||
|
case FX_MODE_NOISE16_4 : paletteIndex = 26; break; //landscape 33
|
||||||
|
case FX_MODE_GLITTER : paletteIndex = 11; break; //rainbow colors
|
||||||
|
case FX_MODE_SUNRISE : paletteIndex = 35; break; //heat palette
|
||||||
|
case FX_MODE_FLOW : paletteIndex = 6; break; //party
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (SEGMENT.mode >= FX_MODE_METEOR && paletteIndex == 0) paletteIndex = 4;
|
||||||
|
|
||||||
|
switch (paletteIndex)
|
||||||
|
{
|
||||||
|
case 0: //default palette. Exceptions for specific effects above
|
||||||
|
targetPalette = PartyColors_p; break;
|
||||||
|
case 1: {//periodically replace palette with a random one. Doesn't work with multiple FastLED segments
|
||||||
|
if (!singleSegmentMode)
|
||||||
|
{
|
||||||
|
targetPalette = PartyColors_p; break; //fallback
|
||||||
|
}
|
||||||
|
if (millis() - _lastPaletteChange > 1000 + ((uint32_t)(255-SEGMENT.intensity))*100)
|
||||||
|
{
|
||||||
|
targetPalette = CRGBPalette16(
|
||||||
|
CHSV(random8(), 255, random8(128, 255)),
|
||||||
|
CHSV(random8(), 255, random8(128, 255)),
|
||||||
|
CHSV(random8(), 192, random8(128, 255)),
|
||||||
|
CHSV(random8(), 255, random8(128, 255)));
|
||||||
|
_lastPaletteChange = millis();
|
||||||
|
} break;}
|
||||||
|
case 2: {//primary color only
|
||||||
|
CRGB prim = col_to_crgb(SEGCOLOR(0));
|
||||||
|
targetPalette = CRGBPalette16(prim); break;}
|
||||||
|
case 3: {//primary + secondary
|
||||||
|
CRGB prim = col_to_crgb(SEGCOLOR(0));
|
||||||
|
CRGB sec = col_to_crgb(SEGCOLOR(1));
|
||||||
|
targetPalette = CRGBPalette16(prim,prim,sec,sec); break;}
|
||||||
|
case 4: {//primary + secondary + tertiary
|
||||||
|
CRGB prim = col_to_crgb(SEGCOLOR(0));
|
||||||
|
CRGB sec = col_to_crgb(SEGCOLOR(1));
|
||||||
|
CRGB ter = col_to_crgb(SEGCOLOR(2));
|
||||||
|
targetPalette = CRGBPalette16(ter,sec,prim); break;}
|
||||||
|
case 5: {//primary + secondary (+tert if not off), more distinct
|
||||||
|
CRGB prim = col_to_crgb(SEGCOLOR(0));
|
||||||
|
CRGB sec = col_to_crgb(SEGCOLOR(1));
|
||||||
|
if (SEGCOLOR(2)) {
|
||||||
|
CRGB ter = col_to_crgb(SEGCOLOR(2));
|
||||||
|
targetPalette = CRGBPalette16(prim,prim,prim,prim,prim,sec,sec,sec,sec,sec,ter,ter,ter,ter,ter,prim);
|
||||||
|
} else {
|
||||||
|
targetPalette = CRGBPalette16(prim,prim,prim,prim,prim,prim,prim,prim,sec,sec,sec,sec,sec,sec,sec,sec);
|
||||||
|
}
|
||||||
|
break;}
|
||||||
|
case 6: //Party colors
|
||||||
|
targetPalette = PartyColors_p; break;
|
||||||
|
case 7: //Cloud colors
|
||||||
|
targetPalette = CloudColors_p; break;
|
||||||
|
case 8: //Lava colors
|
||||||
|
targetPalette = LavaColors_p; break;
|
||||||
|
case 9: //Ocean colors
|
||||||
|
targetPalette = OceanColors_p; break;
|
||||||
|
case 10: //Forest colors
|
||||||
|
targetPalette = ForestColors_p; break;
|
||||||
|
case 11: //Rainbow colors
|
||||||
|
targetPalette = RainbowColors_p; break;
|
||||||
|
case 12: //Rainbow stripe colors
|
||||||
|
targetPalette = RainbowStripeColors_p; break;
|
||||||
|
default: //progmem palettes
|
||||||
|
load_gradient_palette(paletteIndex -13);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (singleSegmentMode && paletteFade) //only blend if just one segment uses FastLED mode
|
||||||
|
{
|
||||||
|
nblendPaletteTowardPalette(currentPalette, targetPalette, 48);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
currentPalette = targetPalette;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gets a single color from the currently selected palette.
|
||||||
|
* @param i Palette Index (if mapping is true, the full palette will be SEGLEN long, if false, 255). Will wrap around automatically.
|
||||||
|
* @param mapping if true, LED position in segment is considered for color
|
||||||
|
* @param wrap FastLED palettes will usally wrap back to the start smoothly. Set false to get a hard edge
|
||||||
|
* @param mcol If the default palette 0 is selected, return the standard color 0, 1 or 2 instead. If >2, Party palette is used instead
|
||||||
|
* @param pbri Value to scale the brightness of the returned color by. Default is 255. (no scaling)
|
||||||
|
* @returns Single color from palette
|
||||||
|
*/
|
||||||
|
uint32_t WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri)
|
||||||
|
{
|
||||||
|
if (SEGMENT.palette == 0 && mcol < 3) return SEGCOLOR(mcol); //WS2812FX default
|
||||||
|
uint8_t paletteIndex = i;
|
||||||
|
if (mapping) paletteIndex = (i*255)/(SEGLEN -1);
|
||||||
|
if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
|
||||||
|
CRGB fastled_col;
|
||||||
|
fastled_col = ColorFromPalette( currentPalette, paletteIndex, pbri, (paletteBlend == 3)? NOBLEND:LINEARBLEND);
|
||||||
|
return fastled_col.r*65536 + fastled_col.g*256 + fastled_col.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
//@returns `true` if color, mode, speed, intensity and palette match
|
||||||
|
bool WS2812FX::segmentsAreIdentical(Segment* a, Segment* b)
|
||||||
|
{
|
||||||
|
//if (a->start != b->start) return false;
|
||||||
|
//if (a->stop != b->stop) return false;
|
||||||
|
for (uint8_t i = 0; i < NUM_COLORS; i++)
|
||||||
|
{
|
||||||
|
if (a->colors[i] != b->colors[i]) return false;
|
||||||
|
}
|
||||||
|
if (a->mode != b->mode) return false;
|
||||||
|
if (a->speed != b->speed) return false;
|
||||||
|
if (a->intensity != b->intensity) return false;
|
||||||
|
if (a->palette != b->palette) return false;
|
||||||
|
//if (a->getOption(SEG_OPTION_REVERSED) != b->getOption(SEG_OPTION_REVERSED)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//gamma 2.4 lookup table used for color correction
|
||||||
|
const byte gammaT[] = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||||
|
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
|
||||||
|
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
|
||||||
|
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
||||||
|
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
|
||||||
|
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
|
||||||
|
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
|
||||||
|
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
|
||||||
|
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
|
||||||
|
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
|
||||||
|
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
|
||||||
|
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
|
||||||
|
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
|
||||||
|
|
||||||
|
uint8_t WS2812FX::gamma8(uint8_t b)
|
||||||
|
{
|
||||||
|
return gammaT[b];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t WS2812FX::gamma32(uint32_t color)
|
||||||
|
{
|
||||||
|
if (!gammaCorrectCol) return color;
|
||||||
|
uint8_t r = (color >> 16);
|
||||||
|
uint8_t g = (color >> 8);
|
||||||
|
uint8_t b = color;
|
||||||
|
r = gammaT[r];
|
||||||
|
g = gammaT[g];
|
||||||
|
b = gammaT[b];
|
||||||
|
return ((r << 16) | (g << 8) | (b));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t WS2812FX::_usedSegmentData = 0;
|
20
components/WS2812FX-idf/LICENSE
Normal file
20
components/WS2812FX-idf/LICENSE
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2013 FastLED
|
||||||
|
|
||||||
|
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, sublicense, 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.
|
55
components/WS2812FX-idf/README.md
Normal file
55
components/WS2812FX-idf/README.md
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# WS2812FX pattern library
|
||||||
|
|
||||||
|
There are a few different pattern libraries scattered throughout the internet. One of the better
|
||||||
|
and more interesting started here:
|
||||||
|
|
||||||
|
https://github.com/kitesurfer1404/WS2812FX
|
||||||
|
|
||||||
|
and it uses NeoPixel, and Arduino.
|
||||||
|
|
||||||
|
This is a port to FastLED, and to ESP-IDF.
|
||||||
|
|
||||||
|
This version started from the WLED source code, for no really good reason, as of 9/11/2020.
|
||||||
|
|
||||||
|
https://github.com/Aircoookie/WLED
|
||||||
|
|
||||||
|
# differences
|
||||||
|
|
||||||
|
This port doesn't have RGBW support, nor for analog LEDs, simply because FastLED doesn't support them, so
|
||||||
|
it was easier to rip them out.
|
||||||
|
|
||||||
|
# using
|
||||||
|
|
||||||
|
See `main.cpp` for an example.
|
||||||
|
|
||||||
|
There is one interesting bit about the port, which is instead of subclassing the LEDs,
|
||||||
|
you init it by passing the CRGB LED array in.
|
||||||
|
|
||||||
|
This means you can support a lot of LEDs on a lot of pins. In order to code for that, make sure the CRGB LED array
|
||||||
|
you create is contiguous, like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
#define NUM_LEDS1
|
||||||
|
#define NUM_LEDS2
|
||||||
|
CRGB leds[NUM_LEDS1 + NUM_LEDS2];
|
||||||
|
FastLED.addLeds<LED_TYPE, DATA_PIN1>(&leds[0], NUM_LEDS1);
|
||||||
|
FastLED.addLeds<LED_TYPE, DATA_PIN1>(&leds[1], NUM_LEDS2);
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you can pass all of the leds array with the entire size.
|
||||||
|
|
||||||
|
Then, another benefit of this interface is the segments system. You can have a completly different mapping of
|
||||||
|
segments, arbitrarily so.
|
||||||
|
|
||||||
|
# porting and notes
|
||||||
|
|
||||||
|
Annoyingly, the old code used Arduino calls. They got urned into `#define`s.
|
||||||
|
|
||||||
|
Arduino code likes milliseconds, but ESP-IDF code likes microseconds. There should probably be some re-coding.
|
||||||
|
|
||||||
|
A benefit of the WLED version is you can reuse the WS2812FX object. Interestingly, some patterns
|
||||||
|
allocate per-pixel memory.
|
||||||
|
|
||||||
|
Probably some of the code should be made more FastLED specific, and use more of the 8-bit code.
|
||||||
|
It should also probably be integrated together with 'show' and double-buffer or similar.
|
||||||
|
|
3
components/WS2812FX-idf/component.mk
Normal file
3
components/WS2812FX-idf/component.mk
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
COMPONENT_SRCDIRS := .
|
||||||
|
COMPONENT_ADD_INCLUDEDIRS := .
|
||||||
|
|
634
components/WS2812FX-idf/palettes.h
Normal file
634
components/WS2812FX-idf/palettes.h
Normal file
@ -0,0 +1,634 @@
|
|||||||
|
/*
|
||||||
|
* Color palettes for FastLED effects (65-73).
|
||||||
|
*/
|
||||||
|
|
||||||
|
// From ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb
|
||||||
|
// Unfortunaltely, these are stored in RAM!
|
||||||
|
|
||||||
|
// Gradient palette "ib_jul01_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/ing/xmas/tn/ib_jul01.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 16 uint8_ts each.
|
||||||
|
// BB: removed PROGMEM because that's an arduino thing
|
||||||
|
|
||||||
|
#ifndef PalettesWLED_h
|
||||||
|
#define PalettesWLED_h
|
||||||
|
|
||||||
|
#define GRADIENT_PALETTE_COUNT 39
|
||||||
|
|
||||||
|
const uint8_t ib_jul01_gp[] = {
|
||||||
|
0, 194, 1, 1,
|
||||||
|
94, 1, 29, 18,
|
||||||
|
132, 57,131, 28,
|
||||||
|
255, 113, 1, 1};
|
||||||
|
|
||||||
|
// Gradient palette "es_vintage_57_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/es/vintage/tn/es_vintage_57.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 20 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t es_vintage_57_gp[] = {
|
||||||
|
0, 2, 1, 1,
|
||||||
|
53, 18, 1, 0,
|
||||||
|
104, 69, 29, 1,
|
||||||
|
153, 167,135, 10,
|
||||||
|
255, 46, 56, 4};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "es_vintage_01_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/es/vintage/tn/es_vintage_01.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 32 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t es_vintage_01_gp[] = {
|
||||||
|
0, 4, 1, 1,
|
||||||
|
51, 16, 0, 1,
|
||||||
|
76, 97,104, 3,
|
||||||
|
101, 255,131, 19,
|
||||||
|
127, 67, 9, 4,
|
||||||
|
153, 16, 0, 1,
|
||||||
|
229, 4, 1, 1,
|
||||||
|
255, 4, 1, 1};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "es_rivendell_15_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/es/rivendell/tn/es_rivendell_15.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 20 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t es_rivendell_15_gp[] = {
|
||||||
|
0, 1, 14, 5,
|
||||||
|
101, 16, 36, 14,
|
||||||
|
165, 56, 68, 30,
|
||||||
|
242, 150,156, 99,
|
||||||
|
255, 150,156, 99};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "rgi_15_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/ds/rgi/tn/rgi_15.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 36 uint8_ts of program space.
|
||||||
|
// Edited to be brighter
|
||||||
|
|
||||||
|
const uint8_t rgi_15_gp[] = {
|
||||||
|
0, 4, 1, 70,
|
||||||
|
31, 55, 1, 30,
|
||||||
|
63, 255, 4, 7,
|
||||||
|
95, 59, 2, 29,
|
||||||
|
127, 11, 3, 50,
|
||||||
|
159, 39, 8, 60,
|
||||||
|
191, 112, 19, 40,
|
||||||
|
223, 78, 11, 39,
|
||||||
|
255, 29, 8, 59};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "retro2_16_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/ma/retro2/tn/retro2_16.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 8 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t retro2_16_gp[] = {
|
||||||
|
0, 188,135, 1,
|
||||||
|
255, 46, 7, 1};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "Analogous_1_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/nd/red/tn/Analogous_1.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 20 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t Analogous_1_gp[] = {
|
||||||
|
0, 3, 0,255,
|
||||||
|
63, 23, 0,255,
|
||||||
|
127, 67, 0,255,
|
||||||
|
191, 142, 0, 45,
|
||||||
|
255, 255, 0, 0};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "es_pinksplash_08_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/es/pink_splash/tn/es_pinksplash_08.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 20 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t es_pinksplash_08_gp[] = {
|
||||||
|
0, 126, 11,255,
|
||||||
|
127, 197, 1, 22,
|
||||||
|
175, 210,157,172,
|
||||||
|
221, 157, 3,112,
|
||||||
|
255, 157, 3,112};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "es_ocean_breeze_036_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/es/ocean_breeze/tn/es_ocean_breeze_036.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 16 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t es_ocean_breeze_036_gp[] = {
|
||||||
|
0, 1, 6, 7,
|
||||||
|
89, 1, 99,111,
|
||||||
|
153, 144,209,255,
|
||||||
|
255, 0, 73, 82};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "departure_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/mjf/tn/departure.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 88 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t departure_gp[] = {
|
||||||
|
0, 8, 3, 0,
|
||||||
|
42, 23, 7, 0,
|
||||||
|
63, 75, 38, 6,
|
||||||
|
84, 169, 99, 38,
|
||||||
|
106, 213,169,119,
|
||||||
|
116, 255,255,255,
|
||||||
|
138, 135,255,138,
|
||||||
|
148, 22,255, 24,
|
||||||
|
170, 0,255, 0,
|
||||||
|
191, 0,136, 0,
|
||||||
|
212, 0, 55, 0,
|
||||||
|
255, 0, 55, 0};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "es_landscape_64_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/es/landscape/tn/es_landscape_64.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 36 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t es_landscape_64_gp[] = {
|
||||||
|
0, 0, 0, 0,
|
||||||
|
37, 2, 25, 1,
|
||||||
|
76, 15,115, 5,
|
||||||
|
127, 79,213, 1,
|
||||||
|
128, 126,211, 47,
|
||||||
|
130, 188,209,247,
|
||||||
|
153, 144,182,205,
|
||||||
|
204, 59,117,250,
|
||||||
|
255, 1, 37,192};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "es_landscape_33_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/es/landscape/tn/es_landscape_33.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 24 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t es_landscape_33_gp[] = {
|
||||||
|
0, 1, 5, 0,
|
||||||
|
19, 32, 23, 1,
|
||||||
|
38, 161, 55, 1,
|
||||||
|
63, 229,144, 1,
|
||||||
|
66, 39,142, 74,
|
||||||
|
255, 1, 4, 1};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "rainbowsherbet_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/ma/icecream/tn/rainbowsherbet.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 28 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t rainbowsherbet_gp[] = {
|
||||||
|
0, 255, 33, 4,
|
||||||
|
43, 255, 68, 25,
|
||||||
|
86, 255, 7, 25,
|
||||||
|
127, 255, 82,103,
|
||||||
|
170, 255,255,242,
|
||||||
|
209, 42,255, 22,
|
||||||
|
255, 87,255, 65};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "gr65_hult_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/hult/tn/gr65_hult.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 24 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t gr65_hult_gp[] = {
|
||||||
|
0, 247,176,247,
|
||||||
|
48, 255,136,255,
|
||||||
|
89, 220, 29,226,
|
||||||
|
160, 7, 82,178,
|
||||||
|
216, 1,124,109,
|
||||||
|
255, 1,124,109};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "gr64_hult_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/hult/tn/gr64_hult.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 32 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t gr64_hult_gp[] = {
|
||||||
|
0, 1,124,109,
|
||||||
|
66, 1, 93, 79,
|
||||||
|
104, 52, 65, 1,
|
||||||
|
130, 115,127, 1,
|
||||||
|
150, 52, 65, 1,
|
||||||
|
201, 1, 86, 72,
|
||||||
|
239, 0, 55, 45,
|
||||||
|
255, 0, 55, 45};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "GMT_drywet_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/gmt/tn/GMT_drywet.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 28 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t GMT_drywet_gp[] = {
|
||||||
|
0, 47, 30, 2,
|
||||||
|
42, 213,147, 24,
|
||||||
|
84, 103,219, 52,
|
||||||
|
127, 3,219,207,
|
||||||
|
170, 1, 48,214,
|
||||||
|
212, 1, 1,111,
|
||||||
|
255, 1, 7, 33};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "ib15_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/ing/general/tn/ib15.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 24 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t ib15_gp[] = {
|
||||||
|
0, 113, 91,147,
|
||||||
|
72, 157, 88, 78,
|
||||||
|
89, 208, 85, 33,
|
||||||
|
107, 255, 29, 11,
|
||||||
|
141, 137, 31, 39,
|
||||||
|
255, 59, 33, 89};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "Tertiary_01_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/nd/vermillion/tn/Tertiary_01.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 20 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t Tertiary_01_gp[] = {
|
||||||
|
0, 0, 1,255,
|
||||||
|
63, 3, 68, 45,
|
||||||
|
127, 23,255, 0,
|
||||||
|
191, 100, 68, 1,
|
||||||
|
255, 255, 1, 4};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "lava_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/neota/elem/tn/lava.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 52 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t lava_gp[] = {
|
||||||
|
0, 0, 0, 0,
|
||||||
|
46, 18, 0, 0,
|
||||||
|
96, 113, 0, 0,
|
||||||
|
108, 142, 3, 1,
|
||||||
|
119, 175, 17, 1,
|
||||||
|
146, 213, 44, 2,
|
||||||
|
174, 255, 82, 4,
|
||||||
|
188, 255,115, 4,
|
||||||
|
202, 255,156, 4,
|
||||||
|
218, 255,203, 4,
|
||||||
|
234, 255,255, 4,
|
||||||
|
244, 255,255, 71,
|
||||||
|
255, 255,255,255};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "fierce_ice_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/neota/elem/tn/fierce-ice.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 28 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t fierce_ice_gp[] = {
|
||||||
|
0, 0, 0, 0,
|
||||||
|
59, 0, 9, 45,
|
||||||
|
119, 0, 38,255,
|
||||||
|
149, 3,100,255,
|
||||||
|
180, 23,199,255,
|
||||||
|
217, 100,235,255,
|
||||||
|
255, 255,255,255};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "Colorfull_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/nd/atmospheric/tn/Colorfull.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 44 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t Colorfull_gp[] = {
|
||||||
|
0, 10, 85, 5,
|
||||||
|
25, 29,109, 18,
|
||||||
|
60, 59,138, 42,
|
||||||
|
93, 83, 99, 52,
|
||||||
|
106, 110, 66, 64,
|
||||||
|
109, 123, 49, 65,
|
||||||
|
113, 139, 35, 66,
|
||||||
|
116, 192,117, 98,
|
||||||
|
124, 255,255,137,
|
||||||
|
168, 100,180,155,
|
||||||
|
255, 22,121,174};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "Pink_Purple_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/nd/atmospheric/tn/Pink_Purple.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 44 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t Pink_Purple_gp[] = {
|
||||||
|
0, 19, 2, 39,
|
||||||
|
25, 26, 4, 45,
|
||||||
|
51, 33, 6, 52,
|
||||||
|
76, 68, 62,125,
|
||||||
|
102, 118,187,240,
|
||||||
|
109, 163,215,247,
|
||||||
|
114, 217,244,255,
|
||||||
|
122, 159,149,221,
|
||||||
|
149, 113, 78,188,
|
||||||
|
183, 128, 57,155,
|
||||||
|
255, 146, 40,123};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "Sunset_Real_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/nd/atmospheric/tn/Sunset_Real.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 28 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t Sunset_Real_gp[] = {
|
||||||
|
0, 120, 0, 0,
|
||||||
|
22, 179, 22, 0,
|
||||||
|
51, 255,104, 0,
|
||||||
|
85, 167, 22, 18,
|
||||||
|
135, 100, 0,103,
|
||||||
|
198, 16, 0,130,
|
||||||
|
255, 0, 0,160};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "Sunset_Yellow_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/nd/atmospheric/tn/Sunset_Yellow.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 44 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t Sunset_Yellow_gp[] = {
|
||||||
|
0, 10, 62,123,
|
||||||
|
36, 56,130,103,
|
||||||
|
87, 153,225, 85,
|
||||||
|
100, 199,217, 68,
|
||||||
|
107, 255,207, 54,
|
||||||
|
115, 247,152, 57,
|
||||||
|
120, 239,107, 61,
|
||||||
|
128, 247,152, 57,
|
||||||
|
180, 255,207, 54,
|
||||||
|
223, 255,227, 48,
|
||||||
|
255, 255,248, 42};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "Beech_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/nd/atmospheric/tn/Beech.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 60 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t Beech_gp[] = {
|
||||||
|
0, 255,252,214,
|
||||||
|
12, 255,252,214,
|
||||||
|
22, 255,252,214,
|
||||||
|
26, 190,191,115,
|
||||||
|
28, 137,141, 52,
|
||||||
|
28, 112,255,205,
|
||||||
|
50, 51,246,214,
|
||||||
|
71, 17,235,226,
|
||||||
|
93, 2,193,199,
|
||||||
|
120, 0,156,174,
|
||||||
|
133, 1,101,115,
|
||||||
|
136, 1, 59, 71,
|
||||||
|
136, 7,131,170,
|
||||||
|
208, 1, 90,151,
|
||||||
|
255, 0, 56,133};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "Another_Sunset_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/nd/atmospheric/tn/Another_Sunset.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 32 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t Another_Sunset_gp[] = {
|
||||||
|
0, 110, 49, 11,
|
||||||
|
29, 55, 34, 10,
|
||||||
|
68, 22, 22, 9,
|
||||||
|
68, 239,124, 8,
|
||||||
|
97, 220,156, 27,
|
||||||
|
124, 203,193, 61,
|
||||||
|
178, 33, 53, 56,
|
||||||
|
255, 0, 1, 52};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "es_autumn_19_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/es/autumn/tn/es_autumn_19.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 52 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t es_autumn_19_gp[] = {
|
||||||
|
0, 26, 1, 1,
|
||||||
|
51, 67, 4, 1,
|
||||||
|
84, 118, 14, 1,
|
||||||
|
104, 137,152, 52,
|
||||||
|
112, 113, 65, 1,
|
||||||
|
122, 133,149, 59,
|
||||||
|
124, 137,152, 52,
|
||||||
|
135, 113, 65, 1,
|
||||||
|
142, 139,154, 46,
|
||||||
|
163, 113, 13, 1,
|
||||||
|
204, 55, 3, 1,
|
||||||
|
249, 17, 1, 1,
|
||||||
|
255, 17, 1, 1};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "BlacK_Blue_Magenta_White_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/nd/basic/tn/BlacK_Blue_Magenta_White.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 28 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t BlacK_Blue_Magenta_White_gp[] = {
|
||||||
|
0, 0, 0, 0,
|
||||||
|
42, 0, 0, 45,
|
||||||
|
84, 0, 0,255,
|
||||||
|
127, 42, 0,255,
|
||||||
|
170, 255, 0,255,
|
||||||
|
212, 255, 55,255,
|
||||||
|
255, 255,255,255};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "BlacK_Magenta_Red_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/nd/basic/tn/BlacK_Magenta_Red.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 20 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t BlacK_Magenta_Red_gp[] = {
|
||||||
|
0, 0, 0, 0,
|
||||||
|
63, 42, 0, 45,
|
||||||
|
127, 255, 0,255,
|
||||||
|
191, 255, 0, 45,
|
||||||
|
255, 255, 0, 0};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "BlacK_Red_Magenta_Yellow_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/nd/basic/tn/BlacK_Red_Magenta_Yellow.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 28 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t BlacK_Red_Magenta_Yellow_gp[] = {
|
||||||
|
0, 0, 0, 0,
|
||||||
|
42, 42, 0, 0,
|
||||||
|
84, 255, 0, 0,
|
||||||
|
127, 255, 0, 45,
|
||||||
|
170, 255, 0,255,
|
||||||
|
212, 255, 55, 45,
|
||||||
|
255, 255,255, 0};
|
||||||
|
|
||||||
|
|
||||||
|
// Gradient palette "Blue_Cyan_Yellow_gp", originally from
|
||||||
|
// http://soliton.vm.uint8_tmark.co.uk/pub/cpt-city/nd/basic/tn/Blue_Cyan_Yellow.png.index.html
|
||||||
|
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||||
|
// Size: 20 uint8_ts of program space.
|
||||||
|
|
||||||
|
const uint8_t Blue_Cyan_Yellow_gp[] = {
|
||||||
|
0, 0, 0,255,
|
||||||
|
63, 0, 55,255,
|
||||||
|
127, 0,255,255,
|
||||||
|
191, 42,255, 45,
|
||||||
|
255, 255,255, 0};
|
||||||
|
|
||||||
|
|
||||||
|
//Custom palette by Aircoookie
|
||||||
|
|
||||||
|
const uint8_t Orange_Teal_gp[] = {
|
||||||
|
0, 0,150, 92,
|
||||||
|
55, 0,150, 92,
|
||||||
|
200, 255, 72, 0,
|
||||||
|
255, 255, 72, 0};
|
||||||
|
|
||||||
|
//Custom palette by Aircoookie
|
||||||
|
|
||||||
|
const uint8_t Tiamat_gp[] = {
|
||||||
|
0, 1, 2, 14, //gc
|
||||||
|
33, 2, 5, 35, //gc from 47, 61,126
|
||||||
|
100, 13,135, 92, //gc from 88,242,247
|
||||||
|
120, 43,255,193, //gc from 135,255,253
|
||||||
|
140, 247, 7,249, //gc from 252, 69,253
|
||||||
|
160, 193, 17,208, //gc from 231, 96,237
|
||||||
|
180, 39,255,154, //gc from 130, 77,213
|
||||||
|
200, 4,213,236, //gc from 57,122,248
|
||||||
|
220, 39,252,135, //gc from 177,254,255
|
||||||
|
240, 193,213,253, //gc from 203,239,253
|
||||||
|
255, 255,249,255};
|
||||||
|
|
||||||
|
//Custom palette by Aircoookie
|
||||||
|
|
||||||
|
const uint8_t April_Night_gp[] = {
|
||||||
|
0, 1, 5, 45, //deep blue
|
||||||
|
10, 1, 5, 45,
|
||||||
|
25, 5,169,175, //light blue
|
||||||
|
40, 1, 5, 45,
|
||||||
|
61, 1, 5, 45,
|
||||||
|
76, 45,175, 31, //green
|
||||||
|
91, 1, 5, 45,
|
||||||
|
112, 1, 5, 45,
|
||||||
|
127, 249,150, 5, //yellow
|
||||||
|
143, 1, 5, 45,
|
||||||
|
162, 1, 5, 45,
|
||||||
|
178, 255, 92, 0, //pastel orange
|
||||||
|
193, 1, 5, 45,
|
||||||
|
214, 1, 5, 45,
|
||||||
|
229, 223, 45, 72, //pink
|
||||||
|
244, 1, 5, 45,
|
||||||
|
255, 1, 5, 45};
|
||||||
|
|
||||||
|
const uint8_t Orangery_gp[] = {
|
||||||
|
0, 255, 95, 23,
|
||||||
|
30, 255, 82, 0,
|
||||||
|
60, 223, 13, 8,
|
||||||
|
90, 144, 44, 2,
|
||||||
|
120, 255,110, 17,
|
||||||
|
150, 255, 69, 0,
|
||||||
|
180, 158, 13, 11,
|
||||||
|
210, 241, 82, 17,
|
||||||
|
255, 213, 37, 4};
|
||||||
|
|
||||||
|
//inspired by Mark Kriegsman https://gist.github.com/kriegsman/756ea6dcae8e30845b5a
|
||||||
|
const uint8_t C9_gp[] = {
|
||||||
|
0, 184, 4, 0, //red
|
||||||
|
60, 184, 4, 0,
|
||||||
|
65, 144, 44, 2, //amber
|
||||||
|
125, 144, 44, 2,
|
||||||
|
130, 4, 96, 2, //green
|
||||||
|
190, 4, 96, 2,
|
||||||
|
195, 7, 7, 88, //blue
|
||||||
|
255, 7, 7, 88};
|
||||||
|
|
||||||
|
const uint8_t Sakura_gp[] = {
|
||||||
|
0, 196, 19, 10,
|
||||||
|
65, 255, 69, 45,
|
||||||
|
130, 223, 45, 72,
|
||||||
|
195, 255, 82,103,
|
||||||
|
255, 223, 13, 17};
|
||||||
|
|
||||||
|
const uint8_t Aurora_gp[] = {
|
||||||
|
0, 1, 5, 45, //deep blue
|
||||||
|
64, 0,200, 23,
|
||||||
|
128, 0,255, 0, //green
|
||||||
|
170, 0,243, 45,
|
||||||
|
200, 0,135, 7,
|
||||||
|
255, 1, 5, 45};//deep blue
|
||||||
|
|
||||||
|
const uint8_t Atlantica_gp[] = {
|
||||||
|
0, 0, 28,112, //#001C70
|
||||||
|
50, 32, 96,255, //#2060FF
|
||||||
|
100, 0,243, 45,
|
||||||
|
150, 12, 95, 82, //#0C5F52
|
||||||
|
200, 25,190, 95, //#19BE5F
|
||||||
|
255, 40,170, 80};//#28AA50
|
||||||
|
|
||||||
|
|
||||||
|
// Single array of defined cpt-city color palettes.
|
||||||
|
// This will let us programmatically choose one based on
|
||||||
|
// a number, rather than having to activate each explicitly
|
||||||
|
// by name every time.
|
||||||
|
const uint8_t* const gGradientPalettes[] = {
|
||||||
|
Sunset_Real_gp, //13-00 Sunset
|
||||||
|
es_rivendell_15_gp, //14-01 Rivendell
|
||||||
|
es_ocean_breeze_036_gp, //15-02 Breeze
|
||||||
|
rgi_15_gp, //16-03 Red & Blue
|
||||||
|
retro2_16_gp, //17-04 Yellowout
|
||||||
|
Analogous_1_gp, //18-05 Analogous
|
||||||
|
es_pinksplash_08_gp, //19-06 Splash
|
||||||
|
Sunset_Yellow_gp, //20-07 Pastel
|
||||||
|
Another_Sunset_gp, //21-08 Sunset2
|
||||||
|
Beech_gp, //22-09 Beech
|
||||||
|
es_vintage_01_gp, //23-10 Vintage
|
||||||
|
departure_gp, //24-11 Departure
|
||||||
|
es_landscape_64_gp, //25-12 Landscape
|
||||||
|
es_landscape_33_gp, //26-13 Beach
|
||||||
|
rainbowsherbet_gp, //27-14 Sherbet
|
||||||
|
gr65_hult_gp, //28-15 Hult
|
||||||
|
gr64_hult_gp, //29-16 Hult64
|
||||||
|
GMT_drywet_gp, //30-17 Drywet
|
||||||
|
ib_jul01_gp, //31-18 Jul
|
||||||
|
es_vintage_57_gp, //32-19 Grintage
|
||||||
|
ib15_gp, //33-20 Rewhi
|
||||||
|
Tertiary_01_gp, //34-21 Tertiary
|
||||||
|
lava_gp, //35-22 Fire
|
||||||
|
fierce_ice_gp, //36-23 Icefire
|
||||||
|
Colorfull_gp, //37-24 Cyane
|
||||||
|
Pink_Purple_gp, //38-25 Light Pink
|
||||||
|
es_autumn_19_gp, //39-26 Autumn
|
||||||
|
BlacK_Blue_Magenta_White_gp, //40-27 Magenta
|
||||||
|
BlacK_Magenta_Red_gp, //41-28 Magred
|
||||||
|
BlacK_Red_Magenta_Yellow_gp, //42-29 Yelmag
|
||||||
|
Blue_Cyan_Yellow_gp, //43-30 Yelblu
|
||||||
|
Orange_Teal_gp, //44-31 Orange & Teal
|
||||||
|
Tiamat_gp, //45-32 Tiamat
|
||||||
|
April_Night_gp, //46-33 April Night
|
||||||
|
Orangery_gp, //47-34 Orangery
|
||||||
|
C9_gp, //48-35 C9
|
||||||
|
Sakura_gp, //49-36 Sakura
|
||||||
|
Aurora_gp, //50-37 Aurora
|
||||||
|
Atlantica_gp, //51-38 Atlantica
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -14,6 +14,8 @@
|
|||||||
#include "esp_spi_flash.h"
|
#include "esp_spi_flash.h"
|
||||||
|
|
||||||
#include "FastLED.h"
|
#include "FastLED.h"
|
||||||
|
#include "FX.h"
|
||||||
|
|
||||||
CRGBPalette16 currentPalette;
|
CRGBPalette16 currentPalette;
|
||||||
TBlendType currentBlending;
|
TBlendType currentBlending;
|
||||||
|
|
||||||
@ -27,6 +29,7 @@ extern const TProgmemPalette16 IRAM_ATTR myRedWhiteBluePalette_p;
|
|||||||
#define BRIGHTNESS 80
|
#define BRIGHTNESS 80
|
||||||
#define LED_TYPE WS2811
|
#define LED_TYPE WS2811
|
||||||
#define COLOR_ORDER RGB
|
#define COLOR_ORDER RGB
|
||||||
|
|
||||||
CRGB leds[NUM_LEDS];
|
CRGB leds[NUM_LEDS];
|
||||||
|
|
||||||
|
|
||||||
@ -34,6 +37,40 @@ extern "C" {
|
|||||||
void app_main();
|
void app_main();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* test using the FX unit
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void blinkWithFx(void *pvParameters) {
|
||||||
|
|
||||||
|
uint16_t mode = FX_MODE_STATIC;
|
||||||
|
|
||||||
|
WS2812FX ws2812fx;
|
||||||
|
|
||||||
|
ws2812fx.init(NUM_LEDS, leds, false); // type was configured before
|
||||||
|
ws2812fx.setBrightness(255);
|
||||||
|
ws2812fx.setMode(0 /*segid*/, mode);
|
||||||
|
|
||||||
|
|
||||||
|
// microseconds
|
||||||
|
uint64_t mode_change_time = esp_timer_get_time();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
if ((mode_change_time + 10000000L) < esp_timer_get_time() ) {
|
||||||
|
mode += 1;
|
||||||
|
mode %= MODE_COUNT;
|
||||||
|
mode_change_time = esp_timer_get_time();
|
||||||
|
ws2812fx.setMode(0 /*segid*/, mode);
|
||||||
|
printf(" changed mode to %d\n", mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
ws2812fx.service();
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS); /*10ms*/
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ChangePalettePeriodically(){
|
void ChangePalettePeriodically(){
|
||||||
|
|
||||||
@ -223,7 +260,8 @@ void app_main() {
|
|||||||
|
|
||||||
// change the task below to one of the functions above to try different patterns
|
// change the task below to one of the functions above to try different patterns
|
||||||
printf("create task for led blinking\n");
|
printf("create task for led blinking\n");
|
||||||
//xTaskCreatePinnedToCore(&blinkLeds_simple, "blinkLeds", 4000, NULL, 5, NULL, 0);
|
|
||||||
|
|
||||||
xTaskCreatePinnedToCore(&fastfade, "blinkLeds", 4000, NULL, 5, NULL, 0);
|
//xTaskCreatePinnedToCore(&blinkLeds_simple, "blinkLeds", 4000, NULL, 5, NULL, 0);
|
||||||
|
//xTaskCreatePinnedToCore(&fastfade, "blinkLeds", 4000, NULL, 5, NULL, 0);
|
||||||
|
xTaskCreatePinnedToCore(&blinkWithFx, "blinkLeds", 4000, NULL, 5, NULL, 0);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user