И так давайте приступим к сборке устройства. Для этого нам понадобиться следующие комплектующие:
1шт. Arduino любая
1шт. Блютус модуль HC-05
1шт. Стабилизатор напряжения LM7805
3шт. Сопротивления R1 ,R2 , R3 на 1кОм
2шт. Конденсаторы C3, C4 на 16в 220 Мкф C
2шт. Керамические конденсаторы C5, C6 на 0.1 Мкф
3шт. Мосфеты Q1, Q2, Q3 STP16NF06.
С лева представлена макетная плата, где показано что куда подключать + для удобства все линии связи имеют свой цвет
Фиолетовый цвет это питание (+12) автомобиля или какого нибудь блока питания. Черный цвет (- т.е GND). Оранжевый +5V который выходит с LM7805. Синий сигнальная линия для управления мосфетом и Синим цветом светодиода. Красный сигнальная линия для управления мосфетом и Красным цветом светодиода. Зеленый сигнальная линия для управления мосфетом и зеленым светодиодом. Бирюзовый для соединения лий TX ардуино с RX HC-05. Розовый для соединения линий RX ардуино с TX HC-05.
На схеме обозначен обычный RGB светодиод подписан как RGB LED, но если вы используете обычную светодиодную ленту то резисторы R1, R2, R3 ставить не нужно!
После того как собрали схему необходимо поменять параметры блютус модуля HC-05, это (переименовать модуль на LEDLamp и помень скорость соединения на 115200) Как это сделать смотрите видео Дмитрия Осипова под спойлером
После того как Вы успешно перепрограммировали модуль HC-05 необходимо загрузить скетч в arduino, но учтите, скетч написан давно поэтому он работает только на древнем Arduino IDE 0022 Скетч ооочень здоровый больше 1200 строк, я даже не разбирался что туда разработчик напихал, работает ну и ладно ;)
#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: Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра. // 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 = 5; // LED Rosso (atmega pin 11) - in futuro 9* const int led_G = 6; // LED Verde (atmega pin 12) - in futuro 10* const int led_B = 3; // 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 = 125; 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() { 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; } */
#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: Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.
// 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 = 5; // LED Rosso (atmega pin 11) - in futuro 9*
const int led_G = 6; // LED Verde (atmega pin 12) - in futuro 10*
const int led_B = 3; // 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 = 125;
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() {
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 , 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;
}
*/
Закачали скетч в Arduino, осталось дело за малым) Скачаем на телефон приложение через GooglePlay LEDLamp вот Здесь
Включаем блютус ищем устройство LEDLamp, теперь мы можем спокойно управлять RGB лентой. Приятного использования
{youtube}Uj-a5-DZwaY{/youtube}