#include #include #include #define IR_KEY_POWER 21 #define IR_KEY_1 0 #define IR_KEY_2 1 #define IR_KEY_3 2 #define IR_KEY_4 3 #define IR_KEY_5 4 #define IR_KEY_6 5 #define IR_KEY_7 6 #define IR_KEY_8 7 #define IR_KEY_9 8 #define IR_KEY_0 9 #define IR_KEY_UP 16 // Channel #define IR_KEY_DOWN 17 // Channel #define IR_KEY_LEFT 19 // Volume #define IR_KEY_RIGHT 18 // Volume #define IR_KEY_BAR 96 #define IR_KEY_TENT 54 #define IR_KEY_VERT_CROSS 37 // AB #define IR_KEY_DIAG_CROSS 20 // Mute #define IR_KEY_MINUS 98 #define IR_KEY_PLUS 11 #define IR_KEY_DISP 58 #define IR_KEY_LAST 59 #define msg7Reset 4 #define msg7Strobe 12 #define msg7Analog A0 #define PushButtonPin 2 // Push Button Causing Interupt 0 #define VolumeInPin A1 // Analog input from Sparkfun BOB-09964 #define VolumeLedPin 10 // Analog output pin to LED on pin #define i2cDataPin A4 // Place holder for i2c pins #define i2cClkPin A5 // Place holder for i2c pins #define GELightsPin 7 // Arduino to GE Lights #define relayPin 8 // Arduino to Relay that controls power to GE Lights #define lightCount 35 // Total # of lights on string #define BounceDuration 1000 // Define an appropriate bounce time in ms for Push Button #define EQLedPin 9 // Only outputting to one LED So, repeat LEDs #define EQLedChannel 2 // Tie LED to EQ Channel 2 of 0-6 #define I2C_Address 9 // Ardunio i2c id 9. Id 18 on the PICAXE const int DebugLevel = 0x00; // 0x00 = Off // 0x01 = ProcessVolumeIn() // 0x02 = Output_EQ_Hort() // 0x04 = ButtonInterupt() // 0x08 = InteruptI2cHandler() // 0x10 = Mode_NitBounce() // X,Y to GE Light Address (When set horizonally) const int HortEQ[7][5] = { { 0,13,14,27,28 }, { 1,12,15,26,29 }, { 2,11,16,25,30 }, { 3,10,17,24,31 }, { 4,9, 18,23,32 }, { 5,8, 19,22,33 }, { 6,7, 20,21,34 } }; // X,Y to GE Light Address (When set vertical) const int VertEQ[5][7] = { { 28,29,30,31,32,33,34 }, { 27,26,25,24,23,22,21 }, { 14,15,16,17,18,19,20 }, { 13,12,11,10, 9, 8, 7 }, { 0, 1, 2, 3, 4, 5, 6 } }; const int HortEqChannelColor[7] = { COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, COLOR_MAGENTA, COLOR_YELLOW, COLOR_ORANGE, COLOR_RED }; const int VertEqStrengthColor[7] = { COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, COLOR_MAGENTA, COLOR_YELLOW, COLOR_ORANGE, COLOR_RED }; const int VertColors[5] = { COLOR_BLUE, COLOR_GREEN, COLOR_MAGENTA, COLOR_ORANGE, COLOR_RED }; int DisplayMode = 0; int MaxDisplayModes = 13; int VolumeLevel = 0; unsigned long BounceTime=0; // holds ms count to debounce after button press int ButtonInterupt = 0; // Set to 1 inside Interupt Handler int IrRemoteCode=-1; int SequenceState=0; int SeqDelay=50; int SeqDelayStep=10; // These Below control the Mode_BitBounce display output int BitX=0; int BitY=0; int BitDir = 0; int BitCnt = 0; int BitDur = 3; GEColorEffects GeLights (GELightsPin, lightCount); // Initialize Constructor for GE Lights // ============================================================================================ // Function ProcessVolumeIn() - Read Volume Mic, Process and Return Value 0-255 // ============================================================================================ int ProcessVolumeIn() { int sensorValue = 0; // value read sensorValue = analogRead(VolumeInPin); // Print the results to the serial monitor: if (DebugLevel & 0x01) { Serial.print ("VOL ["); Serial.print (sensorValue); Serial.println ("]"); } analogWrite(VolumeLedPin, sensorValue); // LED return (sensorValue); } // ============================================================================================ // Function Output_EQ_Center // ============================================================================================ void Output_EQ_Center(int channel, int value, int vol) { int i; int color; int peak; int vint; vint = map(vol, 0, 512, 0, 192); if (channel == 6) { value = value * 2.1; } if (channel == 5) { value = value * 1.2; } if (channel == 2) { value = value * .9; } if (value < 10) { peak=0; } else if (value >=10 && value <135) { peak=1; } else if (value >=135 && value <200) { peak=2; } else { peak=3; } if (peak == 0) { for (i=0; i<=4; i++) { GeLights.set_color(HortEQ[channel][i], DEFAULT_INTENSITY, COLOR_BLACK); } } else if (peak == 1) { GeLights.set_color(HortEQ[channel][2], DEFAULT_INTENSITY, HortEqChannelColor[channel]); GeLights.set_color(HortEQ[channel][0], DEFAULT_INTENSITY, COLOR_BLACK); GeLights.set_color(HortEQ[channel][4], DEFAULT_INTENSITY, COLOR_BLACK); GeLights.set_color(HortEQ[channel][1], DEFAULT_INTENSITY, COLOR_BLACK); GeLights.set_color(HortEQ[channel][3], DEFAULT_INTENSITY, COLOR_BLACK); } else if (peak == 2) { GeLights.set_color(HortEQ[channel][2], DEFAULT_INTENSITY, HortEqChannelColor[channel]); GeLights.set_color(HortEQ[channel][1], DEFAULT_INTENSITY, HortEqChannelColor[channel]); GeLights.set_color(HortEQ[channel][3], DEFAULT_INTENSITY, HortEqChannelColor[channel]); GeLights.set_color(HortEQ[channel][0], DEFAULT_INTENSITY, COLOR_BLACK); GeLights.set_color(HortEQ[channel][4], DEFAULT_INTENSITY, COLOR_BLACK); } else { GeLights.set_color(HortEQ[channel][2], vint, HortEqChannelColor[channel]); GeLights.set_color(HortEQ[channel][1], vint, HortEqChannelColor[channel]); GeLights.set_color(HortEQ[channel][3], vint, HortEqChannelColor[channel]); GeLights.set_color(HortEQ[channel][0], vint, HortEqChannelColor[channel]); GeLights.set_color(HortEQ[channel][4], vint, HortEqChannelColor[channel]); } } // ============================================================================================ // Function Output_EQ_Hort // ============================================================================================ void Output_EQ_Hort(int channel, int value, int vol) { int i; int color; int peak; int vint; if (channel == 6) { value = value * 2.5; } if (channel == 5) { value = value * 1.2; } if (channel == 2) { value = value * .9; } if (value < 10) { peak=0; } else if (value >=10 && value <50) { peak=1; } else if (value >=50 && value <100) { peak=2; } else if (value >=100 && value <150) { peak=3; } else if (value >=150 && value <200) { peak=4; } else { peak=5; } if (peak == 0) { for (i=0; i<=4; i++) { GeLights.set_color(HortEQ[channel][i], DEFAULT_INTENSITY, COLOR_BLACK); } } else { if (peak == 5) { // use volume data to pulse all 5 leds vint = map(vol, 0, 512, 0, 192); } else { vint = DEFAULT_INTENSITY; } for (i=1; i<=5; i++) { if (i <= peak) { color = HortEqChannelColor[channel]; } else { color = COLOR_BLACK; } GeLights.set_color(HortEQ[channel][i-1], vint, color); if (DebugLevel & 0x02) { Serial.print ("c "); Serial.print (channel); Serial.print (" v "); Serial.print (value); Serial.print (" p "); Serial.print (peak); Serial.print (" i "); Serial.print (i-1); Serial.print (" l "); Serial.print (HortEQ[channel][i-1]); Serial.print (" c "); Serial.print (color); Serial.println (""); } } } } // ============================================================================================ // Function Output_EQ_Vert // ============================================================================================ void Output_EQ_Vert(int channel, int value, int vol) { int i; int color; int peak; int vint; if (channel == 6) { return; // Ignore Channel 6 } if (channel == 5) { value = value * 1.2; } if (channel == 2) { value = value * .9; } if (channel>0) { // Merge Channel 0 and 1 channel--; } if (value < 10) { peak=0; } else if (value >=10 && value <35) { peak=1; } else if (value >=35 && value <70) { peak=2; } else if (value >=70 && value <95) { peak=3; } else if (value >=95 && value <125) { peak=4; } else if (value >=125 && value <175) { peak=5; } else if (value >=175 && value <225) { peak=6; } else { peak=7; } if (peak == 0) { for (i=0; i<7; i++) { GeLights.set_color(VertEQ[channel][i], DEFAULT_INTENSITY, COLOR_BLACK); } } else { if (peak == 5) { // use volume data to pulse all 5 leds vint = map(vol, 0, 512, 0, 192); } else { vint = DEFAULT_INTENSITY; } color = VertColors[channel]; for (i=1; i<=7; i++) { if (i <= peak) { // color = VertEqStrengthColor[i-1]; color = VertColors[channel]; } else { color = COLOR_BLACK; } GeLights.set_color(VertEQ[channel][i-1], vint, color); } } } // ============================================================================================ // Function EnumerateLeds // ============================================================================================ int EnumerateLeds() { int i; digitalWrite(relayPin, HIGH); // Disconnect Power from GE Lights delay(2000); // Wait for a few seconds digitalWrite(relayPin, LOW); // Enable Power to GE Lights delay(2000); // Set 1st led to max light count to get it out of the way for (i=0; i=0; x--) { for (y=4; y>=0; y--) { if (x==6) { last = 0; } else { last = x+1; } GeLights.set_color(HortEQ[last][y], DEFAULT_INTENSITY, COLOR_BLACK); GeLights.set_color(HortEQ[x][y], DEFAULT_INTENSITY, COLOR_RED); } delay(SeqDelay); } } // =========================================================================================== // Function Mode_BitBounce // ============================================================================================ int Mode_BitBounce() { int x; int y; if (--BitCnt <=0) { BitDir = random(65536) % 9; // Choose a new direction, perhaps the same BitCnt = BitDur; } x = BitX; y = BitY; switch (BitDir) { case 0 : x--; y++; break; case 1 : y++; break; case 2 : x++; y++; break; case 3 : x--; break; case 4 : x++; break; case 5 : x--; y--; break; case 6 : y--; break; case 7 : x++; y--; break; default : break; } if (x > 6) { x = 6; //BitDir = 3; } else if (x < 0) { x = 0; //BitDir = 4; } if (y > 4) { y = 4; //BitDir = 6; } else if (y < 0) { y = 0; //BitDir = 1; } if (DebugLevel & 0x10) { Serial.print("X ["); Serial.print(x); Serial.print("] Y["); Serial.print(y); Serial.println("]"); } GeLights.set_color(HortEQ[BitX][BitY], DEFAULT_INTENSITY-150, COLOR_BLACK); BitX = x; BitY = y; GeLights.set_color(HortEQ[BitX][BitY], DEFAULT_INTENSITY-150, COLOR_YELLOW); delay(SeqDelay); } // =========================================================================================== // InteruptI2cHandler // =========================================================================================== void InteruptI2cHandler(int howMany) { while(0 < Wire.available()) { // loop through all commands sent. Take the last IrRemoteCode = Wire.read(); // receive byte as a character } if (DebugLevel & 0x08) { Serial.print ("InteruptI2cHandler("); Serial.print (IrRemoteCode); Serial.println (")"); } } // =========================================================================================== // InteruptButtonHandler // =========================================================================================== void InteruptButtonHandler() { if (abs(millis() - BounceTime) > BounceDuration) { DisplayMode = ++DisplayMode % MaxDisplayModes; BounceTime = millis(); ButtonInterupt=1; } } // ============================================================================================ // Function SeqDelayMinus() - Decrement Delay // ============================================================================================ int SeqDelayMinus() { if (SeqDelay >= (SeqDelayStep * 2)) { SeqDelay -= SeqDelayStep; } } // ============================================================================================ // Function SeqDelayPlus() - Increment Delay // ============================================================================================ int SeqDelayPlus() { if (SeqDelay+SeqDelayStep < 400) { SeqDelay += SeqDelayStep; } } // =========================================================================================== // Function GetEqChannel // ============================================================================================ int GetEqChannel(int channel) { int freq; digitalWrite(msg7Reset, HIGH); // reset the MSGEQ7's counter delay(5); digitalWrite(msg7Reset, LOW); // Strobe for each EQ Freq Band, Update LED, Update GE_Lights for (int x = 0; x < 7; x++) { digitalWrite(msg7Strobe, LOW); delayMicroseconds(35); // to allow the output to settle int spectrumRead = analogRead(msg7Analog); if (spectrumRead < 200) { // Filter Noise spectrumRead=200; } int PWMvalue = map(spectrumRead, 200, 1024, 0, 255); // Scale analogRead's value if (x == channel) { freq = PWMvalue; } digitalWrite(msg7Strobe, HIGH); // Strobe We read the value } return (freq); } // =========================================================================================== // CheckForIrCmd // =========================================================================================== void CheckForIrCmd() { if (IrRemoteCode != -1) { // Ignore all codes but Power button if we are shut off if ((DisplayMode == 99) && (IrRemoteCode != IR_KEY_POWER)) { IrRemoteCode = -1; return; } switch(IrRemoteCode) { case IR_KEY_RIGHT: // Speed Up SeqDelayMinus(); break; case IR_KEY_LEFT: // Slow Down SeqDelayPlus(); break; case IR_KEY_UP: // Next Display Mode analogWrite(EQLedPin, 0); // Turn Off LED analogWrite(VolumeLedPin, 0); // Turn Off LED DisplayMode = ++DisplayMode % MaxDisplayModes; break; case IR_KEY_DOWN: // Previous Display Mode analogWrite(EQLedPin, 0); // Turn Off LED analogWrite(VolumeLedPin, 0); // Turn Off LED if (DisplayMode) { --DisplayMode; } else { DisplayMode = MaxDisplayModes-1; } break; case IR_KEY_POWER: // Toggle On/Off analogWrite(EQLedPin, 0); // Turn Off LED analogWrite(VolumeLedPin, 0); // Turn Off LED if (DisplayMode == 99) { DisplayMode = 0; Mode_SequenceLeds_ONOFF(); delay(1000); } else { DisplayMode = 99; Mode_SequenceLeds_ONOFF(); } break; default: break; } IrRemoteCode = -1; // Reset remote code } } // ============================================================================================ // Function setup() -- Run Once to Initialize // ============================================================================================ void setup() { // if analog input pin 0 is unconnected, random analog // noise will cause the call to randomSeed() to generate // different seed numbers each time the sketch runs. // randomSeed() will then shuffle the random function. randomSeed(analogRead(0)); // initialize the digital pin pinMode(EQLedPin, OUTPUT); pinMode(msg7Reset, OUTPUT); pinMode(msg7Strobe, OUTPUT); pinMode(msg7Analog, INPUT); pinMode(VolumeInPin, INPUT); pinMode(relayPin, OUTPUT); pinMode(PushButtonPin, INPUT); EnumerateLeds(); // Initialize GE Leds delay(1000); Mode_SequenceLeds_ONOFF(); // Show we are initialized delay(1000); // Setup Interupt Handler for Button Press attachInterrupt(0, InteruptButtonHandler, RISING); // Interupt0 = Pin 2, Interupt1 = Pin 3 // Setup I2c from PIXAXE and IR remote Wire.begin(I2C_Address); // join i2c bus with specified address Wire.onReceive(InteruptI2cHandler); // Set Interupt Handler // Do After Enumerate so we do create a usb related reset if (DebugLevel) { Serial.begin(9600); Serial.println ("Setup()"); } } // ============================================================================================ // Function loop() -- Loop forever // ============================================================================================ void loop() { // Can't do printing inside Interupt Handlers if (ButtonInterupt) { ButtonInterupt = 0; if (DebugLevel & 0x04) { Serial.println (BounceTime); // Interupt Button Handler } } CheckForIrCmd(); switch(DisplayMode) { case 0: Mode_EqHort(); break; case 1: Mode_EqCent(); break; case 2: Mode_EqVert(); break; case 3: Mode_SequenceLeds(); break; case 4: Mode_RowsUp(); break; case 5: Mode_TwoRowsUp(); break; case 6: Mode_Bounce(); break; case 7: Mode_Screw(); break; case 8: Mode_Spin(); break; case 9: Mode_ColorFlow(); break; case 10: if (GetEqChannel(2)) { Mode_SeqRowsUp(); } break; case 11: Mode_Bounce(); break; case 12: Mode_BitBounce(); break; case 99: // off delay(1000); break; default: // Do Nothing break; } }