Components and supplies
Capacitor 100 nF
1N4007 – High Voltage, High Current Rated Diode
Capacitor 1000 µF
WS2812B 8X32 RGB LED MATRIX
Arduino Nano R3
Pushbutton switch 12mm
Resistor 4.75k ohm
Through Hole Resistor, 390 ohm
PCB Stereo RCA Female Plug
Resistor 100k ohm
4x6 cm generic prototype board
Resistor 10k ohm
Tools and machines
3.5 mm Audio Jack Cable to Stereo RCA Connector
Soldering iron (generic)
Project description
Code
FHT Code Version
arduino
1/* 2 Copyright (c) 2020 Janux 3 4 Permission is hereby granted, free of charge, to any person obtaining a copy 5 of this software and associated documentation files (the "Software"), to deal 6 in the Software without restriction, including without limitation the rights 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 copies of the Software, and to permit persons to whom the Software is 9 furnished to do so, subject to the following conditions: 10 The above copyright notice and this permission notice shall be included in all 11 copies or substantial portions of the Software. 12 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 SOFTWARE. 19 20 Based on an original project for the MAX72xx LED matrix and FFT lib made from Shajeeb. 21 Configuration settings section based on work of Ragnar Ranøyen Homb from Norvegian Creation. 22*/ 23 24#define LIN_OUT 1 //FHT linear output magnitude 25#define FHT_N 128 //set SAMPLES for FHT, Must be a power of 2 26#include <FHT.h> 27 28#define xres 32 //Total number of columns in the display, must be <= SAMPLES/2 29#define yres 8 //Total number of rows in the display 30#define ledPIN 6 //out pint to control Leds 31#define NUM_LEDS (xres * yres) //total leds in Matrix 32#include <Adafruit_NeoPixel.h> 33 34#define colorPIN 5 //pin to change ledcolor 35#define brightnessPIN 10 //pin to change brightness 36 37byte displaycolor = 0; //default color value 38byte brightness = 1; //default brightness level 39 40#include <EEPROM.h> 41#define CONFIG_START 32 //Memory start location 42#define CONFIG_VERSION "VER01" //Config version configuration 43 44typedef struct { 45 char version[6]; 46 byte displaycolor; 47 byte brightness; 48} configuration_type; 49 50configuration_type CONFIGURATION = { 51 CONFIG_VERSION, 52 displaycolor, 53 brightness 54}; 55 56byte yvalue; 57int peaks[xres]; 58byte state = HIGH; // the current reading from the input pin 59byte previousState = LOW; // the previous reading from the input pin 60unsigned long lastDebounceTime = 0; // the last time the output pin was toggled 61unsigned long debounceDelay = 100; // the debounce time; increase if the output flickers 62 63byte data_avgs[xres]; //Array for samplig 64 65// Parameter 1 = number of leds in matrix 66// Parameter 2 = pin number 67// Parameter 3 = pixel type flags, add together as needed: 68// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) 69// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) 70// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) 71// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) 72Adafruit_NeoPixel pixel = Adafruit_NeoPixel(NUM_LEDS, ledPIN, NEO_GRB + NEO_KHZ800); 73 74// EQ filter 75byte eq[32] = { 76 60, 65, 70, 75, 80, 85, 90, 95, 77 100, 100, 100, 100, 100, 100, 100, 100, 78 100, 100, 100, 100, 100, 100, 100, 100, 79 115, 125, 140, 160, 185, 200, 200, 200 80}; 81 82bool EQ_ON = true; // set to false to disable eq 83 84//Define 5 set of colors for leds, 0 for single custom color 85byte colors[][8] = { 86 {170, 160, 150, 140, 130, 120, 1, 1}, 87 {1, 5, 10, 15, 20, 25, 90, 90}, 88 {90, 85, 80, 75, 70, 65, 1, 1}, 89 {90, 90, 90, 30, 30, 30, 1, 1}, 90 {170, 160, 150, 140, 130, 120, 110, 0} 91}; 92 93//Define chars for display settings 94byte charBitmap[] = { 95 0x1C, 0x10, 0x10, 0x10, 0x10, 0x1C, 0x08, 0x18, 0x08, 0x08, 0x08, 0x1C, 96 0x0C, 0x12, 0x04, 0x08, 0x10, 0x1E, 0x0C, 0x12, 0x02, 0x06, 0x12, 0x0C, 97 0x10, 0x10, 0x10, 0x14, 0x1E, 0x04, 0x1E, 0x10, 0x1E, 0x02, 0x12, 0x0C, 98 0x1E, 0x10, 0x10, 0x1E, 0x12, 0x1E, 0x1E, 0x02, 0x04, 0x08, 0x08, 0x08, 99 0x0C, 0x12, 0x0C, 0x12, 0x12, 0x0C, 0x1C, 0x12, 0x1C, 0x12, 0x12, 0x1C 100}; 101 102void setup() { 103 104 pixel.begin(); //initialize Led Matrix 105 106 //Begin FFT operations 107 ADCSRA = 0b11100101; // set ADC to free running mode and set pre-scaler to 32 (0xe5) 108 ADMUX = 0b00000000; // use pin A0 and external voltage reference 109 110 // Read config data from EEPROM 111 if (loadConfig()) { 112 displaycolor = CONFIGURATION.displaycolor; 113 brightness = CONFIGURATION.brightness; 114 } 115 116 //Set brightness loaded from EEPROM 117 pixel.setBrightness(brightness * 24 + 8); 118 119 //Show current config on start 120 //change true to false if you don't want this 121 showSettings(3, true); 122} 123 124void loop() { 125 while (1) { // reduces jitter 126 Sampling(); // FHT Library use only one data array 127 RearrangeFHT(); // re-arrange FHT result to match with no. of display columns 128 SendToDisplay(); // send to display according measured value 129 colorChange(); // check if button pressed to change color 130 brightnessChange(); // check if button pressed to change brightness 131 delay(10); // delay to reduce flickering (FHT is too fast :D) 132 } 133} 134 135void Sampling() { 136 for (int i = 0; i < FHT_N; i++) { 137 while (!(ADCSRA & 0x10)); // wait for ADC to complete current conversion ie ADIF bit set 138 ADCSRA = 0b11110101 ; // clear ADIF bit so that ADC can do next operation (0xf5) 139 //ADLAR bit is 0, so the 10 bits of ADC Data registers are right aligned 140 byte m = ADCL; // fetch adc data 141 byte j = ADCH; 142 int value = (j << 8) | m; // form into an int 143 value -= 0x0200; // form into a signed int 144 value <<= 6; // form into a 16b signed int 145 fht_input[i] = value / 8; // copy to fht input array after compressing 146 } 147 // ++ begin FHT data process -+-+--+-+--+-+--+-+--+-+--+-+--+-+- 148 fht_window(); // window the data for better frequency response 149 fht_reorder(); // reorder the data before doing the fht 150 fht_run(); // process the data in the fht 151 fht_mag_lin(); // take the output of the fht 152} 153 154void RearrangeFHT() { 155 // FHT return real value unsing only one array 156 // after fht_mag_lin() calling the samples value are in 157 // the first FHT_N/2 position of the array fht_lin_out[] 158 int step = (FHT_N / 2) / xres; 159 int c = 0; 160 for (int i = 0; i < (FHT_N / 2); i += step) { 161 data_avgs[c] = 0; 162 for (int k = 0 ; k < step ; k++) { 163 data_avgs[c] = data_avgs[c] + fht_lin_out[i + k]; // linear output magnitude 164 } 165 data_avgs[c] = data_avgs[c] / step ; // save avgs value 166 c++; 167 } 168} 169 170void SendToDisplay() { 171 for (int i = 0; i < xres; i++) { 172 if (EQ_ON) 173 data_avgs[i] = data_avgs[i] * (float)(eq[i]) / 100; // apply eq filter 174 data_avgs[i] = constrain(data_avgs[i], 0, 80); // set max & min values for buckets to 0-80 175 data_avgs[i] = map(data_avgs[i], 0, 80, 0, yres); // remap averaged values to yres 0-8 176 yvalue = data_avgs[i]; 177 peaks[i] = peaks[i] - 1; // decay by one light 178 if (yvalue > peaks[i]) peaks[i] = yvalue; // save peak if > previuos peak 179 yvalue = peaks[i]; // pick peak to display 180 setColumn(i, yvalue); // draw columns 181 } 182 pixel.show(); // show column 183} 184 185// Light up leds of x column according to y value 186void setColumn(byte x, byte y) { 187 int led, i; 188 189 for (i = 0; i < yres; i++) { 190 led = GetLedFromMatrix(x, i); //retrieve current led by x,y coordinates 191 if (peaks[x] > i) { 192 193 switch (displaycolor) { 194 case 4: 195 if (colors[displaycolor][i] == 0) { 196 // show custom color with zero value in array 197 pixel.setPixelColor(led, 255, 255, 255); //withe 198 } 199 else { 200 // standard color defined in colors array 201 pixel.setPixelColor(led, Wheel(colors[displaycolor][i])); 202 } 203 break; 204 205 case 5: 206 //change color by column 207 pixel.setPixelColor(led, Wheel(x * 16)); 208 break; 209 210 case 6: 211 //change color by row 212 pixel.setPixelColor(led, Wheel(i * y * 3)); 213 break; 214 215 case 7: 216 //change color by... country :D 217 218 //Italy flagh 219 //if (x < 11) pixel.setPixelColor(led, 0, 255, 0); 220 //if (x > 10 && x < 21) pixel.setPixelColor(led, 255, 255, 255); 221 //if (x > 20) pixel.setPixelColor(led, 255, 0, 0); 222 223 //stars and stripes 224 if (i < yres - 2) { 225 if (x & 0x01) { 226 pixel.setPixelColor(led, 0, 0, 255); 227 } 228 else { 229 pixel.setPixelColor(led, 255, 0, 0); 230 } 231 } 232 else { 233 pixel.setPixelColor(led, 255, 255, 255); 234 } 235 236 break; 237 238 default: 239 //display colors defined in color array 240 pixel.setPixelColor(led, Wheel(colors[displaycolor][i])); 241 } //END SWITCH 242 } 243 else { 244 //Light off leds 245 pixel.setPixelColor(led, pixel.Color(0, 0, 0)); 246 } 247 } 248} 249 250//================================================================ 251// Calculate a led number by x,y coordinates 252// valid for WS2812B with serpentine layout placed in horizzontal 253// and zero led at bottom right (DIN connector on the right side) 254// input value: x= 0 to xres-1 , y= 0 to yres-1 255// return a led number from 0 to NUM_LED 256//================================================================ 257int GetLedFromMatrix(byte x, byte y) { 258 int led; 259 x = xres - x - 1; 260 if (x & 0x01) { 261 //Odd columns increase backwards 262 led = ((x + 1) * yres - y - 1); 263 } 264 else { 265 //Even columns increase normally 266 led = ((x + 1) * yres - yres + y); 267 } 268 return constrain(led, 0, NUM_LEDS); 269} 270//================================================================ 271 272void colorChange() { 273 int reading = digitalRead(colorPIN); 274 if (reading == HIGH && previousState == LOW && millis() - lastDebounceTime > debounceDelay) { 275 displaycolor++; 276 if (displaycolor > 7) displaycolor = 0; 277 showSettings(1, true); //set to false if you don't want this 278 saveConfig(); 279 lastDebounceTime = millis(); 280 } 281 previousState = reading; 282} 283 284void brightnessChange() { 285 int reading = digitalRead(brightnessPIN); 286 if (reading == HIGH && previousState == LOW && millis() - lastDebounceTime > debounceDelay) { 287 brightness++; 288 if (brightness > 7) brightness = 0; 289 pixel.setBrightness(brightness * 24 + 8); 290 showSettings(2, true); //set to false if you don't want this 291 saveConfig(); 292 lastDebounceTime = millis(); 293 } 294 previousState = reading; 295} 296 297// Utility from Adafruit Neopixel demo sketch 298// Input a value 0 to 255 to get a color value. 299// The colours are a transition R - G - B - back to R. 300unsigned long Wheel(byte WheelPos) { 301 WheelPos = 255 - WheelPos; 302 if (WheelPos < 85) { 303 return pixel.Color(255 - WheelPos * 3, 0, WheelPos * 3); 304 } 305 if (WheelPos < 170) { 306 WheelPos -= 85; 307 return pixel.Color(0, WheelPos * 3, 255 - WheelPos * 3); 308 } 309 WheelPos -= 170; 310 return pixel.Color(WheelPos * 3, 255 - WheelPos * 3, 0); 311} 312 313// load whats in EEPROM in to the local CONFIGURATION if it is a valid setting 314int loadConfig() { 315 if (EEPROM.read(CONFIG_START + 0) == CONFIG_VERSION[0] && 316 EEPROM.read(CONFIG_START + 1) == CONFIG_VERSION[1] && 317 EEPROM.read(CONFIG_START + 2) == CONFIG_VERSION[2] && 318 EEPROM.read(CONFIG_START + 3) == CONFIG_VERSION[3] && 319 EEPROM.read(CONFIG_START + 4) == CONFIG_VERSION[4]) { 320 321 // load (overwrite) the local configuration struct 322 for (unsigned int i = 0; i < sizeof(CONFIGURATION); i++) { 323 *((char*)&CONFIGURATION + i) = EEPROM.read(CONFIG_START + i); 324 } 325 return 1; // return 1 if config loaded 326 } 327 return 0; // return 0 if config NOT loaded 328} 329 330// save the CONFIGURATION in to EEPROM 331void saveConfig() { 332 CONFIGURATION.displaycolor = displaycolor; 333 CONFIGURATION.brightness = brightness; 334 for (unsigned int i = 0; i < sizeof(CONFIGURATION); i++) 335 EEPROM.write(CONFIG_START + i, *((char*)&CONFIGURATION + i)); 336} 337 338// 1 display color level, 2 display brightness level, 3 both 339void showSettings(byte num, bool show) { 340 if (show) { 341 pixel.clear(); 342 if (num == 1 || num == 3) { 343 drawChar(0, 0); 344 drawChar(displaycolor + 1, 5); 345 } 346 if (num == 2 || num == 3) { 347 drawChar(9, xres - 9); 348 drawChar(brightness + 1, xres - 4); 349 } 350 delay(1000); 351 pixel.clear(); 352 } 353} 354 355// Draw custom chars 356void drawChar(byte val, byte pos) { 357 for (int x = 4; x >= 0; x--) { 358 for (int y = 5; y >= 0; y--) { 359 if ((charBitmap[val * 6 + 5 - y] >> x) & 0x01) { 360 pixel.setPixelColor(GetLedFromMatrix(4 - x + pos, y + 1), Wheel((pos > 10) * 170)); 361 pixel.show(); 362 } 363 } 364 } 365} 366//by Janux®, Last version on 28/06/2020.
FHT Code Version
arduino
1/* 2 Copyright (c) 2020 Janux 3 4 Permission is hereby granted, free of charge, to any person obtaining a copy 5 of this software and associated documentation files (the "Software"), to deal 6 in the Software without restriction, including without limitation the rights 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 copies of the Software, and to permit persons to whom the Software is 9 furnished to do so, subject to the following conditions: 10 The above copyright notice and this permission notice shall be included in all 11 copies or substantial portions of the Software. 12 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 SOFTWARE. 19 20 Based on an original project for the MAX72xx LED matrix and FFT lib made from Shajeeb. 21 Configuration settings section based on work of Ragnar Ranøyen Homb from Norvegian Creation. 22*/ 23 24#define LIN_OUT 1 //FHT linear output magnitude 25#define FHT_N 128 //set SAMPLES for FHT, Must be a power of 2 26#include <FHT.h> 27 28#define xres 32 //Total number of columns in the display, must be <= SAMPLES/2 29#define yres 8 //Total number of rows in the display 30#define ledPIN 6 //out pint to control Leds 31#define NUM_LEDS (xres * yres) //total leds in Matrix 32#include <Adafruit_NeoPixel.h> 33 34#define colorPIN 5 //pin to change ledcolor 35#define brightnessPIN 10 //pin to change brightness 36 37byte displaycolor = 0; //default color value 38byte brightness = 1; //default brightness level 39 40#include <EEPROM.h> 41#define CONFIG_START 32 //Memory start location 42#define CONFIG_VERSION "VER01" //Config version configuration 43 44typedef struct { 45 char version[6]; 46 byte displaycolor; 47 byte brightness; 48} configuration_type; 49 50configuration_type CONFIGURATION = { 51 CONFIG_VERSION, 52 displaycolor, 53 brightness 54}; 55 56byte yvalue; 57int peaks[xres]; 58byte state = HIGH; // the current reading from the input pin 59byte previousState = LOW; // the previous reading from the input pin 60unsigned long lastDebounceTime = 0; // the last time the output pin was toggled 61unsigned long debounceDelay = 100; // the debounce time; increase if the output flickers 62 63byte data_avgs[xres]; //Array for samplig 64 65// Parameter 1 = number of leds in matrix 66// Parameter 2 = pin number 67// Parameter 3 = pixel type flags, add together as needed: 68// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) 69// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) 70// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) 71// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) 72Adafruit_NeoPixel pixel = Adafruit_NeoPixel(NUM_LEDS, ledPIN, NEO_GRB + NEO_KHZ800); 73 74// EQ filter 75byte eq[32] = { 76 60, 65, 70, 75, 80, 85, 90, 95, 77 100, 100, 100, 100, 100, 100, 100, 100, 78 100, 100, 100, 100, 100, 100, 100, 100, 79 115, 125, 140, 160, 185, 200, 200, 200 80}; 81 82bool EQ_ON = true; // set to false to disable eq 83 84//Define 5 set of colors for leds, 0 for single custom color 85byte colors[][8] = { 86 {170, 160, 150, 140, 130, 120, 1, 1}, 87 {1, 5, 10, 15, 20, 25, 90, 90}, 88 {90, 85, 80, 75, 70, 65, 1, 1}, 89 {90, 90, 90, 30, 30, 30, 1, 1}, 90 {170, 160, 150, 140, 130, 120, 110, 0} 91}; 92 93//Define chars for display settings 94byte charBitmap[] = { 95 0x1C, 0x10, 0x10, 0x10, 0x10, 0x1C, 0x08, 0x18, 0x08, 0x08, 0x08, 0x1C, 96 0x0C, 0x12, 0x04, 0x08, 0x10, 0x1E, 0x0C, 0x12, 0x02, 0x06, 0x12, 0x0C, 97 0x10, 0x10, 0x10, 0x14, 0x1E, 0x04, 0x1E, 0x10, 0x1E, 0x02, 0x12, 0x0C, 98 0x1E, 0x10, 0x10, 0x1E, 0x12, 0x1E, 0x1E, 0x02, 0x04, 0x08, 0x08, 0x08, 99 0x0C, 0x12, 0x0C, 0x12, 0x12, 0x0C, 0x1C, 0x12, 0x1C, 0x12, 0x12, 0x1C 100}; 101 102void setup() { 103 104 pixel.begin(); //initialize Led Matrix 105 106 //Begin FFT operations 107 ADCSRA = 0b11100101; // set ADC to free running mode and set pre-scaler to 32 (0xe5) 108 ADMUX = 0b00000000; // use pin A0 and external voltage reference 109 110 // Read config data from EEPROM 111 if (loadConfig()) { 112 displaycolor = CONFIGURATION.displaycolor; 113 brightness = CONFIGURATION.brightness; 114 } 115 116 //Set brightness loaded from EEPROM 117 pixel.setBrightness(brightness * 24 + 8); 118 119 //Show current config on start 120 //change true to false if you don't want this 121 showSettings(3, true); 122} 123 124void loop() { 125 while (1) { // reduces jitter 126 Sampling(); // FHT Library use only one data array 127 RearrangeFHT(); // re-arrange FHT result to match with no. of display columns 128 SendToDisplay(); // send to display according measured value 129 colorChange(); // check if button pressed to change color 130 brightnessChange(); // check if button pressed to change brightness 131 delay(10); // delay to reduce flickering (FHT is too fast :D) 132 } 133} 134 135void Sampling() { 136 for (int i = 0; i < FHT_N; i++) { 137 while (!(ADCSRA & 0x10)); // wait for ADC to complete current conversion ie ADIF bit set 138 ADCSRA = 0b11110101 ; // clear ADIF bit so that ADC can do next operation (0xf5) 139 //ADLAR bit is 0, so the 10 bits of ADC Data registers are right aligned 140 byte m = ADCL; // fetch adc data 141 byte j = ADCH; 142 int value = (j << 8) | m; // form into an int 143 value -= 0x0200; // form into a signed int 144 value <<= 6; // form into a 16b signed int 145 fht_input[i] = value / 8; // copy to fht input array after compressing 146 } 147 // ++ begin FHT data process -+-+--+-+--+-+--+-+--+-+--+-+--+-+- 148 fht_window(); // window the data for better frequency response 149 fht_reorder(); // reorder the data before doing the fht 150 fht_run(); // process the data in the fht 151 fht_mag_lin(); // take the output of the fht 152} 153 154void RearrangeFHT() { 155 // FHT return real value unsing only one array 156 // after fht_mag_lin() calling the samples value are in 157 // the first FHT_N/2 position of the array fht_lin_out[] 158 int step = (FHT_N / 2) / xres; 159 int c = 0; 160 for (int i = 0; i < (FHT_N / 2); i += step) { 161 data_avgs[c] = 0; 162 for (int k = 0 ; k < step ; k++) { 163 data_avgs[c] = data_avgs[c] + fht_lin_out[i + k]; // linear output magnitude 164 } 165 data_avgs[c] = data_avgs[c] / step ; // save avgs value 166 c++; 167 } 168} 169 170void SendToDisplay() { 171 for (int i = 0; i < xres; i++) { 172 if (EQ_ON) 173 data_avgs[i] = data_avgs[i] * (float)(eq[i]) / 100; // apply eq filter 174 data_avgs[i] = constrain(data_avgs[i], 0, 80); // set max & min values for buckets to 0-80 175 data_avgs[i] = map(data_avgs[i], 0, 80, 0, yres); // remap averaged values to yres 0-8 176 yvalue = data_avgs[i]; 177 peaks[i] = peaks[i] - 1; // decay by one light 178 if (yvalue > peaks[i]) peaks[i] = yvalue; // save peak if > previuos peak 179 yvalue = peaks[i]; // pick peak to display 180 setColumn(i, yvalue); // draw columns 181 } 182 pixel.show(); // show column 183} 184 185// Light up leds of x column according to y value 186void setColumn(byte x, byte y) { 187 int led, i; 188 189 for (i = 0; i < yres; i++) { 190 led = GetLedFromMatrix(x, i); //retrieve current led by x,y coordinates 191 if (peaks[x] > i) { 192 193 switch (displaycolor) { 194 case 4: 195 if (colors[displaycolor][i] == 0) { 196 // show custom color with zero value in array 197 pixel.setPixelColor(led, 255, 255, 255); //withe 198 } 199 else { 200 // standard color defined in colors array 201 pixel.setPixelColor(led, Wheel(colors[displaycolor][i])); 202 } 203 break; 204 205 case 5: 206 //change color by column 207 pixel.setPixelColor(led, Wheel(x * 16)); 208 break; 209 210 case 6: 211 //change color by row 212 pixel.setPixelColor(led, Wheel(i * y * 3)); 213 break; 214 215 case 7: 216 //change color by... country :D 217 218 //Italy flagh 219 //if (x < 11) pixel.setPixelColor(led, 0, 255, 0); 220 //if (x > 10 && x < 21) pixel.setPixelColor(led, 255, 255, 255); 221 //if (x > 20) pixel.setPixelColor(led, 255, 0, 0); 222 223 //stars and stripes 224 if (i < yres - 2) { 225 if (x & 0x01) { 226 pixel.setPixelColor(led, 0, 0, 255); 227 } 228 else { 229 pixel.setPixelColor(led, 255, 0, 0); 230 } 231 } 232 else { 233 pixel.setPixelColor(led, 255, 255, 255); 234 } 235 236 break; 237 238 default: 239 //display colors defined in color array 240 pixel.setPixelColor(led, Wheel(colors[displaycolor][i])); 241 } //END SWITCH 242 } 243 else { 244 //Light off leds 245 pixel.setPixelColor(led, pixel.Color(0, 0, 0)); 246 } 247 } 248} 249 250//================================================================ 251// Calculate a led number by x,y coordinates 252// valid for WS2812B with serpentine layout placed in horizzontal 253// and zero led at bottom right (DIN connector on the right side) 254// input value: x= 0 to xres-1 , y= 0 to yres-1 255// return a led number from 0 to NUM_LED 256//================================================================ 257int GetLedFromMatrix(byte x, byte y) { 258 int led; 259 x = xres - x - 1; 260 if (x & 0x01) { 261 //Odd columns increase backwards 262 led = ((x + 1) * yres - y - 1); 263 } 264 else { 265 //Even columns increase normally 266 led = ((x + 1) * yres - yres + y); 267 } 268 return constrain(led, 0, NUM_LEDS); 269} 270//================================================================ 271 272void colorChange() { 273 int reading = digitalRead(colorPIN); 274 if (reading == HIGH && previousState == LOW && millis() - lastDebounceTime > debounceDelay) { 275 displaycolor++; 276 if (displaycolor > 7) displaycolor = 0; 277 showSettings(1, true); //set to false if you don't want this 278 saveConfig(); 279 lastDebounceTime = millis(); 280 } 281 previousState = reading; 282} 283 284void brightnessChange() { 285 int reading = digitalRead(brightnessPIN); 286 if (reading == HIGH && previousState == LOW && millis() - lastDebounceTime > debounceDelay) { 287 brightness++; 288 if (brightness > 7) brightness = 0; 289 pixel.setBrightness(brightness * 24 + 8); 290 showSettings(2, true); //set to false if you don't want this 291 saveConfig(); 292 lastDebounceTime = millis(); 293 } 294 previousState = reading; 295} 296 297// Utility from Adafruit Neopixel demo sketch 298// Input a value 0 to 255 to get a color value. 299// The colours are a transition R - G - B - back to R. 300unsigned long Wheel(byte WheelPos) { 301 WheelPos = 255 - WheelPos; 302 if (WheelPos < 85) { 303 return pixel.Color(255 - WheelPos * 3, 0, WheelPos * 3); 304 } 305 if (WheelPos < 170) { 306 WheelPos -= 85; 307 return pixel.Color(0, WheelPos * 3, 255 - WheelPos * 3); 308 } 309 WheelPos -= 170; 310 return pixel.Color(WheelPos * 3, 255 - WheelPos * 3, 0); 311} 312 313// load whats in EEPROM in to the local CONFIGURATION if it is a valid setting 314int loadConfig() { 315 if (EEPROM.read(CONFIG_START + 0) == CONFIG_VERSION[0] && 316 EEPROM.read(CONFIG_START + 1) == CONFIG_VERSION[1] && 317 EEPROM.read(CONFIG_START + 2) == CONFIG_VERSION[2] && 318 EEPROM.read(CONFIG_START + 3) == CONFIG_VERSION[3] && 319 EEPROM.read(CONFIG_START + 4) == CONFIG_VERSION[4]) { 320 321 // load (overwrite) the local configuration struct 322 for (unsigned int i = 0; i < sizeof(CONFIGURATION); i++) { 323 *((char*)&CONFIGURATION + i) = EEPROM.read(CONFIG_START + i); 324 } 325 return 1; // return 1 if config loaded 326 } 327 return 0; // return 0 if config NOT loaded 328} 329 330// save the CONFIGURATION in to EEPROM 331void saveConfig() { 332 CONFIGURATION.displaycolor = displaycolor; 333 CONFIGURATION.brightness = brightness; 334 for (unsigned int i = 0; i < sizeof(CONFIGURATION); i++) 335 EEPROM.write(CONFIG_START + i, *((char*)&CONFIGURATION + i)); 336} 337 338// 1 display color level, 2 display brightness level, 3 both 339void showSettings(byte num, bool show) { 340 if (show) { 341 pixel.clear(); 342 if (num == 1 || num == 3) { 343 drawChar(0, 0); 344 drawChar(displaycolor + 1, 5); 345 } 346 if (num == 2 || num == 3) { 347 drawChar(9, xres - 9); 348 drawChar(brightness + 1, xres - 4); 349 } 350 delay(1000); 351 pixel.clear(); 352 } 353} 354 355// Draw custom chars 356void drawChar(byte val, byte pos) { 357 for (int x = 4; x >= 0; x--) { 358 for (int y = 5; y >= 0; y--) { 359 if ((charBitmap[val * 6 + 5 - y] >> x) & 0x01) { 360 pixel.setPixelColor(GetLedFromMatrix(4 - x + pos, y + 1), Wheel((pos > 10) * 170)); 361 pixel.show(); 362 } 363 } 364 } 365} 366//by Janux®, Last version on 28/06/2020.
Downloadable files
Breadboard
Breadboard
Schematic
Schematic
Breadboard
Breadboard
Comments
Only logged in users can leave comments
janux
0 Followers
•0 Projects
Table of contents
Intro
15
0