|
@@ -0,0 +1,932 @@
|
|
|
+#include <ESP32Lib.h>
|
|
|
+
|
|
|
+#define LEDPin 2
|
|
|
+#define LED_X_PIXELS 25
|
|
|
+#define LED_Y_PIXELS 20
|
|
|
+#define LEADER_PIXELS 0 // unused pixels at the beginning
|
|
|
+SerialLED gfx;
|
|
|
+
|
|
|
+#define STATUS 23 // We've started!
|
|
|
+
|
|
|
+#define seedPin 21 // an unused pin to see the RNG
|
|
|
+
|
|
|
+unsigned char frame[LED_X_PIXELS][LED_Y_PIXELS][3];
|
|
|
+unsigned char difference[LED_X_PIXELS][LED_Y_PIXELS];
|
|
|
+
|
|
|
+/* Animation Functions */
|
|
|
+void cycle(int delaytime); // cycle all pixels through red, green, then blue
|
|
|
+void chasePixel(int delaytime, unsigned char r = 255, unsigned char g = 255, unsigned char b = 255); // pixel left to right, up and down the display
|
|
|
+void fillAndClear(int delaytime, unsigned char r = 255, unsigned char g = 255, unsigned char b = 255); // Fill and then empty
|
|
|
+void mrsparky(unsigned long duration, int delaytime = 0); // chaos, unless there's a
|
|
|
+void squares(int count, int delaytime, bool dir); // squares - dir == true means from the inside out
|
|
|
+
|
|
|
+/* Helper functions */
|
|
|
+void printFrame(); // display whatever's in the frame
|
|
|
+void oneColor(unsigned char r, unsigned char g, unsigned char b); //set all to one color
|
|
|
+
|
|
|
+void setup() {
|
|
|
+ Serial.begin(115200);
|
|
|
+ ota_setup(); // Initialize WiFi and OTA
|
|
|
+
|
|
|
+ //gfx.setGamma(2.8f, 2.8f, 2.8f); // R, G, B gamma correction?
|
|
|
+ gfx.init(LEDPin, LED_X_PIXELS * LED_Y_PIXELS + LEADER_PIXELS, -1, -1);
|
|
|
+
|
|
|
+ Serial.println("Testing pixelMap:");
|
|
|
+ for (int y = LED_Y_PIXELS - 1; y >= 0; y--) {
|
|
|
+ Serial.print("Row "); Serial.print(y); Serial.print(": ");
|
|
|
+ for (int x = 0; x < LED_X_PIXELS; x++) {
|
|
|
+ Serial.print(pixelMap(x, y)); Serial.print(" ");
|
|
|
+ }
|
|
|
+ Serial.println("");
|
|
|
+ }
|
|
|
+
|
|
|
+ oneColor(0, 0, 0);
|
|
|
+ printFrame();
|
|
|
+
|
|
|
+ randomSeed(analogRead(seedPin));
|
|
|
+
|
|
|
+ pinMode(STATUS, OUTPUT);
|
|
|
+ digitalWrite(STATUS, HIGH);
|
|
|
+}
|
|
|
+
|
|
|
+void loop() {
|
|
|
+ vTaskDelay(10); // feed the other tasks
|
|
|
+ switch (random(0, 100)) {
|
|
|
+ case 0:
|
|
|
+ Serial.println("Cycle...");
|
|
|
+ cycle(random(1,15));
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ Serial.println("Chase Pixel...");
|
|
|
+ chasePixel(random(1,10), darkrandColor(), darkrandColor(), darkrandColor());
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ Serial.println("Fill and Clear...");
|
|
|
+ fillAndClear(random(1,10), darkrandColor(), darkrandColor(), darkrandColor());
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ Serial.println("Mr. Sparky...");
|
|
|
+ mrsparky(5000);
|
|
|
+ break;
|
|
|
+ case 4:
|
|
|
+ Serial.println("Mr. Sparky with delay (aka discoteque)...");
|
|
|
+ mrsparky(10000, 100);
|
|
|
+ break;
|
|
|
+ case 5:
|
|
|
+ Serial.println("Mr. Sparky with even longer delay (aka 50s?)...");
|
|
|
+ mrsparky(10000, 750);
|
|
|
+ break;
|
|
|
+ case 6:
|
|
|
+ Serial.println("Squares, inside out...");
|
|
|
+ squares(30, random(0, 100), random(2, 6), true);
|
|
|
+ break;
|
|
|
+ case 7:
|
|
|
+ Serial.println("Squares, outside in...");
|
|
|
+ squares(30, random(0, 100), random(2, 6), false);
|
|
|
+ break;
|
|
|
+ case 8:
|
|
|
+ Serial.println("Wormin...");
|
|
|
+ worm(random(10,70), random(500,1000));
|
|
|
+ break;
|
|
|
+ case 9:
|
|
|
+ Serial.println("Crazy Worms!");
|
|
|
+ crazyworm(random(10,70), random(500,1000));
|
|
|
+ break;
|
|
|
+ case 10:
|
|
|
+ Serial.println("Fading Worm...");
|
|
|
+ fadeworm(random(10,70), random(500,1000), (unsigned char) random(1,10));
|
|
|
+ break;
|
|
|
+ case 11:
|
|
|
+ Serial.println("Starfall...");
|
|
|
+ starfall(random(10,50), random(500,1000), (unsigned char) random(1,10), random(5, 20));
|
|
|
+ break;
|
|
|
+ case 12:
|
|
|
+ Serial.println("Starfall...");
|
|
|
+ rainbowfall(random(10,50), random(500,1000), (unsigned char) random(1,10), random(5, 20));
|
|
|
+ break;
|
|
|
+ case 13:
|
|
|
+ Serial.println("Random cycle...");
|
|
|
+ randomcycle(random(0, 7), random(2000, 5000), random(500, 2000));
|
|
|
+ break;
|
|
|
+ case 14:
|
|
|
+ Serial.println("Gradient cycle...");
|
|
|
+ gradientcycle(random(0, 7), random(2000, 10000), random(500, 2000));
|
|
|
+ break;
|
|
|
+ case 15:
|
|
|
+ Serial.println("Evo Shandor...");
|
|
|
+ show_evo(500);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ Serial.println("Oops... no selection... that's NUMBERWANG!");
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+unsigned char randColor() {
|
|
|
+ // weighted to prefer the lower 128
|
|
|
+ if (random(0, 1)) {
|
|
|
+ return (unsigned char) random(0, 255);
|
|
|
+ } else {
|
|
|
+ return (unsigned char) random(0, 128);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+unsigned char darkrandColor() {
|
|
|
+ // Weighted even more for lower numbers
|
|
|
+ switch (random(1, 3)) {
|
|
|
+ //case 0: return (unsigned char) random(0, 31);
|
|
|
+ case 1: return (unsigned char) random(0, 63);
|
|
|
+ case 2: return (unsigned char) random(0, 127);
|
|
|
+ case 3: return (unsigned char) random(0, 255);
|
|
|
+ }
|
|
|
+ // shouldn't get here
|
|
|
+ return (unsigned char) random(0, 255);
|
|
|
+}
|
|
|
+
|
|
|
+void mrsparky(unsigned long duration, int delaytime) {
|
|
|
+ unsigned long starttime = millis();
|
|
|
+ while (millis() - starttime < duration) {
|
|
|
+ randFrame();
|
|
|
+ printFrame();
|
|
|
+ if (delaytime > 0) {
|
|
|
+ delay(delaytime);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void fillAndClear(int delaytime, unsigned char r, unsigned char g, unsigned char b) {
|
|
|
+ oneColor(0, 0, 0);
|
|
|
+ printFrame();
|
|
|
+
|
|
|
+ // fill with color
|
|
|
+ for (int y = 0; y < LED_Y_PIXELS; y++) {
|
|
|
+ for (int x = 0; x < LED_X_PIXELS; x++) {
|
|
|
+ frame[x][y][0] = r;
|
|
|
+ frame[x][y][1] = g;
|
|
|
+ frame[x][y][2] = b;
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // back to black
|
|
|
+ for (int y = LED_Y_PIXELS - 1; y >= 0; y--) {
|
|
|
+ for (int x = LED_X_PIXELS - 1; x >= 0; x--) {
|
|
|
+ frame[x][y][0] = 0;
|
|
|
+ frame[x][y][1] = 0;
|
|
|
+ frame[x][y][2] = 0;
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void chasePixel(int delaytime, unsigned char r, unsigned char g, unsigned char b) {
|
|
|
+ oneColor(0, 0, 0);
|
|
|
+ printFrame();
|
|
|
+
|
|
|
+ for (int y = 0; y < LED_Y_PIXELS; y++) {
|
|
|
+ if (y % 2 == 0) {
|
|
|
+ // even rows go left to right:
|
|
|
+ for (int x = 0; x < LED_X_PIXELS; x++) {
|
|
|
+ frame[x][y][0] = r;
|
|
|
+ frame[x][y][1] = g;
|
|
|
+ frame[x][y][2] = b;
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ oneColor(0, 0, 0);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // odd rows go right to left
|
|
|
+ for (int x = LED_X_PIXELS - 1; x >= 0; x--) {
|
|
|
+ frame[x][y][0] = r;
|
|
|
+ frame[x][y][1] = g;
|
|
|
+ frame[x][y][2] = b;
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ oneColor(0, 0, 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (int y = LED_Y_PIXELS - 1; y >= 0; y--) {
|
|
|
+ if (y % 2 == 0) {
|
|
|
+ // even rows go right to left:
|
|
|
+ for (int x = LED_X_PIXELS - 1; x >= 0; x--) {
|
|
|
+ frame[x][y][0] = r;
|
|
|
+ frame[x][y][1] = g;
|
|
|
+ frame[x][y][2] = b;
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ oneColor(0, 0, 0);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // odd rows go left to right
|
|
|
+ for (int x = 0; x < LED_X_PIXELS; x++) {
|
|
|
+ frame[x][y][0] = r;
|
|
|
+ frame[x][y][1] = g;
|
|
|
+ frame[x][y][2] = b;
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ oneColor(0, 0, 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void cycle(int delaytime) {
|
|
|
+ // cycle all pixels through red, green, then blue
|
|
|
+ for (unsigned char r = 0; r <= 254; r++) {
|
|
|
+ oneColor(r, 0, 0);
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ }
|
|
|
+ for (unsigned char r = 255; r > 0; r--) {
|
|
|
+ oneColor(r, 0, 0);
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ }
|
|
|
+ for (unsigned char g = 0; g <= 254; g++) {
|
|
|
+ oneColor(0, g, 0);
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ }
|
|
|
+ for (unsigned char g = 255; g > 0; g--) {
|
|
|
+ oneColor(0, g, 0);
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ }
|
|
|
+ for (unsigned char b = 0; b <= 254; b++) {
|
|
|
+ oneColor(0, 0, b);
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ }
|
|
|
+ for (unsigned char b = 255; b > 0; b--) {
|
|
|
+ oneColor(0, 0, b);
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ }
|
|
|
+ oneColor(0, 0, 0);
|
|
|
+ printFrame();
|
|
|
+}
|
|
|
+
|
|
|
+void printFrame() {
|
|
|
+ for (int l = 0; l < LEADER_PIXELS; l++) {
|
|
|
+ // Turn any lead pixels off
|
|
|
+ gfx.setLED(l, 0, 0, 0);
|
|
|
+ }
|
|
|
+ for (int x = 0; x < LED_X_PIXELS; x++) {
|
|
|
+ for (int y = 0; y < LED_Y_PIXELS; y++) {
|
|
|
+ //Serial.print("Setting pixel "); Serial.print(pixelMap(x, y));
|
|
|
+ //Serial.print(" to R:"); Serial.print((int) frame[x][y][0]);
|
|
|
+ //Serial.print(" G:"); Serial.print((int) frame[x][y][1]);
|
|
|
+ //Serial.print(" B:"); Serial.println((int) frame[x][y][2]);
|
|
|
+ gfx.setLED(pixelMap(x, y), frame[x][y][0], frame[x][y][1], frame[x][y][2]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int pixelMap(int x, int y) {
|
|
|
+ // Translates x and y into a pixel number
|
|
|
+ // (0, 0) is bottom left, (LED_X_PIXELS-1, LED_Y_PIXELS-1) is top right)
|
|
|
+ if (x < 0 || x >= LED_X_PIXELS || y < 0 || y >= LED_Y_PIXELS) {
|
|
|
+ Serial.print("ERROR: Cannot map ("); Serial.print(x); Serial.print(","); Serial.print(y); Serial.println(") into wall map");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ x = LED_X_PIXELS - x - 1; // x starts at bottom right, so invert. If x is at bottom left, comment this out.
|
|
|
+
|
|
|
+ int pixel = y * LED_X_PIXELS;
|
|
|
+ if (y % 2 == 0) {
|
|
|
+ // even rows are added
|
|
|
+ pixel += x;
|
|
|
+ } else {
|
|
|
+ // odd rows are subtracted from the next one
|
|
|
+ pixel += LED_X_PIXELS - x - 1;
|
|
|
+ }
|
|
|
+ //assert(pixel < LED_X_PIXELS * LED_Y_PIXELS);
|
|
|
+ return pixel + LEADER_PIXELS;
|
|
|
+}
|
|
|
+
|
|
|
+void oneColor(unsigned char r, unsigned char g, unsigned char b) {
|
|
|
+ // Sets the frame to an initial design
|
|
|
+ for (int x = 0; x < LED_X_PIXELS; x++) {
|
|
|
+ for (int y = 0; y < LED_Y_PIXELS; y++) {
|
|
|
+ frame[x][y][0] = r; // Red
|
|
|
+ frame[x][y][1] = g; // Green
|
|
|
+ frame[x][y][2] = b; // Blue
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void randFrame() {
|
|
|
+ // Generates a random frame
|
|
|
+ for (int x = 0; x < LED_X_PIXELS; x++) {
|
|
|
+ for (int y = 0; y < LED_Y_PIXELS; y++) {
|
|
|
+ frame[x][y][0] = randColor(); // Red
|
|
|
+ frame[x][y][1] = randColor(); // Green
|
|
|
+ frame[x][y][2] = randColor(); // Blue
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* Does nto work at all:
|
|
|
+ void Flames(int delaytime) {
|
|
|
+ for(int y = 0; y < LED_Y_PIXELS; y++) {
|
|
|
+ for(int x = 0; x < LED_X_PIXELS; x++) {
|
|
|
+ int c = pixelMap(x,y);
|
|
|
+ frame[x][y][0] = c;
|
|
|
+ frame[x][y][1] = (c * c) / (255);
|
|
|
+ frame[x][y][2] = (c * c) / (255 * 8);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+
|
|
|
+ for(int c = 0; c < 255; c++) {
|
|
|
+ for(int y = 0; y < LED_Y_PIXELS; y++) {
|
|
|
+ for(int x = 0; x < LED_X_PIXELS; x++) {
|
|
|
+ if(frame[x][y][0] > 127) {
|
|
|
+ // Big number, probably intensify
|
|
|
+ if(random(0, 4) > 0) {
|
|
|
+ // intensify!
|
|
|
+ int diff = 255 - frame[x][y][0];
|
|
|
+ frame[x][y][0] += random(0, diff);
|
|
|
+ } else {
|
|
|
+ // detensify!
|
|
|
+ frame[x][y][0] -= random(0, 127);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // small number, probably weaken
|
|
|
+ // Big number, probably intensify
|
|
|
+ if(random(0, 4) > 0) {
|
|
|
+ // detensify!
|
|
|
+ frame[x][y][0] -= random(0, frame[x][y][0]);
|
|
|
+ } else {
|
|
|
+ // intensify!
|
|
|
+ frame[x][y][0] += random(0, 127);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ frame[x][y][1] = (frame[x][y][0] * frame[x][y][0]) / 255;
|
|
|
+ frame[x][y][2] = (frame[x][y][0] * frame[x][y][0]) / (255 * 8);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ }
|
|
|
+ }
|
|
|
+*/
|
|
|
+
|
|
|
+int maxSquares(void) {
|
|
|
+ // returns the maximum number of squares that can be drawn.
|
|
|
+ // Note that squares can be drawn "outside" of one dimension.
|
|
|
+ int maxdim = min(LED_X_PIXELS, LED_Y_PIXELS);
|
|
|
+ // on an odd number, inside square is 1x1
|
|
|
+ return floor(maxdim / 2);
|
|
|
+}
|
|
|
+
|
|
|
+void drawSquare(int squareno, unsigned char r, unsigned char g, unsigned char b) {
|
|
|
+ // draws the nth square, counting from 0 from the middle out
|
|
|
+ if (squareno > maxSquares()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ int center_x = floor((LED_X_PIXELS - 1) / 2);
|
|
|
+ int center_width = LED_X_PIXELS % 2 == 0 ? 2 : 1; // odd numbers have a 1x1 center
|
|
|
+ int center_y = floor((LED_Y_PIXELS - 1) / 2);
|
|
|
+ int center_height = LED_Y_PIXELS % 2 == 0 ? 2 : 1;
|
|
|
+
|
|
|
+ int x_left = center_x - squareno;
|
|
|
+ int x_right = center_x + center_width + squareno - 1;
|
|
|
+ int y_bottom = center_y - squareno;
|
|
|
+ int y_top = center_y + center_height + squareno - 1;
|
|
|
+ Serial.print("Dimensions: X_left: "); Serial.print(x_left);
|
|
|
+ Serial.print("; X_Right: "); Serial.print(x_right);
|
|
|
+ Serial.print("; Y_Bottom: "); Serial.print(y_bottom);
|
|
|
+ Serial.print("; Y_top: "); Serial.print(y_top);
|
|
|
+ Serial.print("; Center_x: "); Serial.print(center_x);
|
|
|
+ Serial.print("; Center_y: "); Serial.print(center_y);
|
|
|
+ Serial.print("; Center_Width: "); Serial.print(center_width);
|
|
|
+ Serial.print("; Center_Height: "); Serial.println(center_height);
|
|
|
+
|
|
|
+ // top and bottom lines
|
|
|
+ for (int x = x_left; x <= x_right; x++) {
|
|
|
+ if (x < 0 || x > LED_X_PIXELS - 1 || y_bottom < 0 || y_top > LED_Y_PIXELS - 1) {
|
|
|
+ Serial.print(" Skipping: ("); Serial.print(x);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ frame[x][y_bottom][0] = r;
|
|
|
+ frame[x][y_bottom][1] = g;
|
|
|
+ frame[x][y_bottom][2] = b;
|
|
|
+ frame[x][y_top][0] = r;
|
|
|
+ frame[x][y_top][1] = g;
|
|
|
+ frame[x][y_top][2] = b;
|
|
|
+ }
|
|
|
+
|
|
|
+ // left and right lines
|
|
|
+ for (int y = y_bottom; y <= y_top; y++) {
|
|
|
+ if (x_left < 0 || x_right > LED_X_PIXELS - 1 || y < 0 || y > LED_Y_PIXELS - 1) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ frame[x_left][y][0] = r;
|
|
|
+ frame[x_left][y][1] = g;
|
|
|
+ frame[x_left][y][2] = b;
|
|
|
+ frame[x_right][y][0] = r;
|
|
|
+ frame[x_right][y][1] = g;
|
|
|
+ frame[x_right][y][2] = b;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void squares(int count, int delaytime, int numsquares, bool dir) {
|
|
|
+ numsquares += 2; // 2 black squares
|
|
|
+ oneColor(0, 0, 0);
|
|
|
+ // draws squares moving out
|
|
|
+ unsigned char colors[255][3];
|
|
|
+ colors[0][0] = 0; //black makes the motion clearer
|
|
|
+ colors[0][1] = 0;
|
|
|
+ colors[0][2] = 0;
|
|
|
+ colors[1][0] = 0; //black makes the motion clearer
|
|
|
+ colors[1][1] = 0;
|
|
|
+ colors[1][2] = 0;
|
|
|
+ for (int i = 2; i < numsquares; i++) {
|
|
|
+ // assign random colors
|
|
|
+ colors[i][0] = randColor();
|
|
|
+ colors[i][1] = randColor();
|
|
|
+ colors[i][2] = randColor();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (dir) {
|
|
|
+ // inside out
|
|
|
+ for (int i = count; i > 0; i--) {
|
|
|
+ // draw each of the squares
|
|
|
+ for (int squareno = 0; squareno < maxSquares(); squareno++) {
|
|
|
+ Serial.println("--------------");
|
|
|
+ Serial.print("Drawing Square: "); Serial.println(squareno);
|
|
|
+ drawSquare(squareno, colors[(i + squareno) % numsquares][0], colors[(i + squareno) % numsquares][1], colors[(i + squareno) % numsquares][2]);
|
|
|
+ }
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ for (int i = 0; i < count; i++) {
|
|
|
+ // draw each of the squares
|
|
|
+ for (int squareno = 0; squareno < maxSquares(); squareno++) {
|
|
|
+ Serial.println("--------------");
|
|
|
+ Serial.print("Drawing Square: "); Serial.println(squareno);
|
|
|
+ drawSquare(squareno, colors[(i + squareno) % numsquares][0], colors[(i + squareno) % numsquares][1], colors[(i + squareno) % numsquares][2]);
|
|
|
+ }
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void worm(int delaytime, int steps) {
|
|
|
+ int x = random(3, LED_X_PIXELS - 3);
|
|
|
+ int y = random(3, LED_Y_PIXELS - 3);
|
|
|
+ unsigned char color[3];
|
|
|
+ color[0] = randColor();
|
|
|
+ color[1] = randColor();
|
|
|
+ color[2] = randColor();
|
|
|
+ unsigned char trailcolor[3];
|
|
|
+ trailcolor[0] = randColor();
|
|
|
+ trailcolor[1] = randColor();
|
|
|
+ trailcolor[2] = randColor();
|
|
|
+ unsigned char bgcolor[3];
|
|
|
+ bgcolor[0] = darkrandColor();
|
|
|
+ bgcolor[1] = darkrandColor();
|
|
|
+ bgcolor[2] = darkrandColor();
|
|
|
+
|
|
|
+ oneColor(bgcolor[0], bgcolor[1], bgcolor[2]);
|
|
|
+ printFrame();
|
|
|
+
|
|
|
+ bool moved = false;
|
|
|
+ int lastmove = -1;
|
|
|
+ for (int step = 0; step < steps; step++) {
|
|
|
+ frame[x][y][0] = color[0];
|
|
|
+ frame[x][y][1] = color[1];
|
|
|
+ frame[x][y][2] = color[2];
|
|
|
+ printFrame();
|
|
|
+ // it's going to bet the trail color next
|
|
|
+ frame[x][y][0] = trailcolor[0];
|
|
|
+ frame[x][y][1] = trailcolor[1];
|
|
|
+ frame[x][y][2] = trailcolor[2];
|
|
|
+ delay(delaytime);
|
|
|
+
|
|
|
+ // move randomly
|
|
|
+ moved = false;
|
|
|
+ int move;
|
|
|
+ while (moved == false) {
|
|
|
+ move = random(0, 12);
|
|
|
+ if (move > 3) {
|
|
|
+ if (lastmove == 0) {
|
|
|
+ // the odd case of this being our first move
|
|
|
+ move = random(0, 3);
|
|
|
+ }
|
|
|
+ move = lastmove; //repeat the last move
|
|
|
+ }
|
|
|
+ switch (move) {
|
|
|
+ case 0: // move up
|
|
|
+ if (lastmove != 1 && y < LED_Y_PIXELS - 1) {
|
|
|
+ lastmove = 0;
|
|
|
+ y++;
|
|
|
+ moved = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 1: // move down
|
|
|
+ if (lastmove != 0 && y > 0) {
|
|
|
+ lastmove = 1;
|
|
|
+ y--;
|
|
|
+ moved = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 2: // move right
|
|
|
+ if (lastmove != 3 && x < LED_X_PIXELS - 1) {
|
|
|
+ lastmove = 2;
|
|
|
+ x++;
|
|
|
+ moved = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 3: // move left
|
|
|
+ if (lastmove != 2 && x > 0) {
|
|
|
+ lastmove = 3;
|
|
|
+ x--;
|
|
|
+ moved = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void crazyfadebyint(int factor) {
|
|
|
+ for (int x = 0; x < LED_X_PIXELS; x++) {
|
|
|
+ for (int y = 0; y < LED_Y_PIXELS; y++) {
|
|
|
+ if (frame[x][y][0] > factor) {
|
|
|
+ frame[x][y][0] -= factor;
|
|
|
+ } else {
|
|
|
+ frame[x][y][0] = 0;
|
|
|
+ }
|
|
|
+ if (frame[x][y][1] > factor) {
|
|
|
+ frame[x][y][1] -= factor;
|
|
|
+ } else {
|
|
|
+ frame[x][y][1] = 0;
|
|
|
+ }
|
|
|
+ if (frame[x][y][2] > factor) {
|
|
|
+ frame[x][y][2] -= factor;
|
|
|
+ } else {
|
|
|
+ frame[x][y][2] = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void crazyworm(int delaytime, int steps) {
|
|
|
+ int x = random(3, LED_X_PIXELS - 3);
|
|
|
+ int y = random(3, LED_Y_PIXELS - 3);
|
|
|
+ unsigned char color[3];
|
|
|
+ color[0] = randColor();
|
|
|
+ color[1] = randColor();
|
|
|
+ color[2] = randColor();
|
|
|
+
|
|
|
+ oneColor(0, 0, 0);
|
|
|
+ printFrame();
|
|
|
+
|
|
|
+ bool moved = false;
|
|
|
+ int lastmove = -1;
|
|
|
+ for (int step = 0; step < steps; step++) {
|
|
|
+ crazyfadebyint(-10);
|
|
|
+ frame[x][y][0] = color[0];
|
|
|
+ frame[x][y][1] = color[1];
|
|
|
+ frame[x][y][2] = color[2];
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+
|
|
|
+ // move randomly
|
|
|
+ moved = false;
|
|
|
+ int move;
|
|
|
+ while (moved == false) {
|
|
|
+ move = random(0, 12);
|
|
|
+ if (move > 3) {
|
|
|
+ if (lastmove == 0) {
|
|
|
+ // the odd case of this being our first move
|
|
|
+ move = random(0, 3);
|
|
|
+ }
|
|
|
+ move = lastmove; //repeat the last move
|
|
|
+ }
|
|
|
+ switch (move) {
|
|
|
+ case 0: // move up
|
|
|
+ if (lastmove != 1 && y < LED_Y_PIXELS - 1) {
|
|
|
+ lastmove = 0;
|
|
|
+ y++;
|
|
|
+ moved = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 1: // move down
|
|
|
+ if (lastmove != 0 && y > 0) {
|
|
|
+ lastmove = 1;
|
|
|
+ y--;
|
|
|
+ moved = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 2: // move right
|
|
|
+ if (lastmove != 3 && x < LED_X_PIXELS - 1) {
|
|
|
+ lastmove = 2;
|
|
|
+ x++;
|
|
|
+ moved = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 3: // move left
|
|
|
+ if (lastmove != 2 && x > 0) {
|
|
|
+ lastmove = 3;
|
|
|
+ x--;
|
|
|
+ moved = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void fadebyint(unsigned char factor) {
|
|
|
+ for (int x = 0; x < LED_X_PIXELS; x++) {
|
|
|
+ for (int y = 0; y < LED_Y_PIXELS; y++) {
|
|
|
+ //Serial.print('Current R: ');
|
|
|
+ //Serial.print(frame[x][y][0]);
|
|
|
+ //Serial.print('Current G: ');
|
|
|
+ //Serial.print(frame[x][y][1]);
|
|
|
+ //Serial.print('Current B: ');
|
|
|
+ //Serial.println(frame[x][y][2]);
|
|
|
+ if (frame[x][y][0] > factor) {
|
|
|
+ frame[x][y][0] -= factor;
|
|
|
+ } else {
|
|
|
+ frame[x][y][0] = 0;
|
|
|
+ }
|
|
|
+ if (frame[x][y][1] > factor) {
|
|
|
+ frame[x][y][1] -= factor;
|
|
|
+ } else {
|
|
|
+ frame[x][y][1] = 0;
|
|
|
+ }
|
|
|
+ if (frame[x][y][2] > factor) {
|
|
|
+ frame[x][y][2] -= factor;
|
|
|
+ } else {
|
|
|
+ frame[x][y][2] = 0;
|
|
|
+ }
|
|
|
+ //Serial.print('Faded R: ');
|
|
|
+ //Serial.print(frame[x][y][0]);
|
|
|
+ //Serial.print('Faded G: ');
|
|
|
+ //Serial.print(frame[x][y][1]);
|
|
|
+ //Serial.print('Faded B: ');
|
|
|
+ //Serial.println(frame[x][y][2]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void fadeworm(int delaytime, int steps, unsigned char fadefactor) {
|
|
|
+ int x = random(3, LED_X_PIXELS - 3);
|
|
|
+ int y = random(3, LED_Y_PIXELS - 3);
|
|
|
+ unsigned char color[3];
|
|
|
+ color[0] = randColor();
|
|
|
+ color[1] = randColor();
|
|
|
+ color[2] = randColor();
|
|
|
+
|
|
|
+ oneColor(0, 0, 0);
|
|
|
+ printFrame();
|
|
|
+
|
|
|
+ bool moved = false;
|
|
|
+ int lastmove = -1;
|
|
|
+ for (int step = 0; step < steps; step++) {
|
|
|
+ fadebyint(fadefactor);
|
|
|
+ frame[x][y][0] = color[0];
|
|
|
+ frame[x][y][1] = color[1];
|
|
|
+ frame[x][y][2] = color[2];
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+
|
|
|
+ // move randomly
|
|
|
+ moved = false;
|
|
|
+ int move;
|
|
|
+ while (moved == false) {
|
|
|
+ move = random(0, 12);
|
|
|
+ if (move > 3) {
|
|
|
+ if (lastmove == 0) {
|
|
|
+ // the odd case of this being our first move
|
|
|
+ move = random(0, 3);
|
|
|
+ }
|
|
|
+ move = lastmove; //repeat the last move
|
|
|
+ }
|
|
|
+ switch (move) {
|
|
|
+ case 0: // move up
|
|
|
+ if (lastmove != 1 && y < LED_Y_PIXELS - 1) {
|
|
|
+ lastmove = 0;
|
|
|
+ y++;
|
|
|
+ moved = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 1: // move down
|
|
|
+ if (lastmove != 0 && y > 0) {
|
|
|
+ lastmove = 1;
|
|
|
+ y--;
|
|
|
+ moved = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 2: // move right
|
|
|
+ if (lastmove != 3 && x < LED_X_PIXELS - 1) {
|
|
|
+ lastmove = 2;
|
|
|
+ x++;
|
|
|
+ moved = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 3: // move left
|
|
|
+ if (lastmove != 2 && x > 0) {
|
|
|
+ lastmove = 3;
|
|
|
+ x--;
|
|
|
+ moved = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int starfall(int delaytime, int steps, unsigned char fadefactor, int chance) {
|
|
|
+ int pos[LED_X_PIXELS];
|
|
|
+ unsigned char color[3];
|
|
|
+ color[0] = randColor();
|
|
|
+ color[1] = randColor();
|
|
|
+ color[2] = randColor();
|
|
|
+
|
|
|
+ oneColor(0, 0, 0);
|
|
|
+
|
|
|
+ // initialize starting positions
|
|
|
+ for (int p = 0; p < LED_X_PIXELS; p++) {
|
|
|
+ if (random(0, 100) <= chance) {
|
|
|
+ pos[p] = random(0, LED_Y_PIXELS);
|
|
|
+ frame[p][pos[p]][0] = color[0];
|
|
|
+ frame[p][pos[p]][1] = color[1];
|
|
|
+ frame[p][pos[p]][2] = color[2];
|
|
|
+ } else {
|
|
|
+ pos[p] = -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ printFrame();
|
|
|
+
|
|
|
+ for (int step = 0; step < steps; step++) {
|
|
|
+ fadebyint(fadefactor);
|
|
|
+ for (int p = 0; p < LED_X_PIXELS; p++) {
|
|
|
+ if (pos[p] == 0) {
|
|
|
+ //Serial.print("Position "); Serial.print(p); Serial.println(" hit bottom");
|
|
|
+ pos[p] = -1; // it hit the bottom
|
|
|
+ }
|
|
|
+ if (pos[p] > 0) {
|
|
|
+ //Serial.print("Position "); Serial.print(p); Serial.print(" dropping from "); Serial.println(pos[p]);
|
|
|
+ pos[p]--; // drop down one
|
|
|
+ frame[p][pos[p]][0] = color[0];
|
|
|
+ frame[p][pos[p]][1] = color[1];
|
|
|
+ frame[p][pos[p]][2] = color[2];
|
|
|
+ }
|
|
|
+ if (pos[p] == -1 && random(0, 100) <= chance) {
|
|
|
+ // spawn a new one
|
|
|
+ //Serial.print("Position "); Serial.print(p); Serial.println(" spawning.");
|
|
|
+ pos[p] = LED_Y_PIXELS - 1;
|
|
|
+ frame[p][pos[p]][0] = color[0];
|
|
|
+ frame[p][pos[p]][1] = color[1];
|
|
|
+ frame[p][pos[p]][2] = color[2];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int rainbowfall(int delaytime, int steps, unsigned char fadefactor, int chance) {
|
|
|
+ int pos[LED_X_PIXELS];
|
|
|
+ unsigned char colors[LED_X_PIXELS][3];
|
|
|
+
|
|
|
+ oneColor(0, 0, 0);
|
|
|
+
|
|
|
+ // initialize starting positions
|
|
|
+ for (int p = 0; p < LED_X_PIXELS; p++) {
|
|
|
+ if (random(0, 100) <= chance) {
|
|
|
+ pos[p] = random(0, LED_Y_PIXELS);
|
|
|
+ frame[p][pos[p]][0] = colors[p][0] = randColor();
|
|
|
+ frame[p][pos[p]][1] = colors[p][1] = randColor();
|
|
|
+ frame[p][pos[p]][2] = colors[p][2] = randColor();
|
|
|
+ } else {
|
|
|
+ pos[p] = -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ printFrame();
|
|
|
+
|
|
|
+ for (int step = 0; step < steps; step++) {
|
|
|
+ fadebyint(fadefactor);
|
|
|
+ for (int p = 0; p < LED_X_PIXELS; p++) {
|
|
|
+ if (pos[p] == 0) {
|
|
|
+ //Serial.print("Position "); Serial.print(p); Serial.println(" hit bottom");
|
|
|
+ pos[p] = -1; // it hit the bottom
|
|
|
+ }
|
|
|
+ if (pos[p] > 0) {
|
|
|
+ //Serial.print("Position "); Serial.print(p); Serial.print(" dropping from "); Serial.println(pos[p]);
|
|
|
+ pos[p]--; // drop down one
|
|
|
+ frame[p][pos[p]][0] = colors[p][0];
|
|
|
+ frame[p][pos[p]][1] = colors[p][1];
|
|
|
+ frame[p][pos[p]][2] = colors[p][2];
|
|
|
+ }
|
|
|
+ if (pos[p] == -1 && random(0, 100) <= chance) {
|
|
|
+ // spawn a new one
|
|
|
+ //Serial.print("Position "); Serial.print(p); Serial.println(" spawning.");
|
|
|
+ pos[p] = LED_Y_PIXELS - 1;
|
|
|
+ frame[p][pos[p]][0] = colors[p][0] = randColor();
|
|
|
+ frame[p][pos[p]][1] = colors[p][1] = randColor();
|
|
|
+ frame[p][pos[p]][2] = colors[p][2] = randColor();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void randomcycle(int delaytime, int steps, int stepspercycle) {
|
|
|
+ // start with random colors
|
|
|
+ unsigned char colors[LED_X_PIXELS][LED_Y_PIXELS][3];
|
|
|
+ for (int x = 0; x < LED_X_PIXELS; x++) {
|
|
|
+ for (int y = 0; y < LED_Y_PIXELS; y++) {
|
|
|
+ colors[x][y][0] = randColor();
|
|
|
+ colors[x][y][1] = randColor();
|
|
|
+ colors[x][y][2] = randColor();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int step = 0; step < steps; step++) {
|
|
|
+ float factor = 0.5 + 0.5 * sin( (2.0 * 3.14 * step / stepspercycle));
|
|
|
+ //Serial.print("Factor = "); Serial.println(factor);
|
|
|
+ for (int x = 0; x < LED_X_PIXELS; x++) {
|
|
|
+ for (int y = 0; y < LED_Y_PIXELS; y++) {
|
|
|
+ frame[x][y][0] = (unsigned char) floor(factor * colors[x][y][0]);
|
|
|
+ frame[x][y][1] = (unsigned char) floor(factor * colors[x][y][1]);
|
|
|
+ frame[x][y][2] = (unsigned char) floor(factor * colors[x][y][2]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+float distance(int x1, int x2, int y1, int y2) {
|
|
|
+ return (float) sqrt( pow((x2 - x1), 2) + pow((y2 - y1), 2) );
|
|
|
+}
|
|
|
+
|
|
|
+void one_gradientcycle(int delaytime, int stepspercycle) {
|
|
|
+ int c_x = random(0, LED_X_PIXELS);
|
|
|
+ int c_y = random(0, LED_Y_PIXELS);
|
|
|
+ unsigned char basecolor[3];
|
|
|
+ basecolor[0] = randColor();
|
|
|
+ basecolor[1] = randColor();
|
|
|
+ basecolor[2] = randColor();
|
|
|
+
|
|
|
+ float maxdistance = distance(c_x, 0, c_y, 0);
|
|
|
+
|
|
|
+ unsigned char colors[LED_X_PIXELS][LED_Y_PIXELS][3];
|
|
|
+ for (int x = 0; x < LED_X_PIXELS; x++) {
|
|
|
+ for (int y = 0; y < LED_Y_PIXELS; y++) {
|
|
|
+ float gradfactor = 0.5 + 0.5 * sin( 2.0 * 3.14 * distance(x, c_x, y, c_y) / maxdistance - 3.14/2);
|
|
|
+ colors[x][y][0] = (unsigned char) floor(gradfactor * basecolor[0]);
|
|
|
+ colors[x][y][1] = (unsigned char) floor(gradfactor * basecolor[1]);
|
|
|
+ colors[x][y][2] = (unsigned char) floor(gradfactor * basecolor[2]);
|
|
|
+ //Serial.print("Base color: "); Serial.print(colors[x][y][0]);
|
|
|
+ //Serial.print("; Distance: "); Serial.print(distance(x,y));
|
|
|
+ //Serial.print("; Factor: "); Serial.print(gradfactor);
|
|
|
+ //Serial.print("; Setting color: "); Serial.println(colors[x][y][0]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int step = 0; step < stepspercycle; step++) {
|
|
|
+ float factor = 0.5 + 0.5 * sin( -3.14/2 + (2.0 * 3.14 * step / stepspercycle));
|
|
|
+ //Serial.print("Factor = "); Serial.println(factor);
|
|
|
+ for (int x = 0; x < LED_X_PIXELS; x++) {
|
|
|
+ for (int y = 0; y < LED_Y_PIXELS; y++) {
|
|
|
+ frame[x][y][0] = (unsigned char) floor(factor * colors[x][y][0]);
|
|
|
+ frame[x][y][1] = (unsigned char) floor(factor * colors[x][y][1]);
|
|
|
+ frame[x][y][2] = (unsigned char) floor(factor * colors[x][y][2]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ printFrame();
|
|
|
+ delay(delaytime);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void gradientcycle(int delaytime, int steps, int stepspercycle) {
|
|
|
+ for(int step = 0; step < steps/stepspercycle; step++) {
|
|
|
+ one_gradientcycle(delaytime, stepspercycle);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * still not sure how to do this since we're not a square.
|
|
|
+void pilotsquare(int delaytime, int steps) {
|
|
|
+ int center_x = floor((LED_X_PIXELS - 1) / 2);
|
|
|
+ int center_width = LED_X_PIXELS % 2 == 0 ? 2 : 1; // odd numbers have a 1x1 center
|
|
|
+ int center_y = floor((LED_Y_PIXELS - 1) / 2);
|
|
|
+ int center_height = LED_Y_PIXELS % 2 == 0 ? 2 : 1;
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+*/
|