Januar 4, 2012
Arduino Code:// Code for the HPRGB board driving a 8.5 Watt Dealextreme LED // Input Voltage: 12V // Current per LED: 350mA // Board Frequency: 600 KHz // Vf R: 6,39 // Vf G: 9,38 // Vf B: 9,22 // AIN 4 + 5 are used for I2C communication // code by fabian troxler - www.fabiantroxler.ch // parts of the cody by diego martinez // tutors: raphael perret & moritz kemper // 2011 zhdk interaction design - iad.zhdk.ch // Libraries --------------------------------------------------------- #include <Wire.h> // #include <HPRGB2.h> // RGB Led Library #include <RGBConverter.h> #include <SoftwareSerial.h> // Serial Library for LCD display // Instance of HPRGB Object ------------------------------------------ HPRGB ledShield; // default mcp4728 id(0) and default PCA9685 id(0) RGBConverter rgbc; // rgb to Hsv and Hsv to Rgb converter library (https://github.com/ratkins/RGBConverter) // Pin definitions --------------------------------------------------- // LCD Display #define txPin 8 // Serialpin for LCD serial communication //multiplexer Pin definitions --------------------- #define MP11 4 // PinSelector pins #define MP12 3 // PinSelector Pins #define MP13 2 // pinSelector Pins #define MP21 7 // PinSelector pins #define MP22 6 // PinSelector Pins #define MP23 5 // pinSelector Pins #define MPANALOG1 0 // Common Output (Z) - Multiplexer ListenPin (recieves and sends Values) #define MPANALOG2 1 // Common Output (Z) - Multiplexer ListenPin (recieves and sends Values) //RGB Button LED's #define SDI 9 #define CKI 10 #define STRIP_LENGTH 7 // 3 LEDs on this strip <---- adjust here // Variables --------------------------------------------------------- boolean rgbState = true; // RGB or HSB boolean whiteState = false; // white boolean complState = false; // complementary int tRgb = 0; //rgbbutton int tWhite = 0; // whitebutton int tCompl = 0; // complButton int value1 = 0; // virst Value - Red or hue int value2 = 0; // second Value - Green or saturation int value3 = 0; // third Value - Blue or value/brightness double hsv[]= { 0,0,0}; byte rgb[]= { 0,0,0}; //int colorrgb[]= {0,0,0}; int multi1[4] = { MP11,MP12,MP13, MPANALOG1}; int multi2[4] = { MP21,MP22,MP23, MPANALOG2}; int drehPoti1[2] = { 0,1}; // pin numbers (multiplexer!) of the first wheel int drehPoti2[2] = { 2,3}; // pin numbers (multiplexer!) of the second wheel int drehPoti3[2] = { 4,5}; // pin numbers (multiplexer!) of the third wheel int oldNumber[3] = { 0,0,0}; // global Variable for saving the old Numbervalue char* textStatus = ("RGB"); boolean rgbhsv = false; boolean complement = false; // display LCD functions int lcdNo1 = 0; int lcdNo2 = 0; int lcdNo3 = 0; long lcdTime = 0; long lcdDelay = 50; long input0 = 0; long input1 = 0; long input2 = 0; //RGB Button LED's long strip_colors[STRIP_LENGTH]; // create array //save function int counter[6] = { 0,0,0,0,0,0}; int dcm = 15; // counter until saved boolean memoryBT = false; // 6x6 Array - memories[buttonNr][0 = Red, 1 =Green, 2=Blue, 3=Hue, 4=Ssaturation, 5 =Value/Brightness] -- all Values are 0-2047!!!!! int memories[7][6] = { { 0,0,0,0,0,0 } , { 2047,0,0,0,2047,2047 } , // Red { 2047,2047,0,341,2047,2047 } , // Yellow { 0,2047,0,682,2047,2047 } , // Green { 0,2047,2047,1024,2047,2047 } , // Cyan { 0,0,2047,1365,2047,2047 } , // Blue { 2047,0,2047,1706,2047,2047 } // Magenta // play-Button }; // programm play function boolean pBut = false; long pTS = 0; // program timestamp long oldpTS = 0; // old program timestamp boolean pTaste = false; int pSent = true; long pButTS = 0; // playButton Timestamp boolean pRuns = false; int pCount = 1; SoftwareSerial LCD = SoftwareSerial(0, txPin); // since the LCD does not send data back to the Arduino, we should only define the txPin const int LCDdelay=4; // conservative, 2 actually works // Setup ------------------------------------------------------------- void setup() { ledShield.begin(); ledShield.setCurrent(350,350,350); // set maximum current for channel 1-3 (mA) ledShield.setFreq(600 ); // operation frequency of the LED driver (KHz) ledShield.eepromWrite(); // write current settings to EEPROM delay(100); // wait for EEPROM writing ledShield.goToRGB(0, 0, 0); Serial.begin(9600); // Define Multiplexer Selection Pins as Output pinMode(MP11, OUTPUT); pinMode(MP12, OUTPUT); pinMode(MP13, OUTPUT); pinMode(MP21, OUTPUT); pinMode(MP22, OUTPUT); pinMode(MP23, OUTPUT); // RGB button Pin definitions pinMode(SDI, OUTPUT); pinMode(CKI, OUTPUT); pinMode(12,OUTPUT); digitalWrite(12,HIGH); //Clear out the array for(int x = 0 ; x < STRIP_LENGTH ; x++) strip_colors[x] = 0; //LCD pinMode(txPin, OUTPUT); LCD.begin(9600); clearLCD(); goTo(1,0); LCD.print("booting ."); delay(400); oldNumber[0]=oldNumber[1]=oldNumber[2]=0; clearLCD(); goTo(1,0); LCD.print("booting .."); delay(400); clearLCD(); goTo(1,0); LCD.print("booting ..."); delay(400); //prereading and resetting the potivalues value1 = rgbControl(rgbState,0,drehPoti1); // (only to 255, potnumber, YellwoPinNumber, BluePinNumber) value2 = rgbControl(true,1,drehPoti2); // rgb stat e allways to true because in HSB only the hue ist endless. value3 = rgbControl(true,2,drehPoti3); // rgb stat e allways to true because in HSB only the hue ist endless. clearLCD(); goTo(1,0); LCD.print("booting .."); delay(400); oldNumber[0]=oldNumber[1]=oldNumber[2]=0; clearLCD(); goTo(1,0); LCD.print("booting ."); delay(400); value1 = rgbControl(rgbState,0,drehPoti1); // (only to 255, potnumber, YellwoPinNumber, BluePinNumber) value2 = rgbControl(true,1,drehPoti2); // rgb stat e allways to true because in HSB only the hue ist endless. value3 = rgbControl(true,2,drehPoti3); // rgb stat e allways to true because in HSB only the hue ist endless. clearLCD(); pTS = millis(); } // Loop ------------------------------------------------------------- void loop() { tRgb = multiplexer(multi1, 0); // read state of rgb/hsb switch tCompl = multiplexer(multi2, 7); // tWhite = multiplexer(multi2, 6); // value1 = rgbControl(rgbState,0,drehPoti1); // (only to 255, potnumber, YellwoPinNumber, BluePinNumber) value1 = map(value1,0,2047,0,255); value2 = rgbControl(true,1,drehPoti2); // rgb stat e allways to true because in HSB only the hue ist endless. value2 = map(value2,0,2047,0,255); value3 = rgbControl(true,2,drehPoti3); // rgb stat e allways to true because in HSB only the hue ist endless. value3 = map(value3,0,2047,0,255); // debug /* Serial.print("Slider 1: "); Serial.print(value1); Serial.print("\t"); Serial.print("Slider 2: "); Serial.print(value2); Serial.print("\t"); Serial.print("Slider 3: "); Serial.print(value3); Serial.print("\t"); Serial.print("RGBstate: "); Serial.print(tRgb); Serial.print("\t"); Serial.println(); */ if (tWhite <1000){ // read 'white' button whiteState = false; } else{ whiteState = true; } if (tRgb <1000) { rgbState = true; } else{ rgbState = false; } if (tCompl >1000) { if (complState) { complState = false; complement = !complement; } } else { if(!complState) { complement = !complement; } complState = true; // complement = !complement; } //LCD Text stuff if (rgbState)// check if RGB { lcdNo1 = value1; lcdNo2 = value2; lcdNo3 = value3; if (rgbhsv)// if first time change to rgb { textStatus = ("RGB"); rgbhsv = false; Serial.println("first rgb"); rgbc.hsvToRgb(value1/255.0,value2/255.0,value3/255.0,rgb); value1 = int(rgb[0]); value2 =int(rgb[1]); value3 = int(rgb[2]); /* Serial.print("red: "); Serial.print((int)rgb[0]); Serial.print("\t"); Serial.print("green: "); Serial.print((int)rgb[1]); Serial.print("\t"); Serial.print("blue: "); Serial.print((int)rgb[2]); Serial.println("\t"); */ oldNumber[0]=map(rgb[0],0,255,0,2047); oldNumber[1]=map(rgb[1],0,255,0,2047); oldNumber[2]=map(rgb[2],0,255,0,2047); } if (complement){ // check if first time to complementary complement = !complement; Serial.println("first complement rgb"); // complementary hue value oldNumber[0]=map(255-value1,0,255,0,2047); oldNumber[1]=map(255-value2,0,255,0,2047); oldNumber[2]=map(255-value3,0,255,0,2047); } } else // not RGB so its HSV 😉 { if (!rgbhsv)// check if first time change to hsv { textStatus = ("HSV"); rgbhsv = true; Serial.println("first HSV"); rgbc.rgbToHsv(value1,value2,value3,hsv); value1 = int((double)hsv[0]*360.0); value2 =int((double)hsv[1]*100.0); value3 = int((double)hsv[2]*100.0); /* Serial.print("hue: "); Serial.print(value1); Serial.print("\t"); Serial.print("saturation: "); Serial.print(hsv[1]); Serial.print("\t"); Serial.print("value: "); Serial.print(hsv[2]); Serial.println("\t"); */ oldNumber[0]=int(map(value1,0,360,0,2047)); oldNumber[1]=int(map(value2,0,100,0,2047)); oldNumber[2]=int(map(value3,0,100,0,2047)); } if(complement) // check if first time to complementary { complement = !complement; Serial.println("first complement hsv"); if (value1 <=180) { value1 = 180 + value1; } else { value1 = value1 - 180; } oldNumber[0]=int(map(value1,0,360,0,2047)); oldNumber[1]=int(map(value2,0,100,0,2047)); oldNumber[2]=int(map(value3,0,100,0,2047)); } lcdNo1 = int((float)value1*(360.0/255.0)); lcdNo2 = int((float)value2*(100.0/255.0)); lcdNo3 = int((float)value3*(100.0/255.0)); } if(millis()-lcdTime > lcdDelay) { clearLCD(); lcdTime = millis(); } else { goTo(0,6); if(whiteState) { goTo(0,5); textStatus = ("white"); lcdNo1 = 255; lcdNo2 = 255; lcdNo3 = 255; } if(tCompl >1000) { goTo(0,1); textStatus = ("complementary"); } if((whiteState != true) && (tCompl <1000)){ if (rgbState) { textStatus = "RGB"; } else { textStatus = "HSV"; } } LCD.print(textStatus); goTo(1,0); LCD.print(lcdNo1); goTo(1,6); LCD.print(lcdNo2); goTo(1,12); LCD.print(lcdNo3); } if (whiteState == HIGH){ Serial.println("withestatus"); // 'white' button is pressed ledShield.goToRGB(127, 127, 127); } if (whiteState == LOW){ // if 'white' button is not pressed if (rgbState == HIGH){ // we are in rgb mode //Serial.println("LEDgoToRGB"); ledShield.goToRGB(value1, value2, value3); } if (rgbState == LOW) { //Serial.println("LEDgoToHSB"); // we are in hsb mode ledShield.goToHSB(value1, value2, value3); } } // // delay(1000); /* OLD MEMORY SAVING if(t6 >= 1000 && memoryBT==false) { if(counter <= dcm){ // dcm = counter until saved counter++; Serial.println(counter); } else{ clearLCD(); goTo(0,5); LCD.print("saved"); delay(1000); clearLCD(); } } else{ if(counter > 0){ Serial.println("--- BT Memory aus ---"); memoryBT =true; if(counter >= dcm && memoryBT ==true){ Serial.println("--- safe ---"); if(rgbState){ memory6Rgb[0]=oldNumber[0]; memory6Rgb[1]=oldNumber[1]; memory6Rgb[2]= oldNumber[2]; rgbc.rgbToHsv(oldNumber[0]/2047.0*255.0,oldNumber[1]/2047.0*255.0,oldNumber[2]/2047.0*255.0,hsv); memory6Hsv[0]=int(hsv[0]*2047); memory6Hsv[1]=int(hsv[1]*2047); memory6Hsv[2]= int(hsv[2]*2047); } else { memory6Hsv[0]=oldNumber[0]; memory6Hsv[1]=oldNumber[1]; memory6Hsv[2]= oldNumber[2]; rgbc.hsvToRgb(oldNumber[0]/2047.0,oldNumber[1]/2047.0,oldNumber[2]/2047.0,rgb); memory6Rgb[0]=rgb[0]*(2047/255); memory6Rgb[1]=rgb[1]*(2047/255); memory6Rgb[2]= rgb[2]*(2047/255); } memoryBT=false; // weiss = false; counter = 0; } else if(counter < dcm && memoryBT ==true){ Serial.println("--- memory6 ---"); if(rgbState){ oldNumber[0]= memory6Rgb[0]; oldNumber[1]= memory6Rgb[1]; oldNumber[2]= memory6Rgb[2]; } else { oldNumber[0]= memory6Hsv[0]; oldNumber[1]= memory6Hsv[1]; oldNumber[2]= memory6Hsv[2]; } clearLCD(); goTo(0,0); LCD.print("Memory 6 loaded!"); delay(1000); clearLCD(); memoryBT=false; //weiss = false; counter = 0; } } } */ //Memory Save for ( int i = 0; i<=5; i++) { int mTaste = multiplexer(multi1,i+2); if(mTaste >= 1000 && memoryBT==false) { if(counter[i] <= dcm){ // dcm = counter until saved counter[i]++; Serial.println(counter[i]); } else{ clearLCD(); goTo(0,5); LCD.print("saved"); delay(1000); clearLCD(); } } else{ if(counter[i] > 0){ Serial.println("--- BT Memory aus ---"); memoryBT =true; if(counter[i] >= dcm && memoryBT ==true){ Serial.println("--- safe ---"); if(rgbState){ // if current colormode = RGB memories[i+1][0]=oldNumber[0]; // Red memories[i+1][1]=oldNumber[1]; // Green memories[i+1][2]= oldNumber[2]; // Blue rgbc.rgbToHsv(oldNumber[0]/2047.0*255.0,oldNumber[1]/2047.0*255.0,oldNumber[2]/2047.0*255.0,hsv); // convert to HSV memories[i+1][3]=int(hsv[0]*2047); // hue memories[i+1][4]=int(hsv[1]*2047); // saturation memories[i+1][5]= int(hsv[2]*2047); //Value/Brightness } else { // if current colormode = HSV memories[i+1][3]=oldNumber[3]; //Hue memories[i+1][4]=oldNumber[4]; //Saturation memories[i+1][5]= oldNumber[5]; //Value/Brightness rgbc.hsvToRgb(oldNumber[0]/2047.0,oldNumber[1]/2047.0,oldNumber[2]/2047.0,rgb); memories[i+1][0]=rgb[0]*(2047/255); //Red memories[i+1][1]=rgb[1]*(2047/255); //Green memories[i+1][2]= rgb[2]*(2047/255); //Blue } memoryBT=false; // weiss = false; counter[i] = 0; } else if(counter[i] < dcm && memoryBT ==true){ Serial.println("--- memory6 ---"); if(rgbState){ oldNumber[0]= memories[i+1][0]; //Red oldNumber[1]= memories[i+1][1]; //Green oldNumber[2]= memories[i+1][2]; //Blue } else { oldNumber[0]= memories[i+1][3]; // Hue oldNumber[1]= memories[i+1][4]; // Saturation oldNumber[2]= memories[i+1][5]; // value/Brightness } clearLCD(); goTo(0,0); LCD.print("Memory "); LCD.print(i+1); LCD.print(" loaded!"); delay(1000); clearLCD(); memoryBT=false; //weiss = false; counter[i] = 0; } } } } //Play Button int mTaste = multiplexer(multi1,1); if((mTaste > 1000) && (!pRuns) && (millis() - pButTS >= 500)) { Serial.println("Play Button pressed"); pTaste = true; pButTS = millis(); pTS = millis(); } if ((mTaste > 1000) && (millis() - pButTS >= 500)) { pTaste = false; pCount = 1; pRuns = false; pButTS = millis(); memories[0][0] = 0; memories[0][0] = 0; memories[0][0] = 0; } // run programm if (pTaste == true){ play_programm(); } // RGB Save button LED's if (!pRuns){ for(int i=0; i< STRIP_LENGTH; i++){ input0 = (memories[i][0])/2047.0*255.0; // R input1 = (memories[i][1])/2047.0*255.0; // G input2 = (memories[i][2])/2047.0*255.0; // B long color = (long)input0 << 16 | (long)input1 << 8 | (long)input2; // bit shifted to one r g b value strip_colors[i] = (long)color; } post_frame(); } } //Takes the current strip color array and pushes it out void post_frame (void) { //Each LED requires 24 bits of data //MSB: R7, R6, R5..., G7, G6..., B7, B6... B0 //Once the 24 bits have been delivered, the IC immediately relays these bits to its neighbor //Pulling the clock low for 500us or more causes the IC to post the data. for(int LED_number = 0 ; LED_number < STRIP_LENGTH ; LED_number++) { long this_led_color = strip_colors[LED_number]; //24 bits of color data for(byte color_bit = 23 ; color_bit != 255 ; color_bit--) { //Feed color bit 23 first (red data MSB) digitalWrite(CKI, LOW); //Only change data when clock is low long mask = 1L << color_bit; //The 1'L' forces the 1 to start as a 32 bit number, otherwise it defaults to 16-bit. if(this_led_color & mask) digitalWrite(SDI, HIGH); else digitalWrite(SDI, LOW); digitalWrite(CKI, HIGH); //Data is latched when clock goes high } } //Pull clock low to put strip into reset/post mode digitalWrite(CKI, LOW); delayMicroseconds(500); //Wait for 500us to go into reset } void play_programm(void){ pRuns = true; //Serial.println("play program"); // memories[0][0] = 2047; memories[0][1] = 0; memories[0][2] = 0; input0 = (memories[0][0])/2047.0*255.0; // R input1 = (memories[0][1])/2047.0*255.0; // G input2 = (memories[0][2])/2047.0*255.0; // B long color = input0 << 16 | input1 << 8 | input2; strip_colors[0] = color; pSent = true; if (pCount <= 6) { Serial.println(pCount); oldNumber[0]= memories[pCount][0]; //Red oldNumber[1]= memories[pCount][1]; //Green oldNumber[2]= memories[pCount][2]; //Blue for(int i=1; i< STRIP_LENGTH; i++){ // switch thrugh RGB LED's /*Serial.print(pCount); Serial.print("\t"); Serial.print(i); Serial.println();*/ if(i == pCount){ // Check if button is actual color -> only the actual button glows Serial.println("im in"); input0 = (memories[i][0])/2047.0*255.0; // R input1 = (memories[i][1])/2047.0*255.0; // G input2 = (memories[i][2])/2047.0*255.0; // B } else // if not actual coloer then make it grey { input0 = (long)1; // R input1 = (long)1; // G input2 = (long)1; // B } long color = input0 << 16 | input1 << 8 | input2; // bit shifted to one r g b value strip_colors[i] = color; } if(pSent == true){ post_frame(); pSent = false; } if(millis()-pTS >= 2000) // wait 2 Seccond { pCount++; pTS = millis(); pSent = true; } } else { // pRuns = false; pCount = 1; } } void goTo(int row, int col) { LCD.print(0xFE, BYTE); //command flag LCD.print((col + row*64 + 128), BYTE); //position delay(LCDdelay); } void clearLCD(){ LCD.print(0xFE, BYTE); //command flag LCD.print(0x01, BYTE); //clear command. delay(LCDdelay); } void backlightOn() { //turns on the backlight LCD.print(0x7C, BYTE); //command flag for backlight stuff LCD.print(157, BYTE); //light level. delay(LCDdelay); } void backlightOff(){ //turns off the backlight LCD.print(0x7C, BYTE); //command flag for backlight stuff LCD.print(128, BYTE); //light level for off. delay(LCDdelay); } void serCommand(){ //a general function to call the command flag for issuing all other commands LCD.print(0xFE, BYTE); } // potentiometer //global Variables int oldPy[3] = { 0,0,0}; // global Variable for saving the Values int oldPb[3] ={ 0,0,0}; // global Variable for saving the Values int rgbControl(boolean only255, int potNumber, int* potPinNumber) // only255 set the maximum value to 255, Number of the pot, pin of the pot { int py = 0; // potentiometer with the yellow cable (also first Pot) int pb = 0; // potentiometer with the blue cable (also second Pot) int oldpy = 0; // old Value int oldpb = 0; // old Value int realPoti = 0; // Values for Serial-debug int number = 0; // Is the saved value of every potentiometer char* quadrant = ""; // Variable for Serial-Debug int multiplicator = 1; if (only255){ multiplicator = 2; } else { multiplicator = 1; }; // Get the oldpy = oldPy[potNumber]; oldpb = oldPb[potNumber]; number = oldNumber[potNumber]; // use the Multiplexer to read the analog values, py = multiplexer(multi2,potPinNumber[0]); pb = multiplexer(multi2,potPinNumber[1]); // smoothing py = 0.6 * oldpy + 0.4 * py; pb = 0.6 * oldpb + 0.4 * pb; if ((py != oldpy) || (pb != oldpb)) // if no value changed then do nothing { if ((py >256) && (py <768)) // if first pot ist in its good valuerange (becaus the pot has problems in the lowest and highest ranges) { if(pb > 511) // checks if the second pot ist bigger then 512 -> defines the quadrant { number += multiplicator*(oldpy - py); // calculates the diffrence, thats also the speed with wich the pot was moved quadrant = " 1st quarant"; // Serial debug } else if (pb < 511) { number -= multiplicator*(oldpy - py);// calculates the diffrence, thats also the speed with wich the pot was moved quadrant = " 3rd quarant";// Serial debug } realPoti = (oldpy - py);// Serial debug } else if ((pb > 256) && (pb <768)) { if(py > 511) { number -= multiplicator*(oldpb - pb); // calculates the diffrence, thats also the speed with wich the pot was moved quadrant = " 2nd quarant";// Serial debug } else if (py < 511) { number += multiplicator*(oldpb - pb); // calculates the diffrence, thats also the speed with wich the pot was moved quadrant = " 4th quarant";// Serial debug } realPoti = (oldpb - pb);// Serial debug } } // remap the values in 0-255 or in endless (255,0,1,....254,255,0,1...) if (only255){ if (number >= 2047){ number = 2047; } if (number <= 0){ number = 0; } } if(!only255) { if (number > 2047){ number = 0; } if (number < 0){ number = 2047; } } // Serial debug /*if (quadrant != "" ) { Serial.print("\t"); Serial.print(quadrant); Serial.print("\t"); Serial.print(py); Serial.print("\t"); Serial.print(pb); Serial.print("\t"); Serial.print(realPoti); Serial.print("\t"); Serial.print(number); Serial.print("\t"); Serial.print(rgb); Serial.println(); }*/ oldPy[potNumber] = py; // save the values to the Array for the next itteration oldPb[potNumber] = pb; // save the values to the Array for the next itteration oldNumber[potNumber] = number; // save the values to the Array for the next itteration return(number); // return the 255 Value for the rgb-LED } // Multiplexer int multiplexer(int* multi,int outputnr) { int selectionPins[3]; int analogValue = 0; byte binCode = byte(outputnr); // Convert outputnumber in byte // read the last three bits of the number code (1 = HIGH, 0 = LOW) for the multiplexer pinSelection int value1 = bitRead(binCode,0); int value2 = bitRead(binCode,1); int value3 = bitRead(binCode,2); digitalWrite(multi[0], value1); // Set Selection Pins to HIGH or LOW digitalWrite(multi[1], value2); digitalWrite(multi[2], value3); analogValue = analogRead(multi[3]); return(analogValue); }