#include <FastLED.h>
//char -> LED mapping block
const static byte c_set[][2] PROGMEM = {{0,0}, {1,0}, {2,1}, {2,2}, {2,3}, {1,4}, {0,4}};
const static byte c_set_size = 7;
const static byte c_set_width = 3;
const static byte e_set[][2] PROGMEM = {{0,0}, {0,2}, {0,3}, {0,4}, {1,0}, {1,2}, {1,4}, {2,1}, {2,2}, {2,3}};
const static byte e_set_size = 10;
const static byte e_set_width = 3;
const static byte i_set[][2] PROGMEM = {{0,0}, {0,1}, {0,2}, {0,4}};
const static byte i_set_size = 4;
const static byte i_set_width = 1;
const static byte l_set[][2] PROGMEM = {{0,0}, {1,0}, {1,1}, {1,2}, {1,3}, {1,4}};
const static byte l_set_size = 6;
const static byte l_set_width = 2;
const static byte n_set[][2] PROGMEM = {{0,0}, {0,1}, {0,2}, {0,3}, {1,4}, {2,4}, {3,0}, {3,1}, {3,2}, {3,3}, {3,4}};
const static byte n_set_size = 11;
const static byte n_set_width = 4;
const static byte o_set[][2] PROGMEM = {{0,0}, {0,1}, {0,2}, {0,3}, {0,4}, {2,0}, {2,1}, {2,2}, {2,3}, {2,4}, {1,0}, {1,4}};
const static byte o_set_size = 12;
const static byte o_set_width = 3;
const static byte s_set[][2] PROGMEM = {{0,0}, {0,1}, {0,2}, {0,4}, {1,0}, {1,2}, {1,4}, {2,0}, {2,2}, {2,3}, {2,4}};
const static byte s_set_size = 11;
const static byte s_set_width = 3;
const static byte v_set[][2] PROGMEM = {{0,1}, {0,2}, {0,3}, {0,4}, {1,0}, {2,1}, {2,2}, {2,3}, {2,4}};
const static byte v_set_size = 9;
const static byte v_set_width = 3;
const static byte w_set[][2] PROGMEM = {{0,1}, {0,2}, {0,3}, {0,4}, {1,0}, {2,1}, {3,0}, {4,1}, {4,2}, {4,3}, {4,4}};
const static byte w_set_size = 11;
const static byte w_set_width = 5;
//untested way to do a space for setences etc
const static byte space_set[][2] PROGMEM = {};
const static byte space_set_size = 0;
const static byte space_set_width = 1;
//word mapping block
//word[0][0] will grab length of word, required struct.
const static byte nice[][3] {
{4, 0, 0},
{&n_set, n_set_size, n_set_width},
{&i_set, i_set_size, i_set_width},
{&c_set, c_set_size, c_set_width},
{&e_set, e_set_size, e_set_width}
};
const static byte i_test[][3] {
{1, 0, 0},
{i_set, i_set_size, i_set_width},
};
//valid color defs
CRGB valid_colors[5] = {CRGB::Yellow, CRGB::Red, CRGB::Green, CRGB::Cyan, CRGB::Magenta};
//effect-only colors:
/*CRGB::(DarkGreen, LightGreen)*/
// Params for width and height
const uint8_t kMatrixWidth = 32;
const uint8_t kMatrixHeight = 8;
//boiler plate defs
#define LED_PIN 7
#define NUM_LEDS (kMatrixWidth * kMatrixHeight)
CRGB leds[NUM_LEDS];
//FastLED lib config
void setup() {
Serial.begin(9600);
FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
// FastLED.setBrightness(2);
}
void loop() {
CRGB color = fetch_random_color();
for(int i = 0; i < 48; i++) {
scroll_fx(i, color, i_test);
FastLED.show();
delay(100);
FastLED.clear();
}
}
//chat fx fn block
//if this isn't working the problem is most likely inside of render_letter doing pgm_read_byte on the byte set[][2] that's already been delcared into SRAM by that point.
//it's also possible that offset is updating the reference for i in memory passed in from loop instead of the copy you think *offset is making.
void scroll_fx(byte xOffset, CRGB color, byte letter[][3]) {
for(int i = 1; i <= letter[0][0]; i++) {
//this part does the spacing of the letters in a given word, should be generic to any fx, possible encapsulation target.
// if( i > 1 ) {
// xOffset += letter[i][2] + 1;
// }
render_letter(pgm_read_byte(&letter[i][0]), letter[i][1], xOffset + letter[i][2], color);
}
}
//render fn block
void render_letter(byte set[][2], byte set_size, byte xOffset, CRGB color){
for (int k = 0; k < set_size; k++) {
const byte x = set[k][0];
const byte y = set[k][1];
Serial.print("k=");
Serial.println(k);
Serial.print("x=");
Serial.println(x);
Serial.print("y=");
Serial.println(y);
Serial.println("----------END OF CURRENT X/Y----------");
delay(1000);
if(XBC(x + xOffset)) {
leds[XY(x + xOffset, y)] = color;
}
}
Serial.println("Loop end");
}
//util fn block
CRGB fetch_random_color() {
return valid_colors[random(5)];
}
uint16_t XY(uint16_t x, uint16_t y) { // for a serpentine raster
return (x & 0x1) ? x * kMatrixHeight + (kMatrixHeight - 1 - y) : x * kMatrixHeight + y;
}
//`n`BoundaryCheckers to avoid indexing out of bounds
bool XBC(byte x) {
return x < 0 ? false : x > 31 ? false : true;
}
bool YBC(byte y) {
return y < 0 ? false : y > 7 ? false : true;
}