utils.h
1 // SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries 2 // 3 // SPDX-License-Identifier: MIT 4 5 // Assorted useful functions and variables 6 7 // Global variables 8 boolean effectInit = false; // indicates if a pattern has been recently switched 9 uint16_t effectDelay = 0; // time between automatic effect changes 10 unsigned long effectMillis = 0; // store the time of last effect function run 11 unsigned long cycleMillis = 0; // store the time of last effect change 12 unsigned long currentMillis; // store current loop's millis value 13 unsigned long hueMillis; // store time of last hue change 14 byte currentEffect = 0; // index to the currently running effect 15 boolean autoCycle = true; // flag for automatic effect changes 16 byte currentBrightness = STARTBRIGHTNESS; // 0-255 will be scaled to 0-MAXBRIGHTNESS 17 18 19 // Setup information for the NoisePlusPalette noiseplay example 20 #define MAX_DIMENSION ((kMatrixWidth>kMatrixHeight) ? kMatrixWidth : kMatrixHeight) 21 uint16_t speed = 5; 22 uint16_t scale = 30; 23 uint8_t noise[MAX_DIMENSION][MAX_DIMENSION]; 24 25 // The 16 bit version of our coordinates 26 static uint16_t x; 27 static uint16_t y; 28 static uint16_t z; 29 uint8_t colorLoop = 1; 30 31 32 CRGBPalette16 currentPalette(RainbowColors_p); // global palette storage 33 34 typedef void (*functionList)(); // definition for list of effect function pointers 35 extern const byte numEffects; 36 37 // Increment the global hue value for functions that use it 38 byte cycleHue = 0; 39 byte cycleHueCount = 0; 40 void hueCycle(byte incr) { 41 cycleHueCount = 0; 42 cycleHue+=incr; 43 } 44 45 // Set every LED in the array to a specified color 46 void fillAll(CRGB fillColor) { 47 for (byte i = 0; i < NUM_LEDS; i++) { 48 leds[i] = fillColor; 49 } 50 } 51 52 // Fade every LED in the array by a specified amount 53 void fadeAll(byte fadeIncr) { 54 for (byte i = 0; i < NUM_LEDS; i++) { 55 leds[i] = leds[i].fadeToBlackBy(fadeIncr); 56 } 57 } 58 59 // Shift all pixels by one, right or left (0 or 1) 60 void scrollArray(byte scrollDir) { 61 62 byte scrollX = 0; 63 for (byte x = 1; x < kMatrixWidth; x++) { 64 if (scrollDir == 0) { 65 scrollX = kMatrixWidth - x; 66 } else if (scrollDir == 1) { 67 scrollX = x - 1; 68 } 69 70 for (byte y = 0; y < kMatrixHeight; y++) { 71 leds[XY(scrollX,y)] = leds[XY(scrollX + scrollDir*2 - 1,y)]; 72 } 73 } 74 75 } 76 77 78 // Pick a random palette from a list 79 void selectRandomPalette() { 80 81 switch(random8(8)) { 82 case 0: 83 currentPalette = CloudColors_p; 84 break; 85 86 case 1: 87 currentPalette = LavaColors_p; 88 break; 89 90 case 2: 91 currentPalette = OceanColors_p; 92 break; 93 94 case 4: 95 currentPalette = ForestColors_p; 96 break; 97 98 case 5: 99 currentPalette = RainbowColors_p; 100 break; 101 102 case 6: 103 currentPalette = PartyColors_p; 104 break; 105 106 case 7: 107 currentPalette = HeatColors_p; 108 break; 109 } 110 111 } 112 113 // Fill the x/y array of 8-bit noise values using the inoise8 function. 114 void fillnoise8() { 115 // If we're runing at a low "speed", some 8-bit artifacts become visible 116 // from frame-to-frame. In order to reduce this, we can do some fast data-smoothing. 117 // The amount of data smoothing we're doing depends on "speed". 118 uint8_t dataSmoothing = 0; 119 if( speed < 50) { 120 dataSmoothing = 200 - (speed * 4); 121 } 122 123 for(int i = 0; i < MAX_DIMENSION; i++) { 124 int ioffset = scale * i; 125 for(int j = 0; j < MAX_DIMENSION; j++) { 126 int joffset = scale * j; 127 128 uint8_t data = inoise8(x + ioffset,y + joffset,z); 129 130 // The range of the inoise8 function is roughly 16-238. 131 // These two operations expand those values out to roughly 0..255 132 // You can comment them out if you want the raw noise data. 133 data = qsub8(data,16); 134 data = qadd8(data,scale8(data,39)); 135 136 if( dataSmoothing ) { 137 uint8_t olddata = noise[i][j]; 138 uint8_t newdata = scale8( olddata, dataSmoothing) + scale8( data, 256 - dataSmoothing); 139 data = newdata; 140 } 141 142 noise[i][j] = data; 143 } 144 } 145 146 z += speed; 147 148 // apply slow drift to X and Y, just for visual variation. 149 x += speed / 8; 150 y -= speed / 16; 151 } 152 153 void mapNoiseToLEDsUsingPalette() 154 { 155 static uint8_t ihue=0; 156 157 for(int i = 0; i < kMatrixWidth; i++) { 158 for(int j = 0; j < kMatrixHeight; j++) { 159 // We use the value at the (i,j) coordinate in the noise 160 // array for our brightness, and the flipped value from (j,i) 161 // for our pixel's index into the color palette. 162 163 uint8_t index = noise[j][i]; 164 uint8_t bri = noise[i][j]; 165 166 // if this palette is a 'loop', add a slowly-changing base value 167 if( colorLoop) { 168 index += ihue; 169 } 170 171 // brighten up, as the color palette itself often contains the 172 // light/dark dynamic range desired 173 if( bri > 127 ) { 174 bri = 255; 175 } else { 176 bri = dim8_raw( bri * 2); 177 } 178 179 CRGB color = ColorFromPalette( currentPalette, index, bri); 180 leds[XY(i,j)] = color; 181 } 182 } 183 184 ihue+=1; 185 }