I have built a custom installation in my home with 896 WS2812 LED driven by an ArduinoMega 2560 and powered by several rails just fine. However, the installation is arranged in a checkerboard-like pattern. There are 14 panels with 8 strips of 8 LED each (64 LED per panel), The strips are soldered in zigzag pattern within a panel, and the tiles are connected via leads in a "column progressive" fashion.
Hooking this up and running it works well but I'm trying to deal with the unusual pattern I've created, and having a hard time scaling with my current solution. I am worried that my solution is not very graceful and will use up a lot of unnecessary RAM. I am currently using Adafruit's NeoMatrix library.
My solution is to "fake" like I have many more pixels and use the setRemapFunction()
to throw these fake grid points away. But as I continue to add fake pixels, I assume the overhead RAM is set aside for them and I will max out before getting done. I have 896 real pixels total, but at this rate I'll be declaring that I have 1,792. This is my attempt to deal with the offset, and is a work in progress. This is utilizing about half of my total grid so far:
const int16_t grid[] = {
0, 15, 16, 31, 32, 47, 48, 63, -1, -1, -1, -1, -1, -1, -1, -1, 256, 271, 272, 287, 288, 303, 304, 319, -1, -1, -1, -1, -1, -1, -1, -1,
1, 14, 17, 30, 33, 46, 49, 62, -1, -1, -1, -1, -1, -1, -1, -1, 257, 270, 273, 286, 289, 302, 305, 318, -1, -1, -1, -1, -1, -1, -1, -1,
2, 13, 18, 29, 34, 45, 50, 61, -1, -1, -1, -1, -1, -1, -1, -1, 258, 269, 274, 285, 290, 301, 306, 317, -1, -1, -1, -1, -1, -1, -1, -1,
3, 12, 19, 28, 35, 44, 51, 60, -1, -1, -1, -1, -1, -1, -1, -1, 259, 268, 275, 284, 291, 300, 307, 316, -1, -1, -1, -1, -1, -1, -1, -1,
4, 11, 20, 27, 36, 43, 52, 59, -1, -1, -1, -1, -1, -1, -1, -1, 260, 267, 276, 283, 292, 299, 308, 315, -1, -1, -1, -1, -1, -1, -1, -1,
5, 10, 21, 26, 37, 42, 53, 58, -1, -1, -1, -1, -1, -1, -1, -1, 261, 266, 277, 282, 293, 298, 309, 314, -1, -1, -1, -1, -1, -1, -1, -1,
6, 9, 22, 25, 38, 41, 54, 57, -1, -1, -1, -1, -1, -1, -1, -1, 262, 265, 278, 281, 294, 297, 310, 313, -1, -1, -1, -1, -1, -1, -1, -1,
7, 8, 23, 24, 39, 40, 55, 56, -1, -1, -1, -1, -1, -1, -1, -1, 263, 264, 279, 280, 295, 296, 311, 312, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, 128, 143, 144, 159, 160, 175, 176, 191, -1, -1, -1, -1, -1, -1, -1, -1, 384, 399, 400, 415, 416, 431, 432, 447,
-1, -1, -1, -1, -1, -1, -1, -1, 129, 142, 145, 158, 161, 174, 177, 190, -1, -1, -1, -1, -1, -1, -1, -1, 385, 398, 401, 414, 417, 430, 433, 446,
-1, -1, -1, -1, -1, -1, -1, -1, 130, 141, 146, 157, 162, 173, 178, 189, -1, -1, -1, -1, -1, -1, -1, -1, 386, 397, 402, 413, 418, 429, 434, 445,
-1, -1, -1, -1, -1, -1, -1, -1, 131, 140, 147, 156, 163, 172, 179, 188, -1, -1, -1, -1, -1, -1, -1, -1, 387, 396, 403, 412, 419, 428, 435, 444,
-1, -1, -1, -1, -1, -1, -1, -1, 132, 139, 148, 155, 164, 171, 180, 187, -1, -1, -1, -1, -1, -1, -1, -1, 388, 395, 404, 411, 420, 427, 436, 443,
-1, -1, -1, -1, -1, -1, -1, -1, 133, 138, 149, 154, 165, 170, 181, 186, -1, -1, -1, -1, -1, -1, -1, -1, 389, 394, 405, 410, 421, 426, 437, 442,
-1, -1, -1, -1, -1, -1, -1, -1, 134, 137, 150, 153, 166, 169, 182, 185, -1, -1, -1, -1, -1, -1, -1, -1, 390, 393, 406, 409, 422, 425, 438, 441,
-1, -1, -1, -1, -1, -1, -1, -1, 135, 136, 151, 152, 167, 168, 183, 184, -1, -1, -1, -1, -1, -1, -1, -1, 391, 392, 407, 408, 423, 424, 439, 440,
64, 79, 80, 95, 96, 111, 112, 127, -1, -1, -1, -1, -1, -1, -1, -1, 320, 335, 336, 351, 352, 367, 368, 383, -1, -1, -1, -1, -1, -1, -1, -1,
65, 78, 81, 94, 97, 110, 113, 126, -1, -1, -1, -1, -1, -1, -1, -1, 321, 334, 337, 350, 353, 366, 369, 382, -1, -1, -1, -1, -1, -1, -1, -1,
66, 77, 82, 93, 98, 109, 114, 125, -1, -1, -1, -1, -1, -1, -1, -1, 322, 333, 338, 349, 354, 365, 370, 381, -1, -1, -1, -1, -1, -1, -1, -1,
67, 76, 83, 92, 99, 108, 115, 124, -1, -1, -1, -1, -1, -1, -1, -1, 323, 332, 339, 348, 355, 364, 371, 380, -1, -1, -1, -1, -1, -1, -1, -1,
68, 75, 84, 91, 100, 107, 116, 123, -1, -1, -1, -1, -1, -1, -1, -1, 324, 331, 340, 347, 356, 363, 372, 379, -1, -1, -1, -1, -1, -1, -1, -1,
69, 74, 85, 90, 101, 106, 117, 122, -1, -1, -1, -1, -1, -1, -1, -1, 325, 330, 341, 346, 357, 362, 373, 378, -1, -1, -1, -1, -1, -1, -1, -1,
70, 73, 86, 89, 102, 105, 118, 121, -1, -1, -1, -1, -1, -1, -1, -1, 326, 329, 342, 345, 358, 361, 374, 377, -1, -1, -1, -1, -1, -1, -1, -1,
71, 72, 87, 88, 103, 104, 119, 120, -1, -1, -1, -1, -1, -1, -1, -1, 327, 328, 343, 344, 359, 360, 375, 376, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, 192, 207, 208, 223, 224, 239, 240, 255, -1, -1, -1, -1, -1, -1, -1, -1, 448, 463, 464, 479, 480, 495, 496, 511,
-1, -1, -1, -1, -1, -1, -1, -1, 193, 206, 209, 222, 225, 238, 241, 254, -1, -1, -1, -1, -1, -1, -1, -1, 449, 462, 465, 478, 481, 494, 497, 510,
-1, -1, -1, -1, -1, -1, -1, -1, 194, 205, 210, 221, 226, 237, 242, 253, -1, -1, -1, -1, -1, -1, -1, -1, 450, 461, 466, 477, 482, 493, 498, 509,
-1, -1, -1, -1, -1, -1, -1, -1, 195, 204, 211, 220, 227, 236, 243, 252, -1, -1, -1, -1, -1, -1, -1, -1, 451, 460, 467, 476, 483, 492, 499, 508,
-1, -1, -1, -1, -1, -1, -1, -1, 196, 203, 212, 219, 228, 235, 244, 251, -1, -1, -1, -1, -1, -1, -1, -1, 452, 459, 468, 475, 484, 491, 500, 507,
-1, -1, -1, -1, -1, -1, -1, -1, 197, 202, 213, 218, 229, 234, 245, 250, -1, -1, -1, -1, -1, -1, -1, -1, 453, 458, 469, 474, 485, 490, 501, 506,
-1, -1, -1, -1, -1, -1, -1, -1, 198, 201, 214, 217, 230, 233, 246, 249, -1, -1, -1, -1, -1, -1, -1, -1, 454, 457, 470, 473, 486, 489, 502, 505,
-1, -1, -1, -1, -1, -1, -1, -1, 199, 200, 215, 216, 231, 232, 247, 248, -1, -1, -1, -1, -1, -1, -1, -1, 455, 456, 471, 472, 487, 488, 503, 504,
};
I am using this like so:
#define PIN 6
#define WIDTH 32 // So far. Will be 56 when I finish creating array.
#define HEIGHT 32
/**
* Setup the lightwall matrix.
*
* Each panel is 8x8 pixels. There are 7 columns and 2 rows,
* but they are arranged in a checkerboard pattern.
*/
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(WIDTH, HEIGHT,PIN,
NEO_MATRIX_TOP + NEO_MATRIX_LEFT +
NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
NEO_GRBW + NEO_KHZ800
);
uint16_t remapXY(uint16_t x, uint16_t y) {
y = y * WIDTH + x;
return grid[y];
}
void setup() {
matrix.setRemapFunction(remapXY);
matrix.begin();
}
So the remapXY()
returns the correct key of the array, thus the reason for the crazy array pasted above. And that array is only halfway complete (tediously typing it out!)
But so far it is working. I have a pacman animation (not pictured) scrolling across the screen and being "off screen" for a believable amount of time. That is the whole point of this madness. But am I going about it all wrong? Attached is also a picture of the full visible matrix for visual aid.
Starting from the upper left corner is panel 1, then lower left panel 2. Next column top is panel 3, bottom panel 4. And so on.
So will I need more RAM in order for this to be performant? Or is there a better way to code my way out of this problem? I have a lot of animations and ambient effects planned, not all of which will strictly require this offset.
Is there another way to "mask" or delay some pixels off screen temporarily based on where they should be? Only to put them back where they belong afterward?