Merge pull request #51 from vortigont/trials

Aurora demo changes for virtual panel
This commit is contained in:
mrfaptastic 2020-12-22 13:41:43 +00:00 committed by GitHub
commit 25b5f4c89d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 1805 additions and 990 deletions

View file

@ -200,13 +200,16 @@ bool MatrixPanel_I2S_DMA::allocateDMAmemory()
for(int i=lsbMsbTransitionBit + 1; i<PIXEL_COLOR_DEPTH_BITS; i++) { for(int i=lsbMsbTransitionBit + 1; i<PIXEL_COLOR_DEPTH_BITS; i++) {
numDMAdescriptorsPerRow += (1<<(i - lsbMsbTransitionBit - 1)); numDMAdescriptorsPerRow += (1<<(i - lsbMsbTransitionBit - 1));
} }
#if SERIAL_DEBUG
Serial.printf("Recalculated number of DMA descriptors per row: %d\n", numDMAdescriptorsPerRow);
#endif
// Refer to 'DMA_LL_PAYLOAD_SPLIT' code in configureDMA() below to understand why this exists. // Refer to 'DMA_LL_PAYLOAD_SPLIT' code in configureDMA() below to understand why this exists.
// numDMAdescriptorsPerRow is also used to calcaulte descount which is super important in i2s_parallel_config_t SoC DMA setup. // numDMAdescriptorsPerRow is also used to calcaulte descount which is super important in i2s_parallel_config_t SoC DMA setup.
if ( sizeof(rowColorDepthStruct) > DMA_MAX ) { if ( sizeof(rowColorDepthStruct) > DMA_MAX ) {
#if SERIAL_DEBUG #if SERIAL_DEBUG
Serial.println("Split DMA payload required."); Serial.printf("rowColorDepthStruct struct is too large, split DMA payload required. Adding %d DMA descriptors\n", PIXEL_COLOR_DEPTH_BITS-1);
#endif #endif
numDMAdescriptorsPerRow += PIXEL_COLOR_DEPTH_BITS-1; numDMAdescriptorsPerRow += PIXEL_COLOR_DEPTH_BITS-1;
@ -273,7 +276,7 @@ bool MatrixPanel_I2S_DMA::allocateDMAmemory()
return true; return true;
} // end initMatrixDMABuffer() } // end allocateDMAmemory()
@ -301,7 +304,7 @@ void MatrixPanel_I2S_DMA::configureDMA(int r1_pin, int g1_pin, int b1_pin, int
rowColorDepthStruct *fb_malloc_ptr = matrix_row_framebuffer_malloc[row]; rowColorDepthStruct *fb_malloc_ptr = matrix_row_framebuffer_malloc[row];
#if SERIAL_DEBUG #if SERIAL_DEBUG
Serial.printf("DMA payload of %d bytes. DMA_MAX is %d.\r\n", sizeof(rowBitStruct) * PIXEL_COLOR_DEPTH_BITS, DMA_MAX); Serial.printf("Row %d DMA payload of %d bytes. DMA_MAX is %d.\r\n", row, sizeof(rowBitStruct) * PIXEL_COLOR_DEPTH_BITS, DMA_MAX);
#endif #endif
@ -389,13 +392,6 @@ void MatrixPanel_I2S_DMA::configureDMA(int r1_pin, int g1_pin, int b1_pin, int
} }
/*
//End markers
dmadesc_a[desccount-1].eof = 1;
dmadesc_b[desccount-1].eof = 1;
dmadesc_a[desccount-1].qe.stqe_next=(lldesc_t*)&dmadesc_a[0];
dmadesc_b[desccount-1].qe.stqe_next=(lldesc_t*)&dmadesc_b[0];
*/
//Serial.printf("Performing I2S setup.\n"); //Serial.printf("Performing I2S setup.\n");
i2s_parallel_config_t cfg={ i2s_parallel_config_t cfg={

View file

@ -115,7 +115,7 @@
// RGB Panel Constants / Calculated Values // RGB Panel Constants / Calculated Values
#define COLOR_CHANNELS_PER_PIXEL 3 #define COLOR_CHANNELS_PER_PIXEL 3
#define PIXELS_PER_ROW ((MATRIX_WIDTH * MATRIX_HEIGHT) / MATRIX_HEIGHT) // = 64 #define PIXELS_PER_ROW MATRIX_WIDTH // number of all pixels in a row of chained modules
//#define PIXEL_COLOR_DEPTH_BITS (MATRIX_COLOR_DEPTH/COLOR_CHANNELS_PER_PIXEL) // = 8 //#define PIXEL_COLOR_DEPTH_BITS (MATRIX_COLOR_DEPTH/COLOR_CHANNELS_PER_PIXEL) // = 8
#define ROWS_PER_FRAME (MATRIX_HEIGHT/MATRIX_ROWS_IN_PARALLEL) // = 16 #define ROWS_PER_FRAME (MATRIX_HEIGHT/MATRIX_ROWS_IN_PARALLEL) // = 16
@ -170,13 +170,17 @@ typedef struct RGB24 {
uint8_t blue; uint8_t blue;
} RGB24; } RGB24;
/**
* Enumeration of hardware-specific chips
* used to drive matrix modules
*/
enum shift_driver {SHIFT=0, FM6124, FM6126A, ICN2038S}; enum shift_driver {SHIFT=0, FM6124, FM6126A, ICN2038S};
/***************************************************************************************/ /***************************************************************************************/
// Used by val2PWM // Used by val2PWM
//C/p'ed from https://ledshield.wordpress.com/2012/11/13/led-brightness-to-your-eye-gamma-correction-no/ //C/p'ed from https://ledshield.wordpress.com/2012/11/13/led-brightness-to-your-eye-gamma-correction-no/
// Example calculator: https://gist.github.com/mathiasvr/19ce1d7b6caeab230934080ae1f1380e // Example calculator: https://gist.github.com/mathiasvr/19ce1d7b6caeab230934080ae1f1380e
const uint16_t lumConvTab[]={ const uint8_t lumConvTab[]={
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 17, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 28, 29, 30, 30, 31, 31, 32, 33, 33, 34, 35, 35, 36, 37, 38, 38, 39, 40, 41, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83, 84, 86, 87, 88, 90, 91, 92, 93, 95, 96, 98, 99, 100, 102, 103, 105, 106, 107, 109, 110, 112, 113, 115, 116, 118, 120, 121, 123, 124, 126, 128, 129, 131, 133, 134, 136, 138, 139, 141, 143, 145, 146, 148, 150, 152, 154, 156, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 192, 194, 196, 198, 200, 203, 205, 207, 209, 212, 214, 216, 218, 221, 223, 226, 228, 230, 233, 235, 238, 240, 243, 245, 248, 250, 253, 255, 255}; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 17, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 28, 29, 30, 30, 31, 31, 32, 33, 33, 34, 35, 35, 36, 37, 38, 38, 39, 40, 41, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83, 84, 86, 87, 88, 90, 91, 92, 93, 95, 96, 98, 99, 100, 102, 103, 105, 106, 107, 109, 110, 112, 113, 115, 116, 118, 120, 121, 123, 124, 126, 128, 129, 131, 133, 134, 136, 138, 139, 141, 143, 145, 146, 148, 150, 152, 154, 156, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 192, 194, 196, 198, 200, 203, 205, 207, 209, 212, 214, 216, 218, 221, 223, 226, 228, 230, 233, 235, 238, 240, 243, 245, 248, 250, 253, 255, 255};
/***************************************************************************************/ /***************************************************************************************/
@ -238,9 +242,11 @@ class MatrixPanel_I2S_DMA : public Adafruit_GFX {
// Flush the DMA buffers prior to configuring DMA - Avoid visual artefacts on boot. // Flush the DMA buffers prior to configuring DMA - Avoid visual artefacts on boot.
clearScreen(); // Must fill the DMA buffer with the initial output bit sequence or the panel will display garbage clearScreen(); // Must fill the DMA buffer with the initial output bit sequence or the panel will display garbage
if (double_buffering_enabled){
flipDMABuffer(); // flip to backbuffer 1 flipDMABuffer(); // flip to backbuffer 1
clearScreen(); // Must fill the DMA buffer with the initial output bit sequence or the panel will display garbage clearScreen(); // Must fill the DMA buffer with the initial output bit sequence or the panel will display garbage
flipDMABuffer(); // backbuffer 0 flipDMABuffer(); // backbuffer 0
}
// Setup the ESP32 DMA Engine. Sprite_TM built this stuff. // Setup the ESP32 DMA Engine. Sprite_TM built this stuff.
configureDMA(dma_r1_pin, dma_g1_pin, dma_b1_pin, dma_r2_pin, dma_g2_pin, dma_b2_pin, dma_a_pin, dma_b_pin, dma_c_pin, dma_d_pin, dma_e_pin, dma_lat_pin, dma_oe_pin, dma_clk_pin ); //DMA and I2S configuration and setup configureDMA(dma_r1_pin, dma_g1_pin, dma_b1_pin, dma_r2_pin, dma_g2_pin, dma_b2_pin, dma_a_pin, dma_b_pin, dma_c_pin, dma_d_pin, dma_e_pin, dma_lat_pin, dma_oe_pin, dma_clk_pin ); //DMA and I2S configuration and setup

View file

@ -1,46 +1,29 @@
## The mystery of control registers for FM6126A chips ## The mystery of control registers for FM6126A chips
The only available Datasheet for this chips is in Chinese and does not shed a light on what those two control regs are.
Datasheet for this chis chip is in chineese and does not shed a light on what those two control regs are. An excellent insight could be found here https://github.com/hzeller/rpi-rgb-led-matrix/issues/746#issuecomment-453860510
An excellent insight could be found here
https://github.com/hzeller/rpi-rgb-led-matrix/issues/746#issuecomment-453860510
So there are two regs in this chip - **REG1** and **REG2**,
So there are two regs - **REG1** and **REG1**,
one could be written with 12 clock pusles (and usually called reg12, dunno why :)) one could be written with 12 clock pusles (and usually called reg12, dunno why :))
the other one could be written with 13 clock pulses (and usually called reg13, dunno why :))
the other one could be written with 13 clock pusles (and usually called reg13, dunno why :))
I've done some measurmens on power consumption while toggling bits of **REG1** and it looks that it could provide a fine grained brighness control over the entire matrix with no need for bitbanging over RGB or EO pins.
So I've done some measurmens on power consumption while toggling bits of **REG1** and it looks that it could provide a fine grained brighness control over matrix.
There are 6 bits (6 to 11) giving an increased brighness (compared to all-zeroes) and 4 bits (2-5) giving decreased brighness!!! There are 6 bits (6 to 11) giving an increased brighness (compared to all-zeroes) and 4 bits (2-5) giving decreased brighness!!!
Still unclear if FM6112A brightness control is internally PWMed or current limited, might require some poking with oscilloscope.
So it seems that the most bright (and hungry for power) value is bool REG1[16] = {0,0,0,0,0, 1,1,1,1,1,1, 0,0,0,0,0}; and not {0,1,1,1,1, 1,1,1,1,1,1, 1,1,1,1,1} as it is usually used.
So it seems that the most bright (and hungry for power) value is
bool REG1[16] = {0,0,0,0,0, 1,1,1,1,1,1, 0,0,0,0,0}; and not {0,1,1,1,1, 1,1,1,1,1,1, 1,1,1,1,1} as it is usually used.
I'm not sure about bit 1 - it is either not used or I was unable to measure it's influence to brightness/power. I'm not sure about bit 1 - it is either not used or I was unable to measure it's influence to brightness/power.
Giving at least 10 bits of hardware brightness control opens pretty nice options for offloading and simplifiyng matrix output. Should dig into this more deeper.
Giving at least 10 bits of hardware brightness control opens pretty nice options for offloading. Should dig into this more deeper.
Here are some of the measurments I've took for 2 64x64 panels filled with white color - reg value and corresponding current drain in amps. Here are some of the measurments I've took for 2 64x64 panels filled with white color - reg value and corresponding current drain in amps.
|REG1 |bit value|Current, amps | |REG1 |bit value|Current, amps |
|--|--|--| |--|--|--|
|REG1| 0111111 00000| >5 amps| |REG1| 0111111 00000| >5 amps|

View file

