My apologies gentlemen, I thought it would be better to post it zipped since it's 2100 lines and I can't isolate the error to just one section (plus, as mentioned, rearranging the code changes but does not eliminate the 'undeclared' function)
A summary of the error would be:
W:\Documents\SourceCode\uControllers\Arduino\Pixels\Janine\XMasTree_Janine\XMasTree_Janine.ino: In function 'void setup()':
XMasTree_Janine:798:5: error: 'setDefaults' was not declared in this scope
setDefaults();
^~~~~~~~~~~
W:\Documents\SourceCode\uControllers\Arduino\Pixels\Janine\XMasTree_Janine\XMasTree_Janine.ino:798:5: note: suggested alternative: 'setTestDefaults'
setDefaults();
^~~~~~~~~~~
setTestDefaults
And the full error is:
D:\arduino\arduino-builder -dump-prefs -logger=machine -hardware D:\arduino\hardware -hardware C:\Users\Wizard\AppData\Local\Arduino15\packages -hardware W:\Documents\SourceCode\uControllers\hardware -tools D:\arduino\tools-builder -tools D:\arduino\hardware\tools\avr -tools C:\Users\Wizard\AppData\Local\Arduino15\packages -built-in-libraries D:\arduino\libraries -libraries W:\Documents\SourceCode\uControllers\libraries -fqbn=SparkFun:avr:promicro:cpu=16MHzatmega32U4 -ide-version=10819 -build-path C:\Users\Wizard\AppData\Local\Temp\arduino_build_585799 -warnings=default -build-cache C:\Users\Wizard\AppData\Local\Temp\arduino_cache_947569 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avrdude.path=C:\Users\Wizard\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=C:\Users\Wizard\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17 -prefs=runtime.tools.avr-gcc.path=C:\Users\Wizard\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=C:\Users\Wizard\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.arduinoOTA.path=C:\Users\Wizard\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=C:\Users\Wizard\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0 -verbose W:\Documents\SourceCode\uControllers\Arduino\Pixels\Janine\XMasTree_Janine\XMasTree_Janine.ino
D:\arduino\arduino-builder -compile -logger=machine -hardware D:\arduino\hardware -hardware C:\Users\Wizard\AppData\Local\Arduino15\packages -hardware W:\Documents\SourceCode\uControllers\hardware -tools D:\arduino\tools-builder -tools D:\arduino\hardware\tools\avr -tools C:\Users\Wizard\AppData\Local\Arduino15\packages -built-in-libraries D:\arduino\libraries -libraries W:\Documents\SourceCode\uControllers\libraries -fqbn=SparkFun:avr:promicro:cpu=16MHzatmega32U4 -ide-version=10819 -build-path C:\Users\Wizard\AppData\Local\Temp\arduino_build_585799 -warnings=default -build-cache C:\Users\Wizard\AppData\Local\Temp\arduino_cache_947569 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avrdude.path=C:\Users\Wizard\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=C:\Users\Wizard\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17 -prefs=runtime.tools.avr-gcc.path=C:\Users\Wizard\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=C:\Users\Wizard\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.arduinoOTA.path=C:\Users\Wizard\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=C:\Users\Wizard\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0 -verbose W:\Documents\SourceCode\uControllers\Arduino\Pixels\Janine\XMasTree_Janine\XMasTree_Janine.ino
Using board 'promicro' from platform in folder: C:\Users\Wizard\AppData\Local\arduino15\packages\SparkFun\hardware\avr\1.1.13
Using core 'arduino' from platform in folder: C:\Users\Wizard\AppData\Local\arduino15\packages\arduino\hardware\avr\1.8.5
Warning: Board arduino:avr://leonardo doesn't define a 'build.board' preference. Auto-set to: AVR_//LEONARDO
Detecting libraries used...
"C:\\Users\\Wizard\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_PROMICRO -DARDUINO_ARCH_AVR -DUSB_VID=0x1b4f -DUSB_PID=0x9206 "-DUSB_MANUFACTURER=\"Unknown\"" "-DUSB_PRODUCT=\"SparkFun Pro Micro\"" "-IC:\\Users\\Wizard\\AppData\\Local\\arduino15\\packages\\arduino\\hardware\\avr\\1.8.5\\cores\\arduino" "-IC:\\Users\\Wizard\\AppData\\Local\\arduino15\\packages\\SparkFun\\hardware\\avr\\1.1.13\\variants\\promicro" "C:\\Users\\Wizard\\AppData\\Local\\Temp\\arduino_build_585799\\sketch\\XMasTree_Janine.ino.cpp" -o nul
Alternatives for EEPROMex.h: [EEPROMex@1.0.0]
ResolveLibrary(EEPROMex.h)
-> candidates: [EEPROMex@1.0.0]
"C:\\Users\\Wizard\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_PROMICRO -DARDUINO_ARCH_AVR -DUSB_VID=0x1b4f -DUSB_PID=0x9206 "-DUSB_MANUFACTURER=\"Unknown\"" "-DUSB_PRODUCT=\"SparkFun Pro Micro\"" "-IC:\\Users\\Wizard\\AppData\\Local\\arduino15\\packages\\arduino\\hardware\\avr\\1.8.5\\cores\\arduino" "-IC:\\Users\\Wizard\\AppData\\Local\\arduino15\\packages\\SparkFun\\hardware\\avr\\1.1.13\\variants\\promicro" "-IW:\\Documents\\SourceCode\\uControllers\\libraries\\EEPROMex" "C:\\Users\\Wizard\\AppData\\Local\\Temp\\arduino_build_585799\\sketch\\XMasTree_Janine.ino.cpp" -o nul
Alternatives for FastLED.h: [FastLED@3.5.0]
ResolveLibrary(FastLED.h)
-> candidates: [FastLED@3.5.0]
"C:\\Users\\Wizard\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_PROMICRO -DARDUINO_ARCH_AVR -DUSB_VID=0x1b4f -DUSB_PID=0x9206 "-DUSB_MANUFACTURER=\"Unknown\"" "-DUSB_PRODUCT=\"SparkFun Pro Micro\"" "-IC:\\Users\\Wizard\\AppData\\Local\\arduino15\\packages\\arduino\\hardware\\avr\\1.8.5\\cores\\arduino" "-IC:\\Users\\Wizard\\AppData\\Local\\arduino15\\packages\\SparkFun\\hardware\\avr\\1.1.13\\variants\\promicro" "-IW:\\Documents\\SourceCode\\uControllers\\libraries\\EEPROMex" "-IW:\\Documents\\SourceCode\\uControllers\\libraries\\FastLED\\src" "C:\\Users\\Wizard\\AppData\\Local\\Temp\\arduino_build_585799\\sketch\\XMasTree_Janine.ino.cpp" -o nul
Using cached library dependencies for file: W:\Documents\SourceCode\uControllers\libraries\EEPROMex\EEPROMex.cpp
Using cached library dependencies for file: W:\Documents\SourceCode\uControllers\libraries\FastLED\src\FastLED.cpp
Using cached library dependencies for file: W:\Documents\SourceCode\uControllers\libraries\FastLED\src\bitswap.cpp
Using cached library dependencies for file: W:\Documents\SourceCode\uControllers\libraries\FastLED\src\colorpalettes.cpp
Using cached library dependencies for file: W:\Documents\SourceCode\uControllers\libraries\FastLED\src\colorutils.cpp
Using cached library dependencies for file: W:\Documents\SourceCode\uControllers\libraries\FastLED\src\hsv2rgb.cpp
Using cached library dependencies for file: W:\Documents\SourceCode\uControllers\libraries\FastLED\src\lib8tion.cpp
Using cached library dependencies for file: W:\Documents\SourceCode\uControllers\libraries\FastLED\src\noise.cpp
Using cached library dependencies for file: W:\Documents\SourceCode\uControllers\libraries\FastLED\src\platforms\esp\32\clockless_rmt_esp32.cpp
Using cached library dependencies for file: W:\Documents\SourceCode\uControllers\libraries\FastLED\src\platforms.cpp
Using cached library dependencies for file: W:\Documents\SourceCode\uControllers\libraries\FastLED\src\power_mgt.cpp
Using cached library dependencies for file: W:\Documents\SourceCode\uControllers\libraries\FastLED\src\wiring.cpp
Generating function prototypes...
"C:\\Users\\Wizard\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_PROMICRO -DARDUINO_ARCH_AVR -DUSB_VID=0x1b4f -DUSB_PID=0x9206 "-DUSB_MANUFACTURER=\"Unknown\"" "-DUSB_PRODUCT=\"SparkFun Pro Micro\"" "-IC:\\Users\\Wizard\\AppData\\Local\\arduino15\\packages\\arduino\\hardware\\avr\\1.8.5\\cores\\arduino" "-IC:\\Users\\Wizard\\AppData\\Local\\arduino15\\packages\\SparkFun\\hardware\\avr\\1.1.13\\variants\\promicro" "-IW:\\Documents\\SourceCode\\uControllers\\libraries\\EEPROMex" "-IW:\\Documents\\SourceCode\\uControllers\\libraries\\FastLED\\src" "C:\\Users\\Wizard\\AppData\\Local\\Temp\\arduino_build_585799\\sketch\\XMasTree_Janine.ino.cpp" -o "C:\\Users\\Wizard\\AppData\\Local\\Temp\\arduino_build_585799\\preproc\\ctags_target_for_gcc_minus_e.cpp"
"D:\\arduino\\tools-builder\\ctags\\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\\Users\\Wizard\\AppData\\Local\\Temp\\arduino_build_585799\\preproc\\ctags_target_for_gcc_minus_e.cpp"
Compiling sketch...
"C:\\Users\\Wizard\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -flto -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_PROMICRO -DARDUINO_ARCH_AVR -DUSB_VID=0x1b4f -DUSB_PID=0x9206 "-DUSB_MANUFACTURER=\"Unknown\"" "-DUSB_PRODUCT=\"SparkFun Pro Micro\"" "-IC:\\Users\\Wizard\\AppData\\Local\\arduino15\\packages\\arduino\\hardware\\avr\\1.8.5\\cores\\arduino" "-IC:\\Users\\Wizard\\AppData\\Local\\arduino15\\packages\\SparkFun\\hardware\\avr\\1.1.13\\variants\\promicro" "-IW:\\Documents\\SourceCode\\uControllers\\libraries\\EEPROMex" "-IW:\\Documents\\SourceCode\\uControllers\\libraries\\FastLED\\src" "C:\\Users\\Wizard\\AppData\\Local\\Temp\\arduino_build_585799\\sketch\\XMasTree_Janine.ino.cpp" -o "C:\\Users\\Wizard\\AppData\\Local\\Temp\\arduino_build_585799\\sketch\\XMasTree_Janine.ino.cpp.o"
W:\Documents\SourceCode\uControllers\Arduino\Pixels\Janine\XMasTree_Janine\XMasTree_Janine.ino: In function 'void setup()':
XMasTree_Janine:798:5: error: 'setDefaults' was not declared in this scope
setDefaults();
^~~~~~~~~~~
W:\Documents\SourceCode\uControllers\Arduino\Pixels\Janine\XMasTree_Janine\XMasTree_Janine.ino:798:5: note: suggested alternative: 'setTestDefaults'
setDefaults();
^~~~~~~~~~~
setTestDefaults
W:\Documents\SourceCode\uControllers\Arduino\Pixels\Janine\XMasTree_Janine\XMasTree_Janine.ino: In function 'long int color2hex(CRGB)':
W:\Documents\SourceCode\uControllers\Arduino\Pixels\Janine\XMasTree_Janine\XMasTree_Janine.ino:925:28: warning: left shift count >= width of type [-Wshift-count-overflow]
long ret = theColor.r << 16;
^~
Using library EEPROMex at version 1.0.0 in folder: W:\Documents\SourceCode\uControllers\libraries\EEPROMex
Using library FastLED at version 3.5.0 in folder: W:\Documents\SourceCode\uControllers\libraries\FastLED
exit status 1
'setDefaults' was not declared in this scope
The code for XMasTree_Janine.ino is:
/**** XmasWS2811 ***
Controls a string of 2801/2811/2812 etc. "Pixels"** for a Christmas Tree
Patterns, Colors, etc.
** THIS sketch uses the FastLED 3.x.x Library
UnCopyright (u) 2022+ Dr. Wizard K. Pendleton and Wizlights Software
Released under General Public License.
Open Source Rules Apply: No warranty of any kind! It works for me, but I don't guarantee
that it won't crash spectacularly for you!
Send comments, complaints, bug fixes, updates, enhancements, and good dirty jokes to:
dev.arduino@drwiz.net
This is the version for Princess Janine D'Berry's Christmas Tree
and includes a custom effect list just for her.
*/
#include <EEPROMex.h>
#include <EEPROMVar.h>
#include <FastLED.h>
//#include <Wire.h>
#include "DebugUtils.h"
// ****************
// ** WS2811 **
// ** (Pixels) **
// ** L E D s **
// ****************
#define DATA_PIN 21 // aka A3, using that one cuz its right beside VCC, and close to GND
// Obviously, a different pin could be used if necessary.
#define MAX_LEDS 512
int num_leds = 250;
//struct CRGB
//{
// byte r;
// byte g;
// byte b;
//};
// HERE'S THE BIG MEMORY HOG!
// THIS TAKES 5K OF THE ARDUINO MEGA 2560'S 8K OF RAM, RIGHT HERE
// 5 Bytes for each of the 1024 LEDS
// 3 Bytes for the color of each LED,
// 2 Bytes for a list of Pixel #'s in some particular order for certain effects
// such as Sparkle and Dissolve
// Define the array of leds
CRGB leds[MAX_LEDS];
int theList[MAX_LEDS]; // For storing a list of which pixel something was done to on the last pass
// Also used for random dissolve effect
// ****************
// ** Standard **
// ** Colors **
// ****************
#define COLOR_BLACK_OFF 0
#define RGB_BLACK_OFF 0x000000L
#define COLOR_CUSTOM1 1
#define COLOR_CUSTOM2 2
#define COLOR_CUSTOM3 3
#define COLOR_CUSTOM4 4
#define COLOR_CUSTOM5 5
#define COLOR_CUSTOM6 6
#define COLOR_CUSTOM7 7
#define COLOR_CUSTOM8 8
#define COLOR_RED 9
#define RGB_RED 0xff0000L
#define COLOR_GREEN 10
#define RGB_GREEN 0x00ff00L
#define COLOR_BLUE 11
#define RGB_BLUE 0x0000ffL
#define COLOR_YELLOW 12
#define RGB_YELLOW 0x808000L
#define COLOR_CYAN 13
#define RGB_CYAN 0x008080L
#define COLOR_MAGENTA 14
#define RGB_MAGENTA 0x800080L
#define COLOR_WHITE 15
#define RGB_WHITE 0X555555L
#define COLOR_DK_RED 16
#define RGB_DK_RED 0x400000L
#define COLOR_DK_GREEN 17
#define RGB_DK_GREEN 0x004000L
#define COLOR_DK_BLUE 18
#define RGB_DK_BLUE 0x000040L
#define COLOR_DK_YELLOW 19
#define RGB_DK_YELLOW 0x202000L
#define COLOR_DK_CYAN 20
#define RGB_DK_CYAN 0x002020L
#define COLOR_DK_MAGENTA 21
#define RGB_DK_MAGENTA 0x200020L
#define COLOR_DIM_WHITE 22
#define RGB_DIM_WHITE 0x202020L
#define COLOR_LT_RED 23
#define RGB_LT_RED 0xff2020L
#define COLOR_LT_GREEN 24
#define RGB_LT_GREEN 0x20ff20L
#define COLOR_LT_BLUE 25
#define RGB_LT_BLUE 0x2020ffL
#define COLOR_LT_YELLOW 26
#define RGB_LT_YELLOW 0x808020L
#define COLOR_LT_CYAN 27
#define RGB_LT_CYAN 0x208080L
#define COLOR_LT_MAGENTA 28
#define RGB_LT_MAGENTA 0x802080L
#define COLOR_BRT_WHITE 29
#define RGB_BRT_WHITE 0xf8f8f8L
#define COLOR_PINK 30
#define RGB_PINK 0xff2020L
#define COLOR_ORANGE 31
#define RGB_ORANGE 0xffa500
#define COLOR_PURPLE 32
#define RGB_PURPLE 0x500050
#define REGULAR_COLOR_COUNT COLOR_PURPLE + 1
#define COLOR_RANDOM 33 // One of the colors above, at random
#define COLOR_MEDIUM 34 // Random R,G,B values but balanced for medium brightness
#define COLOR_ANY 35 // Any R,G,B values at random (including dim and bright colors)
#define COLOR_COUNT COLOR_ANY + 1
// To avoid memory fragmentation, all color names (including custom colors) are fixed-length character arrays at a uniform 10 chars each
#define COLOR_NAME_SIZE 10 // 10 chars including the trailing zero, so really just 9 chars
// "123456789"; Can't be longer than this!
const char NAME_BLACK_OFF [] PROGMEM = "Black-Off";
const char NAME_RED [] PROGMEM = "Red";
const char NAME_GREEN [] PROGMEM = "Green";
const char NAME_BLUE [] PROGMEM = "Blue";
const char NAME_YELLOW [] PROGMEM = "Yellow";
const char NAME_CYAN [] PROGMEM = "Cyan";
const char NAME_MAGENTA [] PROGMEM = "Magenta";
const char NAME_WHITE [] PROGMEM = "White";
const char NAME_DK_RED [] PROGMEM = "Dk Red";
const char NAME_DK_GREEN [] PROGMEM = "Dk Green";
const char NAME_DK_BLUE [] PROGMEM = "Dk Blue";
const char NAME_DK_YELLOW [] PROGMEM = "Mustard";
const char NAME_DK_CYAN [] PROGMEM = "Teal";
const char NAME_DK_MAGENTA[] PROGMEM = "Fushia";
const char NAME_DIM_WHITE [] PROGMEM = "Dim White";
const char NAME_LT_RED [] PROGMEM = "Lt Red";
const char NAME_LT_GREEN [] PROGMEM = "Lt Green";
const char NAME_LT_BLUE [] PROGMEM = "Lt Blue";
const char NAME_LT_YELLOW [] PROGMEM = "Lt Yellow";
const char NAME_LT_CYAN [] PROGMEM = "Sea";
const char NAME_LT_MAGENTA[] PROGMEM = "Lavender";
const char NAME_BRT_WHITE [] PROGMEM = "Brt White";
const char NAME_PINK [] PROGMEM = "Pink";
const char NAME_ORANGE [] PROGMEM = "Orange";
const char NAME_PURPLE [] PROGMEM = "Purple";
const char NAME_RANDOM [] PROGMEM = "Random";
const char NAME_MEDIUM [] PROGMEM = "Medium";
const char NAME_ANY [] PROGMEM = "Any";
// Factory Default Names for Custom Colors 0-7, may end up being changed by user, stored in EEPROM
const char NAME_CORAL [] PROGMEM = "Coral";
const char NAME_OLIVE [] PROGMEM = "Olive";
const char NAME_WARM_WITE [] PROGMEM = "Warm Wite";
const char NAME_TURQUOISE [] PROGMEM = "Turquoise";
const char NAME_LIME [] PROGMEM = "Lime";
const char NAME_GOLD [] PROGMEM = "Gold";
const char NAME_INDIGO [] PROGMEM = "Indigo";
const char NAME_CRIMSON [] PROGMEM = "Crimson";
PGM_P const COLOR_NAMES[] PROGMEM =
{
NAME_BLACK_OFF,
NAME_RED,
NAME_GREEN,
NAME_BLUE,
NAME_YELLOW,
NAME_CYAN,
NAME_MAGENTA,
NAME_WHITE,
NAME_DK_RED,
NAME_DK_GREEN,
NAME_DK_BLUE,
NAME_DK_YELLOW,
NAME_DK_CYAN,
NAME_DK_MAGENTA,
NAME_DIM_WHITE,
NAME_LT_RED,
NAME_LT_GREEN,
NAME_LT_BLUE,
NAME_LT_YELLOW,
NAME_LT_CYAN,
NAME_LT_MAGENTA,
NAME_BRT_WHITE,
NAME_PINK,
NAME_ORANGE,
NAME_PURPLE,
NAME_RANDOM,
NAME_MEDIUM,
NAME_ANY
};
/*
char customColorName1[COLOR_NAME_SIZE] = {'/0 '};
char customColorName2[COLOR_NAME_SIZE] = {'/0 '};
char customColorName3[COLOR_NAME_SIZE] = {'/0 '};
char customColorName4[COLOR_NAME_SIZE] = {'/0 '};
char customColorName5[COLOR_NAME_SIZE] = {'/0 '};
char customColorName6[COLOR_NAME_SIZE] = {'/0 '};
char customColorName7[COLOR_NAME_SIZE] = {'/0 '};
char customColorName8[COLOR_NAME_SIZE] = {'/0 '};
*/
// To avoid memory fragmentation, all color names (including custom colors) are fixed-length character arrays at a uniform 10 chars each.
// 10 chars includes the trailing zero, so really just 9 chars.
// "123456789"; Can't be longer than this!
char customColorName1[COLOR_NAME_SIZE] = {" "};
char customColorName2[COLOR_NAME_SIZE] = {" "};
char customColorName3[COLOR_NAME_SIZE] = {" "};
char customColorName4[COLOR_NAME_SIZE] = {" "};
char customColorName5[COLOR_NAME_SIZE] = {" "};
char customColorName6[COLOR_NAME_SIZE] = {" "};
char customColorName7[COLOR_NAME_SIZE] = {" "};
char customColorName8[COLOR_NAME_SIZE] = {" "};
#define NUM_CUSTOM_COLORS 8
char *customColorNames[NUM_CUSTOM_COLORS] =
{
customColorName1,
customColorName2,
customColorName3,
customColorName4,
customColorName5,
customColorName6,
customColorName7,
customColorName8
};
// ****************
// ** Patterns **
// ****************
// 0-31 are reserved for the Effects List in menus
#define PATTERN_BASE 40 // Starting number for patterns, Equal to PAT_NONE
#define PAT_NONE 40
#define PAT_DOTS 41
#define PAT_GRADIENT 42
#define PAT_FADE 43
#define PAT_FWDCHASE 44
#define PAT_REVCHASE 45
#define PAT_SPARKLE 46
#define PAT_DISSOLVE 47
#define PAT_PAUSE 48
#define PATTERN_LAST 48 // Highest numbered pattern, should also be equal to PATTERN_BASE + PATTERN_COUNT
#define PATTERN_COUNT 8
#define PATTERN_NAME_SIZE 10 // 10 chars including the trailing zero, so really just 9 chars
// "123456789"; Can't be longer than this!
const char NAME_NONE [] PROGMEM = "None";
const char NAME_DOTS [] PROGMEM = "Dots";
const char NAME_GRADIENT [] PROGMEM = "Gradient";
const char NAME_FADE [] PROGMEM = "Fade";
const char NAME_FWDCHASE [] PROGMEM = "Fwd Chase";
const char NAME_REVCHASE [] PROGMEM = "Rev Chase";
const char NAME_SPARKLE [] PROGMEM = "Sparkle";
const char NAME_DISSOLVE [] PROGMEM = "Dissolve";
const char NAME_PAUSE [] PROGMEM = "Pause";
const char NAME_BLANK [] PROGMEM = "Blank";
//const char NAME_ANY [] PROGMEM = "Any";
//PROGMEM const char *PATTERN_NAMES[] =
PGM_P const PATTERN_NAMES[] PROGMEM =
{
NAME_NONE,
NAME_DOTS,
NAME_GRADIENT,
NAME_FADE,
NAME_FWDCHASE,
NAME_REVCHASE,
NAME_SPARKLE,
NAME_DISSOLVE,
NAME_PAUSE,
};
#define EFFECT_SIZE 16 // Number of bytes used
// ******************
// ******************
// ** Effects **
// ** Class **
// ** Definition **
// ******************
// ******************
class effect
{
public:
effect(); // Initial Constructor
effect(byte thePattern); // Normal Constructor, pattern required
byte pattern();
void pattern(byte thePattern);
void fetchPatternName();
byte time();
void time(byte theTime);
byte speed();
void speed(byte theSpeed);
byte size();
void size(byte theSize);
byte count();
void count(byte theCount);
byte color(byte whichColor);
CRGB colorRGB (byte whichColor);
CRGB fetchColor (byte whichColor);
void fetchColorName (byte whichColor);
void color(byte whichColor, byte colorIndex);
byte backColor();
CRGB backColorRGB ();
void fetchBackColorName ();
void backColor(byte colorIndex);
byte minTime();
byte maxTime();
byte minSpeed();
byte maxSpeed();
byte minSize();
byte maxSize();
byte minCount();
byte maxCount();
void save(byte effectIndex);
void read(byte effectIndex);
void printEffectDetails();
void setDefaults();
private:
byte _pattern;
byte _time;
byte _speed;
byte _size;
byte _count;
byte _color[6];
}; // End effect class
#define FADE_STEPS 32
// defined here, because they are used by the Effect class which follows
void fetchPatternName(byte patternIndex);
void fetchColorName(byte colorIndex);
#define NUM_EFFECTS 32 // Maximum Number
byte effectCount = 0;
byte curEffect = 0;
class effect theEffect;
//CRGB customColors[0];
#define CUSTOM_OFFSET 1 // Color 0 is a regular color (black)
// // Colors 1-8 are Custom, but array holds elements 0 thru 7
// // *THUS* we need this offset!
CRGB colorsRGB[REGULAR_COLOR_COUNT]; // The last "normal" color before Random/Medium/Any
#define COLOR_RGB_SIZE 4
//#define COLOR_NAME_SIZE 10 // 10 chars including the trailing zero, so really just 9 chars
// "123456789"; Can't be longer than this!
// *****************
// ** HeartBeat **
// *****************
//#define heartLED 13 // On-Board LED on Digital Pin 13
// Pro-Minis do not have an On-Board LED
// The TX Led on Pin 1 could be used instead, but might intefere with an upload
// so use at your own risk.
#define heartLED 20 // aka A2
// Chose this one due to its proximity to Gnd, VCC, and 21/A3 used for pixel data.
// Can be changed if desired.
#define heartRate 60 // Beats-Per-Minute
#define heartTime ((60000 / heartRate) / 8)
unsigned long heartNextBeat = millis() + heartTime;
bool heartState = false;
byte heartTic = 0;
// ***********************************
// ** EEPROM Configuration Data **
// ***********************************
byte curConfig = 0;
#define MY_LUCKY_NUMBER 77
// Written into EEPROM location zero, indicates a [probably] valid ws2811 xmas config
// A zero means this board has never been initialized for this program
// Any other value indicates likely corruption
#define CONFIG_VERSION 2
// Start Address of Configuration data in EEPROM
// Byte #1 is the config version. If significant changes are made to config code, the stored config may need to be updated
// A brand new Arduino should have a zero there, meaning we need to set up factory defaults
// Addresses (offsets) in EEPROM where this data is stored
#define ADDR_LUCKY_NUMBER 0
#define ADDR_CONFIG_VERSION 1
#define ADDR_NUM_LEDS 2
#define ADDR_EFFECTS 4 // Therefore, effects are stored starting at location 4
#define ADDR_COLORS (ADDR_EFFECTS + (NUM_EFFECTS * EFFECT_SIZE)) // Should = 516: 32 = future possible max effects, 16 = size of an effect structure
#define ADDR_NAMES (ADDR_COLORS + (NUM_CUSTOM_COLORS * COLOR_RGB_SIZE)) // Should = 548: 16 = future possible custom colors, 4 = size of a long, to hold the color
// *****************
// ** M I S C **
// *****************
char strBuffer[17]; //General purpose buffer for getting strings out of Progmem. 17 char 'cause should never need to do longer than 1 lcd line
unsigned long curMillis = millis();
bool running = true;
// ***********************
// ***********************
// **** EFFECT CLASS ****
// **** PROCEDURES ****
// **** BEGIN ****
// **** HERE ****
// ***********************
// ***********************
// Plain constructor, no parameters
effect::effect()
{
_pattern = PAT_NONE;
//_time = 1;
//_speed = 1;
//_size = 1;
//_count = 0;
//_color[0] = COLOR_RED;
//_color[1] = COLOR_YELLOW;
//_color[2] = COLOR_GREEN;
//_color[3] = COLOR_CYAN;
//_color[4] = COLOR_BLUE;
//_color[5] = COLOR_MAGENTA;
setDefaults();
}
// Constructor specifying a pattern
effect::effect(byte thePattern) // Constructor, pattern required
{
pattern(thePattern);
}
byte effect::pattern() {
return _pattern;
}
void effect::pattern(byte thePattern)
{
if ((thePattern >= PATTERN_BASE) && (thePattern <= PATTERN_LAST))
{
_pattern = thePattern;
if (_time < minTime()) {
_time = minTime();
}
if (_time > maxTime()) {
_time = maxTime();
}
if (_time < minSpeed()) {
_time = minSpeed();
}
if (_time > maxSpeed()) {
_time = maxSpeed();
}
if (_time < minSize()) {
_time = minSize();
}
if (_time > maxSize()) {
_time = maxSize();
}
if (_time < minCount()) {
_time = minCount();
}
if (_time > maxCount()) {
_time = maxCount();
}
// Anytime the pattern # is set (even if reset to the same #) set parameters to default
setDefaults();
}
}
void effect::fetchPatternName()
{
::fetchPatternName(_pattern);
}
byte effect::time() {
return _time;
}
void effect::time(byte theTime)
{
if (theTime < minTime()) {
theTime = minTime();
}
if (theTime > maxTime()) {
theTime = maxTime();
}
_time = theTime;
}
byte effect::speed() {
return _speed;
}
void effect::speed(byte theSpeed)
{
if (theSpeed < minSpeed()) {
theSpeed = minSpeed();
}
if (theSpeed > maxSpeed()) {
theSpeed = maxSpeed();
}
_speed = theSpeed;
}
byte effect::size() {
return _size;
}
void effect::size(byte theSize)
{
if (theSize < minSize()) {
theSize = minSize();
}
if (theSize > maxSize()) {
theSize = maxSize();
}
_size = theSize;
}
byte effect::count() {
return _count;
}
void effect::count(byte theCount)
{
if (theCount < minCount()) {
theCount = minCount();
}
if (theCount > maxCount()) {
theCount = maxCount();
}
_count = theCount;
}
// Note to self:
// 'colorIndex' refers to the color number, 0 to 35 (BLACK to ANY)
// 'whichColor' refers to which of the 6 color slots (0-5) in an effect
byte effect::color(byte whichColor) {
return _color[whichColor];
}
CRGB effect::colorRGB(byte whichColor) {
return fetchColor(_color[whichColor]);
}
void effect::fetchColorName(byte whichColor)
{
::fetchColorName(_color[whichColor]);
}
void effect::color(byte whichColor, byte color)
{
if (whichColor < 6)
{
if (color < COLOR_COUNT)
{
_color[whichColor] = color;
}
}
}
byte effect::backColor() {
return _color[5];
}
CRGB effect::backColorRGB() {
return fetchColor(_color[5]);
}
void effect::fetchBackColorName()
{
fetchColorName(_color[5]);
}
void effect::backColor(byte colorIndex)
{
if (colorIndex < COLOR_COUNT)
{
_color[5] = colorIndex;
}
}
byte effect::minTime()
{
byte ret = 0;
if (_pattern == PAT_PAUSE) {
ret = 1;
}
if (_pattern == PAT_GRADIENT) {
ret = 3;
}
return ret;
}
byte effect::maxTime()
{
byte ret = 240;
return ret;
}
byte effect::minSpeed()
{
byte ret = 1;
return ret;
}
byte effect::maxSpeed()
{
byte ret = 10;
if (_pattern == PAT_PAUSE) {
ret = 1;
}
return ret;
}
byte effect::minSize()
{
byte ret = 1;
return ret;
}
byte effect::maxSize()
{
byte ret = 255;
if (ret > num_leds) {
ret = num_leds;
}
if (_pattern == PAT_PAUSE) {
ret = 1;
}
return ret;
}
byte effect::minCount()
{
byte ret = 1;
if (_pattern == PAT_PAUSE) {
ret = 0;
}
return ret;
}
byte effect::maxCount()
{
byte ret = 6;
if (_pattern == PAT_PAUSE) {
ret = 0;
}
return ret;
}
void effect::save(byte effectIndex)
{
int addr = ADDR_EFFECTS + (int)effectIndex * EFFECT_SIZE;
DEBUG_Print_Info(F("Saving Effect Pattern to slot "));
DEBUG_Print_Info(effectIndex);;
DEBUG_Print_Info(F(" address "));
DEBUG_Print_Info(addr);
DEBUG_Print_Info(F(" is "));
DEBUG_Print_Info(_pattern);
DEBUG_Print_Info(F(" - "));
::fetchPatternName(_pattern);
DEBUG_Println_Info(strBuffer);
EEPROM.writeByte(addr + 0, _pattern);
EEPROM.writeByte(addr + 1, _time);
EEPROM.writeByte(addr + 2, _speed);
EEPROM.writeByte(addr + 3, _size);
EEPROM.writeByte(addr + 4, _count);
EEPROM.writeByte(addr + 5, _color[0]);
EEPROM.writeByte(addr + 6, _color[1]);
EEPROM.writeByte(addr + 7, _color[2]);
EEPROM.writeByte(addr + 8, _color[3]);
EEPROM.writeByte(addr + 9, _color[4]);
EEPROM.writeByte(addr + 10, _color[5]);
delay(250);
}
void effect::read(byte effectIndex)
{
int addr = ADDR_EFFECTS + (int)effectIndex * EFFECT_SIZE;
pattern (EEPROM.readByte (addr + 0));
time (EEPROM.readByte (addr + 1));
speed (EEPROM.readByte (addr + 2));
size (EEPROM.readByte (addr + 3));
count (EEPROM.readByte (addr + 4));
color(0, EEPROM.readByte (addr + 5));
color(1, EEPROM.readByte (addr + 6));
color(2, EEPROM.readByte (addr + 7));
color(3, EEPROM.readByte (addr + 8));
color(4, EEPROM.readByte (addr + 9));
color(5, EEPROM.readByte (addr + 10));
}
void effect::printEffectDetails()
{
byte z;
fetchPatternName();
DEBUG_Print_Info (F(" Effect is "));
DEBUG_Print_Info (_pattern);
DEBUG_Print_Info (F(" - "));
DEBUG_Println_Info(strBuffer);
DEBUG_Print_Info (F(" Time:"));
DEBUG_Println_Info(_time);
DEBUG_Print_Info (F(" Size:"));
DEBUG_Println_Info(_size);
DEBUG_Print_Info (F(" Speed:"));
DEBUG_Println_Info(_speed);
DEBUG_Print_Info (F(" Count:"));
DEBUG_Println_Info(_count);
z = 0;
DEBUG_Print_Info (F("Color 1 is "));
DEBUG_Print_Info (_color[z]);
DEBUG_Print_Info (F(" - "));
fetchColorName(z);
DEBUG_Println_Info (strBuffer);
z = 1;
DEBUG_Print_Info (F("Color 2 is "));
DEBUG_Print_Info (_color[z]);
DEBUG_Print_Info (F(" - "));
fetchColorName(z);
DEBUG_Println_Info (strBuffer);
z = 2;
DEBUG_Print_Info (F("Color 3 is "));
DEBUG_Print_Info (_color[z]);
DEBUG_Print_Info (F(" - "));
fetchColorName(z);
DEBUG_Println_Info (strBuffer);
z = 3;
DEBUG_Print_Info (F("Color 4 is "));
DEBUG_Print_Info (_color[z]);
DEBUG_Print_Info (F(" - "));
fetchColorName(z);
DEBUG_Println_Info (strBuffer);
z = 4;
DEBUG_Print_Info (F("Color 5 is "));
DEBUG_Print_Info (_color[z]);
DEBUG_Print_Info (F(" - "));
fetchColorName(z);
DEBUG_Println_Info (strBuffer);
z = 5;
DEBUG_Print_Info (F("Color 6 is "));
DEBUG_Print_Info (_color[z]);
DEBUG_Print_Info (F(" - "));
fetchColorName(z);
DEBUG_Println_Info (strBuffer);
} // end printEffectDetails
void effect::setDefaults()
{
// Standard defaults, may possibly get overriden below
_time = 30; // Seconds
_speed = 5; // Medium
_size = 6;
_count = 6;
_color[0] = COLOR_RED;
_color[1] = COLOR_YELLOW;
_color[2] = COLOR_GREEN;
_color[3] = COLOR_CYAN;
_color[4] = COLOR_BLUE;
_color[5] = COLOR_MAGENTA;
switch (theEffect.pattern())
{
case PAT_NONE:
//DEBUG_Print_Trace(F("Shouldn't get here! Why does new effect have pattern of none?"));
// Standard defaults are fine
break;
case PAT_DOTS:
// set time to zero
_time = 0;
break;
case PAT_GRADIENT:
// Increase Size, based on num_leds, set time to zero
_time = 0;
_size = num_leds / 6;
break;
case PAT_FWDCHASE:
// Standard defaults are fine
break;
case PAT_REVCHASE:
// Standard defaults are fine
break;
case PAT_FADE:
// Standard defaults are fine
break;
case PAT_SPARKLE:
// Better colors for this effect
_color[5] = COLOR_DK_MAGENTA; // Background
_color[0] = COLOR_BRT_WHITE;
_color[1] = COLOR_WHITE;
_color[2] = COLOR_DIM_WHITE;
_color[3] = COLOR_BRT_WHITE;
_color[4] = COLOR_WHITE;
break;
case PAT_DISSOLVE:
// Standard defaults are fine
break;
case PAT_PAUSE:
// Standard defaults are fine
// time is only parameter that even matters anyway
break;
default:
DEBUG_Print_Trace(F("Shouldn't get here! No Defaults for new pattern!"));
} // end switch
} // end new effect set defaults
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// END OF EFFECT CLASS PROPERTIES AND METHODS
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ***********************
// ***********************
// **** REGULAR ****
// **** PROCEDURES ****
// **** BEGIN ****
// **** HERE ****
// ***********************
// ***********************
// *********************************
// *********************************
// *** ***
// *** F E T C H C O L O R ***
// *** ***
// *********************************
// *********************************
CRGB fetchColor(byte colorIndex)
{
CRGB ret;
if (colorIndex <= REGULAR_COLOR_COUNT)
{
ret = colorsRGB[colorIndex];
}
else
{
if (colorIndex == COLOR_RANDOM)
{
byte rndclr = random(COLOR_COUNT - 2);
ret = colorsRGB[rndclr];
}
if (colorIndex == COLOR_MEDIUM) // Any R,G,B values at random, but balanced for medium brightness
{
ret.r = random(255);
ret.g = random(255 - ret.r);
ret.b = 255 - ret.r - ret.g;
}
if (colorIndex == COLOR_ANY) // Any R,G,B values at random (will include dim and bright colors)
{
ret.r = random(255);
ret.g = random(255);
ret.b = random(255);
}
} // END custom color
return ret;
} // END CRGB fetchColor(byte colorIndex)
// ***********************
// ***********************
// **** ****
// **** S E T U P ****
// **** ****
// ***********************
// ***********************
void setup() {
Serial.begin(9600);
DEBUG_Println_Trace(F("setup()"));
EEPROM.setMemPool(0, 4096);
EEPROM.setMaxAllowedWrites(8192);
//FastLED.addLeds<WS2811, DATA_PIN, GRB>(leds, num_leds);
FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, num_leds);
// Buffer is 'empty' and contains all zeros at this point
// Therefore, this will set all LEDs to black/off
FastLED.show();
//DEBUG_Println_Trace(F("Setup Here 1"));
checkConfig();
if (curConfig != CONFIG_VERSION)
{
// At some future point, may need to check if it has a config, but is an older version that needs updating
// But don't need to worry about that - yet.
DEBUG_Println_Trace(F("WTF? Why doesn't config version match?"));
//infiniteLoop();
setDefaults();
//writeConfig();
readConfig();
dumpConfig();
}
else // has config and is correct version
{
//setTestDefaults(); // TEMPORARY! FOR DEBUGGING PATTERNS AND EFFECTS
readConfig();
DEBUG_Println_Trace(F("Configuration read from EEPROM appears valid!"));
//dumpConfig();
}
initColors(ADDR_COLORS);
//DEBUG_Println_Trace(F("Setup Here 2"));
theEffect.read(0);
DEBUG_Println_Trace(F("End setup()"));
} // End void setup()
// *******************
// *******************
// *** ***
// *** L O O P ***
// *** ***
// *******************
// *******************
void loop() {
//DEBUG_Println_Trace(F("loop()"));
curMillis = millis();
//delay(100); // FOR DEBUGGING, ALLOW TIME FOR SERIAL.PRINT STATUS BEFORE CONTINUING
playEffect(theEffect);
curEffect ++;
if (curEffect >= effectCount)
{
curEffect = 0;
}
theEffect.read(curEffect);
} // End void loop()
// ********************
// *** I D L E ***
// ********************
void idleUntil(unsigned long untilThen)
{
curMillis = millis();
while (curMillis < untilThen)
{
curMillis = millis();
if (curMillis > heartNextBeat)
{
heartTic++;
heartTic &= 7;
heartState = ((heartTic == 1) || (heartTic == 3));
digitalWrite(heartLED, heartState);
heartNextBeat = curMillis + heartTime;
}
}
} // End void idleUntil(unsigned long untilThen)
void initColors(int address)
{
//int addr = ADDR_COLORS;
CRGB clr;
// Color # 0
colorsRGB[COLOR_BLACK_OFF] = hex2color(RGB_BLACK_OFF);
// Colors # 1-9 ** The custom colors
// Read from EEPROM
for (int i = 0; i < NUM_CUSTOM_COLORS; i++)
{
// ignore/skip addr + 0 (Value stored as a long, byte 0 = 0, byte 1 = 4, byte 2 = g, byte 3 = b)
clr.r = EEPROM.readByte(address + 1);
clr.g = EEPROM.readByte(address + 2);
clr.b = EEPROM.readByte(address + 3);
colorsRGB[i + 1] = clr;
address += COLOR_RGB_SIZE;
}
// Colors # 9 thru whatever
colorsRGB[COLOR_RED] = hex2color(RGB_RED);
colorsRGB[COLOR_GREEN] = hex2color(RGB_GREEN);
colorsRGB[COLOR_BLUE] = hex2color(RGB_BLUE);
colorsRGB[COLOR_YELLOW] = hex2color(RGB_YELLOW);
colorsRGB[COLOR_CYAN] = hex2color(RGB_CYAN);
colorsRGB[COLOR_MAGENTA] = hex2color(RGB_MAGENTA);
colorsRGB[COLOR_WHITE] = hex2color(RGB_WHITE);
colorsRGB[COLOR_DK_RED] = hex2color(RGB_DK_RED);
colorsRGB[COLOR_DK_GREEN] = hex2color(RGB_DK_GREEN);
colorsRGB[COLOR_DK_BLUE] = hex2color(RGB_DK_BLUE);
colorsRGB[COLOR_DK_YELLOW] = hex2color(RGB_DK_YELLOW);
colorsRGB[COLOR_DK_CYAN] = hex2color(RGB_DK_CYAN);
colorsRGB[COLOR_DK_MAGENTA] = hex2color(RGB_DK_MAGENTA);
colorsRGB[COLOR_DIM_WHITE] = hex2color(RGB_DIM_WHITE);
colorsRGB[COLOR_LT_RED] = hex2color(RGB_LT_RED);
colorsRGB[COLOR_LT_GREEN] = hex2color(RGB_LT_GREEN);
colorsRGB[COLOR_LT_BLUE] = hex2color(RGB_LT_BLUE);
colorsRGB[COLOR_LT_YELLOW] = hex2color(RGB_LT_YELLOW);
colorsRGB[COLOR_LT_CYAN] = hex2color(RGB_LT_CYAN);
colorsRGB[COLOR_LT_MAGENTA] = hex2color(RGB_LT_MAGENTA);
colorsRGB[COLOR_BRT_WHITE] = hex2color(RGB_BRT_WHITE);
colorsRGB[COLOR_PINK] = hex2color(RGB_PINK);
colorsRGB[COLOR_ORANGE] = hex2color(RGB_ORANGE);
colorsRGB[COLOR_PURPLE] = hex2color(RGB_PURPLE);
} // End void InitColors()
CRGB hex2color(long hexVal)
{
CRGB ret;
long l;
ret.b = hexVal & 0x0000ff;
l = (hexVal & 0x00ff00) >> 8;
ret.g = l;
l = (hexVal & 0xff0000) >> 16;
ret.r = l;
return ret;
} // end hex2color
long color2hex(CRGB theColor)
{
long ret = theColor.r << 16;
ret += theColor.g << 8;
ret += theColor.b;
return ret;
} // end color2hex
byte getEffectPattern(byte effectIndex)
{
byte ret;
int addr = ADDR_EFFECTS + effectIndex * EFFECT_SIZE;
ret = EEPROM.readByte(addr);
return ret;
}
void printCustomColorDetails(byte colorIndex)
{
DEBUG_Print_Info (F("Custom Color "));
DEBUG_Print_Info (colorIndex + CUSTOM_OFFSET);
DEBUG_Print_Info (F(" '"));
fetchColorName(colorIndex + CUSTOM_OFFSET);
DEBUG_Print_Info (strBuffer);
DEBUG_Print_Info (F("' = 0x"));
DEBUG_HexPrint_Info (colorsRGB[colorIndex + CUSTOM_OFFSET].r);
//Serial.print (", ");
DEBUG_HexPrint_Info (colorsRGB[colorIndex + CUSTOM_OFFSET].g);
//Serial.print (", ");
DEBUG_HexPrint_Info (colorsRGB[colorIndex + CUSTOM_OFFSET].b);
DEBUG_Println_Info ();
} // end printCustomColorDetails
void checkConfig()
{
byte cc = 0;
int n = EEPROM.readByte(ADDR_LUCKY_NUMBER);
if (n == MY_LUCKY_NUMBER) // Byte 0 should = My Favorite Magic Number! Means EEPROM was written with a WS8211 Xmas program
{
n = EEPROM.readByte(ADDR_NUM_LEDS);
if ((n > 0) && (n <= MAX_LEDS)) // Byte 2 is number of LEDs
{
cc = EEPROM.readByte(ADDR_CONFIG_VERSION);
if (cc == CONFIG_VERSION)
{
n = EEPROM.readByte(ADDR_EFFECTS);
// Check the first byte of the effects list,
// first byte will be pattern of first effect
// if not PATTERN_NONE
if ((n > PAT_NONE) && (n <= PATTERN_LAST))
{
//n = EEPROM.readByte(ADDR_NAMES);
n = EEPROM.readByte(ADDR_NAMES);
// Check the first byte of the custom color names,
// first byte will first letter of first color name
// if not a zero
if (n)
{
curConfig = cc;
} // first custom color has a name of at least one character
} // fifth byte contains a valid pattern number
} // second byte matches config version
} // third and fourth byte is zero (for now)
} // first byte is my favorite magic number (77)
} // end void checkConfig
// WRITE CONFIG
/*
void writeConfig()
{
// Entire Config should all be written only in the case of a factory defaults reset
setLCDbacklight(LCD_RED);
lcd.setCursor(0,0);
strcpy_P(strBuffer, (char*)FACTORY_DEFAULTS);
lcd.print (strBuffer);
lcd.setCursor(0,1);
lcd.print("Writing: ");
EEPROM.writeByte(ADDR_LUCKY_NUMBER, MY_LUCKY_NUMBER);
EEPROM.writeByte(ADDR_CONFIG_VERSION, CONFIG_VERSION); // See Notes in CheckConfig()
EEPROM.writeInt (ADDR_NUM_LEDS, num_leds);
for (byte i=0; i < NUM_EFFECTS; i++)
{
writeEffect(i);
delay(100);
}
for (byte i = 0; i < NUM_CUSTOM_COLORS; i++)
{
writeCustomColorRGB(i);
delay(100);
}
for (byte i = 0; i < NUM_CUSTOM_COLORS; i++)
{
writeCustomColorName(i);
delay(100);
}
setLCDbacklight(LCD_GREEN);
lcd.setCursor(0,0);
lcd.print (" DEFAULTS SET ");
lcd.setCursor(0,1);
lcd.print (" ");
} // End writeConfig
*/
void dumpConfig()
{
for (byte i = 0; i < NUM_EFFECTS; i++)
{
DEBUG_Print_Info(F("Effect # "));
DEBUG_Println_Info(i);
theEffect.read(i);
theEffect.printEffectDetails();
}
for (byte i = 0; i < NUM_CUSTOM_COLORS; i++)
{
printCustomColorDetails(i);
}
}
void readConfig()
{
int addr;
byte ep;
if (EEPROM.readByte(ADDR_LUCKY_NUMBER) == MY_LUCKY_NUMBER)
{
if (EEPROM.readByte(ADDR_CONFIG_VERSION) == CONFIG_VERSION)
{
num_leds = EEPROM.readInt(ADDR_NUM_LEDS);
if ((num_leds > 0) && (num_leds <= MAX_LEDS))
{
if (EEPROM.readByte(ADDR_EFFECTS) != PAT_NONE)
{
DEBUG_Println_Info(F("Configuration read from EEPROM appears valid"));
DEBUG_Print_Info (F("LED Count = "));
DEBUG_Println_Info(num_leds);
for (byte i = 0; i < NUM_EFFECTS; i++)
{
//readEffect(i);
//delay(50);
addr = ADDR_EFFECTS + (int)i * EFFECT_SIZE;
ep = getEffectPattern(i);
DEBUG_Print_Info(F("Effect Pattern in slot "));
DEBUG_Print_Info(i);;
DEBUG_Print_Info(F(" address "));
DEBUG_Print_Info(addr);
DEBUG_Print_Info(F(" is "));
DEBUG_Print_Info(ep);
DEBUG_Print_Info(F(" - "));
fetchPatternName(ep);
DEBUG_Println_Info(strBuffer);
if ((ep == PAT_NONE) && (effectCount == 0))
{
effectCount = i;
}
}
for (byte i = 0; i < NUM_CUSTOM_COLORS; i++)
{
readCustomColorRGB(i);
//delay(20);
}
}
else // first effect.pattern != none
{
effectCount = 0;
} // end check first effect.pattern is not none
DEBUG_Print_Info(F("Effect Count = "));
DEBUG_Println_Info(effectCount);
}
else // number of leds is invalid (=0 or >1024)
{
DEBUG_Println_Trace(F("Houston, we have a problem in readConfig() Number of LEDs is invalid"));
} // end num_leds check
}
else // config version does NOT match
{
DEBUG_Println_Trace(F("Houston, we have a problem in readConfig() The config version doesn't match"));
} // end config version check
}
else // first byte is not luck number, probably not a valid ws2811 xmas config
{
DEBUG_Println_Trace(F("Houston, we have a problem in readConfig() No Lucky Number"));
} // end lucky number check
} // end readConfig
// WRITE EFFECT
/*
void writeEffect(byte effectIndex)
{
int addr = ADDR_EFFECTS + effectIndex * EFFECT_SIZE;
lcd.setCursor(8,1);
lcd.print(addr);
effectList[effectIndex].save(addr);
} // end writeEffect
void readEffect(byte effectIndex)
{
int addr = ADDR_EFFECTS + effectIndex * EFFECT_SIZE;
lcd.setCursor(8,1);
lcd.print(addr);
effectList[effectIndex].read(addr);
} // end readEffect
*/
void writeCustomColorRGB(byte colorIndex)
{
int addr = ADDR_COLORS + colorIndex * COLOR_RGB_SIZE;
EEPROM.writeByte(addr + 1, colorsRGB[colorIndex + 1].r); // i + 1 because color 0 = black
EEPROM.writeByte(addr + 2, colorsRGB[colorIndex + 1].g);
EEPROM.writeByte(addr + 3, colorsRGB[colorIndex + 1].b);
} // end writeCustomColorRGB
void readCustomColorRGB(byte colorIndex)
{
int addr = ADDR_COLORS + colorIndex * COLOR_RGB_SIZE;
colorsRGB[colorIndex + 1].r = EEPROM.readByte(addr + 1); // i + 1 because color 0 = black
colorsRGB[colorIndex + 1].g = EEPROM.readByte(addr + 2);
colorsRGB[colorIndex + 1].b = EEPROM.readByte(addr + 3);
} // end readCustomColorRGB
void writeCustomColorName(byte customIndex)
{
// Note this is the custom color index, which is zero based and goes from 0 to 7
// (As opposed to the full color list, in which the custom colors are # 1 to 8)
int addr = ADDR_NAMES + customIndex * COLOR_NAME_SIZE;
for (byte i = 0; i < COLOR_NAME_SIZE; i++)
{
EEPROM.writeByte(addr + i, strBuffer[i]);
}
} // end WriteCustomColorName
// fetchHexColorString(struct CRGB &theColor)
/*
fetchHexColorString(struct CRGB &theColor)
{
String ret = "0x00";
ret += String(theColor.r, HEX);
ret += String(theColor.g, HEX);
ret += String(theColor.b, HEX);
return ret;
} // end fetchHexColorString
*/
void fetchPatternName(byte patternIndex)
{
// NOTE: patternIndex is no longer zero-based! It now starts at PATTERN_BASE and goes to PATTERN_LAST, with the # of elements = to PATTERN_COUNT
strcpy_P(strBuffer, (char*)pgm_read_word(&(PATTERN_NAMES[patternIndex - PATTERN_BASE]))); // Necessary casts and dereferencing, just copy.
}
void fetchColorName(byte colorIndex)
{
// Note to self:
// 'colorIndex' refers to the color number, 0 to 35 (BLACK to ANY)
// 'whichColor' refers to which of the 6 color slots (0-5) in an effect
if (colorIndex == COLOR_BLACK_OFF)
{
strcpy_P(strBuffer, (char*)pgm_read_word(&(COLOR_NAMES[colorIndex]))); // Necessary casts and dereferencing, just copy.
}
else
{
if (colorIndex < COLOR_RED)
{
strcpy_P(strBuffer, (char*)pgm_read_word(&(customColorNames[colorIndex]))); // Necessary casts and dereferencing, just copy.
}
else
{
strcpy_P(strBuffer, (char*)pgm_read_word(&(COLOR_NAMES[colorIndex]))); // Necessary casts and dereferencing, just copy.
}
}
}
// ************************
// *** Play Effect ***
// ************************
void playEffect(class effect &theEffect)
{
DEBUG_Println_Trace(F("playEffect()"));
//delay(100); // FOR DEBUGGING, ALLOW TIME FOR SERIAL.PRINT STATUS BEFORE CONTINUING
theEffect.fetchPatternName();
DEBUG_Print_Info(F("Play Effect #"));
DEBUG_Print_Info(curEffect);
DEBUG_Print_Info(F(" - Pattern #"));
DEBUG_Print_Info(theEffect.pattern());
DEBUG_Print_Info(F(" - "));
DEBUG_Println_Info(strBuffer);
strcpy_P(strBuffer, (char*)NAME_BLANK);
theEffect.fetchPatternName();
curMillis = millis();
switch (theEffect.pattern())
{
case PAT_DOTS:
playDotsPattern(theEffect);
break;
case PAT_GRADIENT:
playGradientPattern(theEffect);
break;
case PAT_FADE:
playFadePattern(theEffect);
break;
case PAT_FWDCHASE:
playFwdChasePattern(theEffect);
break;
case PAT_REVCHASE:
playRevChasePattern(theEffect);
break;
case PAT_SPARKLE:
playSparklePattern(theEffect);
break;
case PAT_DISSOLVE:
playDissolvePattern(theEffect);
break;
case PAT_PAUSE:
playPausePattern(theEffect);
break;
default:
DEBUG_Println_Trace(F("WTF? Pattern Not Found "));
} // end switch
} // end playEffect
// ************************
// *** Dots Pattern ***
// ************************
void playDotsPattern(class effect &theEffect)
{
curMillis = millis();
unsigned long endTime = curMillis + (unsigned long)theEffect.time() * 1000;
int batch = theEffect.size() * theEffect.count();
for (int p = 0; p < num_leds; p += batch)
{
for (byte c = 0; c < theEffect.count(); c++)
{
for (byte s = 0; s < theEffect.size(); s++)
{
int n = p + (c * theEffect.size()) + s;
if (n < num_leds)
{
//DEBUG_Print_Info("Should increment ->" + String(n));
leds[n] = theEffect.colorRGB(c);
//DEBUG_Print_Info("LED #" + String(n) + " to Color#" + String(theEffect.color[c]) + " = ");
//DEBUG_Print_Info(hexColorString(leds[n]) + " is ");
//getColorName(theEffect.color[c], strBuffer);
//DEBUG_Println_Info (strBuffer);
}
}
}
}
FastLED.show();
endTime = curMillis + theEffect.time() * 1000; // time in seconds
idleUntil(endTime); // 100 because .time is in 1/10 second and millis is in 1/1000 second
} // end playDots
// ************************
// *** Gradient ***
// ************************
void playGradientPattern(class effect &theEffect)
{
curMillis = millis();
unsigned long endTime = curMillis + (unsigned long)theEffect.time() * 1000;
int n = 0;
CRGB newColor;
byte c2;
while (n < num_leds)
{
for (byte c = 0; c < theEffect.count(); c++)
{
c2 = (c + 1) % theEffect.count();
for (byte f = 0; f < theEffect.size(); f++)
{
if (n < num_leds)
{
DEBUG_Print_Info (F("Color:"));
DEBUG_Print_Info (c);
DEBUG_Print_Info (F(" of "));
DEBUG_Print_Info (theEffect.count());
DEBUG_Print_Info (F("Step:"));
DEBUG_Print_Info (f);
DEBUG_Print_Info (F(" of "));
DEBUG_Print_Info (theEffect.size());
DEBUG_Print_Info (F(" LED:"));
DEBUG_Println_Info (n);
newColor = calcFade(theEffect.colorRGB(c), theEffect.colorRGB(c2), f, theEffect.size());
leds[n] = newColor;
n++;
} // still < num_leds
} // End for size loop
} // END for color
} // End while n < num_leds
FastLED.show();
idleUntil(endTime);
} // end playGradient
// ************************
// *** Fade Pattern ***
// ************************
void playFadePattern(class effect &theEffect)
{
CRGB lastColor;
CRGB newColor;
curMillis = millis();
unsigned long endTime = curMillis + (unsigned long)theEffect.time() * 1000;
int delayAmt = (10 - theEffect.speed());
while (curMillis < endTime)
{
for (byte c = 0; c < theEffect.count(); c++)
{
if (curMillis < endTime)
{
for (byte f = 0; f < FADE_STEPS; f++)
{
// Betweeen steps, set the 'last' color to a very unlikely color to avoid it being cached from the last step
lastColor.r = 7; lastColor.g = 7; lastColor.b = 7;
if (curMillis < endTime)
{
//byte q = FADE_STEPS - f;
for (int p = 0; p < num_leds; p++)
{
// Caching: Don't do a bunch of floating point math if this pixel matches the last one
if (leds[p] == lastColor) // Is this not working?
//if ((leds[p].r == lastColor.r) && (leds[p].g == lastColor.g) && (leds[p].b == lastColor.b))
{
leds[p] = newColor;
//DEBUG_Print_Info(F("^"));
}
else
{
//DEBUG_Print_Info (F("STEP:"));
//DEBUG_Print_Info (f);
//DEBUG_Print_Info (F(" of "));
//DEBUG_Print_Info (FADE_STEPS);
//DEBUG_Print_Info (F(" LED:"));
//DEBUG_Println_Info (p);
lastColor = leds[p];
newColor = calcFade(leds[p], theEffect.colorRGB(c), f, FADE_STEPS);
leds[p] = newColor;
}
} // END for 0 to num_leds
//DEBUG_Println_Info();
FastLED.show();
idleUntil(curMillis + delayAmt);
}
else
{
break;
} // End if millis < endTime
} // End for fade steps
} // End if millis < endTime
} // END for color
} // End while < endtime
} // end playFade
// ************************
// *** Fwd Chase ***
// ************************
void playFwdChasePattern(class effect &theEffect)
{
curMillis = millis();
unsigned long endTime = curMillis + (unsigned long)theEffect.time() * 1000; // 100 because .time is in 1/10 second and millis is in 1/1000 second
int delayAmt = (15 - theEffect.speed()) * 15;
while (curMillis < endTime)
{
CRGB tempColor = leds[0];
for (int p = 1; p < num_leds; p++)
{
leds[p - 1] = leds[p];
}
leds[num_leds - 1] = tempColor;
FastLED.show();
idleUntil(curMillis + delayAmt);
}
} // end playFwdChase
// ************************
// *** Rev Chase ***
// ************************
void playRevChasePattern(class effect &theEffect)
{
curMillis = millis();
unsigned long endTime = curMillis + (unsigned long)theEffect.time() * 1000;
int delayAmt = (15 - theEffect.speed()) * 15;
while (curMillis < endTime)
{
CRGB tempColor = leds[num_leds - 1];
for (int p = num_leds - 1; p > 0; p--)
{
leds[p] = leds[p - 1];
}
leds[0] = tempColor;
FastLED.show();
idleUntil(curMillis + delayAmt);
}
} // end playRevChase
// ************************
// *** Sparkle ***
// ************************
void playSparklePattern(class effect &theEffect)
{
curMillis = millis();
unsigned long endTime = curMillis + (unsigned long)theEffect.time() * 1000;
int delayAmt = (10 - theEffect.speed());
//int batch = num_leds / ((theEffect.count()) * (theEffect.size() + 3));
int batch = num_leds / (theEffect.count() * 3);
DEBUG_Print_Info(F("Sparkle 'Batch' size is "));
DEBUG_Println_Info(batch);
int listIndex = 0;
while (curMillis < endTime)
{
for (int p = 0; p < listIndex; p++)
{
CRGB backColor;
// Sixth/Last/[5] color is the background/default color
//DEBUG_Print_Info(F(" are we crashing here "));
//delay(50);
backColor = theEffect.backColorRGB();
//DEBUG_Print_Info("LED " + String(theList[p]) + " reset to ");
//theEffect.backColorName(strBuffer);
//DEBUG_Println_Info(strBuffer);
leds[theList[p]] = backColor;
//DEBUG_Println_Info(F(" nope. "));
}
listIndex = 0;
//DEBUG_Println_Trace(F("Begin Main Sparkle Loop"));
delay(100);
// up to first five colors [0]-[4] are the sparkle colors
for (byte c = 0; c < theEffect.count(); c++)
{
for (byte b = 0; b < batch; b++)
{
int r = random(num_leds);
//DEBUG_Print_Info("LED " + String(r) + " set to ");
//theEffect.colorName(c, strBuffer);
//DEBUG_Println_Info(strBuffer);
//delay(100);
//DEBUG_Print_Info(F(" get it "));
//delay(100);
leds[r] = theEffect.colorRGB(c);
//DEBUG_Println_Info(F(" set it "));
theList[listIndex] = r;
listIndex++;
if (listIndex > (num_leds / 3))
{
DEBUG_Println_Trace(F("Uh Oh, You screwed up on the batch count!"));
}
} // END for batch
} // END for color
FastLED.show();
delayAmt = theEffect.speed() * 10;
idleUntil(curMillis + delayAmt);
} // END while millis < endTime
} // end playSparkle
// ************************
// *** Dissolve ***
// ************************
void playDissolvePattern(class effect &theEffect)
{
curMillis = millis();
unsigned long endTime = curMillis + (unsigned long)theEffect.time() * 1000;
unsigned long colorTime = theEffect.size() * 1000;
int delayAmt = (10 - theEffect.speed());
while (curMillis < endTime)
{
DEBUG_Print_Info(F("L1 curMills:"));
DEBUG_Print_Info(curMillis);
DEBUG_Print_Info(F(" endTime:"));
DEBUG_Println_Info(endTime);
for (byte c = 0; c < theEffect.count(); c++)
{
if (curMillis < endTime)
{
DEBUG_Print_Info(F("L2 curMills:"));
DEBUG_Print_Info(curMillis);
DEBUG_Print_Info(F(" endTime:"));
DEBUG_Println_Info(endTime);
randomizeTheList();
for (int n = 0; n < num_leds; n++)
{
//DEBUG_Print_Info(F("Dissolving LED "));
//DEBUG_Println_Info(theList[n]);
leds[theList[n]] = theEffect.colorRGB(c);
FastLED.show();
idleUntil(curMillis + delayAmt);
} // end loop thru 'theList' (of leds in random order
if (curMillis < endTime)
{
idleUntil(curMillis + colorTime);
} // < endTime
} // end if curMillis < endTime;
} // end Color Loop
} // End while < endtime
//idleUntil(endTime);
} // end playDissolve
// ************************
// *** Pause ***
// ************************
void playPausePattern(class effect &theEffect)
{
unsigned long endTime = curMillis + (unsigned long)theEffect.time() * 1000;
idleUntil(endTime);
} // end playPause
// ************************
// *** Play Color ***
// ************************
void playColor(CRGB theColor)
{
for (int i = 0; i < num_leds; i++)
{
leds[i] = theColor;
}
FastLED.show();
}
void infiniteLoop()
// ONLY FOR DEBUGGING!
// Puts Arduino in infinite loop, with just heartbeat LED blinking
{
while (running)
{
curMillis = millis();
if (curMillis > heartNextBeat)
{
heartState = ((heartTic == 1) || (heartTic == 4));
digitalWrite(heartLED, heartState);
DEBUG_Print_Info("*");
heartTic++;
heartTic &= 7;
heartNextBeat = curMillis + heartTime;
}
}
}
CRGB calcFade(CRGB startColor, CRGB endColor, byte stepNum, byte ofSteps)
{
CRGB ret = startColor;
/*
DEBUG_Print_Info (F("Fade from "));
DEBUG_Print_Info (startColor.r);
DEBUG_Print_Info (F(", "));
DEBUG_Print_Info (startColor.g);
DEBUG_Print_Info (F(", "));
DEBUG_Println_Info (startColor.b);
DEBUG_Print_Info (F(" to "));
DEBUG_Print_Info (endColor.r);
DEBUG_Print_Info (F(", "));
DEBUG_Print_Info (endColor.g);
DEBUG_Print_Info (F(", "));
DEBUG_Println_Info (endColor.b);
*/
//DEBUG_Print_Info (F(" Step # "));
//DEBUG_Print_Info (stepNum);
//DEBUG_Print_Info (F(" of "));
//DEBUG_Println_Info (ofSteps);
if ((stepNum > 0) && (stepNum < ofSteps))
{
float frac = ofSteps - stepNum + 1;
//DEBUG_Print_Info(F("Ratio should be 1/"));
//DEBUG_Print_Info(frac);
//DEBUG_Println_Info(F("th"));
float ratio = 1 / frac; // Example: step 1 of 5 would be .2, step 2 of 5 would be .25, step 3 of 5 would be .333, step 4 of 5 would be .5
//DEBUG_Print_Info (F(" Ratio "));
//DEBUG_Println_Info (ratio);
int diff = endColor.r - startColor.r;
//DEBUG_Print_Info (F(" R-Diff "));
//DEBUG_Print_Info (diff);
float change = diff * ratio;
change = round(change);
//DEBUG_Print_Info (F(" R-Change "));
//DEBUG_Print_Info (change);
ret.r += (byte)(change);
diff = endColor.g - startColor.g;
//DEBUG_Print_Info (F(" G-Diff "));
//DEBUG_Print_Info (diff);
change = diff * ratio;
change = round(change);
//DEBUG_Print_Info (F(" G-Change "));
//DEBUG_Print_Info (change);
ret.g += (byte)(change);
diff = endColor.b - startColor.b;
//DEBUG_Print_Info (F(" B-Diff "));
//DEBUG_Print_Info (diff);
change = diff * ratio;
change = round(change);
//DEBUG_Print_Info (F(" B-Change "));
//DEBUG_Print_Info (change);
ret.b += (byte)(change);
} // end Step # > 0
if (stepNum == ofSteps)
{
ret = endColor;
}
/*
DEBUG_Print_Info (F(" Output "));
DEBUG_Print_Info (ret.r);
DEBUG_Print_Info (F(", "));
DEBUG_Print_Info (ret.g);
DEBUG_Print_Info (F(", "));
DEBUG_Println_Info (ret.b);
*/
return ret;
}
void randomizeTheList()
{
int m;
int r;
// First pass, fill theList with numbers in order
for (int n = 0; n < num_leds; n++)
{
theList[n] = n;
}
// Second pass, swap random pairs
for (int n = 0; n < num_leds; n++)
{
r = random(num_leds);
m = theList[n];
theList[n] = theList[r];
theList[r] = m;
}
}
void setTestDefaults()
{
// These are the TESTING defaults!
// A simple basic set of effects
// to check whatever I am trying to debug.
// The REAL factory defaults procedure is below,
EEPROM.writeByte(ADDR_LUCKY_NUMBER, MY_LUCKY_NUMBER);
EEPROM.writeByte(ADDR_CONFIG_VERSION, CONFIG_VERSION);
num_leds = 50;
EEPROM.writeInt(ADDR_NUM_LEDS, num_leds);
byte k = 0;
// Write some defaults into EVERY location
// effectively erasing the entire prior
// config and all its effects.
theEffect.pattern(PAT_NONE);
theEffect.time (10);
theEffect.speed(5);
theEffect.size (1);
theEffect.count(6);
theEffect.color(0, COLOR_RED);
theEffect.color(1, COLOR_YELLOW);
theEffect.color(2, COLOR_GREEN);
theEffect.color(3, COLOR_CYAN);
theEffect.color(4, COLOR_BLUE);
theEffect.color(5, COLOR_MAGENTA);
for (byte i = 0; i < NUM_EFFECTS; i++)
{
theEffect.save(i);
}
// Now start refilling with test effects
// Effect #0
theEffect.pattern(PAT_DISSOLVE);
theEffect.time(40);
theEffect.speed(5); // dissolve speed for each color
theEffect.count(4);
theEffect.size(5); // Seconds to wait between colors
theEffect.color(0, COLOR_WHITE);
theEffect.color(1, COLOR_RED);
theEffect.color(2, COLOR_MEDIUM);
theEffect.color(3, COLOR_GREEN);
theEffect.save(k);
k++;
// Effect #1
theEffect.pattern(PAT_GRADIENT);
theEffect.time (10);
theEffect.speed(5); // NOT Used
theEffect.size (10); // Spacing between colors
theEffect.count(5);
theEffect.color(0, COLOR_BLUE);
theEffect.color(1, COLOR_MAGENTA);
theEffect.color(2, COLOR_RED);
theEffect.color(3, COLOR_YELLOW);
theEffect.color(4, COLOR_GREEN);
theEffect.save(k);
k++;
// Effect #2
theEffect.pattern(PAT_FWDCHASE);
theEffect.time (15);
theEffect.speed(10);
theEffect.save(k);
k++;
// #3
theEffect.pattern(PAT_DISSOLVE);
theEffect.time(60);
theEffect.speed(5);
theEffect.count(4);
theEffect.color(0, COLOR_BLACK_OFF);
theEffect.color(1, COLOR_RED);
theEffect.color(2, COLOR_MEDIUM);
theEffect.color(3, COLOR_GREEN);
theEffect.save(k);
k++;
// #4
theEffect.pattern(PAT_SPARKLE);
theEffect.time (30);
theEffect.size (5);
theEffect.count(5);
theEffect.speed(10);
theEffect.backColor(COLOR_DK_MAGENTA);
theEffect.color(0, COLOR_BRT_WHITE);
theEffect.color(1, COLOR_LT_RED);
theEffect.color(2, COLOR_LT_MAGENTA);
theEffect.color(3, COLOR_LT_BLUE);
theEffect.color(4, COLOR_BRT_WHITE);
theEffect.save(k);
k++;
// write a NONE effect to end the list
// #5
theEffect.pattern(PAT_NONE);
theEffect.time (0);
theEffect.save(k);
effectCount = k;
// Write the custom color names
strcpy(strBuffer, NAME_CORAL);
writeCustomColorName(0);
colorsRGB[1] = hex2color(0xf08080); // RGB value in index +1 because color 0 = black
strcpy(strBuffer, NAME_OLIVE);
writeCustomColorName(1);
colorsRGB[2] = hex2color(0x6b8e23);
strcpy(strBuffer, NAME_WARM_WITE);
writeCustomColorName(2);
colorsRGB[3] = hex2color(0xffc0c0);
strcpy(strBuffer, NAME_TURQUOISE);
writeCustomColorName(3);
colorsRGB[4] = hex2color(0x40e0d0);
strcpy(strBuffer, NAME_LIME);
writeCustomColorName(4);
colorsRGB[5] = hex2color(0x40ff40);
strcpy(strBuffer, NAME_GOLD);
writeCustomColorName(5);
colorsRGB[6] = hex2color(0xb0ff20);
strcpy(strBuffer, NAME_INDIGO);
writeCustomColorName(6);
colorsRGB[7] = hex2color(0x4b0082);
strcpy(strBuffer, NAME_CRIMSON);
writeCustomColorName(7);
colorsRGB[8] = hex2color(0xdc143c);
} // End setTestDefaults()
void setDefaults()
{
// These are the normal "default" effects and patterns
// but not really "default" as this set is custom designed
// specifically for Princess Janine D'Berry's Chrismas Tree
EEPROM.writeByte(ADDR_LUCKY_NUMBER, MY_LUCKY_NUMBER);
EEPROM.writeByte(ADDR_CONFIG_VERSION, CONFIG_VERSION);
num_leds = 250;
EEPROM.writeInt(ADDR_NUM_LEDS, num_leds);
byte k = 0;
// Write some defaults into EVERY location
// effectively erasing the entire prior
// config and all its effects.
theEffect.pattern(PAT_NONE);
theEffect.time (10);
theEffect.speed(5);
theEffect.size (1);
theEffect.count(6);
theEffect.color(0, COLOR_RED);
theEffect.color(1, COLOR_YELLOW);
theEffect.color(2, COLOR_GREEN);
theEffect.color(3, COLOR_CYAN);
theEffect.color(4, COLOR_BLUE);
theEffect.color(5, COLOR_MAGENTA);
for (byte i = 0; i < NUM_EFFECTS; i++)
{
theEffect.save(i);
}
// Now start filling in with some actual effects
// Effect #1
theEffect.pattern(PAT_DOTS); // White on Purple, for Richard
theEffect.time (2);
theEffect.speed(3);
theEffect.count(5);
theEffect.size(10);
theEffect.color(0, COLOR_RED);
theEffect.color(1, COLOR_YELLOW);
theEffect.color(2, COLOR_GREEN);
theEffect.color(3, COLOR_BLUE);
theEffect.color(4, COLOR_MAGENTA);
theEffect.save(k);
k++;
//2
theEffect.pattern(PAT_FWDCHASE);
theEffect.time (15);
theEffect.speed(10);
theEffect.save(k);
k++;
//3
theEffect.pattern(PAT_REVCHASE);
theEffect.time (15);
theEffect.speed(10);
theEffect.save(k);
k++;
//4
theEffect.pattern(PAT_DOTS); // Setup for Purple Sparkle
theEffect.time (1);
theEffect.size (50);
theEffect.count(1);
theEffect.color(0, COLOR_DK_MAGENTA);
theEffect.save(k);
k++;
//5
theEffect.pattern(PAT_SPARKLE); // White on Purple, for Richard
theEffect.time (20);
theEffect.speed(3);
theEffect.count(6);
theEffect.backColor(COLOR_DK_MAGENTA);
theEffect.color(0, COLOR_WHITE);
theEffect.color(1, COLOR_BRT_WHITE);
theEffect.color(2, COLOR_WHITE);
theEffect.color(3, COLOR_DIM_WHITE);
theEffect.color(4, COLOR_BRT_WHITE);
theEffect.save(k);
k++;
//6
theEffect.pattern(PAT_FADE); // Rainbow
theEffect.time (30);
theEffect.speed(5);
theEffect.count(6);
theEffect.color(0, COLOR_BLUE);
theEffect.color(1, COLOR_CYAN);
theEffect.color(2, COLOR_GREEN);
theEffect.color(3, COLOR_YELLOW);
theEffect.color(4, COLOR_RED);
theEffect.color(5, COLOR_BLACK_OFF);
theEffect.save(k);
k++;
//7
theEffect.pattern(PAT_GRADIENT);
theEffect.time (5);
theEffect.speed(5); // NOT Used
theEffect.size (50); // Spacing between colors
theEffect.count(5);
theEffect.color(0, COLOR_BLUE);
theEffect.color(1, COLOR_MAGENTA);
theEffect.color(2, COLOR_RED);
theEffect.color(3, COLOR_YELLOW);
theEffect.color(4, COLOR_GREEN);
theEffect.save(k);
k++;
//8
theEffect.pattern(PAT_FWDCHASE);
theEffect.time (15);
theEffect.speed(10);
theEffect.save(k);
k++;
//9
theEffect.pattern(PAT_DISSOLVE);
theEffect.time(4);
theEffect.speed(10);
theEffect.count(3);
theEffect.color(0, COLOR_RED);
theEffect.color(1, COLOR_GREEN);
theEffect.color(2, COLOR_WHITE);
theEffect.save(k);
k++;
//10
theEffect.pattern(PAT_SPARKLE); // Purple on Black, for Richard
theEffect.time (20);
theEffect.speed(3);
theEffect.count(6);
theEffect.backColor(COLOR_BLACK_OFF);
theEffect.color(0, COLOR_PURPLE);
theEffect.color(1, COLOR_MAGENTA);
theEffect.color(2, COLOR_DK_MAGENTA);
theEffect.color(3, COLOR_LT_MAGENTA);
theEffect.color(4, COLOR_MAGENTA);
theEffect.save(k);
k++;
//11
theEffect.pattern(PAT_DOTS); // Setup for Purple Sparkle
theEffect.time (1);
theEffect.size (50);
theEffect.count(1);
theEffect.color(0, COLOR_MEDIUM);
theEffect.save(k);
k++;
//12
theEffect.pattern(PAT_SPARKLE);
theEffect.time (20);
theEffect.speed(5);
theEffect.count(6);
theEffect.color(0, COLOR_DK_BLUE);
theEffect.color(1, COLOR_BRT_WHITE);
theEffect.color(2, COLOR_WHITE);
theEffect.color(3, COLOR_DK_BLUE);
theEffect.color(4, COLOR_BLACK_OFF);
theEffect.color(5, COLOR_DK_BLUE);
theEffect.save(k);
k++;
//13
theEffect.pattern(PAT_SPARKLE);
theEffect.time (20);
theEffect.speed(5);
theEffect.count(6);
theEffect.color(0, COLOR_DK_GREEN);
theEffect.color(1, COLOR_RED);
theEffect.color(2, COLOR_DK_RED);
theEffect.color(3, COLOR_LT_RED);
theEffect.color(4, COLOR_DK_GREEN);
theEffect.color(5, COLOR_DK_GREEN);
theEffect.save(k);
k++;
//14
theEffect.pattern(PAT_GRADIENT);
theEffect.time (5);
theEffect.speed(5); // NOT Used
theEffect.size (75); // Spacing between colors
theEffect.count(2);
theEffect.color(0, COLOR_GREEN);
theEffect.color(1, COLOR_RED);
theEffect.save(k);
k++;
//15
theEffect.pattern(PAT_REVCHASE);
theEffect.time (15);
theEffect.speed(10);
theEffect.save(k);
k++;
//16
theEffect.pattern(PAT_DOTS); // Rainbow
theEffect.time (3);
theEffect.size (1);
theEffect.count(3);
theEffect.color(0, COLOR_RANDOM);
theEffect.color(1, COLOR_ANY);
theEffect.color(2, COLOR_MEDIUM);
theEffect.save(k);
k++;
//17
theEffect.pattern(PAT_DISSOLVE);
theEffect.time(30);
theEffect.speed(1);
theEffect.count(4);
theEffect.color(0, COLOR_BRT_WHITE);
theEffect.color(1, COLOR_WHITE);
theEffect.color(2, COLOR_DIM_WHITE);
theEffect.color(2, COLOR_BLACK_OFF);
theEffect.save(k);
k++;
// Write a NONE effect to end the list
// (18)
theEffect.pattern(PAT_NONE);
theEffect.time (0);
theEffect.save(k);
effectCount = k;
// Write the custom color names
strcpy(strBuffer, NAME_CORAL);
writeCustomColorName(0);
colorsRGB[1] = hex2color(0xf08080); // RGB value in index +1 because color 0 = black
strcpy(strBuffer, NAME_OLIVE);
writeCustomColorName(1);
colorsRGB[2] = hex2color(0x6b8e23);
strcpy(strBuffer, NAME_WARM_WITE);
writeCustomColorName(2);
colorsRGB[3] = hex2color(0xffc0c0);
strcpy(strBuffer, NAME_TURQUOISE);
writeCustomColorName(3);
colorsRGB[4] = hex2color(0x40e0d0);
strcpy(strBuffer, NAME_LIME);
writeCustomColorName(4);
colorsRGB[5] = hex2color(0x40ff40);
strcpy(strBuffer, NAME_GOLD);
writeCustomColorName(5);
colorsRGB[6] = hex2color(0xb0ff20);
strcpy(strBuffer, NAME_INDIGO);
writeCustomColorName(6);
colorsRGB[7] = hex2color(0x4b0082);
strcpy(strBuffer, NAME_CRIMSON);
writeCustomColorName(7);
colorsRGB[8] = hex2color(0xdc143c);
} // End void setDefaults()
And finally, the code for DebugUtils.h is:
//*******************************************************************
// DebugUtils.h - Simple debugging utilities.
// (u) UnCopyright 2022+ Dr. Wizard K. Pendleton, but I take no credit for it.
// Modelled after version by Fabio Varesano <fabio at varesano dot net>
//
// Ideas taken from:
// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1271517197
//
// Open source rules apply under the terms of the version 3 GNU General Public
// License as published by the Free Software Foundation.
// No warranty, use at your own risk, etc.
//********************************************************************
#ifndef DEBUGUTILS_H
#define DEBUGUTILS_H
// Turn various types of debug messages on and off
// FOR DEBUGGING, UN-REMARK ONE OR BOTH DEFINES BELOW
// FOR RELEASE, REMARK BOTH LINES BELOW
#define DEBUG_Mode_Trace
#define DEBUG_Mode_Info
// End Debug/Release defines
#ifdef DEBUG_Mode_Trace
#define DEBUG_Print_Trace(str) \
Serial.print(str); \
Serial.print(F(" - in ")); \
Serial.print(__PRETTY_FUNCTION__); \
Serial.print(F(" in ")); \
Serial.print(__FILE__); \
Serial.print(F(" #")); \
Serial.print(__LINE__); \
Serial.print(F(" @")); \
Serial.print(millis());
#define DEBUG_Println_Trace(str) \
Serial.print(str); \
Serial.print(F(" - in ")); \
Serial.print(__PRETTY_FUNCTION__); \
Serial.print(F(" in ")); \
Serial.print(__FILE__); \
Serial.print(F(" #")); \
Serial.print(__LINE__); \
Serial.print(F(" @")); \
Serial.println(millis());
#else
#define DEBUG_Print_Trace(str)
#define DEBUG_Println_Trace(str)
#endif
#ifdef DEBUG_Mode_Info
#define DEBUG_Print_Info(str) Serial.print (str)
#define DEBUG_Println_Info(str) Serial.println(str)
#define DEBUG_HexPrint_Info(str) Serial.print (str, HEX) // Doesn't work, dangit
//#define DEBUG_Println_Info(str, mod) Serial.println(str, mod)
#else
#define DEBUG_Print_Info(str)
#define DEBUG_Println_Info(str)
#define DEBUG_HexPrint_Info(str)
//#define DEBUG_Println_Info(str, mod)
#endif
#endif //ifndef DEBUGUTILS_H