Code used in RGB-123 Kickstarter. Conways Game of Life

Dependencies:   WS2811_RY_A mbed

Fork of WS2811_RY_A by ohararp@...

Revision:
1:1b91ef74cc9c
Parent:
0:f19c80146d55
--- a/main.cpp	Fri Jan 04 13:43:52 2013 +0000
+++ b/main.cpp	Thu Aug 15 20:22:48 2013 +0000
@@ -1,20 +1,65 @@
 #include "mbed.h"
+#include "matrix.h"
 Serial pc(USBTX, USBRX);
 DigitalOut dat(p5);
-
+DigitalOut bLed(LED1);
 
 //*******************************************************************************    
 // DEFINE WS2811 Strip Parameters
-#define numLEDs 64*5
-uint8_t *pixels;
+#define numLEDs 1536 
+#define BrightMax 64
+#define BrightMin 0
+
+#define ROWS_LEDs 32  // LED_LAYOUT assumed 0 if ROWS_LEDs > 8
+#define COLS_LEDs 48  // all of the following params need to be adjusted for screen size
+
+
+uint8_t RandRed;
+uint8_t RandGrn;
+uint8_t RandBlu;
+
+uint8_t pixels[numLEDs*3];
 Timer guardtime;
 uint32_t bogocal;
+//*******************************************************************************
+//Byte val 2PI Cosine Wave, offset by 1 PI 
+//supports fast trig calcs and smooth LED fading/pulsing.
+uint8_t cos_wave[256] =  
+{0,0,0,0,1,1,1,2,2,3,4,5,6,6,8,9,10,11,12,14,15,17,18,20,22,23,25,27,29,31,33,35,38,40,42,
+45,47,49,52,54,57,60,62,65,68,71,73,76,79,82,85,88,91,94,97,100,103,106,109,113,116,119,
+122,125,128,131,135,138,141,144,147,150,153,156,159,162,165,168,171,174,177,180,183,186,
+189,191,194,197,199,202,204,207,209,212,214,216,218,221,223,225,227,229,231,232,234,236,
+238,239,241,242,243,245,246,247,248,249,250,251,252,252,253,253,254,254,255,255,255,255,
+255,255,255,255,254,254,253,253,252,252,251,250,249,248,247,246,245,243,242,241,239,238,
+236,234,232,231,229,227,225,223,221,218,216,214,212,209,207,204,202,199,197,194,191,189,
+186,183,180,177,174,171,168,165,162,159,156,153,150,147,144,141,138,135,131,128,125,122,
+119,116,113,109,106,103,100,97,94,91,88,85,82,79,76,73,71,68,65,62,60,57,54,52,49,47,45,
+42,40,38,35,33,31,29,27,25,23,22,20,18,17,15,14,12,11,10,9,8,6,6,5,4,3,2,2,1,1,1,0,0,0,0
+};
 
+
+//Gamma Correction Curve
+uint8_t exp_gamma[256] =
+{0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,
+4,4,4,4,4,5,5,5,5,5,6,6,6,7,7,7,7,8,8,8,9,9,9,10,10,10,11,11,12,12,12,13,13,14,14,14,15,15,
+16,16,17,17,18,18,19,19,20,20,21,21,22,23,23,24,24,25,26,26,27,28,28,29,30,30,31,32,32,33,
+34,35,35,36,37,38,39,39,40,41,42,43,44,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,
+61,62,63,64,65,66,67,68,70,71,72,73,74,75,77,78,79,80,82,83,84,85,87,89,91,92,93,95,96,98,
+99,100,101,102,105,106,108,109,111,112,114,115,117,118,120,121,123,125,126,128,130,131,133,
+135,136,138,140,142,143,145,147,149,151,152,154,156,158,160,162,164,165,167,169,171,173,175,
+177,179,181,183,185,187,190,192,194,196,198,200,202,204,207,209,211,213,216,218,220,222,225,
+227,229,232,234,236,239,241,244,246,249,251,253,254,255
+};
 //*******************************************************************************
 void setup () {
-    if ((pixels = (uint8_t *)malloc(numLEDs * 3))) {
+    /*if ((pixels = (uint8_t *)malloc(numLEDs * 3))) {
         memset(pixels, 0x00, numLEDs * 3); // Init to RGB 'off' state
+    }*/
+    
+    for (int j=0; j<numLEDs*3; j++) {
+        pixels[j]=0x00;
     }
+    
     // calibrate delay loops for NRZ 
     int i;
     guardtime.start();
@@ -22,7 +67,8 @@
         /* do nothing */;
     i=guardtime.read_us();
     printf("ws2811:  1000 iters took %d usec.\n", i);
-    bogocal = (1000 / (i*4));//2.4)); // iterations per bitcell (417 nsec)
+    bogocal = (1000 / (i*10)); // iterations per bitcell (417 nsec)
+    bogocal = 1;
     printf("ws2811:  calibrating to %d bogojiffies.\n", bogocal);
 }
 //*******************************************************************************
@@ -74,12 +120,16 @@
 }
 //*******************************************************************************
 void blank(void) {
-    memset(pixels, 0x00, numLEDs * 3);
+    for (int i=0; i<numLEDs*3; i++) {
+        pixels[i]=0x00;
+    }
     show();
 }
 //*******************************************************************************
 void blankDelay(int n) {
-    memset(pixels, 0x00, numLEDs * 3);
+    for (int i=0; i<numLEDs*3; i++) {
+        pixels[i]=0x00;
+    }
     show();
     wait_ms(n);
 }
