└── LED_Wall_main.ino /LED_Wall_main.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define SAMPLES 8 // Must be a power of 2 5 | #define LED_PIN 8 // Data pin to LEDS 6 | #define NUM_LEDS 384 7 | #define BRIGHTNESS 255 // from 0 to 255 8 | #define LED_TYPE WS2811 9 | #define COLOR_ORDER GRB 10 | 11 | #define ROWS 8 12 | #define COLS 8 13 | 14 | #define NUM_MODES 6 15 | 16 | int values[ROWS][COLS]; // 2D array to keep track of the current color of each tile 17 | int mem_values[ROWS][COLS]; // 2D array to keep track Memory Colors 18 | int brightness[ROWS][COLS]; // 2D array to keep track of the current brightness of each tile 19 | 20 | bool escape; 21 | 22 | //-----------------------------Button Set Up----------------------------------------- 23 | const byte rows = 8; 24 | const byte cols = 8; 25 | char keys[rows][cols] = { 26 | {1,2,3,4,5,6,7,8}, 27 | {11,12,13,14,15,16,17,18}, 28 | {21,22,23,24,25,26,27,28}, 29 | {31,32,33,34,35,36,37,38}, 30 | {41,42,43,44,45,46,47,48}, 31 | {51,52,53,54,55,56,57,58}, 32 | {61,62,63,64,65,66,67,68}, 33 | {71,72,73,74,75,76,77,78} 34 | }; 35 | byte rowPins[rows] = {10,9,2,3,4,5,6,7}; //connect to the row pinouts of the keypad 36 | byte colPins[cols] = {38,40,42,44,46,48,50,52}; //connect to the column pinouts of the keypad 37 | Keypad buttons = Keypad( makeKeymap(keys), rowPins, colPins, rows, cols ); 38 | //----------------------------------------------------------------------------------- 39 | 40 | CRGB leds[NUM_LEDS]; // Create LED Object 41 | 42 | int mode = 1; // Start on the first mode 43 | 44 | CRGBPalette16 currentPalette; // Used for christmas mode 45 | 46 | void setup(){ 47 | Serial.begin(9600); 48 | delay(1000); // power-up safety delay 49 | FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip ); 50 | FastLED.setBrightness( BRIGHTNESS ); 51 | 52 | buttons.setHoldTime(500); // require a .5 second hold to change modes 53 | randomSeed(analogRead(0)); //Seed Random 54 | clear_display(); //Make sure the display is blank 55 | } 56 | 57 | void loop(){ 58 | /* --------Light tiles one at a time (testing)----------- 59 | for(int i = 0; i < ROWS; i++){ 60 | for(int j = 0; j < COLS; j++){ 61 | light_tile(i, j, 0, 255); 62 | FastLED.show(); 63 | delay(10); 64 | light_tile(i, j, 256, 0); 65 | } 66 | } 67 | -------------------------------------------------------*/ 68 | 69 | /* //---------Light tile when pressed (testing)------------ 70 | int location = buttons.getKey(); 71 | if (location){ 72 | light_tile(location/10, (location%10)-1, 0, 255); 73 | FastLED.show(); 74 | delay(100); 75 | } 76 | // else 77 | //clear_display(); 78 | // -------------------------------------------------------*/ 79 | 80 | //--------------- Actual Code --------------------------- 81 | 82 | print_menu(); 83 | int location = buttons.getKey(); 84 | mode = buttons.waitForKey(); 85 | switch(mode){ 86 | case 1: 87 | Serial.println("1"); 88 | rainbowColors(); 89 | break; 90 | case 2: 91 | Serial.println("2"); 92 | paint(); 93 | break; 94 | case 3: 95 | Serial.println("3"); 96 | Memory(); 97 | break; 98 | case 4: 99 | Serial.println("4"); 100 | tic(); 101 | break; 102 | case 5: 103 | Serial.println("5"); 104 | filler(); 105 | break; 106 | case 6: 107 | Serial.println("5"); 108 | retro(); 109 | break; 110 | } 111 | //-------------------------------------------------------*/ 112 | } 113 | 114 | //----------------------------------------------------------------------------------- 115 | void light_tile(int row, int col, int color, int bright){ 116 | if (color == 256) 117 | bright = 0; 118 | for(int i=23; i >= 21; i--){ 119 | leds[i - 3*row + 48*col]= CHSV( color, 255, bright); 120 | } 121 | for(int i=24; i <= 26; i++){ 122 | leds[i + 3*row + 48*col]= CHSV( color, 255, bright); 123 | } 124 | values[row][col] = color; 125 | brightness[row][col] = bright; 126 | } 127 | 128 | void clear_display(){ 129 | for(int i = 0; i < ROWS; i++){ 130 | for(int j = 0; j < COLS; j++){ 131 | light_tile(i, j, 256, 0); 132 | values[i][j] = 256; 133 | } 134 | } 135 | FastLED.show(); 136 | } 137 | //----------------------------------------------------------------------------------- 138 | 139 | //----------------------------------------------------------------------------------- 140 | void print_menu(){ 141 | clear_display(); 142 | int color = 0; 143 | for(int i = 1; i <= NUM_MODES; i++){ 144 | light_tile(0, i-1, color, 255); 145 | color += 32; 146 | } 147 | FastLED.show(); 148 | } 149 | //----------------------------------------------------------------------------------- 150 | 151 | //----------------------------------------------------------------------------------- 152 | void rainbowColors(){ 153 | clear_display(); 154 | int bow = 0; 155 | int brt = 255; 156 | for(int i = 0; i < ROWS; i++){ 157 | for(int j = 0; j < COLS; j++){ 158 | light_tile(i, j, bow, brt); 159 | bow += 32; 160 | if(bow > 255) 161 | bow = 0; 162 | } 163 | bow += 32; 164 | if(bow > 255) 165 | bow = 0; 166 | } 167 | FastLED.show(); 168 | bool tap = 1; 169 | while(tap){ 170 | int location = buttons.getKey(); 171 | if (location) 172 | brt -= 50; 173 | if (brt < 100) 174 | brt = 255; 175 | for(int i = 0; i < ROWS; i++){ 176 | for(int j = 0; j < COLS; j++){ 177 | int clr = values[i][j] + 1; 178 | if (clr > 255) 179 | clr = 0; 180 | light_tile(i, j, clr, brt); 181 | if (buttons.getState() == HOLD) 182 | tap = 0; 183 | } 184 | } 185 | FastLED.show(); 186 | } 187 | } 188 | //----------------------------------------------------------------------------------- 189 | 190 | //----------------------------------------------------------------------------------- 191 | void paint(){ 192 | clear_display(); 193 | bool tap = 1; 194 | int color = 0; 195 | while(tap){ //Loop until a button is held 196 | int location = buttons.getKey(); 197 | if (location){ //if a button is pressed 198 | if(values[location/10][(location%10)-1] != 256){ 199 | color = values[location/10][(location%10)-1] + 32; //Update Color if tile is already colored 200 | if (color > 256) 201 | color = 0; 202 | } 203 | else if (color == 256) //Loop back to red at end of rainbow 204 | color = 0; 205 | light_tile(location/10, (location%10)-1, color, 255); //Light tile color 206 | values[location/10][(location%10)-1] = color; 207 | FastLED.show(); //Update display 208 | delay(100); //wait 1/10th of a second 209 | } 210 | if(buttons.getState() == HOLD) //Exit function if tile held 211 | tap = 0; 212 | } 213 | } 214 | //----------------------------------------------------------------------------------- 215 | 216 | //----------------------------------------------------------------------------------- 217 | void Memory(){ 218 | clear_display(); //Clear display 219 | for(int i = 2; i < 6; i++){ //Print Verticle lines of box 220 | light_tile(i, 1, 192, 255); 221 | light_tile(i, 6, 192, 255); 222 | } 223 | for(int i = 1; i < 7; i++){ //Print Horizontal lines of box 224 | light_tile(1, i, 192, 255); 225 | light_tile(6, i, 192, 255); 226 | } 227 | FastLED.show(); 228 | Set_Colors(); //Set Random Color Locations 229 | bool tap = 1; 230 | int color; 231 | int tile1; 232 | int tile2; 233 | int end = 0; 234 | while(tap){ //Loop until BUTTON is held 235 | int location1 = buttons.waitForKey(); 236 | if(buttons.getState() == HOLD) //Exit if button is held 237 | tap = 0; 238 | if (location1){ //When a button is pushed 239 | color = mem_values[location1/10][(location1%10)-1]; //Update the color of the clicked tile 240 | light_tile(location1/10, (location1%10)-1, color, 255); 241 | tile1 = color; 242 | FastLED.show(); 243 | } 244 | int location2 = buttons.waitForKey(); 245 | if(buttons.getState() == HOLD) //Exit if held 246 | tap = 0; 247 | if (location2){ //When a button is pushed 248 | color = mem_values[location2/10][(location2%10)-1]; //Update the color of the clicked tile 249 | light_tile(location2/10, (location2%10)-1, color, 255); 250 | tile2 = color; 251 | FastLED.show(); 252 | } 253 | if(tile1 != tile2 || location1 == location2){ //If tiles are not the same color 254 | light_tile(location1/10, (location1%10)-1, 256, 255); //Light the tiles black 255 | light_tile(location2/10, (location2%10)-1, 256, 255); 256 | } 257 | else 258 | end++; 259 | delay(1000); 260 | FastLED.show(); 261 | if(end == 8) 262 | tap = 0; 263 | } 264 | } 265 | 266 | void Set_Colors(){ //Makes a 4x4 grid of colored pairs in random locations for memory game 267 | int color = 0; 268 | for(int i = 0; i < ROWS; i++) 269 | for(int j = 0; j < COLS; j++) 270 | mem_values[i][j] = 256; 271 | for(int j = 0; j < 8; j++){ //Place 8 colors 272 | for(int i = 0; i< 2; i++){ //place each color twice 273 | bool tile_not_empty = 1; 274 | while(tile_not_empty){ //don't place color over another color 275 | int row = (random()%4)+2; //Get random tile 276 | int col = (random()%4)+2; 277 | if(mem_values[row][col] == 256){ //Check if tile is empty 278 | mem_values[row][col] = color; //Place color 279 | tile_not_empty = 0; //Exit loop 280 | } 281 | } 282 | } 283 | color += 32; //Increment Color 284 | } 285 | } 286 | //----------------------------------------------------------------------------------- 287 | 288 | //----------------------------------------------------------------------------------- 289 | void tic(){ 290 | clear_display(); 291 | for(int i = 4; i < ROWS; i+=2){ 292 | for(int j = 0; j < 5; j++){ 293 | light_tile(i, j, 192, 255); 294 | } 295 | } 296 | for(int i = 3; i < ROWS; i++){ 297 | for(int j = 1; j < 4; j+=2){ 298 | light_tile(i, j, 192, 255); 299 | } 300 | } 301 | FastLED.show(); 302 | bool tap = 1; 303 | bool turn = 0; 304 | while(tacwinner()){ 305 | int location = buttons.waitForKey(); 306 | if(buttons.getState() == HOLD) 307 | return; 308 | else if (location){ 309 | int color = 0; 310 | if(turn) 311 | color = 120; 312 | light_tile(location/10, (location%10)-1, color, 255); 313 | FastLED.show(); 314 | delay(100); 315 | turn = !turn; 316 | } 317 | } 318 | } 319 | 320 | bool tacwinner(){ 321 | for(int i = 3; i < ROWS; i+=2){ 322 | if (values[i][0] == values[i][2] && values[i][0] == values[i][4]){ 323 | if (values[i][0] == 0){ 324 | redwins(); 325 | return 0; 326 | } 327 | if (values[i][0] == 120){ 328 | bluewins(); 329 | return 0; 330 | } 331 | } 332 | } 333 | for(int i = 0; i < 5; i+=2){ 334 | if (values[3][i] == values[5][i] && values[3][i] == values[7][i]){ 335 | if (values[3][i] == 0){ 336 | redwins(); 337 | return 0; 338 | } 339 | if (values[3][i] == 120){ 340 | bluewins(); 341 | return 0; 342 | } 343 | } 344 | } 345 | if (values[3][0] == values[5][2] && values[3][0] == values[7][4]){ 346 | if (values[3][0] == 0){ 347 | redwins(); 348 | return 0; 349 | } 350 | if (values[3][0] == 120){ 351 | bluewins(); 352 | return 0; 353 | } 354 | } 355 | if (values[7][0] == values[5][2] && values[7][0] == values[3][4]){ 356 | if (values[7][0] == 0){ 357 | redwins(); 358 | return 0; 359 | } 360 | if (values[7][0] == 120){ 361 | bluewins(); 362 | return 0; 363 | } 364 | } 365 | for (int i = 3; i < ROWS; i += 2) 366 | for (int j = 0; j < 5; j += 2) 367 | if (values[i][j] == 256) 368 | return 1; 369 | nowins(); 370 | return 0; 371 | } 372 | 373 | void redwins(){ 374 | for (int i = 0; i < ROWS; i++) 375 | for (int j = 0; j < COLS; j++) 376 | light_tile(i, j, 0, 255); 377 | FastLED.show(); 378 | delay(3000); 379 | clear_display(); 380 | } 381 | 382 | void bluewins(){ 383 | for (int i = 0; i < ROWS; i++) 384 | for (int j = 0; j < COLS; j++) 385 | light_tile(i, j, 120, 255); 386 | FastLED.show(); 387 | delay(3000); 388 | clear_display(); 389 | } 390 | 391 | void nowins(){ 392 | bool yes = 0; 393 | for (int i = 0; i < ROWS; i++) 394 | for (int j = 0; j < COLS; j++){ 395 | int color = 0; 396 | if(yes) 397 | color = 120; 398 | light_tile(i, j, color, 255); 399 | yes = !yes; 400 | } 401 | FastLED.show(); 402 | delay(3000); 403 | clear_display(); 404 | } 405 | //----------------------------------------------------------------------------------- 406 | 407 | //----------------------------------------------------------------------------------- 408 | 409 | class Player { 410 | bool tiles[8][8]; 411 | public: 412 | int color; 413 | void setup (int); 414 | void turn(); 415 | void getSelection(); 416 | void changeColor(); 417 | void addBlocks(); 418 | }; 419 | 420 | void Player::setup (int playerID) { 421 | for(int i = 0; i < ROWS; i++) 422 | for(int j = 0; j < COLS; j++) 423 | tiles[i][j] = 0; 424 | if (playerID == 1){ 425 | tiles[7][0] = 1; 426 | color = mem_values[7][0]; 427 | } 428 | else{ 429 | tiles[1][7] = 1; 430 | color = mem_values[1][7]; 431 | } 432 | } 433 | 434 | 435 | void Player::turn(){ 436 | getSelection(); 437 | changeColor(); 438 | addBlocks(); 439 | } 440 | 441 | void Player::getSelection(){ 442 | //Get Button 443 | int location = buttons.waitForKey(); 444 | if(location) 445 | //Get Color at button 446 | color = mem_values[location/10][(location%10)-1]; 447 | } 448 | 449 | void Player::changeColor(){ 450 | //Set all values in mem array to value of color if tiles at that index is 1 451 | for(int i = 0; i < ROWS; i++) 452 | for(int j = 0; j < COLS; j++){ 453 | if (tiles[i][j] == 1){ 454 | mem_values[i][j] = color; 455 | light_tile(i, j, color, 150); 456 | } 457 | } 458 | FastLED.show(); 459 | } 460 | 461 | void Player::addBlocks(){ 462 | for(int i = 0; i < ROWS; i++) 463 | for(int j = 0; j < COLS; j++) 464 | //If a tile is unclaimed, matches the new color, and is adjacent to a claimed tile, then add it to claimed tiles 465 | if (tiles[i][j] == 0 && mem_values[i][j] == color && (tiles[i-1][j]==1 || tiles[i+1][j]==1 || tiles[i][j-1]==1 || tiles[i][j+1]==1)) 466 | tiles[i][j] = 1; 467 | } 468 | 469 | void filler(){ 470 | clear_display(); 471 | initializeBoard(); 472 | Player P1; 473 | Player P2; 474 | P1.setup(1); 475 | P2.setup(2); 476 | escape = 1; 477 | while(escape){ 478 | P1.turn(); 479 | P2.turn(); 480 | escape = gameOver(P1.color); 481 | } 482 | } 483 | 484 | bool gameOver(int c){ 485 | int last = c, current; 486 | for(int i = 1; i < ROWS; i++) 487 | for(int j = 0; j < COLS; j++){ 488 | current = mem_values[i][j]; 489 | if ( current != last) 490 | return 1; 491 | } 492 | return 0; 493 | } 494 | 495 | void initializeBoard(){ 496 | for(int i = 0; i < ROWS; i++) 497 | for(int j = 0; j < COLS; j++) 498 | mem_values[i][j] = 256; 499 | for(int i = 1; i < ROWS; i++) 500 | for(int j = 0; j < COLS; j++) 501 | while(mem_values[i][j] == 256 || mem_values[i][j] == mem_values[i-1][j] || mem_values[i][j] == mem_values[i][j-1]){ 502 | mem_values[i][j] = (random()%6) * 42; 503 | } 504 | for(int i = 0; i < ROWS; i++) 505 | for(int j = 0; j < COLS; j++) 506 | light_tile(i, j, mem_values[i][j], 150); 507 | FastLED.show(); 508 | } 509 | 510 | //----------------------------------------------------------------------------------- 511 | 512 | //----------------------------------------------------------------------------------- 513 | 514 | void retro(){ 515 | clear_display(); 516 | int brt = 255; 517 | for(int i = 0; i < ROWS; i++){ 518 | for(int j = 0; j < COLS; j++){ 519 | if(random()%2 == 0) 520 | light_tile(i, j, 256, brt); 521 | else{ 522 | int col = 128 + (32 * (random() % 4)); 523 | light_tile(i, j, col, brt); 524 | } 525 | } 526 | } 527 | FastLED.show(); 528 | bool tap = 1; 529 | while(tap){ 530 | int r = random() % ROWS; 531 | int c = random() % COLS; 532 | if (values[r][c] == 256){ 533 | int col = 128 + (32 * (random() % 4)); 534 | for (int b = 0; b <= 255; b++){ 535 | light_tile(r, c, col, b); 536 | FastLED.show(); 537 | } 538 | } 539 | else{ 540 | for (int b = 255; b >= 0; b--){ 541 | light_tile(r, c, values[r][c], b); 542 | FastLED.show(); 543 | } 544 | light_tile(r, c, 256, 255); 545 | } 546 | } 547 | } 548 | --------------------------------------------------------------------------------