Last active
December 16, 2015 09:49
Revisions
-
yrrah revised this gist
Apr 25, 2013 . 1 changed file with 463 additions and 444 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ #include <TimerOne.h> #include <DmxSimple.h> #include <TinyXML.h> #define DEBUG 1 #define MIDI_BAUDRATE 31250 #define COMPILE_MIDI_IN 1 // Set this setting to 1 to use the MIDI input. @@ -101,87 +101,79 @@ int clockChan = -1; int clockNote = -1; int clockVelocity = -1; int curRow = 0; int curCol = 0; int files = 0; int CB = INIT_WAIT; void XML_callback(uint8_t statusflags, char* tagName, uint16_t tagNameLen, char* data, uint16_t dataLen) { char ns[] = "num-scenes"; char fn[] = "filename"; char ct[] = "clockType"; char cc[] = "clockChan"; char cn[] = "clockNote"; char cv[] = "clockVelocity"; if (statusflags & STATUS_ATTR_TEXT) { if (!strcmp(ns, tagName)) { numScenes = asciiHexToInt(data, 2); Serial.print("numScenes: "); Serial.println(numScenes); fileNames = (char**) malloc(numScenes * sizeof (char*)); } if (!strcmp(fn, tagName)) { Serial.print("Filename: "); fileNames[files] = (char*) malloc((strlen(data) + 1) * sizeof (char)); strcpy(fileNames[files], data); Serial.println(fileNames[files]); if (numScenes == ++files) { XMLdone = true; } } if (!strcmp(ct, tagName)) { Serial.print("Clock MIDI Message Type: "); clockType = asciiHexToInt(data, 2); Serial.println(clockType); } if (!strcmp(cc, tagName)) { Serial.print("Clock MIDI Channel: "); clockChan = asciiHexToInt(data, 2); Serial.println(clockChan); } if (!strcmp(cn, tagName)) { Serial.print("Clock MIDI Note: "); clockNote = asciiHexToInt(data, 2); Serial.println(clockNote); } if (!strcmp(cv, tagName)) { Serial.print("Clock MIDI Velocity: "); clockVelocity = asciiHexToInt(data, 2); Serial.println(clockVelocity); } } } static void readXML() { TinyXML xml; uint8_t buffer[100]; uint16_t buflen = 100; xml.init((uint8_t*) & buffer, buflen, &XML_callback); while (myFile.available() && !XMLdone) { char c = myFile.read(); xml.processChar(c); } } void loadFrame(int FrameID) { int i; int chan, val, upVal; @@ -207,7 +199,7 @@ void loadFrame(int FrameID) { //read and execute DMX instructions in = myFile.read(); while (myFile.available() && in != '%' && in != '#') { switch (in) { case 'S': case 'P': @@ -261,30 +253,30 @@ void loadFrame(int FrameID) { case 'F': switch (in2) { case 'U'://FU = Fade Up fades[chan][0] = 1; DmxSimple.write(chan, val); break; case 'D'://FD = Fade Down fades[chan][0] = 2; DmxSimple.write(chan, upVal); break; } fades[chan][1] = val; fades[chan][2] = upVal; break; case 'M': /* Serial.print(val); Serial.print(" "); Serial.println(upVal); */ switch (in2) { case '1'://M1 = MIDI Note out = (int) ((global_note / 127)*(upVal - val) + val); break; case '2'://M2 = MIDI Velocity out = (int) ((global_velocity / 127)*(upVal - val) + val); break; } // Serial.println(float2s(out, 5)); DmxSimple.write(chan, out); break; } @@ -313,160 +305,158 @@ void loadScene(char* fileName) { int i; int looplength; // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. myFile.close(); myFile = SD.open(fileName, FILE_READ); if (!myFile) { // if the file didn't open, print an error: #ifdef DEBUG Serial.print("error opening scene: "); Serial.println(fileName); #endif } else { Serial.print("Opening Scene: "); Serial.println(fileName); //free the memory for the old case array if it exists if (fgcount != 0) { for (i = 0; i < fgcount; i++) free(caseArray[i]); free(caseArray); } myFile.readBytes(temp, 2); fgcount = asciiHexToInt(temp, 2); myFile.readBytes(temp, 2); looplength = asciiHexToInt(temp, 2); myFile.readBytes(temp, 2); maxChannel = asciiHexToInt(temp, 2); fades = (int**) malloc(maxChannel * sizeof (int*)); for (i = 0; i < maxChannel; i++) { fades[i] = (int*) malloc(3 * sizeof (int)); fades[i][0] = 0; } #ifdef DEBUG Serial.print("fgcount "); Serial.println(fgcount); Serial.print("looplength "); Serial.println(looplength); Serial.print("maxChannel "); Serial.println(maxChannel); #endif caseInfo = (int**) malloc(fgcount * sizeof (int*)); for (i = 0; i < fgcount; i++) { caseInfo[i] = (int*) malloc(3 * sizeof (int)); while (myFile.read() != '#'); myFile.readBytes(temp, 2); caseInfo[i][FG_LENGTH] = asciiHexToInt(temp, 2); caseInfo[i][FG_ADDR] = myFile.position(); caseInfo[i][CURRENT_F] = 0; #ifdef DEBUG Serial.flush(); Serial.print("------ Case Info "); Serial.print(i); Serial.println(" -------"); Serial.print("FG Length: "); Serial.println(caseInfo[i][FG_LENGTH]); Serial.print("FG Address: "); Serial.println(caseInfo[i][FG_ADDR]); Serial.print("Current Frame: "); Serial.println(caseInfo[i][CURRENT_F]); #endif } while (myFile.read() != '$'); myFile.readBytes(temp, 2); caseCount = asciiHexToInt(temp, 2); int fg = 0; caseArray = (int**) malloc(caseCount * sizeof (int*)); for (i = 0; i < caseCount; i++) { caseArray[i] = (int*) malloc(6 * sizeof (int)); char c = myFile.read(); if (c == '$') { fg++; } caseArray[i][FRAME_GROUP] = fg; //MIDI Listen Channel myFile.readBytes(temp, 2); caseArray[i][LISTEN_CHAN] = asciiHexToInt(temp, 2); //MIDI low case value myFile.readBytes(temp, 2); caseArray[i][CASE_VAL_L] = asciiHexToInt(temp, 2); //MIDI high case value myFile.readBytes(temp, 2); caseArray[i][CASE_VAL_H] = asciiHexToInt(temp, 2); //MIDI varible (pitch,velocity,etc) myFile.readBytes(temp, 1); caseArray[i][MIDI_VAR] = asciiHexToInt(temp, 1); //MIDI message type (note on, note off, etc) myFile.readBytes(temp, 1); caseArray[i][MSG_TYPE] = asciiHexToInt(temp, 1); #ifdef DEBUG Serial.flush(); Serial.print("------ Case Array Index "); Serial.print(i); Serial.println(" -------"); Serial.print("Frame Group "); Serial.println(caseArray[i][FRAME_GROUP]); Serial.print("MIDI Listen Channel "); Serial.println(caseArray[i][LISTEN_CHAN]); Serial.print("MIDI low case value "); Serial.println(caseArray[i][CASE_VAL_L]); Serial.print("MIDI high case value "); Serial.println(caseArray[i][CASE_VAL_H]); Serial.print("MIDI varible "); Serial.println(caseArray[i][MIDI_VAR]); Serial.print("MIDI message type "); Serial.println(caseArray[i][MSG_TYPE]); Serial.flush(); #endif } } } void count() { milliSec++; // Serial.println(milliSec); step = 255 / period; if (step == 0)step = 1; if (S1_count-- == 0) { S1_EN = 1; } if (S2_count-- == 0) { S2_EN = 1; } if (S3_count-- == 0) { S3_EN = 1; } if (S4_count-- == 0) { S4_EN = 1; } if (CB-- == 0) { buttonled(curRow, curCol); } } int asciiHexToInt(char* a, int length) { //converts acii representation of hex eg 'ff' to 0xFF @@ -500,21 +490,21 @@ boolean handleMIDI(int midiType, int midiChan, int note, int velocity) { int i; //MIDI Clock Signal if (((midiType == clockType) || (clockType == -1)) && ((midiChan == clockChan) || (clockChan == -1)) && ((note == clockNote) || (clockNote == -1)) && ((velocity == clockVelocity) || (clockVelocity == -1))) { #ifdef DEBUG Serial.print("Clock... Period: "); Serial.println(period); #endif period = milliSec; milliSec = 0; } #ifdef DEBUG Serial.print("Type: "); Serial.print(midiType); Serial.print(" Chan: "); @@ -523,7 +513,7 @@ boolean handleMIDI(int midiType, int midiChan, int note, int velocity) { Serial.print(note); Serial.print(" velocity: "); Serial.println(velocity); #endif //loop through all cases for (int i = 0; i < caseCount; i++) { @@ -553,210 +543,238 @@ boolean handleMIDI(int midiType, int midiChan, int note, int velocity) { return 0; } void blackout() { digitalWrite(ledground1, HIGH); digitalWrite(ledground2, HIGH); digitalWrite(ledground3, HIGH); digitalWrite(ledground4, HIGH); digitalWrite(redled, LOW); digitalWrite(greenled, LOW); digitalWrite(blueled, LOW); digitalWrite(whiteredled, LOW); digitalWrite(whitegreenled, LOW); digitalWrite(whiteblueled, LOW); } void down1() { if (S1_EN) { S1_EN = 0; S1_P = 1; S1_count = SW_DELAY; } } void down2() { if (S2_EN) { S2_EN = 0; S2_P = 1; S2_count = SW_DELAY; } } void down3() { if (S3_EN) { S3_EN = 0; S3_P = 1; S3_count = SW_DELAY; } } void down4() { if (S4_EN) { S4_EN = 0; S4_P = 1; S4_count = 50; } } void buttonled(int row, int collumn) { blackout(); switch (row) { case 0: digitalWrite(ledground1, LOW); break; case 1: digitalWrite(ledground2, LOW); break; case 2: digitalWrite(ledground3, LOW); break; case 3: digitalWrite(ledground4, LOW); break; } switch (collumn) { case -1: digitalWrite(whiteredled, HIGH); break; case 0: digitalWrite(whiteredled, HIGH); digitalWrite(whitegreenled, HIGH); digitalWrite(whiteblueled, HIGH); break; case 1: digitalWrite(blueled, HIGH); digitalWrite(whiteblueled, HIGH); break; case 2: digitalWrite(greenled, HIGH); digitalWrite(whitegreenled, HIGH); break; case 3: digitalWrite(redled, HIGH); digitalWrite(whiteredled, HIGH); break; } } void loop() { boolean dmx = 0; int i; int newScene = 0; boolean pressed = 0; if (S1_P) { S1_P = 0; pressed = 1; if (++S1_n > 3 || S1_n >= numScenes) { S1_n = 0; } newScene = S1_n; Serial.println(newScene); if (newScene < numScenes) { selectedScene = newScene; buttonled(0, S1_n); curRow = 0; curCol = S1_n; } else { S1_n = 0; buttonled(0, -1); CB = CB_COUNT; } } else if (S2_P) { S2_P = 0; if (++S2_n > 3 || 4 + S2_n >= numScenes) { S2_n = 0; } newScene = 4 + S2_n; if (newScene < numScenes) { pressed = 1; selectedScene = newScene; buttonled(1, S2_n); curRow = 1; curCol = S2_n; } else { S2_n = 0; buttonled(1, -1); CB = CB_COUNT; } } else if (S3_P) { S3_P = 0; if (++S3_n > 3 || 8 + S3_n >= numScenes) { S3_n = 0; } newScene = 8 + S3_n; if (newScene < numScenes) { pressed = 1; selectedScene = newScene; buttonled(2, S3_n); curRow = 2; curCol = S3_n; } else { S3_n = 0; buttonled(2, -1); CB = CB_COUNT; } } else if (S4_P) { S4_P = 0; if (++S4_n > 3 || 12 + S4_n >= numScenes) { S4_n = 0; } newScene = 12 + S4_n; if (newScene < numScenes) { pressed = 1; selectedScene = newScene; buttonled(3, S4_n); curRow = 3; curCol = S4_n; } else { S4_n = 0; buttonled(3, -1); CB = CB_COUNT; } } else { pressed = 0; } if (pressed) { Serial.print("New scene selected: ["); Serial.print(selectedScene); Serial.print("]"); Serial.println(fileNames[selectedScene]); loadScene(fileNames[selectedScene]); } if (usbMIDI.read()) dmx = handleMIDI(usbMIDI.getType(), usbMIDI.getChannel(), usbMIDI.getData1(), usbMIDI.getData2()); else if (MIDI.read()) handleMIDI(MIDI.getType(), MIDI.getChannel(), MIDI.getData1(), MIDI.getData2()); if (step) { for (i = 0; i < maxChannel; i++) { if (fades[i][0] == 1) {//fade up fades[i][1] = fades[i][1] + step; //increase fade if (fades[i][1] < fades[i][2]) {//if val < max DmxSimple.write(i, fades[i][1]); /* Serial.print(i); Serial.print(" fade up "); Serial.print(period); Serial.print(" x "); Serial.println(fades[i][1]); */ } else { fades[i][0] = 0; //disable fade DmxSimple.write(i, 0); } } else if (fades[i][0] == 2) {//fade down fades[i][2] = fades[i][2] - step; //decrease fade if (fades[i][2] > fades[i][1]) {//if val > min DmxSimple.write(i, fades[i][2]); /* Serial.print(i); Serial.print(" fade dn "); Serial.print(period); Serial.print(" x "); Serial.println(fades[i][2]); */ } else { fades[i][0] = 0; //disable fade DmxSimple.write(i, 0); } } else { // DmxSimple.write(i, 0); } } step = 0; } } char * float2s(double f, unsigned int digits) { @@ -797,31 +815,32 @@ char * float2s(double f, unsigned int digits) { return s; } void setup() { DmxSimple.usePin(7); DmxSimple.maxChannel(8); MIDI.begin(MIDI_CHANNEL_OMNI); pinMode(redled, OUTPUT); pinMode(greenled, OUTPUT); pinMode(blueled, OUTPUT); pinMode(whiteredled, OUTPUT); pinMode(whitegreenled, OUTPUT); pinMode(whiteblueled, OUTPUT); pinMode(ledground1, OUTPUT); pinMode(ledground2, OUTPUT); pinMode(ledground3, OUTPUT); pinMode(ledground4, OUTPUT); pinMode(switchground1, INPUT_PULLUP); pinMode(switchground2, INPUT_PULLUP); pinMode(switchground3, INPUT_PULLUP); pinMode(switchground4, INPUT_PULLUP); pinMode(switch1, OUTPUT); pinMode(switch2, OUTPUT); pinMode(switch3, OUTPUT); pinMode(switch4, OUTPUT); Timer1.initialize(10000); //in microseconds (1000000us = 1s) Timer1.attachInterrupt(count); //runs every millisecond @@ -843,27 +862,27 @@ void setup() { #endif return; } myFile = SD.open("config.xml", FILE_READ); if (!myFile) { // if the file didn't open, print an error: #ifdef DEBUG Serial.println("error opening config file"); #endif } else { #ifdef DEBUG Serial.println("initialization done."); #endif readXML(); if (numScenes > 0) loadScene(fileNames[0]); else Serial.println("No scenes to load!"); } attachInterrupt(switchground1, down1, FALLING); attachInterrupt(switchground2, down2, FALLING); attachInterrupt(switchground3, down3, FALLING); attachInterrupt(switchground4, down4, FALLING); } -
yrrah revised this gist
Apr 25, 2013 . 1 changed file with 323 additions and 192 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,9 +3,12 @@ #include <TimerOne.h> #include <DmxSimple.h> #include <TinyXML.h> #define DEBUG 1 #define MIDI_BAUDRATE 31250 #define COMPILE_MIDI_IN 1 // Set this setting to 1 to use the MIDI input. #define COMPILE_MIDI_OUT 0 // Set this setting to 1 to use the MIDI output. #define COMPILE_MIDI_THRU 0 // Set this setting to 1 to use the MIDI Soft Thru feature #define USE_SERIAL_PORT Serial #define USE_RUNNING_STATUS 0 #define USE_1BYTE_PARSING 1 @@ -37,8 +40,8 @@ #define greenled 11 //hole 18 #define redled 12 // this goes to hole 19 on the ribbon cable #define whitegreenled 14 //hole 15 #define whiteblueled 13 #define whiteredled 15 //hole 16 #define switchground1 18 //hole 1 @@ -51,6 +54,9 @@ #define switch3 39 //hole 9 #define switch4 40 //hole 10 #define SW_DELAY 60 //milliseconds #define CB_COUNT 50 #define INIT_WAIT 200 File myFile; volatile int milliSec = 0; @@ -64,128 +70,91 @@ int maxChannel = 20; double global_note, global_velocity; volatile int period = 0; int step = 1; int counte = 0; boolean XMLdone = 0; int numScenes = 0; char** fileNames; int selectedScene = 0; boolean S1_EN = 0; boolean S2_EN = 0; boolean S3_EN = 0; boolean S4_EN = 0; boolean S1_P = 0; boolean S2_P = 0; boolean S3_P = 0; boolean S4_P = 0; int S1_count = INIT_WAIT; int S2_count = INIT_WAIT; int S3_count = INIT_WAIT; int S4_count = INIT_WAIT; int S1_n = 0; int S2_n = 0; int S3_n = 0; int S4_n = 0; int clockType = -1; int clockChan = -1; int clockNote = -1; int clockVelocity = -1; int curRow=0; int curCol=0; int files = 0; int CB = INIT_WAIT; void XML_callback( uint8_t statusflags, char* tagName, uint16_t tagNameLen, char* data, uint16_t dataLen ) { char ns[] = "num-scenes"; char fn[] = "filename"; char ct[] = "clockType"; char cc[] = "clockChan"; char cn[] = "clockNote"; char cv[] = "clockVelocity"; if (statusflags & STATUS_ATTR_TEXT) { if(!strcmp(ns, tagName)){ numScenes = asciiHexToInt(data, 2); Serial.print("numScenes: "); Serial.println(numScenes); fileNames = (char**) malloc(numScenes * sizeof (char*)); } if(!strcmp(fn, tagName)){ Serial.print("Filename: "); fileNames[files] = (char*) malloc((strlen(data)+1)*sizeof(char)); strcpy(fileNames[files],data); Serial.println(fileNames[files]); if(numScenes == ++files){ XMLdone = true; } } if(!strcmp(ct, tagName)){ Serial.print("Clock MIDI Message Type: "); clockType = asciiHexToInt(data, 2); Serial.println(clockType); } if(!strcmp(cc, tagName)){ Serial.print("Clock MIDI Channel: "); clockChan = asciiHexToInt(data, 2); Serial.println(clockChan); } if(!strcmp(cn, tagName)){ Serial.print("Clock MIDI Note: "); clockNote = asciiHexToInt(data, 2); Serial.println(clockNote); } if(!strcmp(cv, tagName)){ Serial.print("Clock MIDI Velocity: "); clockVelocity = asciiHexToInt(data, 2); Serial.println(clockVelocity); } } } @@ -204,7 +173,7 @@ uint16_t buflen = 100; } } @@ -213,13 +182,6 @@ uint16_t buflen = 100; void loadFrame(int FrameID) { int i; int chan, val, upVal; @@ -363,7 +325,8 @@ void loadScene(char* fileName) { Serial.println(fileName); #endif }else{ Serial.print("Opening Scene: "); Serial.println(fileName); //free the memory for the old case array if it exists if (fgcount != 0) { for (i = 0; i < fgcount; i++) @@ -388,11 +351,11 @@ void loadScene(char* fileName) { } #ifdef DEBUG Serial.print("fgcount "); Serial.println(fgcount); Serial.print("looplength "); Serial.println(looplength); Serial.print("maxChannel "); Serial.println(maxChannel); #endif @@ -485,47 +448,25 @@ void count() { // Serial.println(milliSec); step = 255/period; if(step==0)step = 1; if(S1_count--==0){ S1_EN = 1; } if(S2_count--==0){ S2_EN = 1; } if(S3_count--==0){ S3_EN = 1; } if(S4_count--==0){ S4_EN = 1; } if(CB--==0){ buttonled(curRow,curCol); } } int asciiHexToInt(char* a, int length) { //converts acii representation of hex eg 'ff' to 0xFF @@ -559,14 +500,18 @@ boolean handleMIDI(int midiType, int midiChan, int note, int velocity) { int i; //MIDI Clock Signal if ( ((midiType==clockType)||(clockType==-1)) && ((midiChan==clockChan)||(clockChan==-1)) && ((note==clockNote)||(clockNote==-1)) && ((velocity==clockVelocity)||(clockVelocity==-1))){ #ifdef DEBUG Serial.print("Clock... Period: "); Serial.println(period); #endif period = milliSec; milliSec = 0; } #ifdef DEBUG @@ -608,13 +553,170 @@ boolean handleMIDI(int midiType, int midiChan, int note, int velocity) { return 0; } void blackout(){ digitalWrite(ledground1, HIGH); digitalWrite(ledground2, HIGH); digitalWrite(ledground3, HIGH); digitalWrite(ledground4, HIGH); digitalWrite(redled, LOW); digitalWrite(greenled, LOW); digitalWrite(blueled, LOW); digitalWrite(whiteredled, LOW); digitalWrite(whitegreenled, LOW); digitalWrite(whiteblueled, LOW); } void down1() { if(S1_EN){ S1_EN = 0; S1_P=1; S1_count = SW_DELAY; } } void down2() { if(S2_EN){ S2_EN = 0; S2_P=1; S2_count = SW_DELAY; } } void down3() { if(S3_EN){ S3_EN = 0; S3_P=1; S3_count = SW_DELAY; } } void down4() { if(S4_EN){ S4_EN = 0; S4_P=1; S4_count = 50; } } void buttonled(int row,int collumn){ blackout(); switch (row){ case 0: digitalWrite(ledground1,LOW); break; case 1: digitalWrite(ledground2,LOW); break; case 2: digitalWrite(ledground3,LOW); break; case 3: digitalWrite(ledground4,LOW); break; } switch(collumn){ case -1: digitalWrite(whiteredled,HIGH); break; case 0: digitalWrite(whiteredled,HIGH); digitalWrite(whitegreenled,HIGH); digitalWrite(whiteblueled,HIGH); break; case 1: digitalWrite(blueled,HIGH); digitalWrite(whiteblueled,HIGH); break; case 2: digitalWrite(greenled,HIGH); digitalWrite(whitegreenled,HIGH); break; case 3: digitalWrite(redled,HIGH); digitalWrite(whiteredled,HIGH); break; } } void loop() { boolean dmx = 0; int i; int newScene = 0; boolean pressed = 0; if(S1_P){ S1_P = 0; pressed = 1; if(++S1_n>3||S1_n>=numScenes){S1_n = 0;} newScene = S1_n; Serial.println(newScene); if(newScene<numScenes){ selectedScene = newScene; buttonled(0,S1_n); curRow=0;curCol=S1_n; }else{S1_n=0; buttonled(0,-1);CB = CB_COUNT;} }else if(S2_P){ S2_P = 0; if(++S2_n>3||4+S2_n>=numScenes){S2_n = 0;} newScene = 4+S2_n; if(newScene<numScenes){ pressed = 1; selectedScene = newScene; buttonled(1,S2_n); curRow=1;curCol=S2_n; }else{S2_n=0; buttonled(1,-1);CB = CB_COUNT;} }else if(S3_P){ S3_P = 0; if(++S3_n>3||8+S3_n>=numScenes){S3_n = 0;} newScene = 8+S3_n; if(newScene<numScenes){ pressed = 1; selectedScene = newScene; buttonled(2,S3_n); curRow=2;curCol=S3_n; }else{S3_n=0; buttonled(2,-1);CB = CB_COUNT;} }else if(S4_P){ S4_P = 0; if(++S4_n>3||12+S4_n>=numScenes){S4_n = 0;} newScene = 12+S4_n; if(newScene<numScenes){ pressed = 1; selectedScene = newScene; buttonled(3,S4_n); curRow=3;curCol=S4_n; }else{S4_n=0; buttonled(3,-1);CB = CB_COUNT; } }else{ pressed = 0; } if(pressed){ Serial.print("New scene selected: ["); Serial.print(selectedScene); Serial.print("]"); Serial.println(fileNames[selectedScene]); loadScene(fileNames[selectedScene]); } if (usbMIDI.read()) dmx = handleMIDI(usbMIDI.getType(), usbMIDI.getChannel(), usbMIDI.getData1(), usbMIDI.getData2()); @@ -627,25 +729,25 @@ void loop() { fades[i][1] = fades[i][1] + step;//increase fade if(fades[i][1]<fades[i][2]){//if val < max DmxSimple.write(i, fades[i][1]); /* Serial.print(i); Serial.print(" fade up "); Serial.print(period); Serial.print(" x "); Serial.println(fades[i][1]); */ }else{ fades[i][0] = 0;//disable fade DmxSimple.write(i, 0); } }else if(fades[i][0] == 2){//fade down fades[i][2] = fades[i][2] - step;//decrease fade if(fades[i][2]>fades[i][1]){//if val > min DmxSimple.write(i, fades[i][2]); /* Serial.print(i); Serial.print(" fade dn "); Serial.print(period); Serial.print(" x "); Serial.println(fades[i][2]); */ }else{ fades[i][0] = 0;//disable fade DmxSimple.write(i, 0); } @@ -657,15 +759,51 @@ void loop() { } } char * float2s(double f, unsigned int digits) { int index = 0; static char s[16]; // buffer to build string representation // handle sign if (f < 0.0) { s[index++] = '-'; f = -f; } // handle infinite values if (isinf(f)) { strcpy(&s[index], "INF"); return s; } // handle Not a Number if (isnan(f)) { strcpy(&s[index], "NaN"); return s; } // max digits if (digits > 9) digits = 9; long multiplier = pow(10, digits); // fix int => long int exponent = int(log10(f)); double g = f / pow(10, exponent); if ((g < 1.0) && (g != 0.0)) { g *= 10; exponent--; } long whole = long(g); // single digit long part = long((g - whole) * multiplier); // # digits char format[16]; sprintf(format, "%%ld.%%0%dld E%%+d", digits); sprintf(&s[index], format, whole, part, exponent); return s; } void setup() { DmxSimple.usePin(7); DmxSimple.maxChannel(8); MIDI.begin(MIDI_CHANNEL_OMNI); pinMode(redled, OUTPUT); pinMode(greenled, OUTPUT); pinMode(blueled, OUTPUT); pinMode(whiteredled, OUTPUT); @@ -674,29 +812,16 @@ void setup() { pinMode(ledground1, OUTPUT); pinMode(ledground2, OUTPUT); pinMode(ledground3, OUTPUT); pinMode(ledground4, OUTPUT); pinMode(switchground1, INPUT_PULLUP); pinMode(switchground2, INPUT_PULLUP); pinMode(switchground3, INPUT_PULLUP); pinMode(switchground4, INPUT_PULLUP); pinMode(switch1, OUTPUT); pinMode(switch2, OUTPUT); pinMode(switch3, OUTPUT); pinMode(switch4, OUTPUT); Timer1.initialize(10000); //in microseconds (1000000us = 1s) Timer1.attachInterrupt(count); //runs every millisecond @@ -726,13 +851,19 @@ void setup() { Serial.println("error opening config file"); #endif }else{ #ifdef DEBUG Serial.println("initialization done."); #endif readXML(); if(numScenes>0) loadScene(fileNames[0]); else Serial.println("No scenes to load!"); } attachInterrupt(switchground1, down1,FALLING); attachInterrupt(switchground2, down2,FALLING); attachInterrupt(switchground3, down3,FALLING); attachInterrupt(switchground4, down4,FALLING); } -
yrrah revised this gist
Apr 24, 2013 . 1 changed file with 303 additions and 83 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,12 +2,10 @@ #include <MIDI.h> #include <TimerOne.h> #include <DmxSimple.h> #include <TinyXML.h> #include <string.h> #define DEBUG 1 #define USE_SERIAL_PORT Serial #define USE_RUNNING_STATUS 0 #define USE_1BYTE_PARSING 1 @@ -30,6 +28,30 @@ #define POT4 44 #define FADER 45 #define ledground1 8 //hole 2 #define ledground2 5 //hole 4 #define ledground3 24 //hole 13 #define ledground4 16 //hole 11 #define blueled 10 //hole 17 #define greenled 11 //hole 18 #define redled 12 // this goes to hole 19 on the ribbon cable #define whitegreenled 13 //hole 15 #define whiteblueled 14 #define whiteredled 15 //hole 16 #define switchground1 18 //hole 1 #define switchground2 19 //hole 3 #define switchground3 0 //hole 14 #define switchground4 1 //hole 12 #define switch1 26 //hole 7 #define switch2 38 //hole 8 #define switch3 39 //hole 9 #define switch4 40 //hole 10 File myFile; volatile int milliSec = 0; char* temp = ""; @@ -42,6 +64,162 @@ int maxChannel = 20; double global_note, global_velocity; volatile int period = 0; int step = 1; boolean XMLdone = 0; int numScenes = 0; char** fileNames; int switches[4]={switch1,switch2,switch3,switch4}; int switchgrounds[4]={switchground1,switchground2,switchground3,switchground4}; int row; int collumn; int i=1; int j=1; int buttonpress; void buttonled(int row,int collumn){ switch (row){ case 0: digitalWrite(ledground1,LOW); break; case 1: digitalWrite(ledground2,LOW); break; case 2: digitalWrite(ledground3,LOW); break; case 3: digitalWrite(ledground4,LOW); break; } switch(collumn){ case 0: digitalWrite(redled,HIGH); break; case 1: digitalWrite(greenled,HIGH); break; case 2: digitalWrite(blueled,HIGH); break; case 3: digitalWrite(whiteredled,HIGH); digitalWrite(whitegreenled,HIGH); digitalWrite(whiteblueled,HIGH); break; } delay (50); blackout(); } void ledtest(){ for (int i=0; i<4; i++){ for (int j=0; j<4; j++){ buttonled(i,j); delay (50); blackout(); delay(50); } } } void lightbutton(){ for (int i=0; i<4; i++){ for (int j=0; j<4; j++){ digitalWrite(switchgrounds[i],LOW); if (digitalRead(switches[j])==LOW){ buttonpress=4*i+j; buttonled(i,j); Serial.println(buttonpress); } digitalWrite(switchgrounds[i],HIGH); } }} void blackout(){ digitalWrite(ledground1, HIGH); digitalWrite(ledground2, HIGH); digitalWrite(ledground3, HIGH); digitalWrite(ledground4, HIGH); digitalWrite(redled, LOW); digitalWrite(greenled, LOW); digitalWrite(blueled, LOW); digitalWrite(whiteredled, LOW); digitalWrite(whitegreenled, LOW); digitalWrite(whiteblueled, LOW); } void XML_callback( uint8_t statusflags, char* tagName, uint16_t tagNameLen, char* data, uint16_t dataLen ) { char ns[] = "num-scenes"; char fn[] = "filename"; int i = 0; if (statusflags & STATUS_ATTR_TEXT) { /* Serial.print("Attribute:"); Serial.print(tagName); Serial.print(" text:"); Serial.println(data);*/ if(!strcmp(ns, tagName)){ numScenes = asciiHexToInt(data, 1); Serial.print("numScenes: "); Serial.println(numScenes); fileNames = (char**) malloc(numScenes * sizeof (char*)); } if(!strcmp(fn, tagName)){ Serial.print("Filename: "); fileNames[i] = (char*) malloc((strlen(data)+1)*sizeof(char)); strcpy(fileNames[i],data); Serial.println(data); if(numScenes == ++i){ XMLdone = true; } } } } static void readXML(){ TinyXML xml; uint8_t buffer[100]; uint16_t buflen = 100; xml.init((uint8_t*)&buffer,buflen,&XML_callback); while(myFile.available()&&!XMLdone){ char c = myFile.read(); xml.processChar(c); } } void loadFrame(int FrameID) { int i; int chan, val, upVal; @@ -210,11 +388,11 @@ void loadScene(char* fileName) { } #ifdef DEBUG Serial.print("fgcount: "); Serial.println(fgcount); Serial.print("looplength: "); Serial.println(looplength); Serial.print("maxChannel: "); Serial.println(maxChannel); #endif @@ -309,47 +487,44 @@ void count() { if(step==0)step = 1; } char * float2s(double f, unsigned int digits) { int index = 0; static char s[16]; // buffer to build string representation // handle sign if (f < 0.0) { s[index++] = '-'; f = -f; } // handle infinite values if (isinf(f)) { strcpy(&s[index], "INF"); return s; } // handle Not a Number if (isnan(f)) { strcpy(&s[index], "NaN"); return s; } // max digits if (digits > 9) digits = 9; long multiplier = pow(10, digits); // fix int => long int exponent = int(log10(f)); double g = f / pow(10, exponent); if ((g < 1.0) && (g != 0.0)) { g *= 10; exponent--; } long whole = long(g); // single digit long part = long((g - whole) * multiplier); // # digits char format[16]; sprintf(format, "%%ld.%%0%dld E%%+d", digits); sprintf(&s[index], format, whole, part, exponent); return s; } int asciiHexToInt(char* a, int length) { @@ -384,7 +559,7 @@ boolean handleMIDI(int midiType, int midiChan, int note, int velocity) { int i; //MIDI Clock Signal if (midiType == 1 && midiChan == 1 && note == 12/*C1*/ && velocity == 10) { #ifdef DEBUG Serial.print("Clock... Period: "); Serial.println(period); @@ -436,6 +611,10 @@ boolean handleMIDI(int midiType, int midiChan, int note, int velocity) { void loop() { boolean dmx = 0; int i; // lightbutton(); //faderpots(); //ledtest(); if (usbMIDI.read()) dmx = handleMIDI(usbMIDI.getType(), usbMIDI.getChannel(), usbMIDI.getData1(), usbMIDI.getData2()); @@ -448,25 +627,25 @@ void loop() { fades[i][1] = fades[i][1] + step;//increase fade if(fades[i][1]<fades[i][2]){//if val < max DmxSimple.write(i, fades[i][1]); Serial.print(i); Serial.print(" fade up "); Serial.print(period); Serial.print(" x "); Serial.println(fades[i][1]); }else{ fades[i][0] = 0;//disable fade DmxSimple.write(i, 0); } }else if(fades[i][0] == 2){//fade down fades[i][2] = fades[i][2] - step;//decrease fade if(fades[i][2]>fades[i][1]){//if val > min DmxSimple.write(i, fades[i][2]); Serial.print(i); Serial.print(" fade dn "); Serial.print(period); Serial.print(" x "); Serial.println(fades[i][2]); }else{ fades[i][0] = 0;//disable fade DmxSimple.write(i, 0); } @@ -478,41 +657,82 @@ void loop() { } } void my_int1() { Serial.println("interrupt #1"); } void my_int2() { Serial.println("interrupt #2"); } void my_int3() { Serial.println("interrupt #3"); } void my_int4() { Serial.println("interrupt #4"); } void setup() { /* pinMode(redled, OUTPUT); pinMode(greenled, OUTPUT); pinMode(blueled, OUTPUT); pinMode(whiteredled, OUTPUT); pinMode(whitegreenled, OUTPUT); pinMode(whiteblueled, OUTPUT); pinMode(ledground1, OUTPUT); pinMode(ledground2, OUTPUT); pinMode(ledground3, OUTPUT); pinMode(ledground4, OUTPUT);*/ pinMode(switchground1, INPUT); pinMode(switchground2, INPUT); pinMode(switchground3, INPUT); pinMode(switchground4, INPUT); // pinMode(switch1, OUTPUT); // pinMode(switch2, OUTPUT); // pinMode(switch3, OUTPUT); // pinMode(switch4, OUTPUT); // digitalWrite(switch1,HIGH); // digitalWrite(switch2,HIGH); // digitalWrite(switch3,HIGH); // digitalWrite(switch4,HIGH); attachInterrupt(7, my_int1, RISING); attachInterrupt(6, my_int2, RISING); attachInterrupt(1, my_int3, RISING); attachInterrupt(0, my_int4, RISING); DmxSimple.usePin(7); DmxSimple.maxChannel(8); //pinMode(3, OUTPUT); MIDI.begin(MIDI_CHANNEL_OMNI); Timer1.initialize(10000); //in microseconds (1000000us = 1s) Timer1.attachInterrupt(count); //runs every millisecond Timer1.start(); #ifdef DEBUG Serial.print("Initializing SD card..."); #endif // On the Ethernet Shield, CS is pin 4. It's set as an output by default.*/ // Note that even if it's not used as the CS pin, the hardware SS pin // (10 on most Arduino boards, 53 on the Mega) must be left as an output // or the SD library functions will not work. pinMode(20, OUTPUT); if (!SD.begin(20)) { #ifdef DEBUG Serial.println("initialization failed!"); #endif return; } myFile = SD.open("config.xml", FILE_READ); if (!myFile) { // if the file didn't open, print an error: #ifdef DEBUG Serial.println("error opening config file"); #endif }else{ #ifdef DEBUG Serial.println("initialization done."); #endif readXML(); if(numScenes>0) loadScene(fileNames[0]); else Serial.println("No scenes to load!"); } } -
yrrah revised this gist
Apr 22, 2013 . 1 changed file with 95 additions and 30 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,9 +1,9 @@ #include <SD.h> #include <MIDI.h> #include <TimerOne.h> #include <DmxSimple.h> #define DEBUG 1 #define MIDI_BAUDRATE 31250 #define COMPILE_MIDI_IN 1 // Set this setting to 1 to use the MIDI input. #define COMPILE_MIDI_OUT 0 // Set this setting to 1 to use the MIDI output. @@ -34,12 +34,14 @@ File myFile; volatile int milliSec = 0; char* temp = ""; int** caseArray; int caseCount; int** caseInfo; int** fades; int fgcount; //number of frame groups & corresponding cases int maxChannel = 20; double global_note, global_velocity; volatile int period = 0; int step = 1; void loadFrame(int FrameID) { int i; int chan, val, upVal; @@ -49,15 +51,15 @@ void loadFrame(int FrameID) { Serial.print("Load Frame Group:"); Serial.print(FrameID); Serial.print(" Frame:"); Serial.println(caseInfo[FrameID][CURRENT_F]); #endif //seek to location of frame group on SD card myFile.seek(caseInfo[FrameID][FG_ADDR]); //find location of frame i = 0; while (i <= caseInfo[FrameID][CURRENT_F]) { while (myFile.read() != '%'); i++; } @@ -119,31 +121,38 @@ void loadFrame(int FrameID) { case 'F': switch (in2) { case 'U'://FU = Fade Up fades[chan][0] = 1; DmxSimple.write(chan, val); break; case 'D'://FD = Fade Down fades[chan][0] = 2; DmxSimple.write(chan, upVal); break; } fades[chan][1] = val; fades[chan][2] = upVal; break; case 'M': /* Serial.print(val); Serial.print(" "); Serial.println(upVal); */ switch (in2) { case '1'://M1 = MIDI Note out = (int) ((global_note / 127)*(upVal - val) + val); break; case '2'://M2 = MIDI Velocity out = (int) ((global_velocity / 127)*(upVal - val) + val); break; } // Serial.println(float2s(out, 5)); DmxSimple.write(chan, out); break; } break; default: #ifdef DEBUG Serial.println("DMX Instuction Type not implemented yet"); Serial.print(caseInfo[FrameID][CURRENT_F]); Serial.print(" "); Serial.print(FrameID); Serial.print(" "); @@ -156,8 +165,8 @@ void loadFrame(int FrameID) { } //increment frame counter if (++caseInfo[FrameID][CURRENT_F] >= caseInfo[FrameID][FG_LENGTH]) caseInfo[FrameID][CURRENT_F] = 0; } void loadScene(char* fileName) { @@ -172,7 +181,8 @@ void loadScene(char* fileName) { if (!myFile) { // if the file didn't open, print an error: #ifdef DEBUG Serial.print("error opening scene: "); Serial.println(fileName); #endif }else{ @@ -191,6 +201,13 @@ void loadScene(char* fileName) { myFile.readBytes(temp, 2); maxChannel = asciiHexToInt(temp, 2); fades = (int**) malloc(maxChannel * sizeof (int*)); for (i = 0; i < maxChannel; i++) { fades[i] = (int*) malloc(3 * sizeof (int)); fades[i][0] = 0; } #ifdef DEBUG Serial.print("fgcount "); @@ -214,16 +231,24 @@ void loadScene(char* fileName) { caseInfo[i][CURRENT_F] = 0; #ifdef DEBUG Serial.flush(); Serial.print("------ Case Info "); Serial.print(i); Serial.println(" -------"); Serial.print("FG Length: "); Serial.println(caseInfo[i][FG_LENGTH]); Serial.print("FG Address: "); Serial.println(caseInfo[i][FG_ADDR]); Serial.print("Current Frame: "); Serial.println(caseInfo[i][CURRENT_F]); #endif } while (myFile.read() != '$'); myFile.readBytes(temp, 2); caseCount = asciiHexToInt(temp, 2); int fg = 0; @@ -250,14 +275,16 @@ void loadScene(char* fileName) { myFile.readBytes(temp, 1); caseArray[i][MIDI_VAR] = asciiHexToInt(temp, 1); //MIDI message type (note on, note off, etc) myFile.readBytes(temp, 1); caseArray[i][MSG_TYPE] = asciiHexToInt(temp, 1); #ifdef DEBUG Serial.flush(); Serial.print("------ Case Array Index "); Serial.print(i); Serial.println(" -------"); Serial.print("Frame Group "); Serial.println(caseArray[i][FRAME_GROUP]); Serial.print("MIDI Listen Channel "); Serial.println(caseArray[i][LISTEN_CHAN]); Serial.print("MIDI low case value "); @@ -277,6 +304,9 @@ void loadScene(char* fileName) { void count() { milliSec++; // Serial.println(milliSec); step = 255/period; if(step==0)step = 1; } void setup() { @@ -318,7 +348,7 @@ void setup() { Serial.println("initialization done."); #endif loadScene("TestTwo.scn"); } } @@ -354,12 +384,17 @@ boolean handleMIDI(int midiType, int midiChan, int note, int velocity) { int i; //MIDI Clock Signal if (midiType == NoteOn && midiChan == 1 && note == 12/*C1*/ && velocity == 10) { #ifdef DEBUG Serial.print("Clock... Period: "); Serial.println(period); #endif period = milliSec; milliSec = 0; } #ifdef DEBUG Serial.print("Type: "); Serial.print(midiType); Serial.print(" Chan: "); @@ -368,9 +403,9 @@ boolean handleMIDI(int midiType, int midiChan, int note, int velocity) { Serial.print(note); Serial.print(" velocity: "); Serial.println(velocity); #endif //loop through all cases for (int i = 0; i < caseCount; i++) { //check to see if correct message type (Note on, Note off, etc) if (caseArray[i][MSG_TYPE] == midiType @@ -390,7 +425,7 @@ boolean handleMIDI(int midiType, int midiChan, int note, int velocity) { //do comparison and load frame if true if (midiValue >= caseArray[i][CASE_VAL_L] && midiValue <= caseArray[i][CASE_VAL_H]) { loadFrame(caseArray[i][FRAME_GROUP]); return 1; } } @@ -406,11 +441,41 @@ void loop() { dmx = handleMIDI(usbMIDI.getType(), usbMIDI.getChannel(), usbMIDI.getData1(), usbMIDI.getData2()); else if (MIDI.read()) handleMIDI(MIDI.getType(), MIDI.getChannel(), MIDI.getData1(), MIDI.getData2()); if (step){ for (i = 0; i < maxChannel; i++) { if(fades[i][0] == 1){//fade up fades[i][1] = fades[i][1] + step;//increase fade if(fades[i][1]<fades[i][2]){//if val < max DmxSimple.write(i, fades[i][1]); /* Serial.print(i); Serial.print(" fade up "); Serial.print(period); Serial.print(" x "); Serial.println(fades[i][1]); */ }else{ fades[i][0] = 0;//disable fade DmxSimple.write(i, 0); } }else if(fades[i][0] == 2){//fade down fades[i][2] = fades[i][2] - step;//decrease fade if(fades[i][2]>fades[i][1]){//if val > min DmxSimple.write(i, fades[i][2]); /* Serial.print(i); Serial.print(" fade dn "); Serial.print(period); Serial.print(" x "); Serial.println(fades[i][2]); */ }else{ fades[i][0] = 0;//disable fade DmxSimple.write(i, 0); } }else{ // DmxSimple.write(i, 0); } } step=0; } } char * float2s(double f, unsigned int digits) { -
yrrah revised this gist
Apr 21, 2013 . 1 changed file with 389 additions and 376 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,7 +1,8 @@ #include <SD.h> #include <MIDI.h> #include <TimerOne.h> #include <DmxSimple.h> //limited to 64 channels in DmxSimple.h to save memory //define DEBUG 1 #define MIDI_BAUDRATE 31250 #define COMPILE_MIDI_IN 1 // Set this setting to 1 to use the MIDI input. @@ -12,14 +13,15 @@ #define USE_1BYTE_PARSING 1 #define USE_CALLBACKS 0 #define MIDI_SYSEX_ARRAY_SIZE 64 #define FRAME_GROUP 0 #define LISTEN_CHAN 1 #define CASE_VAL_L 2 #define CASE_VAL_H 3 #define MIDI_VAR 4 #define MSG_TYPE 5 #define FG_ADDR 1 #define FG_LENGTH 0 #define CURRENT_F 2 #define PITCH 0 #define VELOCITY 1 #define POT1 41 @@ -29,412 +31,423 @@ #define FADER 45 File myFile; volatile int milliSec = 0; char* temp = ""; int** caseArray; int** caseInfo; int fgcount = 0; //number of frame groups & corresponding cases int maxChannel = 20; double global_note, global_velocity; int period = 0; void loadFrame(int FrameID) { int i; int chan, val, upVal; char in, in2; #ifdef DEBUG Serial.print("Load Frame Group:"); Serial.print(FrameID); Serial.print(" Frame:"); Serial.println(caseArray[FrameID][CURRENT_F]); #endif //seek to location of frame group on SD card myFile.seek(caseArray[FrameID][FG_ADDR]); //find location of frame i = 0; while (i <= caseArray[FrameID][CURRENT_F]) { while (myFile.read() != '%'); i++; } //read and execute DMX instructions in = myFile.read(); while (myFile.available() && in != '%' && in != '#') { switch (in) { case 'S': case 'P': case 'F': case 'M': in2 = myFile.read(); myFile.readBytes(temp, 2); chan = asciiHexToInt(temp, 2); myFile.readBytes(temp, 2); val = asciiHexToInt(temp, 2); myFile.readBytes(temp, 2); upVal = asciiHexToInt(temp, 2); #ifdef DEBUG Serial.flush(); Serial.print("DMX Instruction: chan "); Serial.print(chan, HEX); Serial.print(", "); Serial.print(val, HEX); Serial.print(", "); Serial.println(upVal, HEX); #endif double potValue; int out; switch (in) { case 'S'://ST = Static DmxSimple.write(chan, val); break; case 'P': switch (in2) { case '1'://P1 = Potentiometer 1 potValue = analogRead(POT1); break; case '2'://P1 = Potentiometer 2 potValue = analogRead(POT2); break; case '3'://P1 = Potentiometer 3 potValue = analogRead(POT3); break; case '4'://P1 = Potentiometer 4 potValue = analogRead(POT4); break; case '5'://P1 = Fader / Slider potValue = analogRead(FADER); break; } out = (int) ((potValue / 1023)*(upVal - val) + val); DmxSimple.write(chan, out); break; case 'F': switch (in2) { case 'U'://FU = Fade Up case 'D'://FD = Fade Down break; } break; case 'M': Serial.print(val); Serial.print(" "); Serial.println(upVal); switch (in2) { case '1'://M1 = MIDI Note out = (int) ((global_note / 127)*(upVal - val) + val); break; case '2'://M2 = MIDI Velocity out = (int) ((global_velocity / 127)*(upVal - val) + val); break; } Serial.println(float2s(out, 5)); DmxSimple.write(chan, out); break; } break; default: #ifdef DEBUG Serial.println("DMX Instuction Type not implemented yet"); Serial.print(caseArray[FrameID][CURRENT_F]); Serial.print(" "); Serial.print(FrameID); Serial.print(" "); Serial.print(in); Serial.println(in2); #endif break; } in = myFile.read(); } //increment frame counter if (++caseArray[FrameID][CURRENT_F] >= caseArray[FrameID][FG_LENGTH]) caseArray[FrameID][CURRENT_F] = 0; } void loadScene(char* fileName) { int i; int looplength; // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. myFile.close(); myFile = SD.open(fileName, FILE_READ); if (!myFile) { // if the file didn't open, print an error: #ifdef DEBUG Serial.println("error opening scene"); #endif }else{ //free the memory for the old case array if it exists if (fgcount != 0) { for (i = 0; i < fgcount; i++) free(caseArray[i]); free(caseArray); } myFile.readBytes(temp, 2); fgcount = asciiHexToInt(temp, 2); myFile.readBytes(temp, 2); looplength = asciiHexToInt(temp, 2); myFile.readBytes(temp, 2); maxChannel = asciiHexToInt(temp, 2); #ifdef DEBUG Serial.print("fgcount "); Serial.println(fgcount); Serial.print("looplength "); Serial.println(looplength); Serial.print("maxChannel "); Serial.println(maxChannel); #endif caseInfo = (int**) malloc(fgcount * sizeof (int*)); for (i = 0; i < fgcount; i++) { caseInfo[i] = (int*) malloc(3 * sizeof (int)); while (myFile.read() != '#'); myFile.readBytes(temp, 2); caseInfo[i][FG_LENGTH] = asciiHexToInt(temp, 2); caseInfo[i][FG_ADDR] = myFile.position(); caseInfo[i][CURRENT_F] = 0; #ifdef DEBUG Serial.print("FG located at "); Serial.println(caseArray[i][5]); #endif } while (myFile.read() != '$'); myFile.readBytes(temp, 2); int caseCount = asciiHexToInt(temp, 2); int fg = 0; caseArray = (int**) malloc(caseCount * sizeof (int*)); for (i = 0; i < caseCount; i++) { caseArray[i] = (int*) malloc(6 * sizeof (int)); char c = myFile.read(); if(c == '$'){ fg++; } caseArray[i][FRAME_GROUP] = fg; //MIDI Listen Channel myFile.readBytes(temp, 2); caseArray[i][LISTEN_CHAN] = asciiHexToInt(temp, 2); //MIDI low case value myFile.readBytes(temp, 2); caseArray[i][CASE_VAL_L] = asciiHexToInt(temp, 2); //MIDI high case value myFile.readBytes(temp, 2); caseArray[i][CASE_VAL_H] = asciiHexToInt(temp, 2); //MIDI varible (pitch,velocity,etc) myFile.readBytes(temp, 1); caseArray[i][MIDI_VAR] = asciiHexToInt(temp, 1); //MIDI message type (note on, note off, etc) myFile.readBytes(temp, 2); caseArray[i][MSG_TYPE] = asciiHexToInt(temp, 2); #ifdef DEBUG Serial.flush(); Serial.print("------ Case Array Index "); Serial.print(i); Serial.println(" -------"); Serial.print("MIDI Listen Channel "); Serial.println(caseArray[i][LISTEN_CHAN]); Serial.print("MIDI low case value "); Serial.println(caseArray[i][CASE_VAL_L]); Serial.print("MIDI high case value "); Serial.println(caseArray[i][CASE_VAL_H]); Serial.print("MIDI varible "); Serial.println(caseArray[i][MIDI_VAR]); Serial.print("MIDI message type "); Serial.println(caseArray[i][MSG_TYPE]); Serial.flush(); #endif } } } void count() { milliSec++; } void setup() { DmxSimple.usePin(7); DmxSimple.maxChannel(8); //pinMode(3, OUTPUT); //MIDI.begin(MIDI_CHANNEL_OMNI); Timer1.initialize(10000); //in microseconds (1000000us = 1s) Timer1.attachInterrupt(count); //runs every millisecond Timer1.start(); #ifdef DEBUG Serial.print("Initializing SD card..."); #endif // On the Ethernet Shield, CS is pin 4. It's set as an output by default.*/ // Note that even if it's not used as the CS pin, the hardware SS pin // (10 on most Arduino boards, 53 on the Mega) must be left as an output // or the SD library functions will not work. pinMode(20, OUTPUT); if (!SD.begin(20)) { #ifdef DEBUG Serial.println("initialization failed!"); #endif return; } myFile = SD.open("config.xml", FILE_READ); if (!myFile) { // if the file didn't open, print an error: #ifdef DEBUG Serial.println("error opening config file"); #endif }else{ #ifdef DEBUG Serial.println("initialization done."); #endif loadScene("qq.scn"); } } int asciiHexToInt(char* a, int length) { //converts acii representation of hex eg 'ff' to 0xFF int val; int in; int out = 0; for (int i = length - 1; i >= 0; i--) { in = a[i]; if (in >= 'A' && in <= 'F') { val = in - 55; } else if (in >= 'a' && in <= 'f') { val = in - 87; } else if (in >= '0' & in <= '9') { val = in - 48; } else return -1; out += val * (int) ceil((pow(16, length - 1 - i))); } return out; } boolean handleMIDI(int midiType, int midiChan, int note, int velocity) { global_note = note; global_velocity = velocity; int midiValue = 0; int i; //MIDI Clock Signal if (midiType == NoteOn && midiChan == 1 && note == 12/*C1*/ && velocity == 14) { period = milliSec; milliSec = 0; } //#ifdef DEBUG Serial.print("Type: "); Serial.print(midiType); Serial.print(" Chan: "); Serial.print(midiChan); Serial.print(" note: "); Serial.print(note); Serial.print(" velocity: "); Serial.println(velocity); //#endif //loop through all cases for (int i = 0; i < fgcount; i++) { //check to see if correct message type (Note on, Note off, etc) if (caseArray[i][MSG_TYPE] == midiType && caseArray[i][LISTEN_CHAN] == midiChan) { //get relevant incoming midi data switch (caseArray[i][MIDI_VAR]) { case PITCH: midiValue = note; break; case VELOCITY: midiValue = velocity; break; } //do comparison and load frame if true if (midiValue >= caseArray[i][CASE_VAL_L] && midiValue <= caseArray[i][CASE_VAL_H]) { loadFrame(i); return 1; } } } return 0; } void loop() { boolean dmx = 0; int i; if (usbMIDI.read()) dmx = handleMIDI(usbMIDI.getType(), usbMIDI.getChannel(), usbMIDI.getData1(), usbMIDI.getData2()); else if (MIDI.read()) handleMIDI(MIDI.getType(), MIDI.getChannel(), MIDI.getData1(), MIDI.getData2()); else return; if (!dmx) for (i = 0; i < maxChannel; i++) DmxSimple.write(i, 0); } char * float2s(double f, unsigned int digits) { int index = 0; static char s[16]; // buffer to build string representation // handle sign if (f < 0.0) { s[index++] = '-'; f = -f; } // handle infinite values if (isinf(f)) { strcpy(&s[index], "INF"); return s; } // handle Not a Number if (isnan(f)) { strcpy(&s[index], "NaN"); return s; } // max digits if (digits > 9) digits = 9; long multiplier = pow(10, digits); // fix int => long int exponent = int(log10(f)); double g = f / pow(10, exponent); if ((g < 1.0) && (g != 0.0)) { g *= 10; exponent--; } long whole = long(g); // single digit long part = long((g - whole) * multiplier); // # digits char format[16]; sprintf(format, "%%ld.%%0%dld E%%+d", digits); sprintf(&s[index], format, whole, part, exponent); return s; } -
yrrah revised this gist
Apr 21, 2013 . 1 changed file with 151 additions and 49 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,8 +1,8 @@ #include <SD.h> //#include <MIDI.h> #include <DmxSimple.h> //limited to 64 channels in DmxSimple.h to save memory //define DEBUG 1 #define MIDI_BAUDRATE 31250 #define COMPILE_MIDI_IN 1 // Set this setting to 1 to use the MIDI input. #define COMPILE_MIDI_OUT 0 // Set this setting to 1 to use the MIDI output. @@ -22,18 +22,23 @@ #define CURRENT_F 7 #define PITCH 0 #define VELOCITY 1 #define POT1 41 #define POT2 42 #define POT3 43 #define POT4 44 #define FADER 45 File myFile; char* temp = ""; int** caseArray; int fgcount=0; //number of frame groups & corresponding cases int maxChannel=20; double global_note, global_velocity; void loadFrame(int FrameID){ int i; int chan, val, upVal; char in,in2; #ifdef DEBUG Serial.print("Load Frame Group:"); @@ -56,42 +61,100 @@ void loadFrame(int FrameID){ in = myFile.read(); while(myFile.available()&&in!='%'&&in!='#'){ switch(in){ case 'S': case 'P': case 'F': case 'M': in2 = myFile.read(); myFile.readBytes(temp,2); chan = asciiHexToInt(temp,2); myFile.readBytes(temp,2); val = asciiHexToInt(temp,2); myFile.readBytes(temp,2); upVal = asciiHexToInt(temp,2); #ifdef DEBUG Serial.flush(); Serial.print("DMX Instruction: chan "); Serial.print(chan,HEX); Serial.print(", "); Serial.print(val,HEX); Serial.print(", "); Serial.println(upVal,HEX); #endif double potValue; int out; switch(in){ case 'S'://ST = Static DmxSimple.write(chan,val); break; case 'P': switch(in2){ case '1'://P1 = Potentiometer 1 potValue = analogRead(POT1); break; case '2'://P1 = Potentiometer 2 potValue = analogRead(POT2); break; case '3'://P1 = Potentiometer 3 potValue = analogRead(POT3); break; case '4'://P1 = Potentiometer 4 potValue = analogRead(POT4); break; case '5'://P1 = Fader / Slider potValue = analogRead(FADER); break; } out = (int)((potValue/1023)*(upVal-val) + val); DmxSimple.write(chan,out); break; case 'F': switch(in2){ case 'U'://FU = Fade Up case 'D'://FD = Fade Down break; } break; case 'M': Serial.print(val); Serial.print(" "); Serial.println(upVal); switch(in2){ case '1'://M1 = MIDI Note out = (int)((global_note/127)*(upVal-val) + val); break; case '2'://M2 = MIDI Velocity out = (int)((global_velocity/127)*(upVal-val) + val); break; } Serial.println(float2s(out,5)); DmxSimple.write(chan,out); break; } break; default: #ifdef DEBUG Serial.println("DMX Instuction Type not implemented yet"); Serial.print(caseArray[FrameID][CURRENT_F]); Serial.print(" "); Serial.print(FrameID); Serial.print(" "); Serial.print(in); Serial.println(in2); #endif break; } in = myFile.read(); } //increment frame counter if(++caseArray[FrameID][CURRENT_F]>=caseArray[FrameID][FG_LENGTH]) caseArray[FrameID][CURRENT_F]=0; } void loadCase(){ int i; @@ -188,8 +251,7 @@ void loadScene(){ } } void setup(){ DmxSimple.usePin(7); DmxSimple.maxChannel(8); //pinMode(3, OUTPUT); @@ -217,11 +279,11 @@ Serial.println("initialization done."); #endif // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. myFile = SD.open("qq.scn", FILE_READ); if (!myFile) { // if the file didn't open, print an error: #ifdef DEBUG Serial.println("error opening scene"); #endif } @@ -230,7 +292,6 @@ Serial.println("initialization done."); //myFile.close(); } int asciiHexToInt(char* a, int length){ //converts acii representation of hex eg 'ff' to 0xFF int val; @@ -257,18 +318,14 @@ int asciiHexToInt(char* a, int length){ return out; } void loop(){ boolean dmx=0; int i; if(usbMIDI.read()) dmx = handleMIDI(usbMIDI.getType(), usbMIDI.getChannel(),usbMIDI.getData1(),usbMIDI.getData2()); // else if(MIDI.read()) // handleMIDI(MIDI.getType(), MIDI.getChannel(),MIDI.getData1(),MIDI.getData2()); else return; if(!dmx) @@ -280,10 +337,12 @@ int i; boolean handleMIDI(int midiType, int midiChan, int note, int velocity) { global_note = note; global_velocity = velocity; int midiValue=0; int i; switch (midiType) { case 0:// NoteOff // Note Off midiType = 0x80; @@ -296,7 +355,7 @@ boolean handleMIDI(int midiType, int midiChan, int note, int velocity) { break; } //#ifdef DEBUG Serial.print("Type: "); Serial.print(midiType); Serial.print(" Chan: "); @@ -305,7 +364,7 @@ boolean handleMIDI(int midiType, int midiChan, int note, int velocity) { Serial.print(note); Serial.print(" velocity: "); Serial.println(velocity); //#endif //loop through all cases for(int i=0; i<fgcount; i++){ @@ -318,7 +377,7 @@ boolean handleMIDI(int midiType, int midiChan, int note, int velocity) { switch(caseArray[i][MIDI_VAR]){ case PITCH: midiValue=note; break; case VELOCITY: midiValue=velocity; @@ -335,4 +394,47 @@ boolean handleMIDI(int midiType, int midiChan, int note, int velocity) { } } return 0; } char * float2s(double f, unsigned int digits){ int index = 0; static char s[16]; // buffer to build string representation // handle sign if (f < 0.0) { s[index++] = '-'; f = -f; } // handle infinite values if (isinf(f)) { strcpy(&s[index], "INF"); return s; } // handle Not a Number if (isnan(f)) { strcpy(&s[index], "NaN"); return s; } // max digits if (digits > 9) digits = 9; long multiplier = pow(10, digits); // fix int => long int exponent = int(log10(f)); double g = f / pow(10, exponent); if ((g < 1.0) && (g != 0.0)) { g *= 10; exponent--; } long whole = long(g); // single digit long part = long((g-whole)*multiplier); // # digits char format[16]; sprintf(format, "%%ld.%%0%dld E%%+d", digits); sprintf(&s[index], format, whole, part, exponent); return s; } -
yrrah created this gist
Apr 18, 2013 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,338 @@ #include <SD.h> #include <MIDI.h> #include <DmxSimple.h> //limited to 64 channels in DmxSimple.h to save memory #define DEBUG 1 #define MIDI_BAUDRATE 31250 #define COMPILE_MIDI_IN 1 // Set this setting to 1 to use the MIDI input. #define COMPILE_MIDI_OUT 0 // Set this setting to 1 to use the MIDI output. #define COMPILE_MIDI_THRU 0 // Set this setting to 1 to use the MIDI Soft Thru feature #define USE_SERIAL_PORT Serial #define USE_RUNNING_STATUS 0 #define USE_1BYTE_PARSING 1 #define USE_CALLBACKS 0 #define MIDI_SYSEX_ARRAY_SIZE 64 #define LISTEN_CHAN 0 #define CASE_VAL_L 1 #define CASE_VAL_H 2 #define MIDI_VAR 3 #define MSG_TYPE 4 #define FG_ADDR 5 #define FG_LENGTH 6 #define CURRENT_F 7 #define PITCH 0 #define VELOCITY 1 #define NOTE_ON 'n' File myFile; char* temp = ""; int** caseArray; int fgcount=0; //number of frame groups & corresponding cases int maxChannel=20; void loadFrame(int FrameID){ int i; int chan, val; char in; #ifdef DEBUG Serial.print("Load Frame Group:"); Serial.print(FrameID); Serial.print(" Frame:"); Serial.println(caseArray[FrameID][CURRENT_F]); #endif //seek to location of frame group on SD card myFile.seek(caseArray[FrameID][FG_ADDR]); //find location of frame i=0; while(i<=caseArray[FrameID][CURRENT_F]){ while(myFile.read()!='%'); i++; } //read and execute DMX instructions in = myFile.read(); while(myFile.available()&&in!='%'&&in!='#'){ if(in=='S'){ //static instruction myFile.readBytes(temp,2); chan = asciiHexToInt(temp,2); myFile.readBytes(temp,2); val = asciiHexToInt(temp,2); DmxSimple.write(chan,val); #ifdef DEBUG Serial.flush(); Serial.print("DMX Instruction: chan "); Serial.print(chan,HEX); Serial.print(", "); Serial.println(val,HEX); #endif }else{ #ifdef DEBUG Serial.println("DMX Instuction Type not implemented yet"); Serial.print(caseArray[FrameID][CURRENT_F]); Serial.print(" "); Serial.println(FrameID); #endif } in = myFile.read(); } //increment frame counter if(++caseArray[FrameID][CURRENT_F]>=caseArray[FrameID][FG_LENGTH]) caseArray[FrameID][CURRENT_F]=0; } void loadCase(){ int i; caseArray = (int**) malloc(fgcount*sizeof(int*)); for (i = 0; i < fgcount; i++){ caseArray[i] = (int*) malloc(8*sizeof(int)); //MIDI Listen Channel myFile.readBytes(temp,2); caseArray[i][LISTEN_CHAN] = asciiHexToInt(temp,2); //MIDI low case value myFile.readBytes(temp,2); caseArray[i][CASE_VAL_L] = asciiHexToInt(temp,2); //MIDI high case value myFile.readBytes(temp,2); caseArray[i][CASE_VAL_H] = asciiHexToInt(temp,2); //MIDI varible (pitch,velocity,etc) myFile.readBytes(temp,1); caseArray[i][MIDI_VAR] = asciiHexToInt(temp,1); //MIDI message type (note on, note off, etc) myFile.readBytes(temp,2); caseArray[i][MSG_TYPE] = asciiHexToInt(temp,2); //FG address //caseArray[i][FG_ADDR] gets set in loadScene() //caseArray[i][FG_LENGTH] gets set in loadScene() caseArray[i][CURRENT_F] = 0; #ifdef DEBUG Serial.flush(); Serial.print("------ Case Array Index "); Serial.print(i); Serial.println(" -------"); Serial.print("MIDI Listen Channel "); Serial.println(caseArray[i][0]); Serial.print("MIDI low case value "); Serial.println(caseArray[i][1]); Serial.print("MIDI high case value "); Serial.println(caseArray[i][2]); Serial.print("MIDI varible "); Serial.println(caseArray[i][3]); Serial.print("MIDI message type "); Serial.println(caseArray[i][4]); Serial.flush(); #endif } } void loadScene(){ int i; int looplength; //free the memory for the old case array if it exists if(fgcount!=0){ for (i = 0; i < fgcount; i++) free(caseArray[i]); free(caseArray); } myFile.readBytes(temp,2); fgcount = asciiHexToInt(temp,2); myFile.readBytes(temp,2); looplength = asciiHexToInt(temp,2); myFile.readBytes(temp,2); maxChannel = asciiHexToInt(temp,2); #ifdef DEBUG Serial.print("fgcount "); Serial.println(fgcount); Serial.print("looplength "); Serial.println(looplength); Serial.print("maxChannel "); Serial.println(maxChannel); #endif //create new case array loadCase(); //set FG addresses in case array i = 0; for(i = 0; i<fgcount; i++){ while(myFile.read()!='#'); myFile.readBytes(temp,2); caseArray[i][FG_LENGTH] = asciiHexToInt(temp,2); caseArray[i][FG_ADDR] = myFile.position(); #ifdef DEBUG Serial.print("FG located at "); Serial.println(caseArray[i][5]); #endif } } void setup() { DmxSimple.usePin(7); DmxSimple.maxChannel(8); //pinMode(3, OUTPUT); // MIDI.begin(MIDI_CHANNEL_OMNI); #ifdef DEBUG Serial.print("Initializing SD card..."); #endif // On the Ethernet Shield, CS is pin 4. It's set as an output by default.*/ // Note that even if it's not used as the CS pin, the hardware SS pin // (10 on most Arduino boards, 53 on the Mega) must be left as an output // or the SD library functions will not work. pinMode(20, OUTPUT); if (!SD.begin(20)) { #ifdef DEBUG Serial.println("initialization failed!"); #endif return; } #ifdef DEBUG Serial.println("initialization done."); #endif // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. myFile = SD.open("1.scn", FILE_READ); if (!myFile) { // if the file didn't open, print an error: #ifdef DEBUG Serial.println("error opening test.txt"); #endif } loadScene(); //myFile.close(); } int asciiHexToInt(char* a, int length){ //converts acii representation of hex eg 'ff' to 0xFF int val; int in; int out=0; for(int i=length-1;i>=0;i--){ in = a[i]; if(in>='A'&&in<='F'){ val = in-55; } else if(in>='a'&&in<='f'){ val = in-87; } else if(in>='0'&in<='9'){ val = in-48; } else return -1; out += val * (int)ceil((pow(16,length-1-i))); } return out; } void loop() { boolean dmx=0; int i; if(usbMIDI.read()) dmx = handleMIDI(usbMIDI.getType(), usbMIDI.getChannel(),usbMIDI.getData1(),usbMIDI.getData2()); else if(MIDI.read()) handleMIDI(MIDI.getType(), MIDI.getChannel(),MIDI.getData1(),MIDI.getData2()); else return; if(!dmx) for(i=0; i<maxChannel; i++) DmxSimple.write(i,0); } boolean handleMIDI(int midiType, int midiChan, int note, int velocity) { int midiValue=0; int i; switch (midiType) { case 0:// NoteOff // Note Off midiType = 0x80; break; case 1:// NoteOn // Note On midiType = 0x90; break; default:// InvalidType // For notifying errors midiType = 0; break; } #ifdef DEBUG Serial.print("Type: "); Serial.print(midiType); Serial.print(" Chan: "); Serial.print(midiChan); Serial.print(" note: "); Serial.print(note); Serial.print(" velocity: "); Serial.println(velocity); #endif //loop through all cases for(int i=0; i<fgcount; i++){ //check to see if correct message type (Note on, Note off, etc) if(caseArray[i][MSG_TYPE]==midiType && caseArray[i][LISTEN_CHAN]==midiChan) { //get relevant incoming midi data switch(caseArray[i][MIDI_VAR]){ case PITCH: midiValue=note; break; case VELOCITY: midiValue=velocity; break; } //do comparison and load frame if true if(midiValue>=caseArray[i][CASE_VAL_L] && midiValue<=caseArray[i][CASE_VAL_H]) { loadFrame(i); return 1; } } } return 0; }