Sorry mechanical not electrical engineer but this is the schematic,
also shown the UNO with the code running.
// https://macetech.github.io/FastLED-XY-Map-Generator/ irregular Matrix code
// Irregular Matrix code by Garrett Mace (macetech.com), inspired by Mark Kriegsman
// original code Scott Marley https://github.com/s-marley/LEDMask
// Scott Video https://www.youtube.com/watch?v=zYZkbfmCuEY
// Removed Microphone / sound programming with // but left code in v1
#include <FastLED.h>
#include <EEPROM.h>
#include <JC_Button.h>
#define LED_PIN 6 // Output pin for LEDs [5]
#define MODE_PIN 3 // Input pin for button to change mode [3]
#define PLUS_PIN 2 // Input pin for plus button [2]
#define MINUS_PIN 4 // Input pin for minus button [4]
//#define MIC_PIN A6 // Input pin for microphone [A6]
#define COLOR_ORDER GRB // Color order of LED string [GRB]
#define CHIPSET WS2812B // LED string type [WS2182B]
#define BRIGHTNESS 50 // Overall brightness [50]
#define LAST_VISIBLE_LED 895 // Last LED that's visible [895]
#define MAX_MILLIAMPS 2000 // Max current in mA to draw from supply [Changed to 2000 in v1]
#define SAMPLE_WINDOW 100 // How many ms to sample audio for [100]
#define DEBOUNCE_MS 20 // Number of ms to debounce the button [20]
#define LONG_PRESS 500 // Number of ms to hold the button to count as long press [500]
#define PATTERN_TIME 10 // Seconds to show each pattern on autoChange [10]
#define kMatrixWidth 43 // Matrix width [43 columns]
#define kMatrixHeight 24 // Matrix height [24 pixel max height]
#define NUM_LEDS (kMatrixWidth * kMatrixHeight) // Total number of Leds
#define MAX_DIMENSION ((kMatrixWidth>kMatrixHeight) ? kMatrixWidth : kMatrixHeight) // Largest dimension of matrix 43 wide in v1
CRGB leds[ NUM_LEDS ];
uint8_t brightness = BRIGHTNESS;
uint8_t soundSensitivity = 10;
// Used to check RAM availability. Usage: Serial.println(freeRam());
//int freeRam () {
// extern int __heap_start, *__brkval;
// int v;
// return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
//}
// Button stuff
uint8_t buttonPushCounter = 9; // Was 10 but removed 1 for sound.h not in v1
uint8_t state = 0;
bool autoChangeVisuals = true; // this should mean only button press changes pattern
Button modeBtn(MODE_PIN, DEBOUNCE_MS);
Button plusBtn(PLUS_PIN, DEBOUNCE_MS);
Button minusBtn(MINUS_PIN, DEBOUNCE_MS);
void incrementButtonPushCounter() {
buttonPushCounter = (buttonPushCounter + 1) %11;
EEPROM.write(1, buttonPushCounter);
}
// Include various patterns
#include "Rainbow.h"
#include "Fire.h"
#include "Squares.h"
#include "Circles.h"
#include "Plasma.h"
#include "Matrix.h"
#include "CrossHatch.h"
#include "Drops.h"
#include "Noise.h"
#include "Snake.h"
// Helper to map XY coordinates to irregular matrix
uint16_t XY( uint8_t x, uint8_t y)
{
// any out of bounds address maps to the first hidden pixel
// Vertical serpentine matrix 43 columns max height 24 used for coat
if( (x >= kMatrixWidth) || (y >= kMatrixHeight) ) {
return (LAST_VISIBLE_LED + 1);
}
const uint16_t XYTable[] = {
896, 897, 898, 899, 900, 138, 139, 906, 907, 921, 214, 247, 248, 950, 951, 963, 316, 363, 364, 411, 412, 459, 460, 507, 508, 555, 556, 969, 970, 984, 631, 664, 665,1013,1014,1026, 733, 780,1027,1028,1029,1030,1031,
0, 45, 46, 91, 92, 137, 140, 905, 908, 213, 215, 246, 249, 280, 952, 962, 317, 362, 365, 410, 413, 458, 461, 506, 509, 554, 557, 968, 971, 630, 632, 663, 666, 697,1015,1025, 734, 779, 781, 826, 827, 872, 873,
1, 44, 47, 90, 93, 136, 141, 904, 909, 212, 216, 245, 250, 279, 953, 961, 318, 361, 366, 409, 414, 457, 462, 505, 510, 553, 558, 967, 972, 629, 633, 662, 667, 696,1016,1024, 735, 778, 782, 825, 828, 871, 874,
2, 43, 48, 89, 94, 135, 142, 903, 910, 211, 217, 244, 251, 278, 954, 960, 319, 360, 367, 408, 415, 456, 463, 504, 511, 552, 559, 966, 973, 628, 634, 661, 668, 695,1017,1023, 736, 777, 783, 824, 829, 870, 875,
3, 42, 49, 88, 95, 134, 143, 902, 911, 210, 218, 243, 252, 277, 955, 959, 320, 359, 368, 407, 416, 455, 464, 503, 512, 551, 560, 965, 974, 627, 635, 660, 669, 694,1018,1022, 737, 776, 784, 823, 830, 869, 876,
4, 41, 50, 87, 96, 133, 144, 901, 912, 209, 219, 242, 253, 276, 956, 958, 321, 358, 369, 406, 417, 454, 465, 502, 513, 550, 561, 964, 975, 626, 636, 659, 670, 693,1019,1021, 738, 775, 785, 822, 831, 868, 877,
5, 40, 51, 86, 97, 132, 145, 180, 913, 208, 220, 241, 254, 275, 957, 315, 322, 357, 370, 405, 418, 453, 466, 501, 514, 549, 562, 597, 976, 625, 637, 658, 671, 692,1020, 732, 739, 774, 786, 821, 832, 867, 878,
6, 39, 52, 85, 98, 131, 146, 179, 181, 207, 221, 240, 255, 274, 281, 314, 323, 356, 371, 404, 419, 452, 467, 500, 515, 548, 563, 596, 598, 624, 638, 657, 672, 691, 698, 731, 740, 773, 787, 820, 833, 866, 879,
7, 38, 53, 84, 99, 130, 147, 178, 182, 206, 222, 239, 256, 273, 282, 313, 324, 355, 372, 403, 420, 451, 468, 499, 516, 547, 564, 595, 599, 623, 639, 656, 673, 690, 699, 730, 741, 772, 788, 819, 834, 865, 880,
8, 37, 54, 83, 100, 129, 148, 177, 183, 205, 223, 238, 257, 272, 283, 312, 325, 354, 373, 402, 421, 450, 469, 498, 517, 546, 565, 594, 600, 622, 640, 655, 674, 689, 700, 729, 742, 771, 789, 818, 835, 864, 881,
9, 36, 55, 82, 101, 128, 149, 176, 184, 204, 224, 237, 258, 271, 284, 311, 326, 353, 374, 401, 422, 449, 470, 497, 518, 545, 566, 593, 601, 621, 641, 654, 675, 688, 701, 728, 743, 770, 790, 817, 836, 863, 882,
10, 35, 56, 81, 102, 127, 150, 175, 185, 203, 225, 236, 259, 270, 285, 310, 327, 352, 375, 400, 423, 448, 471, 496, 519, 544, 567, 592, 602, 620, 642, 653, 676, 687, 702, 727, 744, 769, 791, 816, 837, 862, 883,
11, 34, 57, 80, 103, 126, 151, 174, 186, 202, 226, 235, 260, 269, 286, 309, 328, 351, 376, 399, 424, 447, 472, 495, 520, 543, 568, 591, 603, 619, 643, 652, 677, 686, 703, 726, 745, 768, 792, 815, 838, 861, 884,
12, 33, 58, 79, 104, 125, 152, 173, 187, 201, 227, 234, 261, 268, 287, 308, 329, 350, 377, 398, 425, 446, 473, 494, 521, 542, 569, 590, 604, 618, 644, 651, 678, 685, 704, 725, 746, 767, 793, 814, 839, 860, 885,
13, 32, 59, 78, 105, 124, 153, 172, 188, 200, 228, 233, 262, 267, 288, 307, 330, 349, 378, 397, 426, 445, 474, 493, 522, 541, 570, 589, 605, 617, 645, 650, 679, 684, 705, 724, 747, 766, 794, 813, 840, 859, 886,
14, 31, 60, 77, 106, 123, 154, 171, 189, 199, 229, 232, 263, 266, 289, 306, 331, 348, 379, 396, 427, 444, 475, 492, 523, 540, 571, 588, 606, 616, 646, 649, 680, 683, 706, 723, 748, 765, 795, 812, 841, 858, 887,
15, 30, 61, 76, 107, 122, 155, 170, 190, 198, 230, 231, 264, 265, 290, 305, 332, 347, 380, 395, 428, 443, 476, 491, 524, 539, 572, 587, 607, 615, 647, 648, 681, 682, 707, 722, 749, 764, 796, 811, 842, 857, 888,
16, 29, 62, 75, 108, 121, 156, 169, 191, 920, 922, 935, 936, 949, 291, 304, 333, 346, 381, 394, 429, 442, 477, 490, 525, 538, 573, 586, 608, 983, 985, 998, 999,1012, 708, 721, 750, 763, 797, 810, 843, 856, 889,
17, 28, 63, 74, 109, 120, 157, 168, 192, 919, 923, 934, 937, 948, 292, 303, 334, 345, 382, 393, 430, 441, 478, 489, 526, 537, 574, 585, 609, 982, 986, 997,1000,1011, 709, 720, 751, 762, 798, 809, 844, 855, 890,
18, 27, 64, 73, 110, 119, 158, 167, 193, 918, 924, 933, 938, 947, 293, 302, 335, 344, 383, 392, 431, 440, 479, 488, 527, 536, 575, 584, 610, 981, 987, 996,1001,1010, 710, 719, 752, 761, 799, 808, 845, 854, 891,
19, 26, 65, 72, 111, 118, 159, 166, 194, 917, 925, 932, 939, 946, 294, 301, 336, 343, 384, 391, 432, 439, 480, 487, 528, 535, 576, 583, 611, 980, 988, 995,1002,1009, 711, 718, 753, 760, 800, 807, 846, 853, 892,
20, 25, 66, 71, 112, 117, 160, 165, 195, 916, 926, 931, 940, 945, 295, 300, 337, 342, 385, 390, 433, 438, 481, 486, 529, 534, 577, 582, 612, 979, 989, 994,1003,1008, 712, 717, 754, 759, 801, 806, 847, 852, 893,
21, 24, 67, 70, 113, 116, 161, 164, 196, 915, 927, 930, 941, 944, 296, 299, 338, 341, 386, 389, 434, 437, 482, 485, 530, 533, 578, 581, 613, 978, 990, 993,1004,1007, 713, 716, 755, 758, 802, 805, 848, 851, 894,
22, 23, 68, 69, 114, 115, 162, 163, 197, 914, 928, 929, 942, 943, 297, 298, 339, 340, 387, 388, 435, 436, 483, 484, 531, 532, 579, 580, 614, 977, 991, 992,1005,1006, 714, 715, 756, 757, 803, 804, 849, 850, 895
};
uint8_t i = (y * kMatrixWidth) + x;
uint8_t j = XYTable[i];
return j;
}
void setup() {
FastLED.addLeds < CHIPSET, LED_PIN, COLOR_ORDER > (leds, NUM_LEDS).setCorrection(TypicalSMD5050);
FastLED.setBrightness(brightness);
FastLED.clear(true);
//Upload this sketch once, then uncomment the line below and upload again.
// This ensures the EEPROM value is set correctly.
// buttonPushCounter = (int)EEPROM.read(1); // load previous setting
modeBtn.begin();
plusBtn.begin();
minusBtn.begin();
buttonPushCounter = (int)EEPROM.read(1); // load previous setting
Serial.begin(57600);
Serial.print(F("Starting pattern "));
Serial.println(buttonPushCounter);
}
void checkBrightnessButton() {
// On all none-sound reactive patterns, plus and minus control the brightness
plusBtn.read();
minusBtn.read();
if (plusBtn.wasReleased()) {
brightness += 10; // changed to + 10 incriments from 20
FastLED.setBrightness(brightness);
}
if (minusBtn.wasReleased()) {
brightness -= 10; // changed to - 10 incriments from -20
FastLED.setBrightness(brightness);
}
}
void checkSoundLevelButton(){
// On all sound reactive patterns, plus and minus control the sound sensitivity
plusBtn.read();
minusBtn.read();
if (plusBtn.wasReleased()) {
// Increase sound sensitivity
soundSensitivity -= 1;
if (soundSensitivity == 0) soundSensitivity = 1;
}
if (minusBtn.wasReleased()) {
// Decrease sound sensitivity
soundSensitivity += 1;
}
}
bool checkModeButton() {
modeBtn.read();
switch (state) {
case 0:
if (modeBtn.wasReleased()) {
incrementButtonPushCounter();
Serial.print(F("Short press, pattern "));
Serial.println(buttonPushCounter);
autoChangeVisuals = false;
return true;
}
else if (modeBtn.pressedFor(LONG_PRESS)) {
state = 1;
return true;
}
break;
case 1:
if (modeBtn.wasReleased()) {
state = 0;
Serial.print(F("Long press, auto, pattern "));
Serial.println(buttonPushCounter);
autoChangeVisuals = true;
return true;
}
break;
}
if(autoChangeVisuals){
EVERY_N_SECONDS(PATTERN_TIME) {
incrementButtonPushCounter();
Serial.print("Auto, pattern ");
Serial.println(buttonPushCounter);
return true;
}
}
return false;
}
// Functions to run patterns. Done this way so each class stays in scope only while
// it is active, freeing up RAM once it is changed.
//void runSound(){ // edited out sound in v1
// bool isRunning = true;
// Sound sound = Sound();
// while(isRunning) isRunning = sound.runPattern();
//}
void runRainbow(){
bool isRunning = true;
Rainbow rainbow = Rainbow();
while(isRunning) isRunning = rainbow.runPattern();
}
void runFire(){
bool isRunning = true;
Fire fire = Fire();
while(isRunning) isRunning = fire.runPattern();
}
void runSquares(){
bool isRunning = true;
Squares squares = Squares();
while(isRunning) isRunning = squares.runPattern();
}
void runCircles(){
bool isRunning = true;
Circles circles = Circles();
while(isRunning) isRunning = circles.runPattern();
}
void runPlasma(){
bool isRunning = true;
Plasma plasma = Plasma();
while(isRunning) isRunning = plasma.runPattern();
}
void runMatrix(){
bool isRunning = true;
Matrix matrix = Matrix();
while(isRunning) isRunning = matrix.runPattern();
}
void runCrossHatch(){
bool isRunning = true;
CrossHatch crossHatch = CrossHatch();
while(isRunning) isRunning = crossHatch.runPattern();
}
void runDrops(){
bool isRunning = true;
Drops drops = Drops();
while(isRunning) isRunning = drops.runPattern();
}
void runNoise(){
bool isRunning = true;
Noise noise = Noise();
while(isRunning) {
isRunning = noise.runPattern();
}
}
void runSnake(){
bool isRunning = true;
Snake snake = Snake();
while(isRunning) {
isRunning = snake.runPattern();
}
}
// Run selected pattern
void loop() {
switch (buttonPushCounter) {
case 0:
runSnake();
break;
case 1:
runRainbow();
break;
case 2:
runFire();
break;
case 3:
runSquares();
break;
case 4:
runCircles();
break;
case 5:
runPlasma();
break;
case 6:
runMatrix();
break;
case 7:
runCrossHatch();
break;
case 8:
runDrops();
break;
case 9:
runNoise();
break;
}
}