So der erste Prototyp
von meiner LED-RGB-Lamp ist fertig ;o)
Das Ergebnis gefällt mir auch schon sehr ….
Das Einzige was mich hier jetzt noch stört das die widerstände
zu viel Spannung killen müssen ….
Und daher werden sie mir zu warm.
Also wir wohl doch noch eine 5 Volt Version kommen müssen 😉
Es wurden verwendet:
- Arduino Nano
- Serial Bluetooth Adapter
- 3Watt RGB-Led
- Und der übliche Kram 😉
Und hier jetzt noch die Schaltung:
#Edit:
Jetzt habe ich auch die 5 Volt Version fertig …
Die Schaltung wird wie erwartet nicht annähend so heiß wie der 12 Volt Version!
Daher rate ich jeden der das hier nachbauen will zur 5 Volt Version, das die 12 Volt Version schon grenzwertig war.
Hier die neue Schaltung:
Und ein Video…… 😉
https://youtu.be/K45k77karOY
Der Code ist nicht von mir!
Hier die Quelle: http://www.myledlamp.net
Und die App: https://play.google.com/store/apps/details?id=com.mgs.LEDLamp
#include <TimedAction.h> #include <EEPROM.h> //--------------------------- // LED(Lamp) // Firmware by Alessandro Carrara - Via Molino Ronchin, 6 30174 Zelarino (Venice) Italy // web: http://www.myledlamp.net // mail: info@myledlamp.net // LICENSE: GPL3 //--------------------------- //-------------------------------------------------- // formato messaggio *CcVxxx# // |--------------------------- start messaggio // |-------------------------- flag che precede il comando (fisso a C) // |------------------------- valore del comando (fisso a 1chr, exemp: H accendi, L spegni, S imposta colore) // |------------------------ flag valore (fisso a 1chr, exemp: R valore colore R, G B...) // |||--------------------- valore (stringa lunga a piacere) // |-------------------- end messaggio //-------------------------------------------------- //funzioni multi threading TimedAction mainAction = TimedAction(60, main1); //main thread (ricezione comandi) TimedAction karmafade_effectAction = TimedAction(50, karmafade_effect); //karmafade thread TimedAction candle_effectAction = TimedAction(50, candle_effect); //candleeffect thread // costanti versione const String myHWName = "LED(Lamp) 1"; // nome dispositivo hardware const String myHWVer = "v1.0"; // versione dispositivo hardware const String myFWVer = "v0.7"; // versione firmware // configurazione hardware const int ledPin = 13; // the pin that the LED is attached to const int led_R = 9; // LED Rosso (atmega pin 11) - in futuro 9* const int led_G = 10; // LED Verde (atmega pin 12) - in futuro 10* const int led_B = 11; // LED Blu (atmega pin 5) - in futuro 11* //* utilizzare i pin 9 10 11 in quanto hanno la stessa freq. pwm. //------------------------------------ // costanti relative al formato del messaggio in ricezione dal dispositivo const String MSG_START = "*"; // flag start messaggio const String MSG_END = "#"; // flag end messaggio const int MSG_MAX = 16; // lunghezza massima della stringa messaggio (utilizzato per non rimanere in loop in caso di messaggio errato const String MSG_COMMAND = "C"; // flag che precede il codice comando const String MSG_VALUE = "V"; // flag che precede il valore const String MSG_INFO = "I"; // flag che precede il valore di ritorno //------------------------------------ // codici comando (set) // settaggio valori const String MSG_SET_STATE = "1"; const String MSG_SET_RGB_COLOR = "2"; const String MSG_SET_BRIGHTNESS = "3"; const String MSG_SET_RGB_WBT = "4"; // White Balance Threshold const String MSG_GOTO_RGB_COLOR = "5"; // va al colore in modo transizione. const String MSG_GOTO_BRIGHTNESS = "6"; // modifica luminosità in modo transizione. // settaggio effetti const String MSG_SET_EFFECT = "20"; // settaggio velocità effetti const String MSG_SET_KARMAFADE_VELOCITY = "50"; const String MSG_SET_CANDLEEFFECT_VELOCITY = "51"; // salvataggio in memoria const String MSG_SET_DEFAULT_RGB_COLOR = "60"; const String MSG_SET_DEFAULT_BRIGHTNESS = "61"; const String MSG_SET_DEFAULT_KARMAFADE_VELOCITY = "62"; const String MSG_SET_DEFAULT_CANDLEEFFECT_VELOCITY = "63"; // ripristino impostazioni di fabbrica const String MSG_SET_DEVICE_TO_DEFAULT = "90"; // codice comando (get) const String MSG_GET_INFO = "100"; // valori post comando get const String MSG_VALUE_STATE = MSG_SET_STATE; const String MSG_VALUE_RGB_COLOR = MSG_SET_RGB_COLOR; const String MSG_VALUE_BRIGHTNESS = MSG_SET_BRIGHTNESS; const String MSG_VALUE_RGB_WBT = MSG_SET_RGB_WBT; const String MSG_VALUE_DEFAULT_RGB_COLOR = MSG_SET_DEFAULT_RGB_COLOR; const String MSG_VALUE_DEFAULT_BRIGHTNESS = MSG_SET_DEFAULT_BRIGHTNESS; const String MSG_VALUE_KARMAFADE_VELOCITY = MSG_SET_KARMAFADE_VELOCITY; const String MSG_VALUE_CANDLEEFFECT_VELOCITY = MSG_SET_CANDLEEFFECT_VELOCITY; const String MSG_VALUE_DEFAULT_KARMAFADE_VELOCITY = MSG_SET_DEFAULT_KARMAFADE_VELOCITY; const String MSG_VALUE_DEFAULT_CANDLEEFFECT_VELOCITY = MSG_SET_DEFAULT_CANDLEEFFECT_VELOCITY; const String MSG_VALUE_HW_NAME = "100"; const String MSG_VALUE_HW_VER = "101"; const String MSG_VALUE_FW_VER = "102"; // stati di funzionamento const String STATE_OFF = "0"; // valore relativo a lampada spenta const String STATE_ON = "1"; // valore relativo a lampada accesa const String STATE_PAUSE = "2"; // valore relativo a lampada spenta const String STATE_RESUME = "3"; // valore relativo a lampada accesa const String STATE_KARMAFADE_EFFECT = "20"; // valore relativo a effetto karmafade in esecuzione const String STATE_CANDLEEFFECT = "21"; // valore relativo a effetto candle in esecuzione //------------------------------------ // mappa memoria eprom default fabbrica const int EPROM_ADDR_FIRST_TIME_EXEC = 0; // indirizzo memoria in cui è scritto se il dispositivo è la priva volta che viene lanciato const int EPROM_ADDR_VALUE_R = 1; // indirizzo memoria in cui è scritto il valore di default del led rosso const int EPROM_ADDR_VALUE_G = 2; // indirizzo memoria in cui è scritto il valore di default del led verde const int EPROM_ADDR_VALUE_B = 3; // indirizzo memoria in cui è scritto il valore di default del led blu const int EPROM_ADDR_VALUE_WBT_R = 11; // indirizzo memoria in cui è scritto il valore di Threshold per il WB del colore Rosso const int EPROM_ADDR_VALUE_WBT_G = 12; // indirizzo memoria in cui è scritto il valore di Threshold per il WB del colore Verde const int EPROM_ADDR_VALUE_WBT_B = 13; // indirizzo memoria in cui è scritto il valore di Threshold per il WB del colore Blu const int EPROM_ADDR_VALUE_BRIGHTNESS = 21; // indirizzo memoria in cui è scritto il valore della luminosità const int EPROM_ADDR_VALUE_KARMAFADE_VELOCITY = 22; // indirizzo memoria in cui è scritto il valore della Velocità dell'effetto karma const int EPROM_ADDR_VALUE_CANDLEEFFECT_VELOCITY = 23; // indirizzo memoria in cui è scritto il valore della Velocità dell'effetto candle //------------------------------------ // valori di default // colori const int DEFAULT_VALUE_R = 255; const int DEFAULT_VALUE_G = 50; const int DEFAULT_VALUE_B = 50; // Threshold per il White Balance const int DEFAULT_VALUE_WBT_R = 105; const int DEFAULT_VALUE_WBT_G = 0; const int DEFAULT_VALUE_WBT_B = 176; // luminosità ed effetti const int DEFAULT_VALUE_BRIGHTNESS = 125; const int DEFAULT_VALUE_KARMAFADE_VELOCITY = 128; const int DEFAULT_VALUE_CANDLEEFFECT_VELOCITY = 128; //------------------------------------ // costanti relative agli stati di funzionamento String State; // Variabile Stato corrente String PreState; // Variabile Stato precedente la pausa //------------------------------------ // valori globali RGB int global_R_Color = 0; int global_G_Color = 0; int global_B_Color = 0; //------------------------------------ // valori globali di Threshold per i colori primari utilizzati per il white balance. int global_WB_R_Threshold = 0; int global_WB_G_Threshold = 0; int global_WB_B_Threshold = 0; //------------------------------------ // valori globali precedenti alla pausa int pre_global_R_Color = 0; int pre_global_G_Color = 0; int pre_global_B_Color = 0; //------------------------------------ // valori globali Regolazioni int global_Brightness = 0; int global_KarmaFadeVelocity = 0; int global_CandleEffectVelocity = 0; //------------------------------------ // valori per effetto karmafade int kf_fadeValueR = 0; // valore analogico sul led1 int kf_fadeValueG = 0; // valore analogico sul led2 int kf_fadeValueB = 0; // valore analogico sul led3 int kf_minfadeValueR = 0; // valore fade minimo del led1 int kf_minfadeValueG = 0; // valore fade minimo del led2 int kf_minfadeValueB = 0; // valore fade minimo del led3 int kf_maxfadeValueR = 255; // valore fade massimo del led1 int kf_maxfadeValueG = 255; // valore fade massimo del led2 int kf_maxfadeValueB = 255; // valore fade massimo del led3 int kf_fadeDirectionR = 0; // direzione del fade del led1 (0 = aumenta, 1 = diminuisce) int kf_fadeDirectionG = 0; // direzione del fade del led2 (0 = aumenta, 1 = diminuisce) int kf_fadeDirectionB = 0; // direzione del fade del led3 (0 = aumenta, 1 = diminuisce) int kf_timeFadeR = 10; // tempo di fade per ogni salita o discesa int kf_timeFadeG = 5; // tempo di fade per ogni salita o discesa int kf_timeFadeB = 5; // tempo di fade per ogni salita o discesa unsigned long kf_time; // variabile tempo da quando è in esecuzione il programma unsigned long kf_timeLedR; // variabile tempo utilizzata per il led1 unsigned long kf_timeLedG; // variabile tempo utilizzata per il led2 unsigned long kf_timeLedB; // variabile tempo utilizzata per il led3 //------------------------------------ // valori per effetto candeleffect unsigned long ce_time; unsigned long ce_timeLedR; unsigned long ce_timeLedG; int ce_timeFadeR = 5; // tempo di fade per ogni salita o discesa int ce_timeFadeG = 5; // tempo di fade per ogni salita o discesa //--------------------------------------------------------------------------------------- void setup() { for (int i = 0; i < 1024; i++) EEPROM.write(i, 0); digitalWrite(13, HIGH); karmafade_effectAction.disable(); // disattivazione thread effetti candle_effectAction.disable(); //pinMode(ledPin, OUTPUT); // initialize the LED pin as an output: Serial.begin(115200); // initialize serial communication: startDevice(); // esegue check iniziali ed accende i led Serial.print("ready\n"); } void loop() { mainAction.check(); karmafade_effectAction.check(); candle_effectAction.check(); } //-------------------------------------------------------- // funzione che riceve ed elabora la stringa comando. void main1(){ mainAction.disable(); if (Serial.available()){ main2(); } mainAction.enable(); } void main2(){ char inString[MSG_MAX+1]; String srlC; int inCount=0; String Command=""; String Value=""; int nValue=0; boolean waitCommand = false; boolean waitValue = false; do { srlC = ""; inString[inCount] = Serial.read(); srlC = (String)inString[inCount]; if (srlC == MSG_START){ }else if(srlC == MSG_COMMAND){ waitCommand = true; waitValue = false; }else if (srlC == MSG_VALUE){ waitValue = true; waitCommand = false; }else if (srlC == MSG_END){ break; }else{ if (waitCommand){ Command.concat(inString[inCount]); } if (waitValue){ Value.concat(inString[inCount]); } } } while (++inCount < MSG_MAX); //Serial.print //Serial.println("CMD:" + Command + " VAL:" + Value); // lancia esecuzione comandi if(Command != ""){ executeCommand(Command, Value); } } //-------------------------------------------------------- // funzione che esegue i comandi ricevuti void executeCommand(String Command, String Value){ // in caso di nuovo comando disattivo il thread fade // tranne nel caso di richiesta info sul device if (Command != MSG_GET_INFO & Command != MSG_SET_BRIGHTNESS & Command != MSG_SET_KARMAFADE_VELOCITY & Command != MSG_SET_CANDLEEFFECT_VELOCITY){ karmafade_effectAction.disable(); candle_effectAction.disable(); } // funzioni invio stato if (Command == MSG_GET_INFO) { // invia informazioni sulla versione if (Value == MSG_VALUE_HW_NAME){ SendToDevice(MSG_VALUE_HW_NAME + MSG_VALUE + myHWName); } if (Value == MSG_VALUE_HW_VER){ SendToDevice(MSG_VALUE_HW_VER + MSG_VALUE + myHWVer); } if (Value == MSG_VALUE_FW_VER){ SendToDevice(MSG_VALUE_FW_VER + MSG_VALUE + myFWVer); } // invia stato lampada if (Value == MSG_VALUE_STATE){ SendToDevice(MSG_VALUE_STATE + MSG_VALUE + State); } // invia valori RGB globali if (Value == MSG_VALUE_RGB_COLOR){ if (State == STATE_PAUSE) { SendToDevice(MSG_VALUE_RGB_COLOR + MSG_VALUE + addZeroToLeft((String)pre_global_R_Color) + addZeroToLeft((String)pre_global_G_Color) + addZeroToLeft((String)pre_global_B_Color)); }else{ SendToDevice(MSG_VALUE_RGB_COLOR + MSG_VALUE + addZeroToLeft((String)global_R_Color) + addZeroToLeft((String)global_G_Color) + addZeroToLeft((String)global_B_Color)); } } // invia valore luminosità if (Value == MSG_VALUE_BRIGHTNESS){ SendToDevice(MSG_VALUE_BRIGHTNESS + MSG_VALUE + addZeroToLeft((String)global_Brightness)); } // invia valore White Balnce Threshold if (Value == MSG_VALUE_RGB_WBT){ SendToDevice(MSG_VALUE_RGB_WBT + MSG_VALUE + addZeroToLeft((String)global_WB_R_Threshold) + addZeroToLeft((String)global_WB_G_Threshold) + addZeroToLeft((String)global_WB_B_Threshold)); } // invia valore velocità if (Value == MSG_VALUE_KARMAFADE_VELOCITY){ SendToDevice(MSG_VALUE_KARMAFADE_VELOCITY + MSG_VALUE + addZeroToLeft((String)global_KarmaFadeVelocity)); } // invia valore velocità if (Value == MSG_VALUE_CANDLEEFFECT_VELOCITY){ SendToDevice(MSG_VALUE_CANDLEEFFECT_VELOCITY + MSG_VALUE + addZeroToLeft((String)global_CandleEffectVelocity)); } // invia valori RGB di default if (Value == MSG_VALUE_DEFAULT_RGB_COLOR){ SendToDevice(MSG_VALUE_DEFAULT_RGB_COLOR + MSG_VALUE + addZeroToLeft((String)EEPROM.read(EPROM_ADDR_VALUE_R)) + addZeroToLeft((String)EEPROM.read(EPROM_ADDR_VALUE_G)) + addZeroToLeft((String)EEPROM.read(EPROM_ADDR_VALUE_B))); } // invia valori Brightness di default if (Value == MSG_VALUE_DEFAULT_BRIGHTNESS){ SendToDevice(MSG_VALUE_DEFAULT_BRIGHTNESS + MSG_VALUE + addZeroToLeft((String)EEPROM.read(EPROM_ADDR_VALUE_BRIGHTNESS))); } // invia valori Velocity per karma if (Value == MSG_VALUE_DEFAULT_KARMAFADE_VELOCITY){ SendToDevice(MSG_VALUE_DEFAULT_KARMAFADE_VELOCITY + MSG_VALUE + addZeroToLeft((String)EEPROM.read(EPROM_ADDR_VALUE_KARMAFADE_VELOCITY))); } // invia valori Velocity per candle if (Value == MSG_VALUE_DEFAULT_CANDLEEFFECT_VELOCITY){ SendToDevice(MSG_VALUE_DEFAULT_CANDLEEFFECT_VELOCITY + MSG_VALUE + addZeroToLeft((String)EEPROM.read(EPROM_ADDR_VALUE_CANDLEEFFECT_VELOCITY))); } }else if (Command == MSG_SET_STATE) { // accende i led secondo i valori attualmente impostati if (Value == STATE_ON){ lightOn(); } else if (Value == STATE_OFF){ lightOff(); } else if (Value == STATE_PAUSE) { pause(); } else if (Value == STATE_RESUME) { resume(); } else if (Value == STATE_KARMAFADE_EFFECT){ setup_karmafade_effect(); } else if (Value == STATE_CANDLEEFFECT){ setup_candle_effect(); } // Imposta un colore } else if (Command == MSG_SET_RGB_COLOR) { State = STATE_ON; int R_Color = extractColor(Value, 1); int G_Color = extractColor(Value, 2); int B_Color = extractColor(Value, 3); SetRGBColor(R_Color, G_Color, B_Color); // Imposta un colore (modalità transizione) } else if (Command == MSG_GOTO_RGB_COLOR) { State = STATE_ON; int R_Color = extractColor(Value, 1); int G_Color = extractColor(Value, 2); int B_Color = extractColor(Value, 3); transictionFromTo (global_R_Color, global_G_Color, global_B_Color, R_Color, G_Color, B_Color, 1); // Imposta e salva i valori di Threshold per il White Balance } else if (Command == MSG_SET_RGB_WBT) { global_WB_R_Threshold = extractColor(Value, 1); global_WB_G_Threshold = extractColor(Value, 2); global_WB_B_Threshold = extractColor(Value, 3); // li scrivo nella eprom EEPROM.write(EPROM_ADDR_VALUE_WBT_R, global_WB_R_Threshold); EEPROM.write(EPROM_ADDR_VALUE_WBT_G, global_WB_G_Threshold); EEPROM.write(EPROM_ADDR_VALUE_WBT_B, global_WB_B_Threshold); // imposto nuovamente il colore SetRGBColor(global_R_Color, global_G_Color, global_B_Color); // Imposta i valori di luminosità } else if (Command == MSG_SET_BRIGHTNESS) { global_Brightness = stringToInt(Value); SetRGBColor(global_R_Color, global_G_Color, global_B_Color); // Imposta i valori di luminosità (modalità transizione) } else if (Command == MSG_GOTO_BRIGHTNESS) { goto_Brightness(stringToInt(Value)); // Imposta i valori di velocità effetto karma } else if (Command == MSG_SET_KARMAFADE_VELOCITY) { global_KarmaFadeVelocity = stringToInt(Value); // Imposta i valori di velocità effetto candle } else if (Command == MSG_SET_CANDLEEFFECT_VELOCITY) { global_CandleEffectVelocity = stringToInt(Value); // Imposta e salva i valori di colore di accensione di default } else if (Command == MSG_SET_DEFAULT_RGB_COLOR) { int R_Color = extractColor(Value, 1); int G_Color = extractColor(Value, 2); int B_Color = extractColor(Value, 3); EEPROM.write(EPROM_ADDR_VALUE_R, R_Color); EEPROM.write(EPROM_ADDR_VALUE_G, G_Color); EEPROM.write(EPROM_ADDR_VALUE_B, B_Color); // Salva il valore di luminosità di default } else if (Command == MSG_SET_DEFAULT_BRIGHTNESS) { EEPROM.write(EPROM_ADDR_VALUE_BRIGHTNESS, stringToInt(Value)); // Salva il valore di velocità karma di default } else if (Command == MSG_SET_DEFAULT_KARMAFADE_VELOCITY) { EEPROM.write(EPROM_ADDR_VALUE_KARMAFADE_VELOCITY, stringToInt(Value)); // Salva il valore di velocità candle di default } else if (Command == MSG_SET_DEFAULT_CANDLEEFFECT_VELOCITY) { EEPROM.write(EPROM_ADDR_VALUE_CANDLEEFFECT_VELOCITY, stringToInt(Value)); // Comando che esegue un soft reset di tutte le impostazioni (vengono azzerate le preferense utente) } else if (Command == MSG_SET_DEVICE_TO_DEFAULT) { setDeviceToDefault(); } } int extractColor(String Value, int indxColor){ //inxColor 1=R 2=G 3=B String Color; if (indxColor == 1){ Color = Value.substring(0, 3); } else if(indxColor == 2){ Color = Value.substring(3, 6); } else if(indxColor == 3){ Color = Value.substring(6, 9); } return stringToInt(Color); } //-------------------------------------------------------- // accende i led secondo i valori globali void lightOn(){ State = STATE_ON; digitalWrite(ledPin, HIGH); //test transictionFromTo(global_R_Color, global_G_Color, global_B_Color, pre_global_R_Color, pre_global_G_Color , pre_global_B_Color, 8); } //-------------------------------------------------------- // accende i led secondo i valori preventivamente salvati void lightOff(){ State = STATE_OFF; digitalWrite(ledPin, LOW); //test transictionFromTo(global_R_Color, global_G_Color , global_B_Color, 0, 0, 0, 8); } //-------------------------------------------------------- // mette in pausa la funzione corrente void pause(){ digitalWrite(ledPin, LOW); //test // salvo lo stato precendete (serve per il ripristino) PreState = State; /*Serial.println("-PAUSA-"); Serial.println("State " + (String)State); Serial.println("PreState " + (String)PreState);*/ // salvo i colori precendeti (serve per il ripristino e per la trasmissione dei colori al telefono anche con lammpada spenta) pre_global_R_Color = global_R_Color; pre_global_G_Color = global_G_Color; pre_global_B_Color = global_B_Color; if (State == STATE_ON) { lightOff(); }else if (State == STATE_KARMAFADE_EFFECT) { karmafade_effectAction.disable(); lightOff(); }else if (State == STATE_CANDLEEFFECT) { candle_effectAction.disable(); lightOff(); } State = STATE_PAUSE; } //-------------------------------------------------------- // ripristina la funzione messa in pausa void resume(){ digitalWrite(ledPin, HIGH); //test /*Serial.println("-RESUME-"); Serial.println("State " + (String)State); Serial.println("PreState " + (String)PreState);*/ if (PreState == STATE_ON) { lightOn(); }else if (PreState == STATE_OFF) { lightOff(); }else if (PreState == STATE_KARMAFADE_EFFECT) { setup_karmafade_effect(); }else if (PreState == STATE_CANDLEEFFECT) { setup_candle_effect(); } } //-------------------------------------------------------- // accende i led secondo i valori preventivamente salvati //-------------------------------------------------------- // esempio formula white balance: // Colore_in = 200, Threshold = 75 (il software mi invia 255 - valore seekbar) // calcolo max valore possibile visto il Threshold: max valore possibile = (255 - Threshold) (255 - 75 = 180) // calcolo moltiplicatore per valore out: moltiplicatore = (255 / max valore possibile) (255 / 180 = 1,4166) // Colore Out è uguale a colore_in diviso il moltiplicatore: Colore_out = (Colore_in / moltiplicatore) (200 / 1,4166 = 141) void SetRGBColor(int R, int G, int B){ // setto il colore nelle variabili globali // att.ne il colore va settato prima di impostare la luminosità e il WB. global_R_Color=R; global_G_Color=G; global_B_Color=B; // invio il valore ai piedini corrispondenti // dopo aver settato il bilanciamento del bianco e la luminosità int maxRCol; int maxGCol; int maxBCol; float colRMoltip; float colGMoltip; float colBMoltip; float newRCol; float newGCol; float newBCol; int maxB_onRG; int maxG_onRB; int maxR_onGB; float colBMoltip_onRG; float colGMoltip_onRB; float colRMoltip_onGB; float newBCol_onRG; float newGCol_onRB; float newRCol_onGB; // calcolo nuovi valori di colore in base ai valori di treshold // relativi ai colori da tagliare per ottenere una tinta bilanciata. maxRCol = 255 - global_WB_R_Threshold; maxGCol = 255 - global_WB_G_Threshold; maxBCol = 255 - global_WB_B_Threshold; /*Serial.print("maxRCol\n"); Serial.print(maxRCol); Serial.print(maxGCol); Serial.print(maxBCol);*/ if(maxRCol > 0){ colRMoltip = (float) 255 / maxRCol; newRCol = (int) R / colRMoltip; }else{ newRCol = 0; } if(maxGCol > 0){ colGMoltip = (float) 255 / maxGCol; newGCol = (int) G / colGMoltip; }else{ newGCol = 0; } if(maxBCol > 0){ colBMoltip = (float) 255 / maxBCol; newBCol = (int) B / colBMoltip; }else{ newBCol = 0; } /*Serial.print("colRMoltip\n"); serialPrintFloat(colRMoltip, 3); serialPrintFloat(colGMoltip, 3); serialPrintFloat(colBMoltip, 3); Serial.print("newRCol\n"); serialPrintFloat(newRCol, 3); serialPrintFloat(newGCol, 3); serialPrintFloat(newBCol, 3);*/ // rebilanciamento in base a coppie di colori rimanenti // più il valore della coppia di colori rimanente si abbassa // più il colore rimanente si alza a prescindere dal controllo di stabilizzazione del colore // calcolato in precedenza (vince il valore più alto). // serve a massimizzare i valori dei colori che si devono illuminare da soli. maxB_onRG = B - (newRCol + newGCol); maxG_onRB = G - (newRCol + newBCol); maxR_onGB = R - (newGCol + newBCol); if(maxB_onRG > 0){ colBMoltip_onRG = (float) B / maxB_onRG; newBCol_onRG = (float) B / colBMoltip_onRG; }else{ newBCol_onRG = 0; } if(maxG_onRB > 0){ colGMoltip_onRB = (float) G / maxG_onRB; newGCol_onRB = (float) G / colGMoltip_onRB; }else{ newGCol_onRB = 0; } if(maxR_onGB > 0){ colRMoltip_onGB = (float) R / maxR_onGB; newRCol_onGB = (float) R / colRMoltip_onGB; }else{ newRCol_onGB = 0; } if (newBCol_onRG > newBCol) { newBCol = newBCol_onRG; } if (newGCol_onRB > newGCol) { newGCol = newGCol_onRB; } if (newRCol_onGB > newRCol) { newRCol = newRCol_onGB; } analogWrite(led_R, setBrightness(newRCol)); analogWrite(led_G, setBrightness(newGCol)); analogWrite(led_B, setBrightness(newBCol)); /*Serial.print("ricorrezione\n"); serialPrintFloat(newRCol, 3); serialPrintFloat(newGCol, 3); serialPrintFloat(newBCol, 3);*/ } void SetRColor(int R){ SetRGBColor(R, global_G_Color, global_B_Color); } void SetGColor(int G){ SetRGBColor(global_R_Color, G, global_B_Color); } void SetBColor(int B){ SetRGBColor(global_R_Color, global_G_Color, B); } //-------------------------------------------------------- // funzione per la regolazione della luminosità float setBrightness (int Value) { float newValue; float Conts; Conts = (float)global_Brightness / 255; newValue = Value * Conts; return newValue; } //-------------------------------------------------------- // funzione per l'esecuzione di effetti di transizione void transictionFromTo (int fromR, int fromG, int fromB, int toR, int toG, int toB, int velocity) { float R = fromR; float G = fromG; float B = fromB; float ContsR; float ContsG; float ContsB; boolean RComplete = false; boolean GComplete = false; boolean BComplete = false; // disabilito ricezione eventi mainAction.disable(); // setup costanti di di discesa / salita if (R < toR){ ContsR = (float)toR / 255; }else{ ContsR = (float)fromR / 255; } if (G < toG){ ContsG = (float)toG / 255; }else{ ContsG = (float)fromG / 255; } if (B < toB){ ContsB = (float)toB / 255; }else{ ContsB = (float)fromB / 255; } /*serialPrintFloat(ContsR, 3); Serial.print(" "); serialPrintFloat(ContsG, 3); Serial.print(" "); serialPrintFloat(ContsB, 3); Serial.println("");*/ do{ if (!RComplete){ if (R < toR){ R = R + ContsR; if (R >= toR){ RComplete = true; } }else{ R = R - ContsR; if (R <= toR){ RComplete = true; } } } if (!GComplete){ if (G < toG){ G = G + ContsG; if (G >= toG){ GComplete = true; } }else{ G = G - ContsG; if (G <= toG){ GComplete = true; } } } if (!BComplete){ if (B < toB){ B = B + ContsB; if (B >= toB){ BComplete = true; } }else{ B = B - ContsB; if (B <= toB){ BComplete = true; } } } /*serialPrintFloat(R, 3); Serial.print(" "); serialPrintFloat(G, 3); Serial.print(" "); serialPrintFloat(B, 3); Serial.println("");*/ SetRGBColor(R, G, B); delay(velocity); }while(!(RComplete && GComplete && BComplete)); // abilito ricezione eventi mainAction.enable(); } //-------------------------------------------------------- // funzione per la regolazione della luminosità di transizione void goto_Brightness (int toBrightness) { float fromBrightness = global_Brightness; boolean BrComplete = false; float ContsBr; // disabilito ricezione eventi mainAction.disable(); if (fromBrightness < toBrightness){ ContsBr = (float)toBrightness / 255; }else{ ContsBr = (float)fromBrightness / 255; } do{ if (!BrComplete){ if (fromBrightness < toBrightness){ fromBrightness = fromBrightness + ContsBr; if (fromBrightness >= toBrightness){ BrComplete = true; } }else{ fromBrightness = fromBrightness - ContsBr; if (fromBrightness <= toBrightness){ BrComplete = true; } } } /*Serial.print("\n"); serialPrintFloat(fromBrightness, 3); Serial.print(" ");*/ global_Brightness = fromBrightness; SetRGBColor(global_R_Color, global_G_Color, global_B_Color); delay(1); }while(!BrComplete); // abilito ricezione eventi mainAction.enable(); } //-------------------------------------------------------- // invia un valore di ritorno al dispositico connesso void SendToDevice(String msgOut){ Serial.println(MSG_START + MSG_INFO + msgOut + MSG_END); } //-------------------------------------------------------- // setup iniziale effetto fade karma void setup_karmafade_effect(){ State = STATE_KARMAFADE_EFFECT; // imposta timer di sistema kf_time=millis(); kf_timeLedR=millis(); kf_timeLedG=millis(); kf_timeLedB=millis(); kf_fadeValueR = global_R_Color; kf_fadeValueG = global_G_Color; kf_fadeValueB = global_B_Color; karmafade_effectAction.enable(); } //-------------------------------------------------------- // esegue effetto fade karma void karmafade_effect(){ kf_time=millis(); // esegue la funzione ogni tempo random if(kf_time>kf_timeLedR+kf_timeFadeR){ if(kf_fadeValueR==kf_maxfadeValueR){ kf_fadeDirectionR = 1; kf_maxfadeValueR = random(200, 255); kf_timeFadeR = random(10, 210) + global_KarmaFadeVelocity; } if(kf_fadeValueR==kf_minfadeValueR){ kf_fadeDirectionR = 0; kf_minfadeValueR = random(0, 20); kf_timeFadeR = random(10, 210) + global_KarmaFadeVelocity; } SetRColor(kf_fadeValueR); if(kf_fadeDirectionR==0){ kf_fadeValueR++; }else{ kf_fadeValueR--; } kf_timeLedR=millis(); } if(kf_time>kf_timeLedG+kf_timeFadeG){ if(kf_fadeValueG==kf_maxfadeValueG){ kf_fadeDirectionG = 1; kf_maxfadeValueG = random(200, 255); kf_timeFadeG = random(10, 210) + global_KarmaFadeVelocity; } if(kf_fadeValueG==kf_minfadeValueG){ kf_fadeDirectionG = 0; kf_minfadeValueG = random(0, 20); kf_timeFadeG = random(10, 210) + global_KarmaFadeVelocity; } SetGColor(kf_fadeValueG); if(kf_fadeDirectionG==0){ kf_fadeValueG++; }else{ kf_fadeValueG--; } kf_timeLedG=millis(); } if(kf_time>kf_timeLedB+kf_timeFadeB){ if(kf_fadeValueB==kf_maxfadeValueB){ kf_fadeDirectionB = 1; kf_maxfadeValueB = random(200, 255); kf_timeFadeB = random(10, 210) + global_KarmaFadeVelocity; } if(kf_fadeValueB==kf_minfadeValueB){ kf_fadeDirectionB = 0; kf_minfadeValueB = random(0, 20); kf_timeFadeB = random(10, 210) + global_KarmaFadeVelocity; } SetBColor(kf_fadeValueB); if(kf_fadeDirectionB==0){ kf_fadeValueB++; }else{ kf_fadeValueB--; } kf_timeLedB=millis(); } /*Serial.print(fadeValueR); Serial.print(" "); Serial.print(fadeValueG); Serial.print(" "); Serial.print(fadeValueB); Serial.println("");*/ } //-------------------------------------------------------- // setup iniziale effetto fade karma void setup_candle_effect(){ State = STATE_CANDLEEFFECT; // imposta timer di sistema ce_time=millis(); ce_timeLedR=millis(); ce_timeLedG=millis(); SetBColor(0); candle_effectAction.enable(); } //-------------------------------------------------------- // effetto candela void candle_effect(){ ce_time=millis(); if(ce_time > ce_timeLedR + ce_timeFadeR){ transictionFromTo(global_R_Color, global_G_Color, 0, random(180, 255), global_G_Color, 0, 0); ce_timeLedR=millis(); ce_timeFadeR = random(10, 150) + global_CandleEffectVelocity; } if(ce_time > ce_timeLedG + ce_timeFadeG){ transictionFromTo(global_R_Color, global_G_Color, 0, global_R_Color, random(80, 140), 0, 0); ce_timeLedG=millis(); ce_timeFadeG = random(10, 150) + global_CandleEffectVelocity; } } //-------------------------------------------------------- // funzione che copia i dati di default se è la prima volta che viene acceso il device void setDeviceToDefault(){ EEPROM.write(EPROM_ADDR_FIRST_TIME_EXEC, 1); startDevice(); } //-------------------------------------------------------- // funzione di start void startDevice(){ // controllo se è la prima volta che accendo il device ed imposto i valori di default if (EEPROM.read(EPROM_ADDR_FIRST_TIME_EXEC) == 1){ // pulisco memoria eprom //for(int i = 0; i < 256; i++){ // EEPROM.write(i, 255); //} // scrivo valori default per colori EEPROM.write(EPROM_ADDR_VALUE_R, DEFAULT_VALUE_R); EEPROM.write(EPROM_ADDR_VALUE_G, DEFAULT_VALUE_G); EEPROM.write(EPROM_ADDR_VALUE_B, DEFAULT_VALUE_B); // scrivo valori default per White balance EEPROM.write(EPROM_ADDR_VALUE_WBT_R, DEFAULT_VALUE_WBT_R); EEPROM.write(EPROM_ADDR_VALUE_WBT_G, DEFAULT_VALUE_WBT_G); EEPROM.write(EPROM_ADDR_VALUE_WBT_B, DEFAULT_VALUE_WBT_B); // scrivo valori default per parametri effetti e luimnosità EEPROM.write(EPROM_ADDR_VALUE_BRIGHTNESS, DEFAULT_VALUE_BRIGHTNESS); EEPROM.write(EPROM_ADDR_VALUE_KARMAFADE_VELOCITY, DEFAULT_VALUE_KARMAFADE_VELOCITY); EEPROM.write(EPROM_ADDR_VALUE_CANDLEEFFECT_VELOCITY, DEFAULT_VALUE_CANDLEEFFECT_VELOCITY); // resetto attributo di esecuzione per la prima volta EEPROM.write(EPROM_ADDR_FIRST_TIME_EXEC, 0); // setupModem(); } // accendo le luci e carico i valori globali State = STATE_ON; digitalWrite(ledPin, HIGH); //test global_Brightness = EEPROM.read(EPROM_ADDR_VALUE_BRIGHTNESS); // lettura luminosità global_KarmaFadeVelocity = EEPROM.read(EPROM_ADDR_VALUE_KARMAFADE_VELOCITY); // lettura luminosità global_CandleEffectVelocity = EEPROM.read(EPROM_ADDR_VALUE_CANDLEEFFECT_VELOCITY); // lettura luminosità // recupero colore default da memoria int R_Color = EEPROM.read(EPROM_ADDR_VALUE_R); int G_Color = EEPROM.read(EPROM_ADDR_VALUE_G); int B_Color = EEPROM.read(EPROM_ADDR_VALUE_B); // recupero WB da memoria global_WB_R_Threshold = EEPROM.read(EPROM_ADDR_VALUE_WBT_R); global_WB_G_Threshold = EEPROM.read(EPROM_ADDR_VALUE_WBT_G); global_WB_B_Threshold = EEPROM.read(EPROM_ADDR_VALUE_WBT_B); transictionFromTo(0, 0, 0, R_Color, G_Color, B_Color, 8); } void setupModem(){ // bluetooth.begin(9600); // delay(500); //bluetooth.println("AT+BAUD7"); //delay(2000); // bluetooth.println("AT+NAMELEDLamp"); // delay(2000); } //-------------------------------------------------------- // funzione di conversione stringa > int int stringToInt(String string){ // converte stringa > int char cValue[string.length() + 1]; string.toCharArray(cValue, sizeof(cValue)); int iValue = atoi(cValue); return iValue; } String addZeroToLeft(String in){ String s; int count=0; while(count < 3-in.length()){ s.concat("0"); count++; } s.concat(in); return s; } //-------------------------------------------------------- // funzione di debug - stampare numeri float // printFloat prints out the float 'value' rounded to 'places' places after the decimal point void serialPrintFloat(float value, int places) { // this is used to cast digits int digit; float tens = 0.1; int tenscount = 0; int i; float tempfloat = value; // make sure we round properly. this could use pow from <math.h>, but doesn't seem worth the import // if this rounding step isn't here, the value 54.321 prints as 54.3209 // calculate rounding term d: 0.5/pow(10,places) float d = 0.5; if (value < 0) d *= -1.0; // divide by ten for each decimal place for (i = 0; i < places; i++) d/= 10.0; // this small addition, combined with truncation will round our values properly tempfloat += d; // first get value tens to be the large power of ten less than value // tenscount isn't necessary but it would be useful if you wanted to know after this how many chars the number will take if (value < 0) tempfloat *= -1.0; while ((tens * 10.0) <= tempfloat) { tens *= 10.0; tenscount += 1; } // write out the negative if needed if (value < 0) Serial.print('-'); if (tenscount == 0) Serial.print(0, DEC); for (i=0; i< tenscount; i++) { digit = (int) (tempfloat/tens); Serial.print(digit, DEC); tempfloat = tempfloat - ((float)digit * tens); tens /= 10.0; } // if no places after decimal, stop now and return if (places <= 0) return; // otherwise, write the point and continue on Serial.print('.'); // now write out each decimal place by shifting digits one by one into the ones place and writing the truncated value for (i = 0; i < places; i++) { tempfloat *= 10.0; digit = (int) tempfloat; Serial.print(digit,DEC); // once written, subtract off that digit tempfloat = tempfloat - (float) digit; } } /* HSVtoRGB (cc) 2008-2010 Kokiua (alias L.M.) from Sorbolo (Parma) - Italy Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/ algoritmo rielaborato partendo da da http://www.cs.rit.edu/~ncs/color/t_convert.html da RGB a HSB (Hue/Tonalita' - Saturation/Saturazione - Brightness/Luminosita') HSB diventa HSV definendo Brightness = Value per distinguere la variabile B di RGB i valori RGB che tornano sono nel range da 0-255 i valori in entrata sono: h = [0.0-360.0] ( Tonalita' in gradi) s = [0.0-1.0] (Saturazione in % dove 1 = 100%) v = [0.0-1.0] (Luminosita' in % dove 1 = 100%) void HSVtoRGB( unsigned char x, float h, float s, float v ) { int i; float f, p, q, t, r, g, b; if( s == 0 ) { r = g = b = v; // achromatic (grey) return; } else { h /= 60; // sector 0 to 5 i = floor( h ); f = h - i; // factorial part of h p = v * ( 1 - s ); q = v * ( 1 - s * f ); t = v * ( 1 - s * ( 1 - f ) ); switch( i ) { case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break; case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break; case 4: r = t; g = p; b = v; break; default: r = v; g = p; b = q; break; // case 5: } } led[x].r = 255 * r; //converto i valori RGB dal range 0.0-1.0 a 0-255 led[x].g = 255 * g; led[x].b = 255 * b; } */
13 Kommentare
hansi@123.com · 10. April 2015 um 10:40
Eine 3Watt RGB-LED? Können Sie mir bitte mehr darüber erzählen?
Shojo · 10. April 2015 um 12:09
Inwiefern?
Da müsse Sie schon etwas genauer werden. 😉
hansi@123.com · 10. April 2015 um 14:29
Wie heißt Ihre Power-LED und wie funktioniert das mit dem Kühlkörper?
Ich möchte auch gerne wissen wie die Zuordnung der Pins vom MOSFET sind.
Source/Drain/Gate –> ??? ??? ??? (RGB-Pins/Arduino-Pins/GND)
Shojo · 12. April 2015 um 09:45
Hi,
ich hatte damals die 3W LED Emitter on Star genutzt.
Als Kühlkörper habe ich einen alten Chipsatzkühler verwendet.
Die Pinzuordnung kann oben aus dem Schaltplan entnommen werden.
Gruß
Shojo
Klaus · 9. August 2014 um 12:37
Mir ist aufgefallen, dass du an deinen Schaltplänen bei der RGB einen gemeinsamen Plus Pol hast. Bei deiner selbst zusammengebauten hast du allerdings einen Gemeinsamen minus Pol. Zu welchem passt das unten stehende Sketch? und wäre das ein unterschied?
Mfg Klaus
Shojo · 9. August 2014 um 15:49
Moin Klaus,
der Sketch geht für beide „Versionen“!
Es ist ja nur entscheidend ob Du nun Plus oder Minus über die MOSFET schaltest,
und das ist für den Sketch irrelevant.
Gruß
Shojo
Steffen Wirth · 1. August 2014 um 13:35
Hey ich wollte mal nachfragen, der Sketch ist ja veraltet und wenn ich diesen bei mir im Programm Kompiliere zeigt er einige Fehler etc. wie hast du dieses Problem gelöst?
Shojo · 1. August 2014 um 18:32
Hi,
Du muss das nur mit der Arduino ide Version 0023 kompelieren.
(http://arduino.cc/en/Main/OldSoftwareReleases)
Gruß
Shojo
Steffen · 1. August 2014 um 19:00
EIne frage hätte ich noch, ist es für das Programm notwendig dass der BT- Chip mit einer Baudrate von 115200 läuft oder ist es egal?
Vielen Dank 🙂
Shojo · 2. August 2014 um 00:44
Das kannst Du machen wie Du willst ….
Muss dann hier aber angepasst werden
Serial.begin(115200); // initialize serial communication:
Shojo · 31. März 2013 um 13:25
So nun auch die 5 Volt Version verfügbar!
Shojo · 10. März 2013 um 18:56
Code und Links hinzugefügt,
viel Spaß beim Basteln 😉
Jorge Rocha · 28. Februar 2013 um 05:21
Hi,
where can i find the arduino code ande the app ?
Thaks