mirror of
https://github.com/bbulkow/FastLED-idf.git
synced 2025-07-29 18:28:23 +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
|
||||
|
||||
@ -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
|
||||
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`.
|
||||
|
||||
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
|
||||
|
||||
# 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
|
||||
|
||||
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
|
||||
give it a try.
|
||||
|
||||
I've read scary stuff about Rev0 and GPIO. You have to insert a number of NOP statements
|
||||
between bangs of the pins. If you're using that version, you might want to look carefully
|
||||
into the issue.
|
||||
For master, either use the standard `sdkconfig` or build your own. Remove this one,
|
||||
and `idf.py menuconfig`, and set whatever paramenters you need. There is
|
||||
nothing in this library that's specific to any particular version.
|
||||
|
||||
# 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.
|
||||
|
||||
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 ),
|
||||
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
|
||||
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
|
||||
wasn't working, because the use of templates obscured the IRAM_ATTR attribute. Which
|
||||
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.
|
||||
However, I found that the primarily issue with visual artifacts in RMT had to do with
|
||||
the amount of ESP-IDF jitter.
|
||||
|
||||
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
|
||||
|
||||
|
@ -1,6 +1,11 @@
|
||||
#ifndef __INC_LIB8TION_H
|
||||
#define __INC_LIB8TION_H
|
||||
|
||||
/* defines get_millis() */
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_timer.h"
|
||||
|
||||
#include "FastLED.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:
|
||||
// uint32_t get_millisecond_timer();
|
||||
// that provides similar functionality.
|
||||
// You can also force use of the get_millisecond_timer function
|
||||
// by #defining USE_GET_MILLISECOND_TIMER.
|
||||
#if (defined(ARDUINO) || defined(SPARK) || defined(FASTLED_HAS_MILLIS)) && !defined(USE_GET_MILLISECOND_TIMER)
|
||||
// Forward declaration of Arduino function 'millis'.
|
||||
//uint32_t millis();
|
||||
#define GET_MILLIS millis
|
||||
#else
|
||||
uint32_t get_millisecond_timer();
|
||||
#define GET_MILLIS get_millisecond_timer
|
||||
#endif
|
||||
//
|
||||
// On ESP-IDF we have esp_timer_get_time which has microseconds.
|
||||
// It's a little expensive to get micros and divide, but.... good for now and later we'll
|
||||
// fix that uses it
|
||||
|
||||
#define GET_MILLIS() (get_millisecond_timer())
|
||||
static inline uint32_t get_millisecond_timer() { return( esp_timer_get_time() / 1000); }
|
||||
|
||||
// beat16 generates a 16-bit 'sawtooth' wave at a given BPM,
|
||||
/// 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 "FastLED.h"
|
||||
#include "FX.h"
|
||||
|
||||
CRGBPalette16 currentPalette;
|
||||
TBlendType currentBlending;
|
||||
|
||||
@ -27,6 +29,7 @@ extern const TProgmemPalette16 IRAM_ATTR myRedWhiteBluePalette_p;
|
||||
#define BRIGHTNESS 80
|
||||
#define LED_TYPE WS2811
|
||||
#define COLOR_ORDER RGB
|
||||
|
||||
CRGB leds[NUM_LEDS];
|
||||
|
||||
|
||||
@ -34,6 +37,40 @@ extern "C" {
|
||||
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(){
|
||||
|
||||
@ -223,7 +260,8 @@ void app_main() {
|
||||
|
||||
// change the task below to one of the functions above to try different patterns
|
||||
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