@@ -135,12 +185,41 @@
 // Fill the dots one after the other with a color
 void colorWipe(uint32_t c, uint8_t wait) {
   for(uint16_t i=0; i<numPixels(); i++) {
-      setPixelColor(i, c);
+      setPixelColor(Matrix[i], c);      
       show();
       wait_ms(wait);
   }
 }
 //*******************************************************************************
+// Fill the dots one after the other with a color
+void colorAll(uint32_t c, uint16_t wait) {
+  for(uint16_t i=0; i<numPixels(); i++) {
+      setPixelColor(Matrix[i], c);
+  }
+  show();
+  wait_ms(wait);
+}
+
+//*******************************************************************************
+// Fill the dots one after the other with a color
+void RandOne(uint8_t MaxRand, uint16_t wait) {
+  for(uint16_t i=0; i<numPixels(); i++) {
+        setPixelColor(Matrix[rand() % numLEDs-1], rand() % MaxRand,rand() % MaxRand,rand() % MaxRand);
+        show();
+        wait_ms(wait);
+  }
+
+}
+//*******************************************************************************
+// Fill the dots one after the other with a color
+void RandAll(uint8_t MaxRand, uint16_t wait) {
+  for(uint16_t i=0; i<numPixels(); i++) {
+        setPixelColor(Matrix[i], rand() % MaxRand,rand() % MaxRand,rand() % MaxRand);
+  }
+  show();
+  wait_ms(wait);
+}
+//*******************************************************************************
 // Input a value 0 to 255 to get a color value.
 // The colours are a transition r - g - b - back to r.
 uint32_t Wheel(int WheelPos) {
@@ -180,26 +259,349 @@
   }
 }
 //*******************************************************************************