@ -29,7 +29,7 @@ By default the pin mapping is as follows (defaults defined in ESP32-HUB75-Matrix
| R1 G1 | R1 -> IO25 G1 -> IO26 | R1 G1 | R1 -> IO25 G1 -> IO26
| B1 GND | B1 -> IO27 | B1 GND | B1 -> IO27
| R2 G2 | R2 -> IO14 G2 -> IO12 | R2 G2 | R2 -> IO14 G2 -> IO12
| B2 GND | B2 -> IO13 | B2 E | B2 -> IO13 E -> N/A (required for 1/32 scan panels, like 64x64. Any available pin would do, i.e. IO32 )
| A B | A -> IO23 B -> IO19 | A B | A -> IO23 B -> IO19
| C D | C -> IO 5 D -> IO17 | C D | C -> IO 5 D -> IO17
| CLK LAT | CLK -> IO16 LAT -> IO 4 | CLK LAT | CLK -> IO16 LAT -> IO 4
@ -52,7 +52,7 @@ However, if you want to change this, simply provide the wanted pin mapping as pa
#define B_PIN 22 #define B_PIN 22
#define C_PIN 5 #define C_PIN 5
#define D_PIN 17 #define D_PIN 17
#define E_PIN -1 #define E_PIN -1 // required for 1/32 scan panels, like 64x64. Any available pin would do, i.e. IO32
#define LAT_PIN 4 #define LAT_PIN 4
#define OE_PIN 15 #define OE_PIN 15
@ -113,6 +113,8 @@ By default you should not need to change / set the brightness setting as the def
The value to pass 'setPanelBrightness' must be a value less than MATRIX_WIDTH. For example for a single 64x32 LED Matrix Module, a value less than 64. However, if you set the brightness too high, you may experience ghosting. The value to pass 'setPanelBrightness' must be a value less than MATRIX_WIDTH. For example for a single 64x32 LED Matrix Module, a value less than 64. However, if you set the brightness too high, you may experience ghosting.
Also you may use method `setPanelBrightness8(x)`, where x is a uint8_t value between 0-255. Library will recalculate required brightness level depending on matrix width (mostly useful with FastLED-based sketches).
Example: Example:
``` ```
@ -122,6 +124,9 @@ void setup() {
matrix.setPanelBrightness(16); // Set the brightness. 32 or lower ideal for a single 64x32 LED Matrix Panel. matrix.setPanelBrightness(16); // Set the brightness. 32 or lower ideal for a single 64x32 LED Matrix Panel.
matrix.clearScreen(); // You must clear the screen after changing brightness level for it to take effect. matrix.clearScreen(); // You must clear the screen after changing brightness level for it to take effect.
// or another way
matrix.setPanelBrightness(192); // Set the brightness to about 3/4 (192/256) of maximum.
matrix.clearScreen(); // You must clear the screen after changing brightness level for it to take effect.
} }
``` ```

View file

@ -71,7 +71,6 @@ void setup()
listPatterns(); listPatterns();
//patterns.setPattern(0); // // simple noise
patterns.moveRandom(1); // start from a random pattern patterns.moveRandom(1); // start from a random pattern
Serial.print("Starting with pattern: "); Serial.print("Starting with pattern: ");
@ -92,7 +91,6 @@ void loop()
//patterns.move(1); //patterns.move(1);
patterns.start(); patterns.start();
Serial.print("Changing pattern to: "); Serial.print("Changing pattern to: ");
Serial.println(patterns.getCurrentPatternName()); Serial.println(patterns.getCurrentPatternName());

View file

@ -34,7 +34,7 @@ public:
Attractor() { Attractor() {
location = PVector(MATRIX_CENTRE_X, MATRIX_CENTRE_Y); location = PVector(MATRIX_CENTRE_X, MATRIX_CENTRE_Y);
mass = 8; mass = 10;
G = .5; G = .5;
} }

View file

@ -125,14 +125,15 @@ void setup()
void patternAdvance(){ void patternAdvance(){
// Go to next pattern in the list (se Patterns.h) // Go to next pattern in the list (se Patterns.h)
patterns.stop(); patterns.stop();
patterns.move(1); patterns.moveRandom(1);
//patterns.move(1);
patterns.start(); patterns.start();
// Select a random palette as well // Select a random palette as well
effects.RandomPalette(); effects.RandomPalette();
Serial.print("Changing pattern to: "); Serial.print("Changing pattern to: ");
Serial.println(patterns.getCurrentPatternName()); Serial.println(patterns.getCurrentPatternName());
Serial.println(patterns.getPatternIndex()); //Serial.println(patterns.getPatternIndex());
lastPattern = patterns.getPatternIndex(); //lastPattern = patterns.getPatternIndex();
// Save last index. // Save last index.
preferences.begin("RGBMATRIX", false); preferences.begin("RGBMATRIX", false);
preferences.putInt("lastPattern", lastPattern); preferences.putInt("lastPattern", lastPattern);

View file

@ -43,6 +43,11 @@ public:
return 0; return 0;
}; };
virtual void printTesting()
{
Serial.println("Testing...");
}
virtual void start() {}; virtual void start() {};
virtual void stop() {}; virtual void stop() {};
}; };

View file

