From 46b967452cf2310d5bb7d741dd395781dcaf53d6 Mon Sep 17 00:00:00 2001 From: workinghard Date: Sun, 16 Oct 2016 23:51:52 -0700 Subject: [PATCH] init. --- Cube4Fun_CUBE_v1/Cube4Fun_CUBE_v1.ino | 640 ++++++++++++++++++++++++++ 1 file changed, 640 insertions(+) create mode 100644 Cube4Fun_CUBE_v1/Cube4Fun_CUBE_v1.ino diff --git a/Cube4Fun_CUBE_v1/Cube4Fun_CUBE_v1.ino b/Cube4Fun_CUBE_v1/Cube4Fun_CUBE_v1.ino new file mode 100644 index 0000000..7961a59 --- /dev/null +++ b/Cube4Fun_CUBE_v1/Cube4Fun_CUBE_v1.ino @@ -0,0 +1,640 @@ +#include +#include + +//#define DEBUG true +#define COLORSHIFTTIME 100 +#define MAXSTACKSIZE 256 +#define NEWFRAMETIMEOUT 5000 + +#ifdef DEBUG + #define DEBUG_PRINTLN(x) Serial.println (x) + #define DEBUG_PRINT(x) Serial.print (x) + #define DEBUG_PRINTLN_TXT(x) Serial.println (F(x)) + #define DEBUG_PRINT_TXT(x) Serial.print (F(x)) +#else + #define DEBUG_PRINTLN(x) + #define DEBUG_PRINT(x) + #define DEBUG_PRINTLN_TXT(x) + #define DEBUG_PRINT_TXT(x) +#endif + + +// Plasmamatrix +/* +static unsigned char RED[64] = {255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,238,221,204,188,171,154,137,119,102,85, +68,51,34,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,35,52}; +static unsigned char GREEN[64] = {0,17,34,51,68,85,102,119,136,153,170,187,204,221,238,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,238,221,204,188,170,154,136,120,102,86,68,52,34,18,0,0,0,0}; +static unsigned char BLUE[64] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,34,52,68,86,102,120,136,154,170,188, +204,221,238,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255}; +*/ + +// New balanced colors +static unsigned char RED[256] = {255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,247,243,238,230,226,217,213,209, + 200,196,188,183,179,171,166,158,154,145,141,137,128,124,115,111,107,98,94,85,81,77,68,64,56,51,47,39,34, + 26,22,13,9,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,9,13,22,26,35,39,43,52,56, + 64,68,77,81,85,94,98,107,111,115,124,128,136,141,145,153,158,166,171,179,183,188,196,200,209,213,217,226, + 230,239,243,247,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0}; +static unsigned char GREEN[256] = {0,0,7,17,22,30,34,39,47,51,60,64,68,77,81,90,94,98,107,111,119,124,132,136,141,149,153,162,166,170,179, + 183,192,196,200,209,213,221,226,230,238,243,251,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,251,243,238,230,226,221,213,209,200,196, + 192,183,179,170,166,158,154,149,141,136,128,124,120,111,107,98,94,90,81,77,68,64,56,52,47,39,34,26,22,18,9, + 5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0}; +static unsigned char BLUE[256] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,9,18,22,26,34,39,47,52,56,64, + 68,77,81,90,94,98,107,111,120,124,128,136,141,149,154,158,166,170,179,183,188,196,200,209,213,221,226,230, + 238,243,251,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,251,243,239,234,226,221,213,209,200,196,192,183,179,171,166,162,153,149,141, + 136,132,124,120,111,107,103,94,90,81,77,68,64,60,52,47,39,35,30,22,17,255,0}; + +//unsigned char _buffer_2D[8][8]; // PlasmaMatrix = buffer_2D +unsigned char _buffer2_3D[4][4][4]; // +unsigned char _buffer1_3D[4][4][4]; // +unsigned char (* displayBuffer)[4][4][4]; +unsigned char (* writeBuffer)[4][4][4]; +int writeBuffer_top = 0; +unsigned char _receive_buffer[MAXSTACKSIZE]; +unsigned char _receive_buffer_top = 0; +unsigned char _receive_buffer_bot = 0; +unsigned long streamStartedTime = 0; +unsigned long newFrameMillis = 0; +unsigned char z,x,y,colorshift=0; +long animation = 0; +unsigned long lastChangeTime = 0; +unsigned long lastColorShift = 0; +const long animInterval = 300000; // 5 minutes +int __state = 0; // 0 = waiting for cmd +int __stateEnd = 0; // 0 = start +boolean newFrame = false; + +unsigned const char lc_slash = '/'; +unsigned const char lc_question = '?'; +unsigned const char lc_coma = ','; +unsigned const char lc_space = ' '; + + + +/* +Der Sketch verwendet 8.602 Bytes (28%) des Programmspeicherplatzes. Das Maximum sind 30.720 Bytes. +Globale Variablen verwenden 1.763 Bytes (86%) des dynamischen Speichers, 285 Bytes für lokale Variablen verbleiben. Das Maximum sind 2.048 Bytes. +Wenig Arbeitsspeicher verfügbar, es können Stabilitätsprobleme auftreten. + +Der Sketch verwendet 8.594 Bytes (27%) des Programmspeicherplatzes. Das Maximum sind 30.720 Bytes. +Globale Variablen verwenden 1.761 Bytes (85%) des dynamischen Speichers, 287 Bytes für lokale Variablen verbleiben. Das Maximum sind 2.048 Bytes. + +Der Sketch verwendet 8.568 Bytes (27%) des Programmspeicherplatzes. Das Maximum sind 30.720 Bytes. +Globale Variablen verwenden 1.767 Bytes (86%) des dynamischen Speichers, 281 Bytes für lokale Variablen verbleiben. Das Maximum sind 2.048 Bytes. +*/ + +// int receivePart; +/* +byte displayLength = 0; +char blinkColor = 'r'; +boolean blinkSet = false; + +unsigned char blinkCount = 0; +boolean streamMode = false; + +unsigned long lastChangeTime = 0; + +const long animInterval = 300000; // 5 minutes +const long streamTimeoutInterval = 5000; // 5 seconds +#define BLINK_COUNT_MAX 7 +const long blinkInterval = 1000; // interval at which to blink (milliseconds) +unsigned long blinkPreviousMillis = 0; +*/ + + +// --------------- FUNCTIONS ---------------- // +void genPlasmaMatrix() { + // Generate Plasma-Array + for(x = 0; x < 8; x++) { + for(y = 0; y < 8; y++) { + uint32_t color = int(32.0 + (32.0 * sin(x / 4.0)) + 32.0 + (32.0 * sin(y / 4.0))) / 2; + setByteColor2D(color); + } + } +} + +void genPlasmaMatrix2() { + // Generate Plasma2-Array + for(x = 0; x < 8; x++) { + for(y = 0; y < 8; y++) { + uint32_t color = int(32.0 + (32.0 * sin(x / 1.0)) + 32.0 + (32.0 * sin(y / 1.0))) / 2; + setByteColor2D(color); + } + } +} + +void genPlasmaCube() { + // Generate PlasmaCube-Array + for(x = 0; x < 4; x++) { + for(y = 0; y < 4; y++) { + for(z = 0; z < 4; z++) { + int color = int(32.0 + (32.0 * sin(x / 1.0))+ 32.0 + (32.0 * sin(y / 1.0)) + 32.0 + (32.0 * sin(z / 1.0))) / 3; + setByteColor3D(color); + } + } + } +} + +void genPlasmaCube2() { + // Generate PlasmaCube2-Array + for(x = 0; x < 4; x++) { + for(y = 0; y < 4; y++) { + for(z = 0; z < 4; z++) { + int color = int(32.0 + (32.0 * sin(x / 4.0))+ 32.0 + (32.0 * sin(y / 4.0)) + 32.0 + (32.0 * sin(z / 4.0))) / 3; + setByteColor3D(color); + } + } + } +} + +void genPlasmaCube3() { + // Generate PlasmaCube3-Array + for(x = 0; x < 4; x++) { + for(y = 0; y < 4; y++) { + for(z = 0; z < 4; z++) { + int color = int(32.0 + (32.0 * sin(x / 8.0))+ 32.0 + (32.0 * sin(y / 8.0)) + 32.0 + (32.0 * sin(z / 8.0))) / 3; + setByteColor3D(color); + } + } + } +} + +void setByteColor2D(uint32_t color) { + unsigned char color255 = (color * 4 + colorshift ) % 256; // Transform to 8 Bit color + if ( color255 > 0 ) { + if ( color255 > 253 ) { // 254 and 255 are reserved + color255 = 253; + } + }else{ + color255 = 0; + } // Range 0 ... 253 + + Rb.setPixelXY(x,y,RED[color255],GREEN[color255],BLUE[color255]); +} + +void setByteColor3D(uint32_t color) { + unsigned char color255 = (color * 4 + colorshift ) % 256; // Transform to 8 Bit color + if ( color255 > 0 ) { + if ( color255 > 253 ) { // 254 and 255 are reserved + color255 = 253; + } + }else{ + color255 = 0; + } // Range 0 ... 253 + + Rb.setPixelZXY(z,x,y,RED[color255],GREEN[color255],BLUE[color255]); +} + +/* +void draw2D() { + for(x=0;x<8;x++) { + for(y=0;y<8;y++) { + setByteColor2D(); + } + } +} +*/ + +/* +void draw3D() { + for(x=0;x<4;x++) { + for(y=0;y<4;y++) { + for(z=0;z<4;z++) { + setByteColor3D(); + } + } + } +} +*/ + +/* +void drawMoodlamp() { + for(z=0; z<254 ;z++) { + for(x=0;x<8;x++) { + for(y=0;y<8;y++) { + //Paint random colors + Rb.setPixelXY(x,y,RED[z],GREEN[z],BLUE[z]); //uses R, G and B color bytes + } + } + delay(100); + } + for(z=253; z > 0 ;z--) { + for(x=0;x<8;x++) { + for(y=0;y<8;y++) { + //Paint random colors + Rb.setPixelXY(x,y,RED[z],GREEN[z],BLUE[z]); //uses R, G and B color bytes + } + } + delay(100); + } +} +*/ + +void drawNewFrame() { + for(x=0;x<4;x++) { + for(y=0;y<4;y++) { + for(z=0;z<4;z++) { + Rb.setPixelZXY(z,x,y,(RED[(*displayBuffer)[x][y][z]]),(GREEN[(*displayBuffer)[x][y][z]]),(BLUE[(*displayBuffer)[x][y][z]])); //uses R, G and B color bytes + } + } + } + // Update the timeout timer + streamStartedTime = millis(); +} + +void changeAnim() { + animation = random(0,5); + //animation = 0; +} + + +// Flip the write and display buffer +void flipBuffer() { + unsigned char (* p_tmp)[4][4][4]; + p_tmp = displayBuffer; + displayBuffer = writeBuffer; + writeBuffer = p_tmp; + + // Remember the timestamp + newFrameMillis = millis(); +} + + + +void receiveEvent(int howMany) { + while ( Wire.available() > 0 ) { + if ( _receive_buffer_top < MAXSTACKSIZE ) { + _receive_buffer[_receive_buffer_top] = (unsigned char)Wire.read(); + _receive_buffer_top ++; + }else{ + DEBUG_PRINTLN_TXT("Buffer overflow"); + Wire.read(); // Empty the queue + } + } +} + + +/* + +// function that executes whenever data is received from master +// this function is registered as an event, see setup() +void receiveEvent(int howMany) { + DEBUG_PRINT_TXT("Howmany: "); + DEBUG_PRINTLN(howMany); + DEBUG_PRINT_TXT("Wire-Available: "); + DEBUG_PRINTLN(Wire.available()); + if(Wire.available() > 0) { + // receive Data in parts + if ( receivePart > 0 && receivePart < 3 && Wire.available() == 32) { + switch (receivePart) { + unsigned char receivedValue; + case 1 : // Part 1 + for(y=0;y<4;y++) { + for(z=0;z<4;z++) { + receivedValue = Wire.read(); + buffer3D[0][y][z] = receivedValue; + //DEBUG_PRINT(receivedValue); + } + } + for(y=0;y<4;y++) { + for(z=0;z<4;z++) { + receivedValue = Wire.read(); + buffer3D[1][y][z] = receivedValue; + //DEBUG_PRINT(receivedValue); + } + } + receivePart++; + break; + case 2 : // Part2 + for(y=0;y<4;y++) { + for(z=0;z<4;z++) { + receivedValue = Wire.read(); + buffer3D[2][y][z] = receivedValue; // integer read + //DEBUG_PRINT(receivedValue); + } + } + for(y=0;y<4;y++) { + for(z=0;z<4;z++) { + receivedValue = Wire.read(); + buffer3D[3][y][z] = receivedValue; // integer read + //DEBUG_PRINT(receivedValue); + } + } + if ( true == streamMode ) { + receivePart = 0; + newFrame = true; + }else{ + receivePart++; + } + break; + default: + receivePart++; + } + return; // go back + + } + if ( receivePart > 3 ) { // Reset if something went wrong + DEBUG_PRINTLN_TXT("Incomplete data received. receivePart > 3"); + receivePart = 0; + } + + + char c = Wire.read(); // first char identify the command + //DEBUG_PRINTLN_TXT("Data received"); + //DEBUG_PRINT(c); + switch (c) { + case 'f' : // Frame was sent + DEBUG_PRINTLN_TXT("Frame receive started"); + receivePart = 1; + break; + case 'F' : // Frame completed + displayLength = Wire.read(); // how long should it be displayed + DEBUG_PRINT(displayLength); + if ( receivePart == 3 ) { + newFrame = true; + DEBUG_PRINTLN_TXT("Frame data received"); + } + receivePart = 0; // Reset the counter + break; + case 'b' : // Blink command + blinkSet = true; + blinkColor = Wire.read(); + blinkCount = 0; + DEBUG_PRINTLN_TXT("Blink data received"); + break; + case 'd' : // Delete screen + performClearScreen(); + DEBUG_PRINTLN_TXT("Clear screen received"); + break; + case 's' : // Stream mode + DEBUG_PRINTLN_TXT("Stream mode set"); + streamMode = true; + receivePart = 1; + streamStartedTime = millis(); + break; + case 'n' : // Next frame + //DEBUG_PRINTLN_TXT("Expect next frame"); + receivePart = 1; + break; + case 'S' : // Stream mode ended + DEBUG_PRINTLN_TXT("Stream mode ended"); + streamMode = false; + receivePart = 0; + return; + break; + } + + if ( newFrame == false && blinkSet == false && receivePart < 1) { + DEBUG_PRINTLN_TXT("Incomplete data received"); + DEBUG_PRINTLN(streamMode); + //streamMode = false; + blinkSet = false; + receivePart = 0; + // clear rest buffer + while ( Wire.available() > 0 ) { + char c = Wire.read(); + } + } + } +} + +*/ + +void fillBuffer(unsigned char pc_input, int p_pos) { + int li_tmp = 0; + for(int lx=0;lx<4;lx++) { + for(int ly=0;ly<4;ly++) { + for(int lz=0;lz<4;lz++) { + if ( li_tmp == p_pos ) { + (*writeBuffer)[lx][ly][lz] = pc_input; + return; + } + li_tmp++; + } + } + } +} +unsigned char getBuffer(int p_pos) { + int li_tmp = 0; + for(int lx=0;lx<4;lx++) { + for(int ly=0;ly<4;ly++) { + for(int lz=0;lz<4;lz++) { + if ( li_tmp == p_pos ) { + return (*writeBuffer)[lx][ly][lz]; + } + li_tmp++; + } + } + } + return 0; +} + +int checkEnd(unsigned char pc_input) { + int isEnd = 1; + switch (__stateEnd) { + case 0: + if ( pc_input == lc_coma) { + __stateEnd = __stateEnd + 1; + } + break; + case 1: + if ( pc_input == lc_coma ) { + __stateEnd = __stateEnd + 1; + }else{ + __stateEnd = 0; // Roll back + } + break; + case 2: + if ( pc_input == lc_space ) { + __stateEnd = __stateEnd + 1; + }else{ + __stateEnd = 0; // Roll back + } + break; + case 3: + if ( pc_input == lc_space ) { + // End found + isEnd = 0; + } + __stateEnd = 0; // Roll back + + } + return isEnd; +} + + +void processIn(unsigned char pc_input) { + switch (__state) { + case 0: + if ( checkEnd(pc_input) == 0 ) { + // Reset the values + //DEBUG_PRINTLN_TXT("End found."); + //DEBUG_PRINT_TXT("Pos: "); + //DEBUG_PRINTLN(gi_buffer2_pos); + __state = 0; + writeBuffer_top = 0; + } + if ( pc_input == lc_slash ) { + __state = __state + 1; + //DEBUG_PRINTLN_TXT("0->1"); + } + break; + case 1: + if ( pc_input == lc_slash ) { + __state = __state + 1; + //DEBUG_PRINTLN_TXT("1->2"); + }else{ + // something went wrong, roll back + __state = 0; + //DEBUG_PRINTLN_TXT("1->0"); + } + break; + case 2: + if ( pc_input == lc_question ) { + __state = __state + 1; + //DEBUG_PRINTLN_TXT("2->3"); + }else{ + // something went wrong, roll back + __state = 0; + //DEBUG_PRINTLN_TXT("2->0"); + } + break; + case 3: + if ( pc_input == lc_question ) { + __state = __state + 1; + //DEBUG_PRINTLN_TXT("3->4"); + }else{ + // something went wrong, roll back + __state = 0; + } + break; + case 4: + //DEBUG_PRINT(writeBuffer_top); + //DEBUG_PRINT_TXT(":"); + //DEBUG_PRINTLN(pc_input); + if ( checkEnd(pc_input) == 0 ) { + // Reset the values + __state = 0; + writeBuffer_top = 0; + DEBUG_PRINTLN_TXT("ERR: End found."); + }else{ + // Reading data + fillBuffer(pc_input, writeBuffer_top); + if ( writeBuffer_top < 64 ) { // Fill 64 chars + writeBuffer_top++; + } + if ( writeBuffer_top == 64 ) { + unsigned char lc_check = 0; + for (int i=0; i<64;i++) { + lc_check = lc_check + getBuffer(i); + //DEBUG_PRINT(i); + //DEBUG_PRINT_TXT(":"); + //DEBUG_PRINTLN(getBuffer(i)); + } + DEBUG_PRINT_TXT("Checksum: "); + DEBUG_PRINTLN(lc_check); + + newFrame = true; // Draw new frame + flipBuffer(); // Change to the second buffer, so the first one can be displayed + writeBuffer_top = 0; // Reset the writeBuffer + __state = 0; // Change state to listen + __stateEnd = 0; // Reset endState check + } + } + } + +} + +// ---------------- MAIN --------------- // +void setup() { + Rb.init(); //initialize Rainbowduino driver + Wire.begin(2); // initialize wire connection as slave #2 + Wire.onReceive(receiveEvent); // set function to be called + +#ifdef DEBUG + Serial.begin(57600); +#endif + DEBUG_PRINTLN_TXT("Empfaenger 2"); + + randomSeed(analogRead(0)); // Init randomizer + + displayBuffer = &_buffer2_3D; + writeBuffer = &_buffer1_3D; + + changeAnim(); // First random animation +} + + +void loop() { + + if ( _receive_buffer_top != _receive_buffer_bot ) { + while ( _receive_buffer_top != _receive_buffer_bot ) { + //DEBUG_PRINT(_receive_buffer[_receive_buffer_bot]); + processIn(_receive_buffer[_receive_buffer_bot]); + _receive_buffer_bot++; // Consume input + } + //DEBUG_PRINTLN_TXT(""); + } + if ( _receive_buffer_top == _receive_buffer_bot && _receive_buffer_top > 0) { + _receive_buffer_top = 0; + _receive_buffer_bot = 0; + } + + unsigned long currentMillis = millis(); + + if ( newFrame == true ) { + // Draw received frame + drawNewFrame(); + // Check for the timeout + if ( currentMillis - newFrameMillis > NEWFRAMETIMEOUT ) { + newFrameMillis = currentMillis; + newFrame = false; + } + }else{ + if ( currentMillis - lastChangeTime > animInterval) { + lastChangeTime = currentMillis; + changeAnim(); + } + + switch (animation) { + case 0: // Plasma1 + genPlasmaMatrix(); + break; + case 1: // Plasma2 + genPlasmaMatrix2(); + break; + case 2: // Cube3 + genPlasmaCube3(); + break; + case 3: // Cube1 + genPlasmaCube(); + break; + case 4: // Cube2 + genPlasmaCube2(); + break; + default: + genPlasmaCube(); + } + + if ( currentMillis - lastColorShift > COLORSHIFTTIME) { // + lastColorShift = currentMillis; + colorshift = colorshift + 1; + } + //delay(100); + } + + + +} +