+void Ring(int RingArray[], uint8_t r, uint8_t g, uint8_t b, uint8_t RingWait) {
+   
+    for (int i=1;i<RingArray[0];++i) {
+        setPixelColor(RingArray[i], r, g, b);
+        //pc.printf("RingArray[%d,%d]\n",RingArray[i],RingArray[0]);
+    }
+    show();
+    wait_ms(RingWait);
+}
+//*******************************************************************************
+void RingFadeUp(int RingArray[], uint8_t r, uint8_t g, uint8_t b, uint8_t FadeSteps, uint8_t FadeTime, uint16_t RingWait) {
+    uint8_t rBump, gBump, bBump;
+    uint8_t rStep, gStep, bStep;
+    
+    rStep = r/FadeSteps; if(rStep == 0) {rStep = 1;}
+    gStep = g/FadeSteps; if(gStep == 0) {gStep = 1;}
+    bStep = b/FadeSteps; if(bStep == 0) {bStep = 1;}
+        
+    rBump = 0;
+    gBump = 0;
+    bBump = 0;
+    
+    for (int j=0;j<FadeSteps;++j) {
+        rBump += rStep; if(rBump > BrightMax) {rBump = 0;} //Account for Int rollover
+        gBump += gStep; if(gBump > BrightMax) {gBump = 0;} //Account for Int rollover
+        bBump += bStep; if(bBump > BrightMax) {bBump = 0;} //Account for Int rollover
+        for (int i=1;i<RingArray[0];++i) {
+            setPixelColor(RingArray[i], rBump, gBump, bBump);
+            pc.printf("UP [%d,%d %d]\n",rBump, gBump, bBump);
+        }
+        show();
+    wait_ms(FadeTime);    
+    };
+    wait_ms(RingWait);
+}
+//*******************************************************************************
+void RingFadeDn(int RingArray[], uint8_t r, uint8_t g, uint8_t b, uint8_t FadeSteps, uint8_t FadeTime, uint16_t RingWait) {
+    uint8_t rBump, gBump, bBump;
+    uint8_t rStep, gStep, bStep;
+    
+    rStep = r/FadeSteps; if(rStep == 0) {rStep = 1;}
+    gStep = g/FadeSteps; if(gStep == 0) {gStep = 1;}
+    bStep = b/FadeSteps; if(bStep == 0) {bStep = 1;}
+    
+    rBump = r;
+    gBump = g;
+    bBump = b;
+    
+    for (int j=0;j<FadeSteps;++j) {
+        rBump -= rStep; if(rBump > BrightMax) {rBump = 0;} //Account for Int rollover
+        gBump -= gStep; if(gBump > BrightMax) {gBump = 0;} //Account for Int rollover
+        bBump -= bStep; if(bBump > BrightMax) {bBump = 0;} //Account for Int rollover
+        for (int i=1;i<RingArray[0];++i) {
+            setPixelColor(RingArray[i], rBump, gBump, bBump);
+            pc.printf("DN [%d,%d %d]\n",rBump, gBump, bBump);
+        }
+        show();
+    wait_ms(FadeTime);    
+    };
+    wait_ms(RingWait);
+}
+//*******************************************************************************
+uint8_t ColorRand(void) {
+    return (rand()%(BrightMax-BrightMin)+BrightMin);
+}
+//*******************************************************************************
+inline uint8_t fastCosineCalc( uint16_t preWrapVal)
+{
+  uint8_t wrapVal = (preWrapVal % 255);
+  if (wrapVal<=0){
+  wrapVal=255+wrapVal;
+  }
+  return cos_wave[wrapVal]; 
+}
+//*******************************************************************************
+void Plasma()
+{
+    unsigned long frameCount=25500;  // arbitrary seed to calculate the three time displacement variables t,t2,t3
+    while(1) {
+        frameCount++ ; //42 35 38
+        uint16_t t = fastCosineCalc((128 * frameCount)/100);  //time displacement - fiddle with these til it looks good...
+        uint16_t t2 = fastCosineCalc((128 * frameCount)/100); 
+        uint16_t t3 = fastCosineCalc((128 * frameCount)/100);
+        
+        for (uint8_t y = 0; y < ROWS_LEDs; y++) {
+          int left2Right, pixelIndex;
+          if (((y % (ROWS_LEDs/8)) & 1) == 0) {
+            left2Right = 1;
+            pixelIndex = y * COLS_LEDs;
+          } else {
+            left2Right = -1;
+            pixelIndex = (y + 1) * COLS_LEDs - 1;
+          }
+          for (uint8_t x = 0; x < COLS_LEDs ; x++) {
+            //Calculate 3 seperate plasma waves, one for each color channel
+            uint8_t r = fastCosineCalc(((x << 3) + (t >> 1) + fastCosineCalc((t2 + (y << 3)))));
+            uint8_t g = fastCosineCalc(((y << 3) + t + fastCosineCalc(((t3 >> 2) + (x << 3)))));
+            uint8_t b = fastCosineCalc(((y << 3) + t2 + fastCosineCalc((t + x + (g >> 2)))));
+            //uncomment the following to enable gamma correction
+            r=exp_gamma[r];  
+            g=exp_gamma[g];
+            b=exp_gamma[b];
+            setPixelColor(Matrix[pixelIndex],r,g,b);
+            //pc.printf("Plasma [%d,%d,%d %d]\n",pixelIndex,r,g,b);
+            pixelIndex += left2Right;
+          }
+        }
+        show();
+    }
+}
+
+//*******************************************************************************
+//http://onehourhacks.blogspot.com/2012/03/conways-game-of-life-on-arduino.html
+const int ROWS = 48;
+const int COLS = 32;
+int boardnum = 0; // number of boards run by the game
+int iteration = 0; // current round in the current board
+int numberAround(int row, int col);
+
+// The "Alive" cells on the board.
+uint32_t alive[ROWS] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+//*******************************************************************************
+bool isAlive(int row, int col)
+{
+return alive[row] & (1<<(col));
+}
+//*******************************************************************************
+void setAlive(int row, int col)
+{
+alive[row] |= 1 << col;
+}
+//*******************************************************************************
+/*
+ * Sets the alive array to all falses.
+ */
+void blank_alive()
+{
+for(int i = 0; i < ROWS; ++i)
+ alive[i] = 0;
+}
+//*******************************************************************************
+/**
+ * Writes output to the console.
+ */
+ 
+void do_output()
+{
+ //blank();
+ //pc.printf("Board: %d",boardnum);
+ //pc.printf(" Iteration: %d\n",iteration);
+    for(int i = 0; i < ROWS; i++)
+    {
+     for(int j = 0; j < COLS; j++)
+     {
+      // WIDTH, HEIGHT
+      if(isAlive(i,j))
+       {
+       setPixelColor(Matrix[i+RowIdx[j]],rand() % BrightMax,rand() % BrightMax,rand() % BrightMax);
+       //pc.printf("Alive: %d %d\n",i,j);
+       }
+      else
+       setPixelColor(Matrix[i+RowIdx[j]],0,0,0);
+     }
+    }
+}
+
+/**
+ * Randomly fills the grid with alive cells after blanking.
+ */
+void random_fill()
+{
+blank_alive();
+
+// Fill up 10-30% of the cells
+int numToFill = (ROWS * COLS) * (rand() % 30+10) / 100 ;
+
+for(int r = 0; r < numToFill; r ++)
+{
+ int row = rand() % ROWS;
+ int col = rand() % COLS;
+ 
+ setAlive(row,col);
+}
+}
+
+/**
+ * Returns the index of the row below the current one.
+ */
+int rowBelow(int row)
+{
+return (row + 1 < ROWS) ? row + 1 : 0;
+}
+
+/**
+ * Returns the index of the row above the given one
+ */
+int rowAbove(int row)
+{
+return (row > 0) ? row - 1 : ROWS - 1;
+}
+
+/** Returns the index of the col to the right of this one */
+int colRight(int col)
+{
+return (col + 1 < COLS) ? col + 1 : 0;
+}
+
+/** Returns the index of the col to the left of this one */
+int colLeft(int col)
+{
+return (col > 0) ? col - 1 : COLS -1;
+}
+
+/** true if the cell to the left is alive*/
+bool left(int row, int col)
+{
+col = colLeft(col);
+return isAlive(row,col);
+}
+
+/** true if the cell to the right is alive*/
+bool right(int row, int col)
+{
+col = colRight(col);
+return isAlive(row,col);
+}
+
+/** true if the cell above is alive*/
+bool above(int row, int col)
+{
+row = rowAbove(row);
+return isAlive(row,col);
+}
+
+/** true if the cell below is alive*/
+bool below(int row, int col)
+{
+row = rowBelow(row);
+return isAlive(row,col);
+}
+
+/** true if the cell NE is alive*/
+bool aboveright(int row, int col)
+{
+row = rowAbove(row);
+col = colRight(col);
+return isAlive(row,col);
+}
+
+/** true if the cell SE is alive*/
+bool belowright(int row, int col)
+{
+row = rowBelow(row);
+col = colRight(col);
+return isAlive(row,col);
+}
+
+/** true if the cell NW is alive*/
+bool aboveleft(int row, int col)
+{
+row = rowAbove(row);
+col = colLeft(col);
+return isAlive(row,col);
+}
+
+/** true if the cell SW is alive*/
+bool belowleft(int row, int col)
+{
+row = rowBelow(row);
+col = colLeft(col);
+return isAlive(row,col);
+}
+
+/**Returns the number of living cells sorrounding this one.*/
+int numberAround(int row, int col)
+{
+int around = 0;
+if(left(row,col))
+ around++;
+
+if(right(row,col))
+ around++;
+
+if(above(row,col))
+ around++;
+
+if(below(row,col))
+ around++;
+
+if(aboveright(row,col))
+ around++;
+
+if(aboveleft(row,col))
+ around++;
+
+if(belowright(row,col))
+ around++;
+
+if(belowleft(row,col))
+ around++;
+
+return around;
+}
+
+/**
+ * Moves all of the cells
+ */
+void move()
+{
+uint32_t nextRows[ROWS] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+for(int i = 0; i < ROWS; i++)
+{
+ for(int j = 0; j < COLS; j++)
+ {
+  int na = numberAround(i,j);
+  if((na == 2 && isAlive(i,j)) || na == 3)
+   nextRows[i] |= 1 << j;
+ }
+}
+for(int i = 0; i < ROWS; i++)
+ alive[i] = nextRows[i];
+}
+
+//*******************************************************************************
 int main() {
     pc.baud(38400);
     setup();
     while (1) {
         pc.printf("Top of the Loop\n");
-        colorWipe(Color(64, 0, 0), 50); // Red
-        blankDelay(250);
-        colorWipe(Color(0, 64, 0), 50); // Grn
-        blankDelay(250);
-        colorWipe(Color(0, 0, 64), 50); // Blu
-        blankDelay(250);
-        //rainbow(20);
-        //blankDelay(250);
-        //rainbowCycle(10);
-        //blankDelay(250);
+        bLed = !bLed;
+        blankDelay(0);
+  
+        boardnum++;
+        random_fill();
         
+        for(iteration = 0;iteration < 500; iteration++)
+        {
+         do_output();
+         show();
+         move(); 
+         wait_ms(0);
+        }
     }
-}
-
-//write(128);
-//wait_us(10);
-//write(0);
-//wait_us(10);
\ No newline at end of file
+}
\ No newline at end of file