@ -1,29 +1,29 @@
/* /*
Aurora: https://github.com/pixelmatix/aurora * Aurora: https://github.com/pixelmatix/aurora
Copyright (c) 2014 Jason Coon * Copyright (c) 2014 Jason Coon
*
Portions of this code are adapted from "Funky Clouds" by Stefan Petrick: https://gist.github.com/anonymous/876f908333cd95315c35 * Portions of this code are adapted from "Funky Clouds" by Stefan Petrick: https://gist.github.com/anonymous/876f908333cd95315c35
Portions of this code are adapted from "NoiseSmearing" by Stefan Petrick: https://gist.github.com/StefanPetrick/9ee2f677dbff64e3ba7a * Portions of this code are adapted from "NoiseSmearing" by Stefan Petrick: https://gist.github.com/StefanPetrick/9ee2f677dbff64e3ba7a
Copyright (c) 2014 Stefan Petrick * Copyright (c) 2014 Stefan Petrick
http://www.stefan-petrick.de/wordpress_beta * http://www.stefan-petrick.de/wordpress_beta
*
Permission is hereby granted, free of charge, to any person obtaining a copy of * 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 * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * 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, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * 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 * 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 * 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. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef Effects_H #ifndef Effects_H
@ -31,32 +31,45 @@
/* ---------------------------- GLOBAL CONSTANTS ----------------------------- */ /* ---------------------------- GLOBAL CONSTANTS ----------------------------- */
//const int MATRIX_CENTER_X = MATRIX_WIDTH / 2;
//const int MATRIX_CENTER_Y = MATRIX_HEIGHT / 2;
//const byte MATRIX_CENTRE_X = MATRIX_CENTER_X - 1;
//const byte MATRIX_CENTRE_Y = MATRIX_CENTER_Y - 1;
const int MATRIX_CENTER_X = VPANEL_W / 2; const int MATRIX_CENTER_X = VPANEL_W / 2;
const int MATRIX_CENTER_Y = VPANEL_H / 2; const int MATRIX_CENTER_Y = VPANEL_H / 2;
const byte MATRIX_CENTRE_X = MATRIX_CENTER_X - 1; // US vs GB, huh? :)
const byte MATRIX_CENTRE_Y = MATRIX_CENTER_Y - 1; //const byte MATRIX_CENTRE_X = MATRIX_CENTER_X - 1;
//const byte MATRIX_CENTRE_Y = MATRIX_CENTER_Y - 1;
#define MATRIX_CENTRE_X MATRIX_CENTER_X
#define MATRIX_CENTRE_Y MATRIX_CENTER_Y
const uint16_t NUM_LEDS = (VPANEL_W * VPANEL_H) + 1; // one led spare to capture out of bounds const uint16_t NUM_LEDS = (VPANEL_W * VPANEL_H) + 1; // one led spare to capture out of bounds
// forward declaration
uint16_t XY16( uint16_t x, uint16_t y);
/* Convert x,y co-ordinate to flat array index. /* Convert x,y co-ordinate to flat array index.
x and y positions start from 0, so must not be >= 'real' panel width or height * x and y positions start from 0, so must not be >= 'real' panel width or height
(i.e. 64 pixels or 32 pixels.). Max value: MATRIX_WIDTH-1 etc. * (i.e. 64 pixels or 32 pixels.). Max value: VPANEL_W-1 etc.
* Ugh... uint8_t - really??? this weak method can't cope with 256+ pixel matrixes :(
*/ */
uint16_t XY( uint8_t x, uint8_t y) uint16_t XY( uint8_t x, uint8_t y)
{ {
if ( x >= VPANEL_W || x < 0) return 0; return XY16(x, y);
if ( y >= VPANEL_H || y < 0) return 0;
return (y * VPANEL_W) + x + 1; // everything offset by one to capture out of bounds stuff - never displayed by ShowFrame()
} }
/// Some mathematics provided by FastLED /**
* The one for 256+ matrixes
* otherwise this:
* for (uint8_t i = 0; i < VPANEL_W; i++) {}
* turns into an infinite loop
*/
uint16_t XY16( uint16_t x, uint16_t y)
{
if( x >= VPANEL_W) return 0;
if( y >= VPANEL_H) return 0;
return (y * VPANEL_W) + x + 1; // everything offset by one to capute out of bounds stuff - never displayed by ShowFrame()
}
uint8_t beatcos8(accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255, uint32_t timebase = 0, uint8_t phase_offset = 0) uint8_t beatcos8(accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255, uint32_t timebase = 0, uint8_t phase_offset = 0)
{ {
uint8_t beat = beat8(beats_per_minute, timebase); uint8_t beat = beat8(beats_per_minute, timebase);
@ -84,7 +97,7 @@ uint8_t mapcos8(uint8_t theta, uint8_t lowest = 0, uint8_t highest = 255) {
} }
// Array of temperature readings at each simulation cell // Array of temperature readings at each simulation cell
byte heat[NUM_LEDS]; //byte heat[NUM_LEDS]; // none of the currently enabled effects uses this
uint32_t noise_x; uint32_t noise_x;
uint32_t noise_y; uint32_t noise_y;
@ -92,34 +105,55 @@ uint32_t noise_z;
uint32_t noise_scale_x; uint32_t noise_scale_x;
uint32_t noise_scale_y; uint32_t noise_scale_y;
uint8_t noise[VPANEL_W][VPANEL_H]; //uint8_t noise[VPANEL_W][VPANEL_H];
uint8_t **noise = nullptr; // we will allocate mem later
uint8_t noisesmoothing; uint8_t noisesmoothing;
class Effects { class Effects {
public: public:
//CRGB *leds; CRGB *leds;
CRGB leds[NUM_LEDS]; //CRGB leds[NUM_LEDS];
CRGB leds2[NUM_LEDS]; // Faptastic: getting rid of this and any dependant effects or algos. to save memory 24*64*32 bytes of ram (50k). //CRGB leds2[NUM_LEDS]; // Faptastic: getting rid of this and any dependant effects or algos. to save memory 24*64*32 bytes of ram (50k).
Effects(){
// we do dynamic allocation for leds buffer, otherwise esp32 toolchain can't link static arrays of such a big size for 256+ matrixes
leds = (CRGB *)malloc(NUM_LEDS * sizeof(CRGB));
// allocate mem for noise effect
// (there should be some guards for malloc errors eventually)
noise = (uint8_t **)malloc(VPANEL_W * sizeof(uint8_t *));
for (int i = 0; i < VPANEL_W; ++i) {
noise[i] = (uint8_t *)malloc(VPANEL_H * sizeof(uint8_t));
}
ClearFrame();
matrix.clearScreen();
}
~Effects(){
free(leds);
for (int i = 0; i < VPANEL_W; ++i) {
free(noise[i]);
}
free(noise);
}
/* The only 'framebuffer' we have is what is contained in the leds and leds2 variables. /* The only 'framebuffer' we have is what is contained in the leds and leds2 variables.
We don't store what the color a particular pixel might be, other than when it's turned * We don't store what the color a particular pixel might be, other than when it's turned
into raw electrical signal output gobbly-gook (i.e. the DMA matrix buffer), but this * is not reversible. * into raw electrical signal output gobbly-gook (i.e. the DMA matrix buffer), but this * is not reversible.
*
As such, any time these effects want to write a pixel color, we first have to update * As such, any time these effects want to write a pixel color, we first have to update
the leds or leds2 array, and THEN write it to the RGB panel. This enables us to 'look up' the array to see what a pixel color was previously, each drawFrame(). * the leds or leds2 array, and THEN write it to the RGB panel. This enables us to 'look up' the array to see what a pixel color was previously, each drawFrame().
*/ */
void drawBackgroundFastLEDPixelCRGB(int16_t x, int16_t y, CRGB color) void drawBackgroundFastLEDPixelCRGB(int16_t x, int16_t y, CRGB color)
{ {
leds[XY(x, y)] = color; leds[XY(x, y)] = color;
virtualDisp.drawPixelRGB888(x, y, color.r, color.g, color.b); //matrix.drawPixelRGB888(x, y, color.r, color.g, color.b);
} }
// write one pixel with the specified color from the current palette to coordinates // write one pixel with the specified color from the current palette to coordinates
void Pixel(int x, int y, uint8_t colorIndex) { void Pixel(int x, int y, uint8_t colorIndex) {
CRGB temp = ColorFromCurrentPalette(colorIndex); leds[XY(x, y)] = ColorFromCurrentPalette(colorIndex);
leds[XY(x, y)] = temp; //matrix.drawPixelRGB888(x, y, temp.r, temp.g, temp.b); // now draw it?
virtualDisp.drawPixelRGB888(x, y, temp.r, temp.g, temp.b); // now draw it?
} }
void PrepareFrame() { void PrepareFrame() {
@ -127,24 +161,25 @@ class Effects {
} }
void ShowFrame() { void ShowFrame() {
#if (FASTLED_VERSION >= 3001000) //#if (FASTLED_VERSION >= 3001000)
nblendPaletteTowardPalette(currentPalette, targetPalette, 24); // nblendPaletteTowardPalette(currentPalette, targetPalette, 24);
#else //#else
currentPalette = targetPalette; currentPalette = targetPalette;
#endif //#endif
// backgroundLayer.swapBuffers(); // backgroundLayer.swapBuffers();
// leds = (CRGB*) backgroundLayer.backBuffer(); // leds = (CRGB*) backgroundLayer.backBuffer();
// LEDS.countFPS(); // LEDS.countFPS();
for (int y = 0; y < VPANEL_H; y++) {
for (int x = 0; x < VPANEL_W; x++) for (int y=0; y<VPANEL_H; ++y){
{ for (int x=0; x<VPANEL_W; ++x){
CRGB tmp_led = leds[XY(x, y)]; //Serial.printf("Flushing x, y coord %d, %d\n", x, y);
virtualDisp.drawPixelRGB888( x, y, tmp_led.r, tmp_led.g, tmp_led.b); uint16_t _pixel = XY16(x,y);
virtualDisp.drawPixelRGB888( x, y, leds[_pixel].r, leds[_pixel].g, leds[_pixel].b);
} // end loop to copy fast led to the dma matrix } // end loop to copy fast led to the dma matrix
} }
} }
// scale the brightness of the screenbuffer down // scale the brightness of the screenbuffer down
void DimAll(byte value) void DimAll(byte value)
{ {
@ -156,12 +191,12 @@ class Effects {
void ClearFrame() void ClearFrame()
{ {
memset(leds, 0x00, sizeof(leds)); // flush memset(leds, 0x00, NUM_LEDS * sizeof(CRGB)); // flush
} }
/*
void CircleStream(uint8_t value) { void CircleStream(uint8_t value) {
DimAll(value); ShowFrame(); DimAll(value); ShowFrame();
@ -193,7 +228,7 @@ class Effects {
} }
} }
} }
*/
// palettes // palettes
static const int paletteCount = 10; static const int paletteCount = 10;
@ -233,6 +268,10 @@ class Effects {
targetPalette = RainbowColors_p; targetPalette = RainbowColors_p;
currentPaletteName = (char *)"Rainbow"; currentPaletteName = (char *)"Rainbow";
break; break;
//case 1:
// targetPalette = RainbowStripeColors_p;
// currentPaletteName = (char *)"RainbowStripe";
// break;
case 1: case 1:
targetPalette = OceanColors_p; targetPalette = OceanColors_p;
currentPaletteName = (char *)"Ocean"; currentPaletteName = (char *)"Ocean";
@ -276,6 +315,8 @@ class Effects {
void setPalette(String paletteName) { void setPalette(String paletteName) {
if (paletteName == "Rainbow") if (paletteName == "Rainbow")
loadPalette(0); loadPalette(0);
//else if (paletteName == "RainbowStripe")
// loadPalette(1);
else if (paletteName == "Ocean") else if (paletteName == "Ocean")
loadPalette(1); loadPalette(1);
else if (paletteName == "Cloud") else if (paletteName == "Cloud")
@ -343,7 +384,7 @@ class Effects {
// the oscillators: linear ramps 0-255 // the oscillators: linear ramps 0-255
byte osci[6]; byte osci[6];
// sin8(osci) swinging between 0 to MATRIX_WIDTH - 1 // sin8(osci) swinging between 0 to VPANEL_W - 1
byte p[6]; byte p[6];
// set the speeds (and by that ratios) of the oscillators here // set the speeds (and by that ratios) of the oscillators here
@ -356,7 +397,7 @@ class Effects {
if (osci[4] % 2 == 0) if (osci[4] % 2 == 0)
osci[5] = osci[5] + 1; // .5 osci[5] = osci[5] + 1; // .5
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
p[i] = map8(sin8(osci[i]), 0, VPANEL_W - 1); //why? to keep the result in the range of 0-MATRIX_WIDTH (matrix size) p[i] = map8(sin8(osci[i]), 0, VPANEL_W - 1); //why? to keep the result in the range of 0-VPANEL_W (matrix size)
} }
} }
@ -368,9 +409,9 @@ class Effects {
void Caleidoscope1() { void Caleidoscope1() {
for (int x = 0; x < MATRIX_CENTER_X; x++) { for (int x = 0; x < MATRIX_CENTER_X; x++) {
for (int y = 0; y < MATRIX_CENTER_Y; y++) { for (int y = 0; y < MATRIX_CENTER_Y; y++) {
leds[XY(VPANEL_W - 1 - x, y)] = leds[XY(x, y)]; leds[XY16(VPANEL_W - 1 - x, y)] = leds[XY16(x, y)];
leds[XY(VPANEL_W - 1 - x, VPANEL_H - 1 - y)] = leds[XY(x, y)]; leds[XY16(VPANEL_W - 1 - x, VPANEL_H - 1 - y)] = leds[XY16(x, y)];
leds[XY(x, VPANEL_H - 1 - y)] = leds[XY(x, y)]; leds[XY16(x, VPANEL_H - 1 - y)] = leds[XY16(x, y)];
} }
} }
} }
@ -380,18 +421,18 @@ class Effects {
void Caleidoscope2() { void Caleidoscope2() {
for (int x = 0; x < MATRIX_CENTER_X; x++) { for (int x = 0; x < MATRIX_CENTER_X; x++) {
for (int y = 0; y < MATRIX_CENTER_Y; y++) { for (int y = 0; y < MATRIX_CENTER_Y; y++) {
leds[XY(VPANEL_W - 1 - x, y)] = leds[XY(y, x)]; leds[XY16(VPANEL_W - 1 - x, y)] = leds[XY16(y, x)];
leds[XY(x, VPANEL_H - 1 - y)] = leds[XY(y, x)]; leds[XY16(x, VPANEL_H - 1 - y)] = leds[XY16(y, x)];
leds[XY(VPANEL_W - 1 - x, VPANEL_H - 1 - y)] = leds[XY(x, y)]; leds[XY16(VPANEL_W - 1 - x, VPANEL_H - 1 - y)] = leds[XY16(x, y)];
} }
} }
} }
// copy one diagonal triangle into the other one within a 16x16 // copy one diagonal triangle into the other one within a 16x16
void Caleidoscope3() { void Caleidoscope3() {
for (int x = 0; x <= MATRIX_CENTRE_X; x++) { for (int x = 0; x <= MATRIX_CENTRE_X && x < VPANEL_H; x++) {
for (int y = 0; y <= x; y++) { for (int y = 0; y <= x && y<VPANEL_H; y++) {
leds[XY(x, y)] = leds[XY(y, x)]; leds[XY16(x, y)] = leds[XY16(y, x)];
} }
} }
} }
@ -400,7 +441,7 @@ class Effects {
void Caleidoscope4() { void Caleidoscope4() {
for (int x = 0; x <= MATRIX_CENTRE_X; x++) { for (int x = 0; x <= MATRIX_CENTRE_X; x++) {
for (int y = 0; y <= MATRIX_CENTRE_Y - x; y++) { for (int y = 0; y <= MATRIX_CENTRE_Y - x; y++) {
leds[XY(MATRIX_CENTRE_Y - y, MATRIX_CENTRE_X - x)] = leds[XY(x, y)]; leds[XY16(MATRIX_CENTRE_Y - y, MATRIX_CENTRE_X - x)] = leds[XY16(x, y)];
} }
} }
} }
@ -408,39 +449,39 @@ class Effects {
// copy one diagonal triangle into the other one within a 8x8 // copy one diagonal triangle into the other one within a 8x8
void Caleidoscope5() { void Caleidoscope5() {
for (int x = 0; x < VPANEL_W / 4; x++) { for (int x = 0; x < VPANEL_W / 4; x++) {
for (int y = 0; y <= x; y++) { for (int y = 0; y <= x && y<=VPANEL_H; y++) {
leds[XY(x, y)] = leds[XY(y, x)]; leds[XY16(x, y)] = leds[XY16(y, x)];
} }
} }
for (int x = VPANEL_W / 4; x < VPANEL_W / 2; x++) { for (int x = VPANEL_W / 4; x < VPANEL_W / 2; x++) {
for (int y = VPANEL_H / 4; y >= 0; y--) { for (int y = VPANEL_H / 4; y >= 0; y--) {
leds[XY(x, y)] = leds[XY(y, x)]; leds[XY16(x, y)] = leds[XY16(y, x)];
} }
} }
} }
void Caleidoscope6() { void Caleidoscope6() {
for (int x = 1; x < MATRIX_CENTER_X; x++) { for (int x = 1; x < MATRIX_CENTER_X; x++) {
leds[XY(7 - x, 7)] = leds[XY(x, 0)]; leds[XY16(7 - x, 7)] = leds[XY16(x, 0)];
} //a } //a
for (int x = 2; x < MATRIX_CENTER_X; x++) { for (int x = 2; x < MATRIX_CENTER_X; x++) {
leds[XY(7 - x, 6)] = leds[XY(x, 1)]; leds[XY16(7 - x, 6)] = leds[XY16(x, 1)];
} //b } //b
for (int x = 3; x < MATRIX_CENTER_X; x++) { for (int x = 3; x < MATRIX_CENTER_X; x++) {
leds[XY(7 - x, 5)] = leds[XY(x, 2)]; leds[XY16(7 - x, 5)] = leds[XY16(x, 2)];
} //c } //c
for (int x = 4; x < MATRIX_CENTER_X; x++) { for (int x = 4; x < MATRIX_CENTER_X; x++) {
leds[XY(7 - x, 4)] = leds[XY(x, 3)]; leds[XY16(7 - x, 4)] = leds[XY16(x, 3)];
} //d } //d
for (int x = 5; x < MATRIX_CENTER_X; x++) { for (int x = 5; x < MATRIX_CENTER_X; x++) {
leds[XY(7 - x, 3)] = leds[XY(x, 4)]; leds[XY16(7 - x, 3)] = leds[XY16(x, 4)];
} //e } //e
for (int x = 6; x < MATRIX_CENTER_X; x++) { for (int x = 6; x < MATRIX_CENTER_X; x++) {
leds[XY(7 - x, 2)] = leds[XY(x, 5)]; leds[XY16(7 - x, 2)] = leds[XY16(x, 5)];
} //f } //f
for (int x = 7; x < MATRIX_CENTER_X; x++) { for (int x = 7; x < MATRIX_CENTER_X; x++) {
leds[XY(7 - x, 1)] = leds[XY(x, 6)]; leds[XY16(7 - x, 1)] = leds[XY16(x, 6)];
} //g } //g
} }
@ -449,20 +490,20 @@ class Effects {
void SpiralStream(int x, int y, int r, byte dimm) { void SpiralStream(int x, int y, int r, byte dimm) {
for (int d = r; d >= 0; d--) { // from the outside to the inside for (int d = r; d >= 0; d--) { // from the outside to the inside
for (int i = x - d; i <= x + d; i++) { for (int i = x - d; i <= x + d; i++) {
leds[XY(i, y - d)] += leds[XY(i + 1, y - d)]; // lowest row to the right leds[XY16(i, y - d)] += leds[XY16(i + 1, y - d)]; // lowest row to the right
leds[XY(i, y - d)].nscale8(dimm); leds[XY16(i, y - d)].nscale8(dimm);
} }
for (int i = y - d; i <= y + d; i++) { for (int i = y - d; i <= y + d; i++) {
leds[XY(x + d, i)] += leds[XY(x + d, i + 1)]; // right colum up leds[XY16(x + d, i)] += leds[XY16(x + d, i + 1)]; // right colum up
leds[XY(x + d, i)].nscale8(dimm); leds[XY16(x + d, i)].nscale8(dimm);
} }
for (int i = x + d; i >= x - d; i--) { for (int i = x + d; i >= x - d; i--) {
leds[XY(i, y + d)] += leds[XY(i - 1, y + d)]; // upper row to the left leds[XY16(i, y + d)] += leds[XY16(i - 1, y + d)]; // upper row to the left
leds[XY(i, y + d)].nscale8(dimm); leds[XY16(i, y + d)].nscale8(dimm);
} }
for (int i = y + d; i >= y - d; i--) { for (int i = y + d; i >= y - d; i--) {
leds[XY(x - d, i)] += leds[XY(x - d, i - 1)]; // left colum down leds[XY16(x - d, i)] += leds[XY16(x - d, i - 1)]; // left colum down
leds[XY(x - d, i)].nscale8(dimm); leds[XY16(x - d, i)].nscale8(dimm);
} }
} }
} }
@ -485,24 +526,24 @@ class Effects {
while (a >= b) while (a >= b)
{ {
// move them out one pixel on the radius // move them out one pixel on the radius
leds[XY(a + centerX, b + centerY)] = leds[XY(nextA + centerX, nextB + centerY)]; leds[XY16(a + centerX, b + centerY)] = leds[XY16(nextA + centerX, nextB + centerY)];
leds[XY(b + centerX, a + centerY)] = leds[XY(nextB + centerX, nextA + centerY)]; leds[XY16(b + centerX, a + centerY)] = leds[XY16(nextB + centerX, nextA + centerY)];
leds[XY(-a + centerX, b + centerY)] = leds[XY(-nextA + centerX, nextB + centerY)]; leds[XY16(-a + centerX, b + centerY)] = leds[XY16(-nextA + centerX, nextB + centerY)];
leds[XY(-b + centerX, a + centerY)] = leds[XY(-nextB + centerX, nextA + centerY)]; leds[XY16(-b + centerX, a + centerY)] = leds[XY16(-nextB + centerX, nextA + centerY)];
leds[XY(-a + centerX, -b + centerY)] = leds[XY(-nextA + centerX, -nextB + centerY)]; leds[XY16(-a + centerX, -b + centerY)] = leds[XY16(-nextA + centerX, -nextB + centerY)];
leds[XY(-b + centerX, -a + centerY)] = leds[XY(-nextB + centerX, -nextA + centerY)]; leds[XY16(-b + centerX, -a + centerY)] = leds[XY16(-nextB + centerX, -nextA + centerY)];
leds[XY(a + centerX, -b + centerY)] = leds[XY(nextA + centerX, -nextB + centerY)]; leds[XY16(a + centerX, -b + centerY)] = leds[XY16(nextA + centerX, -nextB + centerY)];
leds[XY(b + centerX, -a + centerY)] = leds[XY(nextB + centerX, -nextA + centerY)]; leds[XY16(b + centerX, -a + centerY)] = leds[XY16(nextB + centerX, -nextA + centerY)];
// dim them // dim them
leds[XY(a + centerX, b + centerY)].nscale8(dimm); leds[XY16(a + centerX, b + centerY)].nscale8(dimm);
leds[XY(b + centerX, a + centerY)].nscale8(dimm); leds[XY16(b + centerX, a + centerY)].nscale8(dimm);
leds[XY(-a + centerX, b + centerY)].nscale8(dimm); leds[XY16(-a + centerX, b + centerY)].nscale8(dimm);
leds[XY(-b + centerX, a + centerY)].nscale8(dimm); leds[XY16(-b + centerX, a + centerY)].nscale8(dimm);
leds[XY(-a + centerX, -b + centerY)].nscale8(dimm); leds[XY16(-a + centerX, -b + centerY)].nscale8(dimm);
leds[XY(-b + centerX, -a + centerY)].nscale8(dimm); leds[XY16(-b + centerX, -a + centerY)].nscale8(dimm);
leds[XY(a + centerX, -b + centerY)].nscale8(dimm); leds[XY16(a + centerX, -b + centerY)].nscale8(dimm);
leds[XY(b + centerX, -a + centerY)].nscale8(dimm); leds[XY16(b + centerX, -a + centerY)].nscale8(dimm);
b++; b++;
if (radiusError < 0) if (radiusError < 0)
@ -532,12 +573,12 @@ class Effects {
{ {
for (int x = fromX + 1; x < toX; x++) { for (int x = fromX + 1; x < toX; x++) {
for (int y = fromY; y < toY; y++) { for (int y = fromY; y < toY; y++) {
leds[XY(x, y)] += leds[XY(x - 1, y)]; leds[XY16(x, y)] += leds[XY16(x - 1, y)];
leds[XY(x, y)].nscale8(scale); leds[XY16(x, y)].nscale8(scale);
} }
} }
for (int y = fromY; y < toY; y++) for (int y = fromY; y < toY; y++)
leds[XY(0, y)].nscale8(scale); leds[XY16(0, y)].nscale8(scale);
} }
// give it a linear tail to the left // give it a linear tail to the left
@ -545,12 +586,12 @@ class Effects {
{ {
for (int x = toX; x < fromX; x++) { for (int x = toX; x < fromX; x++) {
for (int y = fromY; y < toY; y++) { for (int y = fromY; y < toY; y++) {
leds[XY(x, y)] += leds[XY(x + 1, y)]; leds[XY16(x, y)] += leds[XY16(x + 1, y)];
leds[XY(x, y)].nscale8(scale); leds[XY16(x, y)].nscale8(scale);
} }
} }
for (int y = fromY; y < toY; y++) for (int y = fromY; y < toY; y++)
leds[XY(0, y)].nscale8(scale); leds[XY16(0, y)].nscale8(scale);
} }
// give it a linear tail downwards // give it a linear tail downwards
@ -558,12 +599,12 @@ class Effects {
{ {
for (int x = 0; x < VPANEL_W; x++) { for (int x = 0; x < VPANEL_W; x++) {
for (int y = 1; y < VPANEL_H; y++) { for (int y = 1; y < VPANEL_H; y++) {
leds[XY(x, y)] += leds[XY(x, y - 1)]; leds[XY16(x, y)] += leds[XY16(x, y - 1)];
leds[XY(x, y)].nscale8(scale); leds[XY16(x, y)].nscale8(scale);
} }
} }
for (int x = 0; x < VPANEL_W; x++) for (int x = 0; x < VPANEL_W; x++)
leds[XY(x, 0)].nscale8(scale); leds[XY16(x, 0)].nscale8(scale);
} }
// give it a linear tail upwards // give it a linear tail upwards
@ -571,12 +612,12 @@ class Effects {
{ {
for (int x = 0; x < VPANEL_W; x++) { for (int x = 0; x < VPANEL_W; x++) {
for (int y = VPANEL_H - 2; y >= 0; y--) { for (int y = VPANEL_H - 2; y >= 0; y--) {
leds[XY(x, y)] += leds[XY(x, y + 1)]; leds[XY16(x, y)] += leds[XY16(x, y + 1)];
leds[XY(x, y)].nscale8(scale); leds[XY16(x, y)].nscale8(scale);
} }
} }
for (int x = 0; x < VPANEL_W; x++) for (int x = 0; x < VPANEL_W; x++)
leds[XY(x, VPANEL_H - 1)].nscale8(scale); leds[XY16(x, VPANEL_H - 1)].nscale8(scale);
} }
// give it a linear tail up and to the left // give it a linear tail up and to the left
@ -584,14 +625,14 @@ class Effects {
{ {
for (int x = 0; x < VPANEL_W - 1; x++) { for (int x = 0; x < VPANEL_W - 1; x++) {
for (int y = VPANEL_H - 2; y >= 0; y--) { for (int y = VPANEL_H - 2; y >= 0; y--) {
leds[XY(x, y)] += leds[XY(x + 1, y + 1)]; leds[XY16(x, y)] += leds[XY16(x + 1, y + 1)];
leds[XY(x, y)].nscale8(scale); leds[XY16(x, y)].nscale8(scale);
} }
} }
for (int x = 0; x < VPANEL_W; x++) for (int x = 0; x < VPANEL_W; x++)
leds[XY(x, VPANEL_H - 1)].nscale8(scale); leds[XY16(x, VPANEL_H - 1)].nscale8(scale);
for (int y = 0; y < VPANEL_H; y++) for (int y = 0; y < VPANEL_H; y++)
leds[XY(VPANEL_W - 1, y)].nscale8(scale); leds[XY16(VPANEL_W - 1, y)].nscale8(scale);
} }
// give it a linear tail up and to the right // give it a linear tail up and to the right
@ -599,24 +640,24 @@ class Effects {
{ {
for (int x = 0; x < VPANEL_W - 1; x++) { for (int x = 0; x < VPANEL_W - 1; x++) {
for (int y = VPANEL_H - 2; y >= 0; y--) { for (int y = VPANEL_H - 2; y >= 0; y--) {
leds[XY(x + 1, y)] += leds[XY(x, y + 1)]; leds[XY16(x + 1, y)] += leds[XY16(x, y + 1)];
leds[XY(x, y)].nscale8(scale); leds[XY16(x, y)].nscale8(scale);
} }
} }
// fade the bottom row // fade the bottom row
for (int x = 0; x < VPANEL_W; x++) for (int x = 0; x < VPANEL_W; x++)
leds[XY(x, VPANEL_H - 1)].nscale8(scale); leds[XY16(x, VPANEL_H - 1)].nscale8(scale);
// fade the right column // fade the right column
for (int y = 0; y < VPANEL_H; y++) for (int y = 0; y < VPANEL_H; y++)
leds[XY(VPANEL_W - 1, y)].nscale8(scale); leds[XY16(VPANEL_W - 1, y)].nscale8(scale);
} }
// just move everything one line down // just move everything one line down
void MoveDown() { void MoveDown() {
for (int y = VPANEL_H - 1; y > 0; y--) { for (int y = VPANEL_H - 1; y > 0; y--) {
for (int x = 0; x < VPANEL_W; x++) { for (int x = 0; x < VPANEL_W; x++) {
leds[XY(x, y)] = leds[XY(x, y - 1)]; leds[XY16(x, y)] = leds[XY16(x, y - 1)];
} }
} }
} }
@ -625,7 +666,7 @@ class Effects {
void VerticalMoveFrom(int start, int end) { void VerticalMoveFrom(int start, int end) {
for (int y = end; y > start; y--) { for (int y = end; y > start; y--) {
for (int x = 0; x < VPANEL_W; x++) { for (int x = 0; x < VPANEL_W; x++) {
leds[XY(x, y)] = leds[XY(x, y - 1)]; leds[XY16(x, y)] = leds[XY16(x, y - 1)];
} }
} }
} }
@ -635,7 +676,7 @@ class Effects {
void Copy(byte x0, byte y0, byte x1, byte y1, byte x2, byte y2) { void Copy(byte x0, byte y0, byte x1, byte y1, byte x2, byte y2) {
for (int y = y0; y < y1 + 1; y++) { for (int y = y0; y < y1 + 1; y++) {
for (int x = x0; x < x1 + 1; x++) { for (int x = x0; x < x1 + 1; x++) {
leds[XY(x + x2 - x0, y + y2 - y0)] = leds[XY(x, y)]; leds[XY16(x + x2 - x0, y + y2 - y0)] = leds[XY16(x, y)];
} }
} }
} }
@ -644,7 +685,7 @@ class Effects {
void RotateTriangle() { void RotateTriangle() {
for (int x = 1; x < MATRIX_CENTER_X; x++) { for (int x = 1; x < MATRIX_CENTER_X; x++) {
for (int y = 0; y < x; y++) { for (int y = 0; y < x; y++) {
leds[XY(x, 7 - y)] = leds[XY(7 - x, y)]; leds[XY16(x, 7 - y)] = leds[XY16(7 - x, y)];
} }
} }
} }
@ -653,7 +694,7 @@ class Effects {
void MirrorTriangle() { void MirrorTriangle() {
for (int x = 1; x < MATRIX_CENTER_X; x++) { for (int x = 1; x < MATRIX_CENTER_X; x++) {
for (int y = 0; y < x; y++) { for (int y = 0; y < x; y++) {
leds[XY(7 - y, x)] = leds[XY(7 - x, y)]; leds[XY16(7 - y, x)] = leds[XY16(7 - x, y)];
} }
} }
} }
@ -679,7 +720,7 @@ class Effects {
int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1; int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
int err = dx + dy, e2; int err = dx + dy, e2;
for (;;) { for (;;) {
leds[XY(x0, y0)] += color; leds[XY16(x0, y0)] += color;
if (x0 == x1 && y0 == y1) break; if (x0 == x1 && y0 == y1) break;
e2 = 2 * err; e2 = 2 * err;
if (e2 > dy) { if (e2 > dy) {
@ -723,10 +764,10 @@ class Effects {
} }
void FillNoise() { void FillNoise() {
for (uint8_t i = 0; i < VPANEL_W; i++) { for (uint16_t i = 0; i < VPANEL_W; i++) {
uint32_t ioffset = noise_scale_x * (i - MATRIX_CENTRE_Y); uint32_t ioffset = noise_scale_x * (i - MATRIX_CENTRE_Y);
for (uint8_t j = 0; j < VPANEL_H; j++) { for (uint16_t j = 0; j < VPANEL_H; j++) {
uint32_t joffset = noise_scale_y * (j - MATRIX_CENTRE_Y); uint32_t joffset = noise_scale_y * (j - MATRIX_CENTRE_Y);
byte data = inoise16(noise_x + ioffset, noise_y + joffset, noise_z) >> 8; byte data = inoise16(noise_x + ioffset, noise_y + joffset, noise_z) >> 8;
@ -752,16 +793,16 @@ class Effects {
// Shift Left: https://codedost.com/c/arraypointers-in-c/c-program-shift-elements-array-left-direction/ // Shift Left: https://codedost.com/c/arraypointers-in-c/c-program-shift-elements-array-left-direction/
// Computationally heavier but doesn't need an entire leds2 array // Computationally heavier but doesn't need an entire leds2 array
tmp = leds[XY(0, y)]; tmp = leds[XY16(0, y)];
for (int m = 0; m < delta; m++) for (int m = 0; m < delta; m++)
{ {
// Do this delta time for each row... computationally expensive potentially. // Do this delta time for each row... computationally expensive potentially.
for (int x = 0; x < VPANEL_H; x++) for(int x = 0; x < VPANEL_W; x++)
{ {
leds[XY(x, y)] = leds [XY(x + 1, y)]; leds[XY16(x, y)] = leds [XY16(x+1, y)];
} }
leds[XY(VPANEL_W - 1, y)] = tmp; leds[XY16(VPANEL_W-1, y)] = tmp;
} }
@ -773,7 +814,7 @@ class Effects {
// Wrap around // Wrap around
for (int x = VPANEL_W - delta; x < VPANEL_W; x++) { for (int x = VPANEL_W - delta; x < VPANEL_W; x++) {
leds2[XY(x, y)] = leds[XY(x + delta - VPANEL_H, y)]; leds2[XY(x, y)] = leds[XY(x + delta - VPANEL_W, y)];
} }
*/ */
} // end row loop } // end row loop
@ -794,120 +835,20 @@ class Effects {
CRGB tmp = 0; CRGB tmp = 0;
for (int x = 0; x < VPANEL_W; x++) for (int x = 0; x < VPANEL_W; x++)
{ {
tmp = leds[XY(x, 0)]; tmp = leds[XY16(x, 0)];
for (int m = 0; m < delta; m++) // moves for (int m = 0; m < delta; m++) // moves
{ {
// Do this delta time for each row... computationally expensive potentially. // Do this delta time for each row... computationally expensive potentially.
for(int y = 0; y < VPANEL_H; y++) for(int y = 0; y < VPANEL_H; y++)
{ {
leds[XY(x, y)] = leds [XY(x, y + 1)]; leds[XY16(x, y)] = leds [XY16(x, y+1)];
} }
leds[XY(x, VPANEL_H - 1)] = tmp; leds[XY16(x, VPANEL_H-1)] = tmp;
} }
} // end column loop } // end column loop
} /// MoveY } /// MoveY
void MoveFractionalNoiseX(byte amt = 16) {
// move delta pixelwise
for (int y = 0; y < VPANEL_H; y++) {
uint16_t amount = noise[0][y] * amt;
byte delta = 31 - (amount / 256);
for (int x = 0; x < VPANEL_W - delta; x++) {
leds2[XY(x, y)] = leds[XY(x + delta, y)];
}
for (int x = VPANEL_H - delta; x < VPANEL_W; x++) {
leds2[XY(x, y)] = leds[XY(x + delta - VPANEL_W, y)];
}
}
//move fractions
CRGB PixelA;
CRGB PixelB;
for (uint8_t y = 0; y < VPANEL_H; y++) {
uint16_t amount = noise[0][y] * amt;
byte delta = 31 - (amount / 256);
byte fractions = amount - (delta * 256);
for (uint8_t x = 1; x < VPANEL_W; x++) {
PixelA = leds2[XY(x, y)];
PixelB = leds2[XY(x - 1, y)];
PixelA %= 255 - fractions;
PixelB %= fractions;
leds[XY(x, y)] = PixelA + PixelB;
}
PixelA = leds2[XY(0, y)];
PixelB = leds2[XY(VPANEL_W - 1, y)];
PixelA %= 255 - fractions;
PixelB %= fractions;
leds[XY(0, y)] = PixelA + PixelB;
}
}
void MoveFractionalNoiseY(byte amt = 16) {
// move delta pixelwise
for (int x = 0; x < VPANEL_W; x++) {
uint16_t amount = noise[x][0] * amt;
byte delta = 31 - (amount / 256);
for (int y = 0; y < VPANEL_W - delta; y++) {
leds2[XY(x, y)] = leds[XY(x, y + delta)];
}
for (int y = VPANEL_W - delta; y < VPANEL_W; y++) {
leds2[XY(x, y)] = leds[XY(x, y + delta - VPANEL_W)];
}
}
//move fractions
CRGB PixelA;
CRGB PixelB;
for (uint8_t x = 0; x < VPANEL_H; x++) {
uint16_t amount = noise[x][0] * amt;
byte delta = 31 - (amount / 256);
byte fractions = amount - (delta * 256);
for (uint8_t y = 1; y < VPANEL_W; y++) {
PixelA = leds2[XY(x, y)];
PixelB = leds2[XY(x, y - 1)];
PixelA %= 255 - fractions;
PixelB %= fractions;
leds[XY(x, y)] = PixelA + PixelB;
}
PixelA = leds2[XY(x, 0)];
PixelB = leds2[XY(x, VPANEL_W - 1)];
PixelA %= 255 - fractions;
PixelB %= fractions;
leds[XY(x, 0)] = PixelA + PixelB;
}
}
void standardNoiseSmearing() {
noise_x += 1000;
noise_y += 1000;
noise_scale_x = 4000;
noise_scale_y = 4000;
FillNoise();
MoveX(3);
MoveFractionalNoiseY(4);
MoveY(3);
MoveFractionalNoiseX(4);
}
}; };

View file

@ -52,7 +52,7 @@ public:
unsigned int drawFrame() { unsigned int drawFrame() {
// dim all pixels on the display // dim all pixels on the display
uint8_t dim = beatsin8(2, 170, 250); uint8_t dim = beatsin8(2, 170, 250);
effects.DimAll(dim); effects.ShowFrame(); effects.DimAll(dim);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
Boid boid = boids[i]; Boid boid = boids[i];
@ -66,7 +66,8 @@ public:
boids[i] = boid; boids[i] = boid;
} }
return 15; effects.ShowFrame();
return 0;
} }
}; };

View file

@ -0,0 +1,73 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* 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.
*/
#ifndef PatternBounce_H
class PatternBounce : public Drawable {
private:
static const int count = 32;
PVector gravity = PVector(0, 0.0125);
public:
PatternBounce() {
name = (char *)"Bounce";
}
void start() {
unsigned int colorWidth = 256 / count;
for (int i = 0; i < count; i++) {
Boid boid = Boid(i, 0);
boid.velocity.x = 0;
boid.velocity.y = i * -0.01;
boid.colorIndex = colorWidth * i;
boid.maxforce = 10;
boid.maxspeed = 10;
boids[i] = boid;
}
}
unsigned int drawFrame() {
// dim all pixels on the display
effects.DimAll(170); effects.ShowFrame();
for (int i = 0; i < count; i++) {
Boid boid = boids[i];
boid.applyForce(gravity);
boid.update();
effects.drawBackgroundFastLEDPixelCRGB(boid.location.x, boid.location.y, effects.ColorFromCurrentPalette(boid.colorIndex));
if (boid.location.y >= VPANEL_H - 1) {
boid.location.y = VPANEL_H - 1;
boid.velocity.y *= -1.0;
}
boids[i] = boid;
}
return 15;
}
};
#endif

View file

@ -0,0 +1,219 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from Noel Bundy's work: https://github.com/TwystNeko/Object3d
* Copyright (c) 2014 Noel Bundy
*
* Portions of this code are adapted from the Petty library: https://code.google.com/p/peggy/
* Copyright (c) 2008 Windell H Oskay. All right reserved.
*
* 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.
*/
#ifndef PatternCube_H
#define PatternCube_H
class PatternCube : public Drawable {
private:
float focal = 30; // Focal of the camera
int cubeWidth = 28; // Cube size
float Angx = 20.0, AngxSpeed = 0.05; // rotation (angle+speed) around X-axis
float Angy = 10.0, AngySpeed = 0.05; // rotation (angle+speed) around Y-axis
float Ox = 15.5, Oy = 15.5; // position (x,y) of the frame center
int zCamera = 110; // distance from cube to the eye of the camera
// Local vertices
Vertex local[8];
// Camera aligned vertices
Vertex aligned[8];
// On-screen projected vertices
Point screen[8];
// Faces
squareFace face[6];
// Edges
EdgePoint edge[12];
int nbEdges;
// ModelView matrix
float m00, m01, m02, m10, m11, m12, m20, m21, m22;
// constructs the cube
void make(int w)
{
nbEdges = 0;
local[0].set(-w, w, w);
local[1].set(w, w, w);
local[2].set(w, -w, w);
local[3].set(-w, -w, w);
local[4].set(-w, w, -w);
local[5].set(w, w, -w);
local[6].set(w, -w, -w);
local[7].set(-w, -w, -w);
face[0].set(1, 0, 3, 2);
face[1].set(0, 4, 7, 3);
face[2].set(4, 0, 1, 5);
face[3].set(4, 5, 6, 7);
face[4].set(1, 2, 6, 5);
face[5].set(2, 3, 7, 6);
int f, i;
for (f = 0; f < 6; f++)
{
for (i = 0; i < face[f].length; i++)
{
face[f].ed[i] = this->findEdge(face[f].sommets[i], face[f].sommets[i ? i - 1 : face[f].length - 1]);
}
}
}
// finds edges from faces
int findEdge(int a, int b)
{
int i;
for (i = 0; i < nbEdges; i++)
if ((edge[i].x == a && edge[i].y == b) || (edge[i].x == b && edge[i].y == a))
return i;
edge[nbEdges++].set(a, b);
return i;
}
// rotates according to angle x&y
void rotate(float angx, float angy)
{
int i;
float cx = cos(angx);
float sx = sin(angx);
float cy = cos(angy);
float sy = sin(angy);
m00 = cy;
m01 = 0;
m02 = -sy;
m10 = sx * sy;
m11 = cx;
m12 = sx * cy;
m20 = cx * sy;
m21 = -sx;
m22 = cx * cy;
for (i = 0; i < 8; i++)
{
aligned[i].x = m00 * local[i].x + m01 * local[i].y + m02 * local[i].z;
aligned[i].y = m10 * local[i].x + m11 * local[i].y + m12 * local[i].z;
aligned[i].z = m20 * local[i].x + m21 * local[i].y + m22 * local[i].z + zCamera;
screen[i].x = floor((Ox + focal * aligned[i].x / aligned[i].z));
screen[i].y = floor((Oy - focal * aligned[i].y / aligned[i].z));
}
for (i = 0; i < 12; i++)
edge[i].visible = false;
Point *pa, *pb, *pc;
for (i = 0; i < 6; i++)
{
pa = screen + face[i].sommets[0];
pb = screen + face[i].sommets[1];
pc = screen + face[i].sommets[2];
boolean back = ((pb->x - pa->x) * (pc->y - pa->y) - (pb->y - pa->y) * (pc->x - pa->x)) < 0;
if (!back)
{
int j;
for (j = 0; j < 4; j++)
{
edge[face[i].ed[j]].visible = true;
}
}
}
}
byte hue = 0;
int step = 0;
public:
PatternCube() {
name = (char *)"Cube";
make(cubeWidth);
}
unsigned int drawFrame() {
uint8_t blurAmount = beatsin8(2, 10, 255);
#if FASTLED_VERSION >= 3001000
blur2d(effects.leds, VPANEL_W, VPANEL_H, blurAmount);
#else
effects.DimAll(blurAmount); effects.ShowFrame();
#endif
zCamera = beatsin8(2, 100, 140);
AngxSpeed = beatsin8(3, 1, 10) / 100.0f;
AngySpeed = beatcos8(5, 1, 10) / 100.0f;
// Update values
Angx += AngxSpeed;
Angy += AngySpeed;
if (Angx >= TWO_PI)
Angx -= TWO_PI;
if (Angy >= TWO_PI)
Angy -= TWO_PI;
rotate(Angx, Angy);
// Draw cube
int i;
CRGB color = effects.ColorFromCurrentPalette(hue, 128);
// Backface
EdgePoint *e;
for (i = 0; i < 12; i++)
{
e = edge + i;
if (!e->visible) {
matrix.drawLine(screen[e->x].x, screen[e->x].y, screen[e->y].x, screen[e->y].y, color);
}
}
color = effects.ColorFromCurrentPalette(hue, 255);
// Frontface
for (i = 0; i < 12; i++)
{
e = edge + i;
if (e->visible)
{
matrix.drawLine(screen[e->x].x, screen[e->x].y, screen[e->y].x, screen[e->y].y, color);
}
}
step++;
if (step == 8) {
step = 0;
hue++;
}
effects.ShowFrame();
return 20;
}
};
#endif

View file

@ -70,7 +70,7 @@ class PatternElectricMandala : public Drawable {
unsigned int drawFrame() { unsigned int drawFrame() {
#if FASTLED_VERSION >= 3001000 #if FASTLED_VERSION >= 3001000
// a new parameter set every 15 seconds // a new parameter set every 15 seconds
EVERY_N_SECONDS(25) { EVERY_N_SECONDS(15) {
//SetupRandomPalette3(); //SetupRandomPalette3();
dy = random16(500) - 250; // random16(2000) - 1000 is pretty fast but works fine, too dy = random16(500) - 250; // random16(2000) - 1000 is pretty fast but works fine, too
dx = random16(500) - 250; dx = random16(500) - 250;
@ -92,13 +92,13 @@ class PatternElectricMandala : public Drawable {
effects.ShowFrame(); effects.ShowFrame();
return 0; return 30;
} }
// show just one layer // show just one layer
void ShowNoiseLayer(byte layer, byte colorrepeat, byte colorshift) { void ShowNoiseLayer(byte layer, byte colorrepeat, byte colorshift) {
for (uint8_t i = 0; i < VPANEL_W; i++) { for (uint16_t i = 0; i < VPANEL_W; i++) {
for (uint8_t j = 0; j < VPANEL_H; j++) { for (uint16_t j = 0; j < VPANEL_H; j++) {
uint8_t color = noise[i][j]; uint8_t color = noise[i][j];
@ -107,7 +107,7 @@ class PatternElectricMandala : public Drawable {
// assign a color depending on the actual palette // assign a color depending on the actual palette
CRGB pixel = ColorFromPalette(effects.currentPalette, colorrepeat * (color + colorshift), bri); CRGB pixel = ColorFromPalette(effects.currentPalette, colorrepeat * (color + colorshift), bri);
effects.leds[XY(i, j)] = pixel; effects.leds[XY16(i, j)] = pixel;
} }
} }
} }

View file

@ -1,30 +1,28 @@
/* /*
Aurora: https://github.com/pixelmatix/aurora * Aurora: https://github.com/pixelmatix/aurora
Copyright (c) 2014 Jason Coon * Copyright (c) 2014 Jason Coon
*
Portions of this code are adapted from FastLED Fire2012 example by Mark Kriegsman: https://github.com/FastLED/FastLED/tree/master/examples/Fire2012WithPalette * Portions of this code are adapted from FastLED Fire2012 example by Mark Kriegsman: https://github.com/FastLED/FastLED/tree/master/examples/Fire2012WithPalette
Copyright (c) 2013 FastLED * Copyright (c) 2013 FastLED
*
Permission is hereby granted, free of charge, to any person obtaining a copy of * 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 * this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * 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, * the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: * subject to the following conditions:
*
The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. * copies or substantial portions of the Software.
*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * 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 * 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 * 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. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
// Note: (Kosso) : Doesn't look good with certain palettes.
#ifndef PatternFire_H #ifndef PatternFire_H
#define PatternFire_H #define PatternFire_H
@ -92,12 +90,10 @@ class PatternFire : public Drawable {
colorIndex = scale8(colorIndex, 200); colorIndex = scale8(colorIndex, 200);
// override color 0 to ensure a black background? // override color 0 to ensure a black background?
//if (colorIndex != 0) { if (colorIndex != 0)
// effects.leds[xy] = CRGB::Black; // effects.leds[xy] = CRGB::Black;
//} // else
//else {
effects.leds[xy] = effects.ColorFromCurrentPalette(colorIndex); effects.leds[xy] = effects.ColorFromCurrentPalette(colorIndex);
//}
} }
} }
@ -109,9 +105,10 @@ class PatternFire : public Drawable {
noise_scale_y = 4000; noise_scale_y = 4000;
effects.FillNoise(); effects.FillNoise();
// effects.MoveX(2); effects.MoveX(2);
effects.MoveFractionalNoiseX(2); effects.MoveFractionalNoiseX(2);
effects.ShowFrame(); effects.ShowFrame();
return 15; return 15;

View file

@ -0,0 +1,64 @@
/*
*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* 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.
*/
#ifndef PatternIncrementalDrift2_H
#define PatternIncrementalDrift2_H
class PatternIncrementalDrift2 : public Drawable {
public:
PatternIncrementalDrift2() {
name = (char *)"Incremental Drift Rose";
}
unsigned int drawFrame() {
uint8_t dim = beatsin8(2, 170, 250);
effects.DimAll(dim); effects.ShowFrame();
for (int i = 2; i < VPANEL_H / 2; ++i)
//for (uint8_t i = 0; i < 32; i++)
{
CRGB color;
uint8_t x = 0;
uint8_t y = 0;
if (i < 16) {
x = beatcos8((i + 1) * 2, i, VPANEL_W - i);
y = beatsin8((i + 1) * 2, i, VPANEL_H - i);
color = effects.ColorFromCurrentPalette(i * 14);
}
else
{
x = beatsin8((32 - i) * 2, VPANEL_W - i, i + 1);
y = beatcos8((32 - i) * 2, VPANEL_H - i, i + 1);
color = effects.ColorFromCurrentPalette((31 - i) * 14);
}
effects.drawBackgroundFastLEDPixelCRGB(x, y, color);
}
return 0;
}
};
#endif

View file

@ -31,7 +31,9 @@ public:
unsigned int drawFrame() { unsigned int drawFrame() {
// dim all pixels on the display slightly // dim all pixels on the display slightly
// to 250/255 (98%) of their current brightness // to 250/255 (98%) of their current brightness
effects.DimAll(250); effects.ShowFrame(); blur2d(effects.leds, VPANEL_W > 255 ? 255 : VPANEL_W, VPANEL_H > 255 ? 255 : VPANEL_H, 250);
// effects.DimAll(250); effects.ShowFrame();
// the Effects class has some sample oscillators // the Effects class has some sample oscillators
// that move from 0 to 255 at different speeds // that move from 0 to 255 at different speeds
@ -51,7 +53,8 @@ public:
// draw a pixel at x,y using a color from the current palette // draw a pixel at x,y using a color from the current palette
effects.Pixel(x, y, hue); effects.Pixel(x, y, hue);
return 15; effects.ShowFrame();
return 30;
} }
}; };

View file

@ -0,0 +1,154 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Inspired by 'Space Invader Generator': https://the8bitpimp.wordpress.com/2013/05/07/space-invader-generator
*
* 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.
*/
#ifndef PatternInvaders_H
#define PatternInvaders_H
class PatternInvadersSmall : public Drawable {
private:
uint8_t x = 1;
uint8_t y = 1;
public:
PatternInvadersSmall() {
name = (char *)"Invaders Small";
}
void start() {
matrix.fillScreen(0);
}
unsigned int drawFrame() {
CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255));
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 5; j++) {
CRGB color = CRGB::Black;
if (random(0, 2) == 1) color = color1;
effects.drawBackgroundFastLEDPixelCRGB(x + i, y + j, color);
if (i < 2)
effects.drawBackgroundFastLEDPixelCRGB(x + (4 - i), y + j, color);
}
}
x += 6;
if (x > 25) {
x = 1;
y += 6;
}
if (y > 25) y = x = 1;
effects.ShowFrame();
return 125;
}
};
class PatternInvadersMedium : public Drawable {
private:
uint8_t x = 0;
uint8_t y = 0;
public:
PatternInvadersMedium() {
name = (char *)"Invaders Medium";
}
void start() {
matrix.fillScreen(0);
}
unsigned int drawFrame() {
CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255));
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 5; j++) {
CRGB color = CRGB::Black;
if (random(0, 2) == 1) color = color1;
matrix.fillRect(x + (i * 2), y + (j * 2), x + (i * 2 + 1), y + (j * 2 + 1), color);
if (i < 2)
matrix.fillRect(x + (8 - i * 2), y + (j * 2), x + (9 - i * 2), y + (j * 2 + 1), color);
}
}
x += 11;
if (x > 22) {
x = 0;
y += 11;
}
if (y > 22) y = x = 0;
effects.ShowFrame();
return 500;
}
};
class PatternInvadersLarge : public Drawable {
private:
public:
PatternInvadersLarge() {
name = (char *)"Invaders Large";
}
void start() {
matrix.fillScreen(0);
}
unsigned int drawFrame() {
matrix.fillScreen(0);
CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255));
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 5; y++) {
CRGB color = CRGB::Black;
if (random(0, 2) == 1) {
color = color1;
}
matrix.fillRect(1 + x * 6, 1 + y * 6, 5 + x * 6, 5 + y * 6, color);
if (x < 2)
matrix.fillRect(1 + (4 - x) * 6, 1 + y * 6, 5 + (4 - x) * 6, 5 + y * 6, color);
}
}
effects.ShowFrame();
return 2000;
}
};
#endif

View file

@ -246,7 +246,7 @@ public:
if (algorithm >= algorithmCount) if (algorithm >= algorithmCount)
algorithm = 0; algorithm = 0;
return 1000; return 0;
} }
effects.ShowFrame(); effects.ShowFrame();
@ -255,7 +255,7 @@ public:
} }
void start() { void start() {
matrix.fillScreen(0); effects.ClearFrame();
cellCount = 0; cellCount = 0;
hue = 0; hue = 0;
} }

View file

@ -40,9 +40,9 @@ public:
unsigned int drawFrame() { unsigned int drawFrame() {
for (byte x = 0; x < VPANEL_W; x++) { for (uint16_t x = 0; x < VPANEL_W; x++) {
for (byte y = 0; y < VPANEL_H; y++) { for (uint16_t y = 0; y < VPANEL_H; y++) {
effects.leds[XY(x, y)] = (x ^ y ^ flip) < count ? effects.ColorFromCurrentPalette(((x ^ y) << 2) + generation) : CRGB::Black; effects.leds[XY16(x, y)] = (x ^ y ^ flip) < count ? effects.ColorFromCurrentPalette(((x ^ y) << 2) + generation) : CRGB::Black;
// The below is more pleasant // The below is more pleasant
// effects.leds[XY(x, y)] = effects.ColorFromCurrentPalette(((x ^ y) << 2) + generation) ; // effects.leds[XY(x, y)] = effects.ColorFromCurrentPalette(((x ^ y) << 2) + generation) ;
@ -66,7 +66,6 @@ public:
// show it ffs! // show it ffs!
effects.ShowFrame(); effects.ShowFrame();
return 60; return 60;
} }
}; };

View file

@ -65,10 +65,10 @@ public:
effects.FillNoise(); effects.FillNoise();
effects.MoveX(8); effects.MoveX(8);
// effects.MoveFractionalNoiseX(); effects.MoveFractionalNoiseX();
effects.MoveY(8); effects.MoveY(8);
// effects.MoveFractionalNoiseY(); effects.MoveFractionalNoiseY();
patternNoiseSmearingHue++; patternNoiseSmearingHue++;
@ -103,10 +103,10 @@ public:
effects.FillNoise(); effects.FillNoise();
effects.MoveX(3); effects.MoveX(3);
// effects.MoveFractionalNoiseY(4); effects.MoveFractionalNoiseY(4);
effects.MoveY(3); effects.MoveY(3);
//effects.MoveFractionalNoiseX(4); effects.MoveFractionalNoiseX(4);
patternNoiseSmearingHue++; patternNoiseSmearingHue++;
@ -137,10 +137,10 @@ public:
effects.FillNoise(); effects.FillNoise();
effects.MoveX(3); effects.MoveX(3);
// effects.MoveFractionalNoiseY(4); effects.MoveFractionalNoiseY(4);
effects.MoveY(3); effects.MoveY(3);
// effects.MoveFractionalNoiseX(4); effects.MoveFractionalNoiseX(4);
effects.ShowFrame(); effects.ShowFrame();
@ -170,10 +170,10 @@ public:
effects.FillNoise(); effects.FillNoise();
effects.MoveX(8); effects.MoveX(8);
// effects.MoveFractionalNoiseX(); effects.MoveFractionalNoiseX();
effects.MoveY(8); effects.MoveY(8);
// effects.MoveFractionalNoiseY(); effects.MoveFractionalNoiseY();
patternNoiseSmearingHue++; patternNoiseSmearingHue++;
@ -206,10 +206,10 @@ public:
effects.FillNoise(); effects.FillNoise();
effects.MoveX(3); effects.MoveX(3);
// effects.MoveFractionalNoiseY(4); effects.MoveFractionalNoiseY(4);
effects.MoveY(4); effects.MoveY(4);
// effects.MoveFractionalNoiseX(4); effects.MoveFractionalNoiseX(4);
return 0; return 0;
} }
@ -241,10 +241,10 @@ public:
effects.FillNoise(); effects.FillNoise();
effects.MoveX(3); effects.MoveX(3);
// effects.MoveFractionalNoiseX(4); effects.MoveFractionalNoiseX(4);
effects.MoveY(3); effects.MoveY(3);
//effects.MoveFractionalNoiseY(4); effects.MoveFractionalNoiseY(4);
return 0; return 0;
} }
@ -261,8 +261,8 @@ public:
effects.DimAll(170); effects.ShowFrame(); effects.DimAll(170); effects.ShowFrame();
// draw a rainbow color palette // draw a rainbow color palette
for (uint8_t y = 0; y < MATRIX_HEIGHT; y++) { for (uint8_t y = 0; y < VPANEL_H; y++) {
for (uint8_t x = 0; x < MATRIX_WIDTH; x++) { for (uint8_t x = 0; x < VPANEL_W; x++) {
effects.leds[XY(x, y)] += effects.ColorFromCurrentPalette(x * 8, y * 8 + 7); effects.leds[XY(x, y)] += effects.ColorFromCurrentPalette(x * 8, y * 8 + 7);
} }
} }
@ -280,7 +280,7 @@ public:
//effects.MoveFractionalNoiseY(4); //effects.MoveFractionalNoiseY(4);
effects.MoveY(3); effects.MoveY(3);
// effects.MoveFractionalNoiseX(4); effects.MoveFractionalNoiseX(4);
effects.ShowFrame(); effects.ShowFrame();
return 0; return 0;
@ -327,10 +327,10 @@ public:
effects.FillNoise(); effects.FillNoise();
effects.MoveX(3); effects.MoveX(3);
// effects.MoveFractionalNoiseY(4); effects.MoveFractionalNoiseY(4);
effects.MoveY(3); effects.MoveY(3);
// effects.MoveFractionalNoiseX(4); effects.MoveFractionalNoiseX(4);
return 0; return 0;
} }

View file

@ -34,6 +34,12 @@
#ifndef PatternPendulumWave_H #ifndef PatternPendulumWave_H
#define PatternPendulumWave_H #define PatternPendulumWave_H
#define WAVE_BPM 25
#define AMP_BPM 2
#define SKEW_BPM 4
#define WAVE_TIMEMINSKEW VPANEL_W/8
#define WAVE_TIMEMAXSKEW VPANEL_W/2
class PatternPendulumWave : public Drawable { class PatternPendulumWave : public Drawable {
public: public:
PatternPendulumWave() { PatternPendulumWave() {
@ -41,15 +47,19 @@ class PatternPendulumWave : public Drawable {
} }
unsigned int drawFrame() { unsigned int drawFrame() {
effects.DimAll(170); effects.ShowFrame(); effects.ClearFrame();
for (int x = 0; x < VPANEL_W; x++) for (int x = 0; x < VPANEL_W; ++x)
{ {
uint8_t y = beatsin8(x + VPANEL_W, 0, VPANEL_H); uint16_t amp = beatsin16(AMP_BPM, VPANEL_H/8, VPANEL_H-1);
uint16_t offset = (VPANEL_H - beatsin16(AMP_BPM, 0, VPANEL_H))/2;
uint8_t y = beatsin16(WAVE_BPM, 0, amp, x*beatsin16(SKEW_BPM, WAVE_TIMEMINSKEW, WAVE_TIMEMAXSKEW)) + offset;
effects.drawBackgroundFastLEDPixelCRGB(x, y, effects.ColorFromCurrentPalette(x * 7)); effects.drawBackgroundFastLEDPixelCRGB(x, y, effects.ColorFromCurrentPalette(x * 7));
} }
effects.ShowFrame();
return 15; return 20;
} }
}; };

View file

@ -0,0 +1,82 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Based at least in part on someone else's work that I can no longer find.
* Please let me know if you recognize any of this code!
*
* 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.
*/
#ifndef PatternPulse_H
#define PatternPulse_H
class PatternPulse : public Drawable {
private:
int hue;
int centerX = 0;
int centerY = 0;
int step = -1;
int maxSteps = 16;
float fadeRate = 0.8;
int diff;
public:
PatternPulse() {
name = (char *)"Pulse";
}
unsigned int drawFrame() {
effects.DimAll(235);
if (step == -1) {
centerX = random(32);
centerY = random(32);
hue = random(256); // 170;
step = 0;
}
if (step == 0) {
matrix.drawCircle(centerX, centerY, step, effects.ColorFromCurrentPalette(hue));
step++;
}
else {
if (step < maxSteps) {
// initial pulse
matrix.drawCircle(centerX, centerY, step, effects.ColorFromCurrentPalette(hue, pow(fadeRate, step - 2) * 255));
// secondary pulse
if (step > 3) {
matrix.drawCircle(centerX, centerY, step - 3, effects.ColorFromCurrentPalette(hue, pow(fadeRate, step - 2) * 255));
}
step++;
}
else {
step = -1;
}
}
effects.standardNoiseSmearing();
effects.ShowFrame();
return 30;
}
};
#endif

View file

@ -60,17 +60,17 @@ class PatternSimplexNoise : public Drawable {
effects.ShowFrame(); effects.ShowFrame();
return 0; return 30;
} }
// show just one layer // show just one layer
void ShowNoiseLayer(byte layer, byte colorrepeat, byte colorshift) { void ShowNoiseLayer(byte layer, byte colorrepeat, byte colorshift) {
for (uint8_t i = 0; i < VPANEL_W; i++) { for (uint16_t i = 0; i < VPANEL_W; i++) {
for (uint8_t j = 0; j < VPANEL_H; j++) { for (uint16_t j = 0; j < VPANEL_H; j++) {
uint8_t pixel = noise[i][j]; uint8_t pixel = noise[i][j];
// assign a color depending on the actual palette // assign a color depending on the actual palette
effects.leds[XY(i, j)] = effects.ColorFromCurrentPalette(colorrepeat * (pixel + colorshift), pixel); effects.leds[XY16(i, j)] = effects.ColorFromCurrentPalette(colorrepeat * (pixel + colorshift), pixel);
} }
} }
} }

View file

@ -101,7 +101,7 @@ private:
} }
}; };
static const int snakeCount = 40; static const int snakeCount = 6;
Snake snakes[snakeCount]; Snake snakes[snakeCount];
public: public:

View file

@ -0,0 +1,113 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from FastLED Fire2012 example by Mark Kriegsman: https://github.com/FastLED/FastLED/tree/master/examples/Fire2012WithPalette
* Copyright (c) 2013 FastLED
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternSpark_H
#define PatternSpark_H
class PatternSpark : public Drawable {
private:
public:
PatternSpark() {
name = (char *)"Spark";
}
// There are two main parameters you can play with to control the look and
// feel of your fire: COOLING (used in step 1 above), and SPARKING (used
// in step 3 above).
//
// COOLING: How much does the air cool as it rises?
// Less cooling = taller flames. More cooling = shorter flames.
// Default 55, suggested range 20-100
uint8_t cooling = 100;
// SPARKING: What chance (out of 255) is there that a new spark will be lit?
// Higher chance = more roaring fire. Lower chance = more flickery fire.
// Default 120, suggested range 50-200.
uint8_t sparking = 50;
unsigned int drawFrame() {
// Add entropy to random number generator; we use a lot of it.
random16_add_entropy( random16());
effects.DimAll(235); effects.ShowFrame();
for (uint8_t x = 0; x < VPANEL_W; x++) {
// Step 1. Cool down every cell a little
for (int y = 0; y < VPANEL_H; y++) {
int xy = XY(x, y);
heat[xy] = qsub8(heat[xy], random8(0, ((cooling * 10) / VPANEL_H) + 2));
}
// Step 2. Heat from each cell drifts 'up' and diffuses a little
for (int y = 0; y < VPANEL_H; y++) {
heat[XY(x, y)] = (heat[XY(x, y + 1)] + heat[XY(x, y + 2)] + heat[XY(x, y + 2)]) / 3;
}
// Step 2. Randomly ignite new 'sparks' of heat
if (random8() < sparking) {
uint8_t xt = random8(MATRIX_CENTRE_X - 2, MATRIX_CENTER_X + 3);
int xy = XY(xt, VPANEL_H - 1);
heat[xy] = qadd8(heat[xy], random8(160, 255));
}
// Step 4. Map from heat cells to LED colors
for (int y = 0; y < VPANEL_H; y++) {
int xy = XY(x, y);
byte colorIndex = heat[xy];
// Recommend that you use values 0-240 rather than
// the usual 0-255, as the last 15 colors will be
// 'wrapping around' from the hot end to the cold end,
// which looks wrong.
colorIndex = scale8(colorIndex, 240);
// override color 0 to ensure a black background?
if (colorIndex != 0)
// effects.leds[xy] = CRGB::Black;
// else
effects.leds[xy] = effects.ColorFromCurrentPalette(colorIndex);
}
}
// Noise
noise_x += 1000;
noise_y += 1000;
noise_z += 1000;
noise_scale_x = 4000;
noise_scale_y = 4000;
effects.FillNoise();
effects.MoveX(3);
effects.MoveFractionalNoiseX(4);
effects.ShowFrame();
return 15;
}
};
#endif

View file

@ -0,0 +1,100 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* 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.
*/
#ifndef PatternSpin_H
class PatternSpin : public Drawable {
public:
PatternSpin() {
name = (char *)"Spin";
}
float degrees = 0;
float radius = 16;
float speedStart = 1;
float velocityStart = 0.6;
float maxSpeed = 30;
float speed = speedStart;
float velocity = velocityStart;
void start() {
speed = speedStart;
velocity = velocityStart;
degrees = 0;
}
unsigned int drawFrame() {
effects.DimAll(190); effects.ShowFrame();
CRGB color = effects.ColorFromCurrentPalette(speed * 8);
// start position
int x;
int y;
// target position
float targetDegrees = degrees + speed;
float targetRadians = radians(targetDegrees);
int targetX = (int) (MATRIX_CENTER_X + radius * cos(targetRadians));
int targetY = (int) (MATRIX_CENTER_Y - radius * sin(targetRadians));
float tempDegrees = degrees;
do{
float radians = radians(tempDegrees);
x = (int) (MATRIX_CENTER_X + radius * cos(radians));
y = (int) (MATRIX_CENTER_Y - radius * sin(radians));
effects.drawBackgroundFastLEDPixelCRGB(x, y, color);
effects.drawBackgroundFastLEDPixelCRGB(y, x, color);
tempDegrees += 1;
if (tempDegrees >= 360)
tempDegrees = 0;
} while (x != targetX || y != targetY);
degrees += speed;
// add velocity to the particle each pass around the accelerator
if (degrees >= 360) {
degrees = 0;
speed += velocity;
if (speed <= speedStart) {
speed = speedStart;
velocity *= -1;
}
else if (speed > maxSpeed){
speed = maxSpeed - velocity;
velocity *= -1;
}
}
return 0;
}
};
#endif

View file

@ -37,7 +37,7 @@ class PatternSpiro : public Drawable {
uint8_t spirocount = 1; uint8_t spirocount = 1;
uint8_t spirooffset = 256 / spirocount; uint8_t spirooffset = 256 / spirocount;
boolean spiroincrement = false; boolean spiroincrement = true;
boolean handledChange = false; boolean handledChange = false;
@ -46,8 +46,12 @@ class PatternSpiro : public Drawable {
name = (char *)"Spiro"; name = (char *)"Spiro";
} }
void start(){
effects.ClearFrame();
};
unsigned int drawFrame() { unsigned int drawFrame() {
effects.DimAll(254); effects.ShowFrame(); blur2d(effects.leds, VPANEL_W > 255 ? 255 : VPANEL_W, VPANEL_H > 255 ? 255 : VPANEL_H, 192);
boolean change = false; boolean change = false;
@ -100,6 +104,7 @@ class PatternSpiro : public Drawable {
hueoffset += 1; hueoffset += 1;
} }
effects.ShowFrame();
return 0; return 0;
} }
}; };

View file

@ -36,6 +36,7 @@ class PatternSwirl : public Drawable {
} }
void start() { void start() {
effects.ClearFrame();
} }
unsigned int drawFrame() { unsigned int drawFrame() {
@ -46,24 +47,25 @@ class PatternSwirl : public Drawable {
uint8_t blurAmount = beatsin8(2, 10, 255); uint8_t blurAmount = beatsin8(2, 10, 255);
#if FASTLED_VERSION >= 3001000 #if FASTLED_VERSION >= 3001000
blur2d(effects.leds, VPANEL_W, VPANEL_H, blurAmount); blur2d(effects.leds, VPANEL_W > 255 ? 255 : VPANEL_W, VPANEL_H > 255 ? 255 : VPANEL_H, blurAmount);
#else #else
effects.DimAll(blurAmount); effects.DimAll(blurAmount);
#endif #endif
// Use two out-of-sync sine waves // Use two out-of-sync sine waves
uint8_t i = beatsin8(27, borderWidth, VPANEL_H - borderWidth); uint8_t i = beatsin8(256/VPANEL_H, borderWidth, VPANEL_W - borderWidth);
uint8_t j = beatsin8(41, borderWidth, VPANEL_W - borderWidth); uint8_t j = beatsin8(2048/VPANEL_W, borderWidth, VPANEL_H - borderWidth);
// Also calculate some reflections // Also calculate some reflections
uint8_t ni = (VPANEL_W - 1) - i; uint8_t ni = (VPANEL_W - 1) - i;
uint8_t nj = (VPANEL_W - 1) - j; uint8_t nj = (VPANEL_H - 1) - j;
// The color of each point shifts over time, each at a different speed. // The color of each point shifts over time, each at a different speed.
uint16_t ms = millis(); uint16_t ms = millis();
effects.leds[XY(i, j)] += effects.ColorFromCurrentPalette(ms / 11); effects.leds[XY(i, j)] += effects.ColorFromCurrentPalette(ms / 11);
effects.leds[XY(j, i)] += effects.ColorFromCurrentPalette(ms / 13); //effects.leds[XY(j, i)] += effects.ColorFromCurrentPalette(ms / 13); // this doesn't work for non-square matrixes
effects.leds[XY(ni, nj)] += effects.ColorFromCurrentPalette(ms / 17); effects.leds[XY(ni, nj)] += effects.ColorFromCurrentPalette(ms / 17);
effects.leds[XY(nj, ni)] += effects.ColorFromCurrentPalette(ms / 29); //effects.leds[XY(nj, ni)] += effects.ColorFromCurrentPalette(ms / 29); // this doesn't work for non-square matrixes
effects.leds[XY(i, nj)] += effects.ColorFromCurrentPalette(ms / 37); effects.leds[XY(i, nj)] += effects.ColorFromCurrentPalette(ms / 37);
effects.leds[XY(ni, j)] += effects.ColorFromCurrentPalette(ms / 41); effects.leds[XY(ni, j)] += effects.ColorFromCurrentPalette(ms / 41);

View file

@ -0,0 +1,20 @@
#ifndef PatternTest_H
#define PatternTest_H
class PatternTest : public Drawable {
private:
public:
PatternTest() {
name = (char *)"Test Pattern";
}
unsigned int drawFrame() {
matrix.fillScreen(matrix.color565(128, 0, 0));
return 1000;
}
};
#endif

View file

@ -34,52 +34,75 @@
* *
* Commented out patterns are due to the fact they either didn't work properly with a non-square display, * Commented out patterns are due to the fact they either didn't work properly with a non-square display,
* or from my personal opinion, are crap. * or from my personal opinion, are crap.
*
* Kosso: I have removed the crappy ones and added a less crappy (and working!) Fire demo ;)
*
*/ */
#include "PaletteFireKoz.h" // Added by Kosso
#include "PatternFireKoz.h" // Added by Kosso #include "PatternTest.h"
//#include "PatternNoiseSmearing.h" // Doesn't seem to work, omitting.
#include "PatternSpiro.h" #include "PatternSpiro.h"
#include "PatternRadar.h" #include "PatternRadar.h"
#include "PatternSwirl.h" #include "PatternSwirl.h"
#include "PatternPendulumWave.h" #include "PatternPendulumWave.h"
#include "PatternFlowField.h" #include "PatternFlowField.h"
#include "PatternIncrementalDrift.h" #include "PatternIncrementalDrift.h"
#include "PatternIncrementalDrift2.h" // Doesn't seem to work, omitting.
#include "PatternMunch.h" #include "PatternMunch.h"
#include "PatternElectricMandala.h" #include "PatternElectricMandala.h"
//#include "PatternSpin.h" // Doesn't seem to work, omitting.
#include "PatternSimplexNoise.h" #include "PatternSimplexNoise.h"
#include "PatternWave.h" #include "PatternWave.h"
#include "PatternAttract.h" #include "PatternAttract.h"
//#include "PatternBounce.h" // Doesn't seem to work, omitting.
#include "PatternFlock.h" #include "PatternFlock.h"
#include "PatternInfinity.h" #include "PatternInfinity.h"
#include "PatternPlasma.h" #include "PatternPlasma.h"
#include "PatternSnake.h" #include "PatternSnake.h"
#include "PatternFire.h" // Not very good. #include "PatternInvaders.h"
//#include "PatternCube.h" // Doesn't seem to work, omitting.
//#include "PatternFire.h" // Doesn't seem to work, omitting.
#include "PatternLife.h" #include "PatternLife.h"
#include "PatternMaze.h" #include "PatternMaze.h"
//#include "PatternPulse.h" // Doesn't seem to work, omitting.
//#include "PatternSpark.h" // Doesn't seem to work, omitting.
#include "PatternSpiral.h" #include "PatternSpiral.h"
class Patterns : public Playlist { class Patterns : public Playlist {
private: private:
PatternFireKoz fireKoz; PatternTest patternTest;
// PatternRainbowFlag rainbowFlag; // doesn't work
// PatternPaletteSmear paletteSmear;
// PatternMultipleStream multipleStream; // doesn't work
// PatternMultipleStream2 multipleStream2; // doesn't work
// PatternMultipleStream3 multipleStream3; // doesn't work
// PatternMultipleStream4 multipleStream4; // doesn't work
// PatternMultipleStream5 multipleStream5; // doesn't work
// PatternMultipleStream8 multipleStream8; // doesn't work
PatternSpiro spiro; PatternSpiro spiro;
// PatternRadar radar;
PatternSwirl swirl; PatternSwirl swirl;
PatternPendulumWave pendulumWave; PatternPendulumWave pendulumWave;
PatternFlowField flowField; PatternFlowField flowField;
PatternIncrementalDrift incrementalDrift; PatternIncrementalDrift incrementalDrift;
PatternIncrementalDrift2 incrementalDrift2;
PatternMunch munch; PatternMunch munch;
PatternElectricMandala electricMandala; PatternElectricMandala electricMandala;
// PatternSpin spin;
PatternSimplexNoise simplexNoise; PatternSimplexNoise simplexNoise;
PatternWave wave; PatternWave wave;
PatternAttract attract; PatternAttract attract;
// PatternBounce bounce;
PatternFlock flock; PatternFlock flock;
PatternInfinity infinity;
PatternPlasma plasma; PatternPlasma plasma;
PatternInvadersSmall invadersSmall;
// PatternInvadersMedium invadersMedium;
// PatternInvadersLarge invadersLarge;
PatternSnake snake; PatternSnake snake;
PatternFire fire; // PatternCube cube;
// PatternFire fire;
PatternLife life; PatternLife life;
PatternMaze maze; PatternMaze maze;
// PatternPulse pulse;
// PatternSpark spark;
PatternSpiral spiral; PatternSpiral spiral;
int currentIndex = 0; int currentIndex = 0;
@ -89,29 +112,49 @@ class Patterns : public Playlist {
return currentIndex; return currentIndex;
} }
const static int PATTERN_COUNT = 18; const static int PATTERN_COUNT = 14;
Drawable* shuffledItems[PATTERN_COUNT]; Drawable* shuffledItems[PATTERN_COUNT];
Drawable* items[PATTERN_COUNT] = { Drawable* items[PATTERN_COUNT] = {
&fireKoz, // added by Kosso // &patternTest, // ok
&spiro, &spiro, // cool
&life, // &paletteSmear, // fail
// &multipleStream, // fail
// &multipleStream8,// fail
// &multipleStream5,// fail
// &multipleStream3,// fail
// &radar, // fail
// &multipleStream4, // fail
// &multipleStream2, // fail
&life, // ok
&flowField, &flowField,
&pendulumWave, &pendulumWave, //11 ok
&incrementalDrift,
&munch, &incrementalDrift, //12 ok
&electricMandala, &incrementalDrift2, // 13 fail
&simplexNoise, &munch, // 14 ok
&wave, // &electricMandala, // 15 ok, but ugly (vortigont)
&attract, // &spin, // 16 ok but repeditivev
&swirl, // &simplexNoise, // 17 - cool!
&flock, // &wave, // 18 ok (can't work with 256+ matrix due to uint8_t vars)
&plasma, // &rainbowFlag, //20 // fail
&snake, &attract, // 21 ok
&fire, // &swirl, // 22 ok, but ugly (vortigont)
&maze, // &bounce, // boncing line crap
&spiral, &flock, // works
&infinity, // works
&plasma, // works
// &invadersSmall, // works ish, but ugly (vortigont)
// &invadersMedium, // fail
// &invadersLarge, // fail
&snake, // ok
// &cube, // works ish
// &fire, // ok ish
&maze, // ok
// &pulse,// fail
// &spark, // same as fire
&spiral, // ok
}; };
public: public:
@ -212,11 +255,6 @@ class Patterns : public Playlist {
Serial.println("}"); Serial.println("}");
} }
int getPatternIndex()
{
return currentIndex;
}
char * getCurrentPatternName() char * getCurrentPatternName()
{ {
return currentItem->name; return currentItem->name;