diff --git a/examples/tester.zsh b/examples/tester.zsh index 491e0bd..4cc3cb3 100755 --- a/examples/tester.zsh +++ b/examples/tester.zsh @@ -8,11 +8,9 @@ # output a file and go get a cup of coffee: # ./tester.zsh > tester.txt -# add the Arduino IDE 1.0 application to $PATH -# export PATH="$PATH:/Applications/Arduino IDE.app/Contents/MacOS" - # path to the Arduino IDE 2.0 CLI executable (for MacOS) -alias -g arduinoCLI="/Applications/Arduino\ IDE.app/Contents/Resources/app/node_modules/arduino-ide-extension/build/arduino-cli" +#alias -g arduinoCLI="/Applications/Arduino\ IDE.app/Contents/Resources/app/node_modules/arduino-ide-extension/build/arduino-cli" +alias -g arduinoCLI="/Applications/Arduino\ IDE.app/Contents/Resources/app/lib/backend/resources/arduino-cli" # test that we can execute the Arduino command # arduinoCLI version @@ -22,12 +20,14 @@ alias -g leonardo-board="arduino:avr:leonardo" alias -g esp8266-board="esp8266:esp8266:nodemcuv2" alias -g esp32-board="esp32:esp32:esp32doit-devkit-v1" alias -g rp2040-board="rp2040:rp2040:rpipico" +alias -g ATtiny-board="megaTinyCore:megaavr:atxy2" # port aliases alias -g leonardo-port="/dev/cu.usbmodem14101 (Arduino Leonardo)" alias -g esp8266-port="/dev/cu.usbserial-0001" alias -g esp32-port="/dev/cu.usbserial-0001" alias -g rp2040-port="/dev/cu.usbmodem14101 (Raspberry Pi Pico)" +alias -g ATtiny-port="/dev/cu.usbserial-2340 SerialPort (USB)" # Arduino Nano used as a programmer # example compile command: # arduinoCLI compile -b leonardo-board ws2812fx_segments/ws2812fx_segments.ino @@ -109,3 +109,7 @@ arduinoCLI compile --no-color -b esp8266-board ws2812fx_soundfx/ws2812fx_soundfx # the ws2812fx_dma example sketch is written to work only on ESP8266 boards, so test that separately echo "\nCompiling ws2812fx_dma/ws2812fx_dma.ino for ESP8266" arduinoCLI compile --no-color -b esp8266-board ws2812fx_dma/ws2812fx_dma.ino 2>/dev/null; echo "exit status" $? + +# the ATtiny board is special, so test that separately +echo "\nCompiling ws2812fx_ATtiny/ws2812fx_ATtiny.ino for ATtiny412" +arduinoCLI compile --no-color -b ATtiny-board ws2812fx_ATtiny/ws2812fx_ATtiny.ino 2>/dev/null; echo "exit status" $? diff --git a/examples/tester_June2024.txt b/examples/tester_June2024.txt new file mode 100644 index 0000000..c2d1060 --- /dev/null +++ b/examples/tester_June2024.txt @@ -0,0 +1,364 @@ + +Compiling auto_mode_cycle/auto_mode_cycle.ino for Arduino Leonardo + +Used platform Version Path +arduino:avr 1.8.6 /Users/klord/Library/Arduino15/packages/arduino/hardware/avr/1.8.6 +exit status 1 + +Compiling external_trigger/external_trigger.ino for Arduino Leonardo + +Used platform Version Path +arduino:avr 1.8.6 /Users/klord/Library/Arduino15/packages/arduino/hardware/avr/1.8.6 +exit status 1 + +Compiling serial_control/serial_control.ino for Arduino Leonardo + +Used platform Version Path +arduino:avr 1.8.6 /Users/klord/Library/Arduino15/packages/arduino/hardware/avr/1.8.6 +exit status 1 + +Compiling ws2812fx_audio_reactive/ws2812fx_audio_reactive.ino for Arduino Leonardo + +Used platform Version Path +arduino:avr 1.8.6 /Users/klord/Library/Arduino15/packages/arduino/hardware/avr/1.8.6 +exit status 1 + +Compiling ws2812fx_custom_effect/ws2812fx_custom_effect.ino for Arduino Leonardo + +Used platform Version Path +arduino:avr 1.8.6 /Users/klord/Library/Arduino15/packages/arduino/hardware/avr/1.8.6 +exit status 1 + +Compiling ws2812fx_custom_effect2/ws2812fx_custom_effect2.ino for Arduino Leonardo + +Used platform Version Path +arduino:avr 1.8.6 /Users/klord/Library/Arduino15/packages/arduino/hardware/avr/1.8.6 +exit status 1 + +Compiling ws2812fx_custom_FastLED/ws2812fx_custom_FastLED.ino for Arduino Leonardo + +Used platform Version Path +arduino:avr 1.8.6 /Users/klord/Library/Arduino15/packages/arduino/hardware/avr/1.8.6 +exit status 1 + +Compiling ws2812fx_limit_current/ws2812fx_limit_current.ino for Arduino Leonardo + +Used platform Version Path +arduino:avr 1.8.6 /Users/klord/Library/Arduino15/packages/arduino/hardware/avr/1.8.6 +exit status 1 + +Compiling ws2812fx_matrix/ws2812fx_matrix.ino for Arduino Leonardo + +Used platform Version Path +arduino:avr 1.8.6 /Users/klord/Library/Arduino15/packages/arduino/hardware/avr/1.8.6 +exit status 1 + +Compiling ws2812fx_msgeq7/ws2812fx_msgeq7.ino for Arduino Leonardo + +Used platform Version Path +arduino:avr 1.8.6 /Users/klord/Library/Arduino15/packages/arduino/hardware/avr/1.8.6 +exit status 1 + +Compiling ws2812fx_overlay/ws2812fx_overlay.ino for Arduino Leonardo + +Used platform Version Path +arduino:avr 1.8.6 /Users/klord/Library/Arduino15/packages/arduino/hardware/avr/1.8.6 +exit status 1 + +Compiling ws2812fx_segment_sequence/ws2812fx_segment_sequence.ino for Arduino Leonardo + +Used platform Version Path +arduino:avr 1.8.6 /Users/klord/Library/Arduino15/packages/arduino/hardware/avr/1.8.6 +exit status 1 + +Compiling ws2812fx_segments/ws2812fx_segments.ino for Arduino Leonardo + +Used platform Version Path +arduino:avr 1.8.6 /Users/klord/Library/Arduino15/packages/arduino/hardware/avr/1.8.6 +exit status 1 + +Compiling ws2812fx_spi/ws2812fx_spi.ino for Arduino Leonardo + +Used platform Version Path +arduino:avr 1.8.6 /Users/klord/Library/Arduino15/packages/arduino/hardware/avr/1.8.6 +exit status 1 + +Compiling ws2812fx_transitions/ws2812fx_transitions.ino for Arduino Leonardo + +Used platform Version Path +arduino:avr 1.8.6 /Users/klord/Library/Arduino15/packages/arduino/hardware/avr/1.8.6 +exit status 1 + +Compiling ws2812fx_virtual_strip/ws2812fx_virtual_strip.ino for Arduino Leonardo + +Used platform Version Path +arduino:avr 1.8.6 /Users/klord/Library/Arduino15/packages/arduino/hardware/avr/1.8.6 +exit status 1 + +Compiling auto_mode_cycle/auto_mode_cycle.ino for ESP8266 +exit status 1 + +Compiling external_trigger/external_trigger.ino for ESP8266 +exit status 1 + +Compiling serial_control/serial_control.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_audio_reactive/ws2812fx_audio_reactive.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_custom_effect/ws2812fx_custom_effect.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_custom_effect2/ws2812fx_custom_effect2.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_custom_FastLED/ws2812fx_custom_FastLED.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_limit_current/ws2812fx_limit_current.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_matrix/ws2812fx_matrix.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_msgeq7/ws2812fx_msgeq7.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_overlay/ws2812fx_overlay.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_segment_sequence/ws2812fx_segment_sequence.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_segments/ws2812fx_segments.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_spi/ws2812fx_spi.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_transitions/ws2812fx_transitions.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_virtual_strip/ws2812fx_virtual_strip.ino for ESP8266 +exit status 1 + +Compiling auto_mode_cycle/auto_mode_cycle.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling external_trigger/external_trigger.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling serial_control/serial_control.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_audio_reactive/ws2812fx_audio_reactive.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_custom_effect/ws2812fx_custom_effect.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_custom_effect2/ws2812fx_custom_effect2.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_custom_FastLED/ws2812fx_custom_FastLED.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_limit_current/ws2812fx_limit_current.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_matrix/ws2812fx_matrix.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_msgeq7/ws2812fx_msgeq7.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_overlay/ws2812fx_overlay.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_segment_sequence/ws2812fx_segment_sequence.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_segments/ws2812fx_segments.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_spi/ws2812fx_spi.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_transitions/ws2812fx_transitions.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_virtual_strip/ws2812fx_virtual_strip.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling auto_mode_cycle/auto_mode_cycle.ino for RP2040 +exit status 1 + +Compiling external_trigger/external_trigger.ino for RP2040 +exit status 1 + +Compiling serial_control/serial_control.ino for RP2040 +exit status 1 + +Compiling ws2812fx_audio_reactive/ws2812fx_audio_reactive.ino for RP2040 +exit status 1 + +Compiling ws2812fx_custom_effect/ws2812fx_custom_effect.ino for RP2040 +exit status 1 + +Compiling ws2812fx_custom_effect2/ws2812fx_custom_effect2.ino for RP2040 +exit status 1 + +Compiling ws2812fx_custom_FastLED/ws2812fx_custom_FastLED.ino for RP2040 +exit status 1 + +Compiling ws2812fx_limit_current/ws2812fx_limit_current.ino for RP2040 +exit status 1 + +Compiling ws2812fx_matrix/ws2812fx_matrix.ino for RP2040 +exit status 1 + +Compiling ws2812fx_msgeq7/ws2812fx_msgeq7.ino for RP2040 +exit status 1 + +Compiling ws2812fx_overlay/ws2812fx_overlay.ino for RP2040 +exit status 1 + +Compiling ws2812fx_segment_sequence/ws2812fx_segment_sequence.ino for RP2040 +exit status 1 + +Compiling ws2812fx_segments/ws2812fx_segments.ino for RP2040 +exit status 1 + +Compiling ws2812fx_spi/ws2812fx_spi.ino for RP2040 +exit status 1 + +Compiling ws2812fx_transitions/ws2812fx_transitions.ino for RP2040 +exit status 1 + +Compiling ws2812fx_virtual_strip/ws2812fx_virtual_strip.ino for RP2040 +exit status 1 + +Compiling esp8266_webinterface/esp8266_webinterface.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_alexa/ws2812fx_alexa.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_patterns_web/ws2812fx_patterns_web.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_segments_OTA/ws2812fx_segments_OTA.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_segments_web/ws2812fx_segments_web.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_extData/ws2812fx_extData.ino for ESP8266 +exit status 1 + +Compiling esp8266_webinterface/esp8266_webinterface.ino for ESP32 + +Used library Version Path +WiFi 2.0.0 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1/libraries/WiFi +Networking 1.0.0 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1/libraries/Network +WebServer 2.0.0 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1/libraries/WebServer +FS 2.0.0 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1/libraries/FS + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_alexa/ws2812fx_alexa.ino for ESP32 + +Used library Version Path +WiFi 2.0.0 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1/libraries/WiFi +Networking 1.0.0 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1/libraries/Network + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_patterns_web/ws2812fx_patterns_web.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_segments_OTA/ws2812fx_segments_OTA.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_segments_web/ws2812fx_segments_web.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_extData/ws2812fx_extData.ino for ESP32 + +Used platform Version Path +esp32:esp32 3.0.1 /Users/klord/Library/Arduino15/packages/esp32/hardware/esp32/3.0.1 +exit status 1 + +Compiling ws2812fx_soundfx/ws2812fx_soundfx.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_dma/ws2812fx_dma.ino for ESP8266 +exit status 1 + +Compiling ws2812fx_ATtiny/ws2812fx_ATtiny.ino for ATtiny412 + +Used platform Version Path +megaTinyCore:megaavr 2.6.10 /Users/klord/Library/Arduino15/packages/megaTinyCore/hardware/megaavr/2.6.10 +exit status 1 diff --git a/examples/ws2812fx_ATtiny/ws2812fx_ATtiny.ino b/examples/ws2812fx_ATtiny/ws2812fx_ATtiny.ino new file mode 100644 index 0000000..f1095cb --- /dev/null +++ b/examples/ws2812fx_ATtiny/ws2812fx_ATtiny.ino @@ -0,0 +1,96 @@ +/* + WS2812FX ATtiny demo. + + Keith Lord - 2024 + + FEATURES + * example of WS2812FX using an ATtiny processor. + + ATtiny support is provided by Spence Konde's megaTinyCore package. + Install it with Board Manager by following the instructions here: + https://github.com/SpenceKonde/megaTinyCore/blob/master/Installation.md + + Note, we're using megaTinyCore's tinyNeoPixel_Static library under the + hood, which currently requires a tweak in order to make it compatible + with WS2812FX. Without this tweak you'll get compile errors about + variables being "private within this context". + The tweak involves editing the library's tinyNeoPixel_Static.h file + (Arduino15/packages/megaTinyCore/hardware/megaavr/2.6.10/libraries/tinyNeoPixel_Static/tinyNeoPixel_Static.h) + and change line 308 from "private:" to "protected:". This allows WS2812FX + to access inherited variables from the tinyNeoPixel_Static lib. + A Github PR has been submitted to fix this issue in the megaTinyCore + source code, which will hopefully be accepted soon and eliminate the + need for this hack. + + Also note, the ATtiny is extremely memory constrained. Consequently + processors with less than 4k of flash memory are not supported. + Processors with 4k of flash memory only support the following + seven effects: + FX_MODE_STATIC + FX_MODE_BLINK + FX_MODE_STROBE + FX_MODE_COLOR_WIPE + FX_MODE_COLOR_WIPE_REV + FX_MODE_TRICOLOR_CHASE + FX_MODE_SPARKLE + Also note, processors with only 4k of flash do not have enough + memory to include the Serial library. Adding Serial statements + to print debug info will lead to strange behavior. + + Processors with only 256 bytes of RAM can support a maximum of + about 40 RGB LEDs. + + + LICENSE + + The MIT License (MIT) + + Copyright (c) 2024 Keith Lord + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, 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. + + + CHANGELOG + 2024-05-20 initial version + +*/ + +#include + +#define LED_PIN PIN_PA1 // digital pin used to drive the LED strip +#define LED_COUNT 32 // number of LEDs on the strip + +byte pixelArray[LED_COUNT * 3]; // the ATtiny library requires the pixel array be statically allocated +WS2812FX ws2812fx = WS2812FX(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800, pixelArray); + +void setup() { + pinMode(LED_PIN, OUTPUT); // the ATtiny library requires setting the LED GPIO pinMode + +//ws2812fx.init(); // running the init() function is not required for the ATtiny library + ws2812fx.setBrightness(8); + + // parameters: index, start, stop, mode, color, speed, reverse + ws2812fx.setSegment(0, 0, LED_COUNT - 1, FX_MODE_BLINK, GREEN); // the ATtiny library only allows one segment + + ws2812fx.start(); +} + +void loop() { + ws2812fx.service(); +} diff --git a/extras/WS2812FX change log.txt b/extras/WS2812FX change log.txt index 30151b4..06bc4aa 100644 --- a/extras/WS2812FX change log.txt +++ b/extras/WS2812FX change log.txt @@ -1,6 +1,25 @@ WS2182FX Change Log +v1.4.3 changes 05/12/2024 +------------------------- + +1) Added support for ATtiny processors using the tinyNeoPixel + library from megaTinyCore. + https://github.com/SpenceKonde/megaTinyCore + Note ATtiny processors are extremely memory constrained. + It's very easy to create sketches that are too big and either + won't compile or cause strange behavior at run time. + +2) Added the ws2812fx_ATtiny example sketch. + +3) Overriding the parent library's show() function was becoming + problematic, so WS2812FX's show() function has been renamed + execShow(). User sketches shouldn't call show() directly, + but if you do, show() will now execute the parent classes + show() function and skip any customShow code. + + v1.4.2 changes 05/11/2023 ------------------------- diff --git a/library.json b/library.json index 63426bf..81746ec 100644 --- a/library.json +++ b/library.json @@ -6,7 +6,7 @@ "name": "Harm Aldick", "url": "https://github.com/kitesurfer1404/WS2812FX" }, - "version": "1.4.2", + "version": "1.4.3", "frameworks": "arduino", "platforms": "*", "repository": { diff --git a/library.properties b/library.properties index 7982c3e..13a901a 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WS2812FX -version=1.4.2 +version=1.4.3 author=Harm Aldick maintainer=Harm Aldick sentence=WS2812 FX Library for Arduino and ESP microprocessors. diff --git a/src/WS2812FX.cpp b/src/WS2812FX.cpp index 5580b88..5eed240 100644 --- a/src/WS2812FX.cpp +++ b/src/WS2812FX.cpp @@ -56,7 +56,7 @@ void WS2812FX::init() { resetSegmentRuntimes(); - Adafruit_NeoPixel::begin(); + begin(); } // void WS2812FX::timer() { @@ -86,7 +86,7 @@ bool WS2812FX::service() { } if(doShow) { delay(1); // for ESP32 (see https://forums.adafruit.com/viewtopic.php?f=47&t=117327) - show(); + execShow(); } _triggered = false; } @@ -108,17 +108,21 @@ void WS2812FX::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b) { } void WS2812FX::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w) { +#if defined(MEGATINYCORE) // if compiling for an ATtiny device (to conserve memory, no gamma correction) + tinyNeoPixel::setPixelColor(n, r, g, b, w); +#else if(IS_GAMMA) { Adafruit_NeoPixel::setPixelColor(n, gamma8(r), gamma8(g), gamma8(b), gamma8(w)); } else { Adafruit_NeoPixel::setPixelColor(n, r, g, b, w); } +#endif } // custom setPixelColor() function that bypasses the Adafruit_Neopixel global brightness rigmarole void WS2812FX::setRawPixelColor(uint16_t n, uint32_t c) { if (n < numLEDs) { - uint8_t *p = (wOffset == rOffset) ? &pixels[n * 3] : &pixels[n * 4]; + uint8_t *p = (wOffset == rOffset) ? &pixels[n * 3] : &pixels[n * 4]; uint8_t w = (uint8_t)(c >> 24), r = (uint8_t)(c >> 16), g = (uint8_t)(c >> 8), b = (uint8_t)c; p[wOffset] = w; @@ -133,7 +137,7 @@ uint32_t WS2812FX::getRawPixelColor(uint16_t n) { if (n >= numLEDs) return 0; // Out of bounds, return no color. if(wOffset == rOffset) { // RGB - uint8_t *p = &pixels[n * 3]; + uint8_t *p = &pixels[n * 3]; return ((uint32_t)p[rOffset] << 16) | ((uint32_t)p[gOffset] << 8) | (uint32_t)p[bOffset]; } else { // RGBW uint8_t *p = &pixels[n * 4]; @@ -150,15 +154,15 @@ void WS2812FX::copyPixels(uint16_t dest, uint16_t src, uint16_t count) { // change the underlying Adafruit_NeoPixel pixels pointer (use with care) void WS2812FX::setPixels(uint16_t num_leds, uint8_t* ptr) { - free(Adafruit_NeoPixel::pixels); // free existing data (if any) - Adafruit_NeoPixel::pixels = ptr; - Adafruit_NeoPixel::numLEDs = num_leds; - Adafruit_NeoPixel::numBytes = num_leds * ((wOffset == rOffset) ? 3 : 4); + free(pixels); // free existing data (if any) + pixels = ptr; + numLEDs = num_leds; + numBytes = num_leds * ((wOffset == rOffset) ? 3 : 4); } -// overload show() functions so we can use custom show() -void WS2812FX::show(void) { - customShow == NULL ? Adafruit_NeoPixel::show() : customShow(); +// run the default or custom show() function +void WS2812FX::execShow(void) { + customShow == NULL ? show() : customShow(); } void WS2812FX::start() { @@ -238,8 +242,8 @@ void WS2812FX::setColors(uint8_t seg, uint32_t* c) { void WS2812FX::setBrightness(uint8_t b) { //b = constrain(b, BRIGHTNESS_MIN, BRIGHTNESS_MAX); - Adafruit_NeoPixel::setBrightness(b); - show(); + brightness = b; + execShow(); } void WS2812FX::increaseBrightness(uint8_t s) { @@ -258,12 +262,12 @@ void WS2812FX::setLength(uint16_t b) { // Decrease numLEDs to maximum available memory do { - Adafruit_NeoPixel::updateLength(b); + updateLength(b); b--; - } while(!Adafruit_NeoPixel::numLEDs && b > 1); + } while(!(numLEDs && b > 1)); _segments[0].start = 0; - _segments[0].stop = Adafruit_NeoPixel::numLEDs - 1; + _segments[0].stop = numLEDs - 1; } void WS2812FX::increaseLength(uint16_t s) { @@ -274,7 +278,7 @@ void WS2812FX::increaseLength(uint16_t s) { void WS2812FX::decreaseLength(uint16_t s) { uint16_t seglen = _segments[0].stop - _segments[0].start + 1; fill(BLACK, _segments[0].start, seglen); - show(); + execShow(); if (s < seglen) setLength(seglen - s); } @@ -558,8 +562,8 @@ void WS2812FX::resetSegmentRuntime(uint8_t seg) { * Turns everything off. Doh. */ void WS2812FX::strip_off() { - Adafruit_NeoPixel::clear(); - show(); + clear(); + execShow(); } /* diff --git a/src/WS2812FX.h b/src/WS2812FX.h index e65ab43..ef3d6a0 100644 --- a/src/WS2812FX.h +++ b/src/WS2812FX.h @@ -40,7 +40,11 @@ #define FSH(x) (__FlashStringHelper*)(x) #define MAX_MILLIS (0UL - 1UL) /* ULONG_MAX */ -#include +#if defined(MEGATINYCORE) // if compiling for an ATtiny device + #include +#else + #include +#endif #define DEFAULT_BRIGHTNESS (uint8_t)50 #define DEFAULT_MODE (uint8_t)0 @@ -120,6 +124,327 @@ #define CLR_CYCLE (_seg_rt->aux_param2 &= ~CYCLE) #define CLR_FRAME_CYCLE (_seg_rt->aux_param2 &= ~(FRAME | CYCLE)) +#if defined(MEGATINYCORE) // if compiling for an ATtiny device +class WS2812FX : public tinyNeoPixel { + + public: + typedef uint16_t (WS2812FX::*mode_ptr)(void); + + // segment parameters + typedef struct Segment { // 20 bytes + uint16_t start = 0; + uint16_t stop = 0; + uint16_t speed = DEFAULT_SPEED; + uint8_t mode = DEFAULT_MODE; + uint8_t options = 0; + uint32_t colors[MAX_NUM_COLORS] = DEFAULT_COLORS; + } segment; + + // segment runtime parameters + typedef struct Segment_runtime { // 20 bytes for Arduino, 24 bytes for ESP + unsigned long next_time; + uint32_t counter_mode_step; + uint32_t counter_mode_call; + uint8_t aux_param; // auxilary param (usually stores a color_wheel index) + uint8_t aux_param2; // auxilary param (usually stores bitwise options) + uint16_t aux_param3; // auxilary param (usually stores a segment index) + uint8_t* extDataSrc = NULL; // external data array + uint16_t extDataCnt = 0; // number of elements in the external data array + } segment_runtime; + + WS2812FX(uint16_t num_leds, uint8_t pin, neoPixelType type, byte* pixelPtr) + : tinyNeoPixel(num_leds, pin, type, pixelPtr) { + + brightness = 16; // default the brightness quite low to limit the current draw + +/* since an ATtiny is so memory constrained, we only allow one LED segment. Since the + number of segments is fixed, we can initialize the segment variable in the class + declaration (see below) instead of in the constructor. This means we can eliminate + using "new" to dynamically allocate the segment variables, which won't link in + malloc() and free() functions, saving quite a bit of flash memory. +*/ + // _running = false; + + // _segments_len = 1; + // _active_segments_len = 1; + + // create all the segment arrays and init to zeros + // _segments = new segment[_segments_len](); + // _active_segments = new uint8_t[_active_segments_len](); + // _segment_runtimes = new segment_runtime[_active_segments_len](); + + // init segment pointers + // _seg = _segments; + // _seg_rt = _segment_runtimes; + + // resetSegments(); + // setSegment(0, 0, num_leds - 1, DEFAULT_MODE, DEFAULT_COLOR, DEFAULT_SPEED, NO_OPTIONS); + }; + + // tinyNeoPixel_Static does not have an updateLength() function, so create + // a dummy function so the WS2812FX lib can compile. + void updateLength(uint16_t n) { return; }; + + void +// timer(void), + init(void), + start(void), + stop(void), + pause(void), + resume(void), + strip_off(void), + fade_out(void), + fade_out(uint32_t), + setMode(uint8_t m), + setMode(uint8_t seg, uint8_t m), + setOptions(uint8_t seg, uint8_t o), + setCustomMode(uint16_t (*p)()), + setCustomShow(void (*p)()), + setSpeed(uint16_t s), + setSpeed(uint8_t seg, uint16_t s), + increaseSpeed(uint8_t s), + decreaseSpeed(uint8_t s), + setColor(uint8_t r, uint8_t g, uint8_t b), + setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w), + setColor(uint32_t c), + setColor(uint8_t seg, uint32_t c), + setColors(uint8_t seg, uint32_t* c), + fill(uint32_t c, uint16_t f, uint16_t cnt), + setBrightness(uint8_t b), + increaseBrightness(uint8_t s), + decreaseBrightness(uint8_t s), + setLength(uint16_t b), + increaseLength(uint16_t s), + decreaseLength(uint16_t s), + trigger(void), + setCycle(void), + setNumSegments(uint8_t n), + + setSegment(), + setSegment(uint8_t n), + setSegment(uint8_t n, uint16_t start), + setSegment(uint8_t n, uint16_t start, uint16_t stop), + setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode), + setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, uint32_t color), + setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, uint32_t color, uint16_t speed), + setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, uint32_t color, uint16_t speed, bool reverse), + setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, uint32_t color, uint16_t speed, uint8_t options), + + setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, const uint32_t colors[]), + setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, const uint32_t colors[], uint16_t speed), + setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, const uint32_t colors[], uint16_t speed, bool reverse), + setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, const uint32_t colors[], uint16_t speed, uint8_t options), + + setIdleSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, uint32_t color, uint16_t speed), + setIdleSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, uint32_t color, uint16_t speed, uint8_t options), + setIdleSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, const uint32_t colors[], uint16_t speed, uint8_t options), + addActiveSegment(uint8_t seg), + removeActiveSegment(uint8_t seg), + swapActiveSegment(uint8_t oldSeg, uint8_t newSeg), + + resetSegments(void), + resetSegmentRuntimes(void), + resetSegmentRuntime(uint8_t), + setPixelColor(uint16_t n, uint32_t c), + setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b), + setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w), + setRawPixelColor(uint16_t n, uint32_t c), + copyPixels(uint16_t d, uint16_t s, uint16_t c), + setPixels(uint16_t, uint8_t*), + setRandomSeed(uint16_t), + setExtDataSrc(uint8_t seg, uint8_t *src, uint8_t cnt), + execShow(void); + + bool + service(void), + isRunning(void), + isTriggered(void), + isFrame(void), + isFrame(uint8_t), + isCycle(void), + isCycle(uint8_t), + isActiveSegment(uint8_t seg); + + uint8_t + random8(void), + random8(uint8_t), + getMode(void), + getMode(uint8_t), + getModeCount(void), + setCustomMode(const __FlashStringHelper* name, uint16_t (*p)()), + setCustomMode(uint8_t i, const __FlashStringHelper* name, uint16_t (*p)()), + getNumSegments(void), + get_random_wheel_index(uint8_t), + getOptions(uint8_t), + getNumBytesPerPixel(void); + + uint16_t + random16(void), + random16(uint16_t), + getSpeed(void), + getSpeed(uint8_t), + getLength(void), + getNumBytes(void); + + uint32_t + color_wheel(uint8_t), + getColor(void), + getColor(uint8_t), + intensitySum(void); + + uint32_t* getColors(uint8_t); + uint32_t* intensitySums(void); + uint8_t* getActiveSegments(void); + uint8_t* blend(uint8_t*, uint8_t*, uint8_t*, uint16_t, uint8_t); + + const __FlashStringHelper* getModeName(uint8_t m); + + WS2812FX::Segment* getSegment(void); + + WS2812FX::Segment* getSegment(uint8_t); + + WS2812FX::Segment* getSegments(void); + + WS2812FX::Segment_runtime* getSegmentRuntime(void); + + WS2812FX::Segment_runtime* getSegmentRuntime(uint8_t); + + WS2812FX::Segment_runtime* getSegmentRuntimes(void); + + // mode helper functions + uint16_t + blink(uint32_t, uint32_t, bool strobe), + color_wipe(uint32_t, uint32_t, bool), + twinkle(uint32_t, uint32_t), + twinkle_fade(uint32_t), + sparkle(uint32_t, uint32_t), + chase(uint32_t, uint32_t, uint32_t), + chase_flash(uint32_t, uint32_t), + running(uint32_t, uint32_t), + fireworks(uint32_t), + fire_flicker(int), + tricolor_chase(uint32_t, uint32_t, uint32_t), + scan(uint32_t, uint32_t, bool); + + uint32_t + color_blend(uint32_t, uint32_t, uint8_t), + getRawPixelColor(uint16_t n); + + // 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_wipe_inv(void), + mode_color_wipe_rev(void), + mode_color_wipe_rev_inv(void), + mode_color_wipe_random(void), + mode_color_sweep_random(void), + mode_random_color(void), + mode_single_dynamic(void), + mode_multi_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_twinkle(void), + mode_twinkle_random(void), + mode_twinkle_fade(void), + mode_twinkle_fade_random(void), + mode_sparkle(void), + mode_flash_sparkle(void), + mode_hyper_sparkle(void), + mode_multi_strobe(void), + mode_chase_white(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_chase_blackout(void), + mode_chase_blackout_rainbow(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_fireworks_random(void), + mode_merry_christmas(void), + mode_halloween(void), + mode_fire_flicker(void), + mode_fire_flicker_soft(void), + mode_fire_flicker_intense(void), + mode_circus_combustus(void), + mode_bicolor_chase(void), + mode_tricolor_chase(void), + mode_twinkleFOX(void), + mode_rain(void), + mode_block_dissolve(void), + mode_icu(void), + mode_dual_larson(void), + mode_running_random2(void), + mode_filler_up(void), + mode_rainbow_larson(void), + mode_rainbow_fireworks(void), + mode_trifade(void), + mode_vu_meter(void), + mode_heartbeat(void), + mode_bits(void), + mode_multi_comet(void), + mode_flipbook(void), + mode_popcorn(void), + mode_oscillator(void), + mode_custom_0(void), + mode_custom_1(void), + mode_custom_2(void), + mode_custom_3(void), + mode_custom_4(void), + mode_custom_5(void), + mode_custom_6(void), + mode_custom_7(void); + + private: + uint16_t _rand16seed; + uint16_t (*customModes[1])(void) { // to save space, only one custom mode allowed for ATtiny devices + // []{ return (uint16_t)1000; }, + // []{ return (uint16_t)1000; }, + // []{ return (uint16_t)1000; }, + // []{ return (uint16_t)1000; }, + // []{ return (uint16_t)1000; }, + // []{ return (uint16_t)1000; }, + // []{ return (uint16_t)1000; }, + []{ return (uint16_t)1000; } + }; + void (*customShow)(void) = NULL; + + bool + _running = false, + _triggered = false; + + segment _segments[1]; // array of segments (20 bytes per element) + segment_runtime _segment_runtimes[1]; // array of segment runtimes (16 bytes per element) + uint8_t _active_segments[1]; // array of active segments (1 bytes per element) + + uint8_t _segments_len = 1; // size of _segments array + uint8_t _active_segments_len = 1; // size of _segments_runtime and _active_segments arrays + uint8_t _num_segments = 0; // number of configured segments in the _segments array + + segment* _seg = _segments; // currently active segment (20 bytes) + segment_runtime* _seg_rt = _segment_runtimes; // currently active segment runtime (16 bytes) + + uint16_t _seg_len; // num LEDs in the currently active segment +}; +#else class WS2812FX : public Adafruit_NeoPixel { public: @@ -239,7 +564,7 @@ class WS2812FX : public Adafruit_NeoPixel { setPixels(uint16_t, uint8_t*), setRandomSeed(uint16_t), setExtDataSrc(uint8_t seg, uint8_t *src, uint8_t cnt), - show(void); + execShow(void); bool service(void), @@ -454,9 +779,9 @@ class WS2812FXT { } void service(void) { - bool doShow = v1->service() || v2->service(); - if(doShow) { - _show(); + bool isShowtime = v1->service() || v2->service(); + if(isShowtime) { + execShow(); } } @@ -467,7 +792,7 @@ class WS2812FXT { } private: - void _show(void) { + void execShow(void) { unsigned long now = millis(); uint8_t *dest_p = dest->getPixels(); @@ -484,7 +809,7 @@ class WS2812FXT { dest->blend(dest_p, vstart_p, vstop_p, numBytes, blendAmt); } - dest->Adafruit_NeoPixel::show(); + dest->show(); } public: @@ -495,6 +820,7 @@ class WS2812FXT { uint16_t transitionDuration = 5000; bool transitionDirection = true; }; +#endif // data struct used by the flipbook effect struct Flipbook { @@ -514,12 +840,14 @@ struct Popcorn { // data struct used by the oscillator effect struct Oscillator { uint8_t size; - int16_t pos; + uint16_t pos; int8_t speed; }; #if defined(ESP8266) || defined(ESP32) || defined(ARDUINO_ARCH_RP2040) #include "modes_esp.h" +#elif defined(MEGATINYCORE) + #include "modes_attiny.h" #else #include "modes_arduino.h" #endif diff --git a/src/custom/TwinkleFox.h b/src/custom/TwinkleFox.h index d54f703..ca702cc 100644 --- a/src/custom/TwinkleFox.h +++ b/src/custom/TwinkleFox.h @@ -73,7 +73,7 @@ uint16_t twinkleFox(void) { // Use the counter_mode_call var as a clock "tick" counter and calc the blend index uint8_t blendIndex = (initValue + (segrt->counter_mode_call * incrValue)) & 0xff; // 0-255 // Index into the built-in Adafruit_NeoPixel sine table to lookup the blend amount - uint8_t blendAmt = Adafruit_NeoPixel::sine8(blendIndex); // 0-255 + uint8_t blendAmt = sine8(blendIndex); // 0-255 // If colors[0] is BLACK, blend random colors if(color0 == BLACK) { diff --git a/src/modes.cpp b/src/modes.cpp index 4ca1609..efb60b5 100644 --- a/src/modes.cpp +++ b/src/modes.cpp @@ -302,7 +302,7 @@ uint16_t WS2812FX::mode_theater_chase_rainbow(void) { */ uint16_t WS2812FX::mode_running_lights(void) { uint8_t size = 1 << SIZE_OPTION; - uint8_t sineIncr = max(1, (256 / _seg_len) * size); + uint8_t sineIncr = max((uint8_t)1, (256 / _seg_len) * size); for(uint16_t i=0; i < _seg_len; i++) { int lum = (int)sine8(((i + _seg_rt->counter_mode_step) * sineIncr)); uint32_t color = color_blend(_seg->colors[0], _seg->colors[1], lum); @@ -644,7 +644,7 @@ uint16_t WS2812FX::mode_twinkleFOX(void) { // Use the counter_mode_call var as a clock "tick" counter and calc the blend index uint8_t blendIndex = (initValue + (_seg_rt->counter_mode_call * incrValue)) & 0xff; // 0-255 // Index into the built-in Adafruit_NeoPixel sine table to lookup the blend amount - uint8_t blendAmt = Adafruit_NeoPixel::sine8(blendIndex); // 0-255 + uint8_t blendAmt = sine8(blendIndex); // 0-255 // If colors[0] is BLACK, blend random colors if(color0 == BLACK) { @@ -865,7 +865,7 @@ uint16_t WS2812FX::mode_rainbow_fireworks(void) { // occasionally create a random red pixel if(random8(4) == 0) { - uint16_t index = _seg->start + 6 + random16(max(1, _seg_len - 12)); + uint16_t index = _seg->start + 6 + random16(max((uint8_t)1, _seg_len - 12)); setRawPixelColor(index, RED); // set the raw pixel color (ignore global brightness) SET_CYCLE; } @@ -1095,7 +1095,7 @@ uint16_t WS2812FX::mode_popcorn(void) { uint32_t popcornColor = (_seg->colors[0] == bgColor) ? color_wheel(random8()) : _seg->colors[0]; - for(int8_t i=0; i < cnt; i++) { // for each kernel + for(uint8_t i=0; i < cnt; i++) { // for each kernel if(src[i].position >= 0.0f) { // if kernel is active, update its position and slow it down src[i].position += src[i].velocity; src[i].velocity -= 0.1f; // gravity = -0.1 @@ -1120,14 +1120,14 @@ uint16_t WS2812FX::mode_popcorn(void) { uint16_t WS2812FX::mode_oscillator(void) { static Oscillator oscillators[] = { // 2 default oscillators {(uint8_t)(_seg_len/4), 0, 1}, // size, pos, speed - {(uint8_t)(_seg_len/4), (int16_t)(_seg_len - 1), -2} + {(uint8_t)(_seg_len/4), (uint16_t)(_seg_len - 1), -2} }; // if external data source not set, config for two oscillators. Oscillator* src = _seg_rt->extDataSrc != NULL ? (Oscillator*)_seg_rt->extDataSrc : oscillators; uint16_t cnt = _seg_rt->extDataCnt != 0 ? _seg_rt->extDataCnt : 2; - for(int8_t i=0; i < cnt; i++) { + for(uint16_t i=0; i < cnt; i++) { Oscillator* osc = &src[i]; if(osc->size == 0) osc->size = 1; // make sure the size is at least one osc->pos += osc->speed; // update the osc position @@ -1141,10 +1141,10 @@ uint16_t WS2812FX::mode_oscillator(void) { } // update LEDs based on new positions - for(int16_t i=0; i < _seg_len; i++) { + for(uint16_t i=0; i < _seg_len; i++) { // if the oscillators overlap, blend their colors uint32_t blendedcolor = BLACK; - for(int8_t j=0; j < cnt; j++) { + for(uint8_t j=0; j < cnt; j++) { Oscillator* osc = &src[j]; uint32_t oscColor = _seg->colors[j % MAX_NUM_COLORS]; if(i >= osc->pos && i < osc->pos + osc->size) { diff --git a/src/modes_attiny.h b/src/modes_attiny.h new file mode 100644 index 0000000..b08120d --- /dev/null +++ b/src/modes_attiny.h @@ -0,0 +1,225 @@ +/* + modes_attiny.h - WS2812FX header file for ATtiny microprocessors + + 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. + + + CHANGELOG + + 2022-03-23 Separated from the original WS2812FX.h file +*/ +#ifndef mode_attiny_h +#define mode_attiny_h + +#define MODE_COUNT (sizeof(_names)/sizeof(_names[0])) +#define MODE_PTR(x) this->*_modes[x] +#define MODE_NAME(x) _names[x] + +#define FX_MODE_STATIC 0 +#define FX_MODE_BLINK 1 +#define FX_MODE_STROBE 2 +#define FX_MODE_COLOR_WIPE 3 +#define FX_MODE_COLOR_WIPE_REV 4 +#define FX_MODE_TRICOLOR_CHASE 5 +#define FX_MODE_SPARKLE 6 + +#if (PROGMEM_SIZE > 4096UL) // if ATtiny has more tha 4k flash memory, include more effects +#define FX_MODE_BREATH 7 +#define FX_MODE_BICOLOR_CHASE 8 +#define FX_MODE_LARSON_SCANNER 9 +#define FX_MODE_RAINBOW_CYCLE 10 +#define FX_MODE_RANDOM_COLOR 11 +#define FX_MODE_FADE 12 +#define FX_MODE_COLOR_WIPE_RANDOM 13 +#define FX_MODE_COLOR_SWEEP_RANDOM 14 +#endif + +#if (PROGMEM_SIZE > 8192UL) // if ATtiny has more tha 8k flash memory, include more effects +#define FX_MODE_FIREWORKS 15 +#define FX_MODE_FIREWORKS_RANDOM 16 +#define FX_MODE_FIRE_FLICKER 17 +#define FX_MODE_FIRE_FLICKER_SOFT 18 +#define FX_MODE_FIRE_FLICKER_INTENSE 19 +#define FX_MODE_RUNNING_COLOR 20 +#define FX_MODE_RUNNING_LIGHTS 21 +#define FX_MODE_RUNNING_RANDOM 22 +#define FX_MODE_SINGLE_DYNAMIC 23 +#define FX_MODE_MULTI_DYNAMIC 24 +#define FX_MODE_TWINKLEFOX 25 +#define FX_MODE_HEARTBEAT 26 +#define FX_MODE_BLOCK_DISSOLVE 27 +#define FX_MODE_ICU 28 +#endif + +#if (PROGMEM_SIZE > 16384UL) // if ATtiny has more tha 16k flash memory, include more effects +#define FX_MODE_RAIN 29 +#define FX_MODE_POPCORN 30 +#define FX_MODE_OSCILLATOR 31 +#endif + +#define FX_MODE_CUSTOM_0 0 // custom modes are not supported and will simply run the STATIC effect + +// create GLOBAL names to allow WS2812FX to compile with sketches and other libs +// that store strings in PROGMEM (get rid of the "section type conflict with __c" +// errors once and for all. Amen.) +const char name_0[] PROGMEM = "Static"; +const char name_1[] PROGMEM = "Blink"; +const char name_2[] PROGMEM = "Strobe"; +const char name_3[] PROGMEM = "Color Wipe"; +const char name_4[] PROGMEM = "Color Wipe Reverse"; +const char name_5[] PROGMEM = "Tricolor Chase"; +const char name_6[] PROGMEM = "Sparkle"; + + +#if (PROGMEM_SIZE > 4096UL) // if ATtiny has more tha 4k flash memory, include more effects +const char name_7[] PROGMEM = "Breath"; +const char name_8[] PROGMEM = "Bicolor Chase"; +const char name_9[] PROGMEM = "Larson Scanner"; +const char name_10[] PROGMEM = "Rainbow Cycle"; +const char name_11[] PROGMEM = "Random Color"; +const char name_12[] PROGMEM = "Fade"; +const char name_13[] PROGMEM = "Color Wipe Random"; +const char name_14[] PROGMEM = "Color Sweep Random"; +#endif + +#if (PROGMEM_SIZE > 8192UL) // if ATtiny has more tha 8k flash memory, include more effects +const char name_15[] PROGMEM = "Fireworks"; +const char name_16[] PROGMEM = "Fireworks Random"; +const char name_17[] PROGMEM = "Fire Flicker"; +const char name_18[] PROGMEM = "Fire Flicker Soft"; +const char name_19[] PROGMEM = "Fire Flicker Intense"; +const char name_20[] PROGMEM = "Running Color"; +const char name_21[] PROGMEM = "Running Lights"; +const char name_22[] PROGMEM = "Running Random"; +const char name_23[] PROGMEM = "Single Dynamic"; +const char name_24[] PROGMEM = "Multi Dynamic"; +const char name_25[] PROGMEM = "TinkleFox"; +const char name_26[] PROGMEM = "Heartbeat"; +const char name_27[] PROGMEM = "Block Dissolve"; +const char name_28[] PROGMEM = "ICU"; +#endif + +#if (PROGMEM_SIZE > 16384UL) // if ATtiny has more tha 16k flash memory, include more effects +const char name_29[] PROGMEM = "Rain"; +const char name_30[] PROGMEM = "Popcorn"; +const char name_31[] PROGMEM = "Oscillator"; +#endif + +const char name_32[] PROGMEM = "Custom 0"; // custom modes need to go at the end + + __attribute__ ((unused)) static const __FlashStringHelper* _names[] = { + FSH(name_0), + FSH(name_1), + FSH(name_2), + FSH(name_3), + FSH(name_4), + FSH(name_5), + FSH(name_6), + +#if (PROGMEM_SIZE > 4096UL) // if ATtiny has more tha 4k flash memory, include more effects + FSH(name_7), + FSH(name_8), + FSH(name_9), + FSH(name_10), + FSH(name_11), + FSH(name_12), + FSH(name_13), + FSH(name_14), +#endif + +#if (PROGMEM_SIZE > 8192UL) // if ATtiny has more tha 8k flash memory, include more effects + FSH(name_15), + FSH(name_16), + FSH(name_17), + FSH(name_18), + FSH(name_19), + FSH(name_20), + FSH(name_21), + FSH(name_22), + FSH(name_23), + FSH(name_24), + FSH(name_25), + FSH(name_26), + FSH(name_27), + FSH(name_28), +#endif + +#if (PROGMEM_SIZE > 16384UL) // if ATtiny has more tha 16k flash memory, include more effects + FSH(name_29), + FSH(name_30), + FSH(name_31), +#endif + + FSH(name_32) +}; + +// define static array of member function pointers. +// function pointers MUST be in the same order as the corresponding name in the _name array. +__attribute__ ((unused)) static WS2812FX::mode_ptr _modes[] = { + &WS2812FX::mode_static, + &WS2812FX::mode_blink, + &WS2812FX::mode_strobe, + &WS2812FX::mode_color_wipe, + &WS2812FX::mode_color_wipe_rev, + &WS2812FX::mode_tricolor_chase, + &WS2812FX::mode_sparkle, + +#if (PROGMEM_SIZE > 4096UL) // if ATtiny has more tha 4k flash memory, include more effects + &WS2812FX::mode_breath, + &WS2812FX::mode_bicolor_chase, + &WS2812FX::mode_larson_scanner, + &WS2812FX::mode_rainbow_cycle, + &WS2812FX::mode_random_color, + &WS2812FX::mode_fade, + &WS2812FX::mode_color_wipe_random, + &WS2812FX::mode_color_sweep_random, +#endif + +#if (PROGMEM_SIZE > 8192UL) // if ATtiny has more tha 8k flash memory, include more effects + &WS2812FX::mode_fireworks, + &WS2812FX::mode_fireworks_random, + &WS2812FX::mode_fire_flicker, + &WS2812FX::mode_fire_flicker_soft, + &WS2812FX::mode_fire_flicker_intense, + &WS2812FX::mode_running_color, + &WS2812FX::mode_running_lights, + &WS2812FX::mode_running_random, + &WS2812FX::mode_single_dynamic, + &WS2812FX::mode_multi_dynamic, + &WS2812FX::mode_twinkleFOX, + &WS2812FX::mode_heartbeat, + &WS2812FX::mode_block_dissolve, + &WS2812FX::mode_icu, +#endif + +#if (PROGMEM_SIZE > 16384UL) // if ATtiny has more tha 16k flash memory, include more effects + &WS2812FX::mode_rain, + &WS2812FX::mode_popcorn, + &WS2812FX::mode_oscillator, +#endif + + &WS2812FX::mode_custom_0 +}; +#endif diff --git a/src/modes_funcs.cpp b/src/modes_funcs.cpp index 97054b7..01c97f5 100644 --- a/src/modes_funcs.cpp +++ b/src/modes_funcs.cpp @@ -386,7 +386,7 @@ uint16_t WS2812FX::fireworks(uint32_t color) { uint8_t size = 2 << SIZE_OPTION; if(!_triggered) { - for(uint16_t i=0; istart + random16(_seg_len - size + 1); fill(color, index, size); @@ -394,7 +394,7 @@ uint16_t WS2812FX::fireworks(uint32_t color) { } } } else { - for(uint16_t i=0; istart + random16(_seg_len - size + 1); fill(color, index, size); SET_CYCLE;