Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Progressed a little on shiftbrite_slave. Really primitive command

language is present, though you can't do much.
  • Loading branch information...
commit e0bf693dcd807c549326d0089e23c9a46620967d 1 parent 6489380
Chris Hodapp authored
View
12 README
@@ -1,6 +1,12 @@
-Various stuff to work with the Hive13 LED windowmatrix
-
-More info:
+Various things to work with the Hive13 LED window matrix.
+More info about that window matrix is here:
http://wiki.hive13.org/Glass_Block_LED_Matrix
+For the Arduino with a Shiftbrite Shield and a string of Shiftbrite LEDs:
+ - shiftbrite_slave contains (unfinished) firmware to turn the Arduino into a
+slave which receives commands over the serial port to control what is
+displayed.
+ - Shiftbrite_plasma contains firmware to run a few display demos such as
+plasma or Conway's Game of Life.
+
View
26 Shiftbrite_plasma/Rainbow_Plasma.pde
@@ -2,7 +2,7 @@
// amount of other stuff that's been added to this...
// Choose which demo is run here:
-enum { PLASMA, CONWAY_LIFE, COLORTEST } demo = PLASMA;
+enum { PLASMA, CONWAY_LIFE, COLORTEST } demo = CONWAY_LIFE;
/*
@@ -49,12 +49,10 @@ based on Pladma for the Meggy Jr. by Ken Corey
#define screenHeight 8
#define paletteSize 64
-#define MAXBRIGHT 1023 // not used?
-
-// dotclock / current register setup - 0 - 127: ~30% - 100% power
-#define MAXCURRENTRED 120
-#define MAXCURRENTGREEN 120
-#define MAXCURRENTBLUE 120
+#define MAXBRIGHT 1023
+#define MAXCURRENTRED 50
+#define MAXCURRENTGREEN 50
+#define MAXCURRENTBLUE 50
// Pins.
#define clockpin 13 // CI
@@ -123,7 +121,7 @@ lifeStateType lifeTable[screenWidth][screenHeight];
long lifeResetCycle = 100;
// How many cycles until a simulation that has not changed
// resets itself.
-long idleResetCycle = 5;
+long idleResetCycle = 3;
// Current cycle
long lifeCycle = 0;
@@ -168,7 +166,9 @@ void cycle_game_of_life() {
// lifeCycle intentionally starts out at 0 so it is initialized
// when it first runs.
if (lifeCycle % lifeResetCycle == 0) {
- float p = random(250,750)/1000.0;
+ // Denser configurations die out very quickly, so p is kept
+ // in [0.125, 0.5]
+ float p = random(125,500)/1000.0;
life_randomize(p);
char buf[100];
// Using %f doesn't work for some reason. I get a question mark.
@@ -231,21 +231,21 @@ void cycle_game_of_life() {
break;
case STARVED:
- r = 255;
+ r = 32;
if (neighbors == 3) newState = BORN;
else newState = DEAD;
break;
case OVERCROWDED:
- g = 255;
+ g = 32;
if (neighbors == 3) newState = BORN;
else newState = DEAD;
break;
case BORN:
- b = 255;
+ b = g = 255;
if (neighbors < 2) newState = STARVED;
else if (neighbors > 3) newState = OVERCROWDED;
@@ -295,7 +295,7 @@ void cycle_game_of_life() {
Serial.println("Game has been idle too long. Triggering reset.");
}
- delay(500);
+ delay(1500);
}
int count_live_neighbors(int x, int y) {
View
134 shiftbrite_slave/shiftbrite_slave.pde
@@ -5,6 +5,12 @@
//
// It is based off of Rainbow_Plasma.pde from the existing code in the repo.
// =============================================================================
+// As of now it also has a really rudimentary serial command language.
+// cC clears the screen (it's overwritten very quickly though)
+// cQ queries for screen size (it will reply with x and y)
+// (First byte is BLOCK_START, which is now "c" - it signifies the start of the
+// command. Second byte is the command (see macros starting with CMD_). C and Q
+// are the only functioning ones right now.
#include <math.h>
#include <avr/pgmspace.h>
@@ -47,17 +53,43 @@ int frame = 0;
// WriteLEDArray
int LEDArray[screenWidth][screenHeight][3] = {0};
+// For our serial command protocol
+// ===============================
+
+// c
+#define BLOCK_START 0x63
+
+// P
+#define CMD_PING 0x50
+// Q
+#define CMD_QUERY 0x51
+// D
+#define CMD_DEMO 0x44
+// F
+#define CMD_FRAME 0x46
+// C
+#define CMD_CLEAR 0x43
+
// =============================================================================
// Function prototypes
// =============================================================================
void SetPixel(int x, int y, int r, int g, int b);
void WriteLEDArray();
+void checkSerial();
// =============================================================================
// Arduino entry points
// =============================================================================
void setup() {
+ // These serial messages probably should be removed once a proper command
+ // system is added.
Serial.begin(9600);
+ {
+ char buf[100];
+ snprintf(buf, 100, "Hello from Arduino with %ix%i LED screen.", screenWidth, screenHeight);
+ //Serial.println(buf);
+ }
+
//_init();
// Set board LED pin - ledPin
@@ -81,6 +113,8 @@ void setup() {
delayMicroseconds(15);
digitalWrite(latchpin,LOW);
+ //Serial.println("Shiftbrite initialization done.");
+
// Initialize the screen
for(int x = 0; x < screenWidth; ++x) {
for(int y = 0; y < screenHeight; ++y) {
@@ -90,6 +124,9 @@ void setup() {
SetPixel(x, y, r, g, b);
}
}
+ WriteLEDArray();
+
+ //Serial.println("Wrote first frame.");
}
void loop() {
@@ -98,17 +135,43 @@ void loop() {
else digitalWrite(13, LOW);
// Compute a frame
+ /*
for(int x = 0; x < screenWidth; ++x) {
for(int y = 0; y < screenHeight; ++y) {
- int r = (x * 255 / screenWidth + frame >> 2) & 0xFF;
- int g = (y * 255 / screenHeight + frame >> 3) & 0xFF;
- int b = (frame >> 4) & 0xFF;
+ int r = (x * 255 / screenWidth + frame >> 9) & 0xFF;
+ int g = (y * 255 / screenHeight + frame >> 10) & 0xFF;
+ int b = (frame >> 11) & 0xFF;
SetPixel(x, y, r, g, b);
}
}
+ */
+
+ // Shift everything by one column.
+ for(int x = screenWidth-1; x > 0; --x) {
+ for(int y = 0; y < screenHeight; ++y) {
+ LEDArray[x][y][0] = LEDArray[x-1][y][0];
+ LEDArray[x][y][1] = LEDArray[x-1][y][1];
+ LEDArray[x][y][2] = LEDArray[x-1][y][2];
+ }
+ }
+ // Add in a new column with random colors
+ for(int y = 0; y < screenHeight; ++y) {
+ LEDArray[0][y][0] = random(0,255);
+ LEDArray[0][y][1] = random(0,255);
+ LEDArray[0][y][2] = random(0,255);
+ }
+ int d = 250.0 * (sin(frame >> 4) + 1.0);
+ /*char buf[100];
+ snprintf(buf, 100, "%i", d);
+ Serial.println(buf);*/
+ delay(d);
+ //delay(500);
+
// Actually send that frame
WriteLEDArray();
+
+ checkSerial();
// Increment frame number
++frame;
@@ -166,6 +229,71 @@ void WriteLEDArray() {
}
// =============================================================================
+// Serial communication
+// =============================================================================
+void checkSerial() {
+ byte b;
+ long i = 0;
+
+ enum { WAITING, INSIDE_COMMAND } state;
+ state = WAITING;
+
+ while (Serial.available() > 0) {
+ b = Serial.read();
+ switch(state) {
+ case WAITING:
+ if (b == BLOCK_START) {
+ state = INSIDE_COMMAND;
+ } else {
+ // Some sort of error here...
+ }
+ break;
+ case INSIDE_COMMAND:
+ switch(b) {
+ case CMD_PING:
+ Serial.println("Ping");
+ break;
+ case CMD_DEMO:
+ Serial.println("Demo");
+ break;
+ case CMD_CLEAR:
+ Serial.println("Clearing");
+ for(int x = 0; x < screenWidth; ++x) {
+ for(int y = 0; y < screenHeight; ++y) {
+ LEDArray[x][y][0] = 0;
+ LEDArray[x][y][1] = 0;
+ LEDArray[x][y][2] = 0;
+ }
+ }
+ break;
+ case CMD_FRAME:
+ Serial.println("Frame...");
+ break;
+ case CMD_QUERY:
+ char buf[100];
+ snprintf(buf, 100, "%i %i", screenWidth, screenHeight);
+ Serial.print(buf);
+ break;
+ default:
+ Serial.println("Unknown command!");
+ break;
+ }
+ state = WAITING;
+ break;
+ default:
+ break;
+ }
+ ++i;
+ }
+
+ if (i) {
+ char buf[100];
+ snprintf(buf, 100, "Just received %i bytes over serial.", i);
+ //Serial.println(buf);
+ }
+}
+
+// =============================================================================
// General graphics functionality
// =============================================================================
void SetPixel(int x, int y, int r, int g, int b)
Please sign in to comment.
Something went wrong with that request. Please try again.