Saturday,30-January-2016
RGB LED control via Arduino and BT serial
EN | BG |
In that topic will show my first attempt to create R-G-B LED control via timer`s PWM and serial commands based on HC-06 interface hardware and BT serial app for Android. | Това е първият ми опит да използвам сериен порт базиран на блутут комуникация между Андроид телефон и ардуино нано. RGB диода се управлява посредством шим базиран на хардуерен таймер |
Hardware setup | Oпитна установка |
Arduino Nano - HC-06 - RGB LED
1) USB to RS232 TTL PL2303HX
2) HC-06
3) Arduino IDE
My set up for HC-06 | Mоите настройки за НС-06 |
USB to RS232 TTL PL2303HX - HC-06
+5V - VCC
GND - GND
RX - TX
TX - RX
Arduino IDE -> COM port: com(XX)
Arduino IDE -> Programmer : Parallel Programmer
Arduino IDE -> Serial monitor -> NO end line -> 9600 baud
Some of the versions of HC-06 require “Both NL/CR” set at 9600 bbp to get into AT mode
Plug PL2303HX into USB / поставете PL2303HX в USB-то
In serial window write: / В прозореца за серийни команди напишете:
SERIAL SEND: AT <enter>
SERIAL RETURN: OK
SERIAL SEND: AT+NAMERGB <enter> <- new name will be “RGB” / новото име ще е “RGB”
SERIAL RETURN: OKsetname
SERIAL SEND: AT+PIN0000 <enter> <- new pin will be “0000” / новият пин ще е “0000”
SERIAL RETURN: OKsetname
SERIAL SEND: AT+BAUD4 <enter> <- new baud “9600” / новата скорост ще е “9600”
SERIAL RETURN: OK9600
1 - 1200bps
2 - 2400bps
3 - 4800bps
4 - 9600bps (Default)
5 - 19200bps
6 - 38400bps
7 - 57600bps
8 - 115200bps
In one new HC-06 modules I bought in 2017 it keep as that:
AT+VERSION:
>VERSION:3.0-20170609
AT+NAME
>+NAME:HC-06
to set new, write: AT+NAME=NEW_NAME
AT+UART
> +UART:9600,0,0
Set new speed: > AT+UART:115200,0,0 <- set to 115200, stop bit1 (0-1bit / 1-2bit) , parity none(0-none/1-odd / 2-even)
AT+PSWD
>+PIN:”1234”
to set new, write: AT+PSWD=”0000” , set pin to 0000
It look to be something similar to HC-05, but work :))
// Arduino IDE settings for serial: [x] autoscroll - No line ednding - 38400baud // example: // 255000000d#<enter> - full red / само червено // f <enter> - floating colors / преливащи цветове // w <enter> - full white / само бял // r <enter> - full off / всичко спряно // < or > <enter> - dec./inc. brightness - усилване намалявне на яркостта // d <enter> - return last state / върти обратно // 0-off 255-pull 100% / за цвят - 0 - без, 255 - 100% // based on http://www.easyrgb.com/index.php?X=MATH&H=19#text19 #define RED 6// D6 timer 0 oc0a #define GREEN 5// D5 timer 0 oc0b #define BLUE 3// D3 timer 2 OCR2B int state = 0; long previousMillis = 0; long serialDelay = 0; int counter = 255; char command[10]={0,0,0,0,0,0,0,0,0,'d'}; //R 0,0,0 G 0,0,0 B 0,0,0 Float 0 int fill = 0; int red,green,blue; int brightUp,brightDown; int rgbState[3] = {0,0,0}; // 0_R , 1_G , 2_B int long hslState[3] = {0,0,0}; // 0_H , 1_S , 2_L int luminSteps=0; int rgbInit[3] = {0,0,0}; boolean rgb = false; boolean white = false; int whiteStep=0; void setup() { pinMode(RED, OUTPUT); pinMode(GREEN, OUTPUT); pinMode(BLUE, OUTPUT); TCCR0A = (1<<COM0A1) | (1<<COM0A0) | (1<<COM0B1) | (1<<COM0B0) | (1<<WGM01) | (1<<WGM00); TCCR0B = (0<< FOC0A) | (0<<FOC0B) | (0<<WGM02) | (0<<CS02) | (1<<CS01) | (1<<CS00); TCCR2A = (1<<COM2A1) | (1<<COM2A0) | (1<<COM2B1) | (1<<COM2B0) | (1<<WGM21) | (1<<WGM20); TCCR2B = (0<< FOC2A) | (0<<FOC2B) | (0<<WGM22) | (1<<CS22) | (0<<CS21) | (0<<CS20); //OCR0A = 255; //OCR0B = 255; //OCR2A = 255; //OCR2B = 255; TCNT2=0; TCNT0=0; Serial.begin(38400); Serial.println("Welcome to RGB!"); } //----------------------------------------- additional to HSL to RGB --------- int hue2rgb(float v1,float v2,float vh){ if(vh < 0) vh +=1; if(vh > 1) vh -=1; if((6*vh) < 1) { float tma = v1 + ((v2-v1)*6.0*vh); tma = (tma*255.0)+0.5; return(tma); }else if ((2.0*vh) < 1) { float tmb = (v2*255.0)+0.5; return (tmb); }else if ((3*vh) < 2 ){ float tmc = v1 + ((v2-v1)*((0.6666 - vh)*6)); tmc = (tmc*255.0)+0.5; return (tmc); }else{ v1 = (v1*255.0)+0.5; return ( v1 ); } } //----------------------------------------------------------------------- void printBack(){ // uncomment for debuging only // if(command[9] == 'f'){ // Serial.println("RGB float:ON"); // }else{ // Serial.print("RGB float:OFF | "); // Serial.print("RED:"); // Serial.print(rgbInit[0],DEC); // Serial.print(" Green:"); // Serial.print(rgbInit[1],DEC); // Serial.print(" BLUE:"); // Serial.println(rgbInit[2],DEC); // // Serial.print("H:"); // Serial.print(hslState[0],DEC); // Serial.print(" S:"); // Serial.print( hslState[1],DEC); // Serial.print(" L:"); // Serial.println( hslState[2],DEC); // Serial.print("R:"); Serial.print(rgbState[0],DEC); Serial.print(" G:"); Serial.print(rgbState[1],DEC); Serial.print(" B:"); Serial.println(rgbState[2],DEC); // // Serial.print("STEP:"); // Serial.println(luminSteps); // } }//end print // --------------RGB to HSL ----- void rgb2hsl(){ float var_R = (float) rgbState[0] / 255.0; float var_G = (float) rgbState[1] / 255.0; float var_B = (float) rgbState[2] / 255.0; float tmpMax, tmpMin; if(var_B > var_G) { tmpMax = var_B; }else{ tmpMax = var_G; } if(var_R > tmpMax){ tmpMax = var_R; } if(var_G < var_B) { tmpMin = var_G; }else{ tmpMin = var_B; } if(var_R < tmpMin){ tmpMin = var_R; } float luminance, saturation, hue, delta, tmpA; tmpA = tmpMax+tmpMin; luminance = tmpA/2; delta = tmpMax-tmpMin; if(luminance < 0.5) { saturation = delta/tmpA; }else{ saturation = delta/(2.0-tmpMax-tmpMin); } if(delta == 0){ hue = 0; saturation = 0; }else{ float tmpA2 = tmpMax / 2.0; float del_R = ((tmpMax - var_R)/6) + (tmpA2 / tmpMax); float del_G = ((tmpMax - var_G)/6) + (tmpA2 / tmpMax); float del_B = ((tmpMax - var_B)/6) + (tmpA2 / tmpMax); if(var_R == tmpMax){ hue = (del_B - del_G)/delta; }else if(var_G == tmpMax){ hue = 0.3333 + ((del_R - del_B)/delta); }else if(var_B == tmpMax){ hue = 0.6666 + ((del_G - del_R)/delta); } if( hue < 0 ){ hue += 1;} if( hue > 1 ){ hue -= 1;} hslState[0] = hue*360.0; hslState[1] = saturation*1000.0; hslState[2] = luminance*1000.0; } }//end rgb2hsl //-------------------------------------- from HSL to RGB ----------------------- void hsl2rgb(){ int nR,nG,nB; float var1,var2,newHue; float lumin = (float) hslState[2] / 1000.0; float satur = (float) hslState[1] / 1000.0; newHue = float(hslState[0])/360.0; if(satur == 0){ nR = (float)255*lumin; nG = (float)255*lumin; nB = (float)255*lumin; }else{ if(lumin<0.5){ var2 = lumin*(1+satur); }else{ var2 = (lumin+satur)-(satur*lumin); } var1 = (2*lumin)-var2; rgbState[0] = hue2rgb(var1,var2,newHue+0.3333); //R rgbState[1] = hue2rgb(var1,var2,newHue); //G rgbState[2] = hue2rgb(var1,var2,newHue-0.3333); //B } }//end hsl2rgb void loop(){ while(Serial.available()>0) { char serialBuffer = Serial.read(); if(serialBuffer != '#'){ if(serialBuffer == 'w'){ white = true; rgb = false; if(command[9] == 'r'){ command[9] = 'd'; }else{ rgbState[0] = 255; rgbState[1] = 255; rgbState[2] = 255; } //Serial.println("WHITE:ON"); } else if(serialBuffer == 'r'){ command[9] = 'r'; //Serial.println("FULL:OFF"); } else if(serialBuffer == 'f'){ command[9] = 'f'; //Serial.println("FLOAT:ON"); } else if(serialBuffer == 'd'){ command[9] = 'd'; //Serial.println("I`m back :)"); } else if(serialBuffer == '<'){ if(white == true){ if(whiteStep < 4){ whiteStep += 1; rgbState[0] -= 63; rgbState[1] -= 63 ; rgbState[2] -= 63 ; } }if(rgb == true){ rgb2hsl(); if(luminSteps < 4){ luminSteps += 1; hslState[2] -= 100; } hsl2rgb(); printBack(); } }else if(serialBuffer =='>'){ if(white == true){ if(whiteStep > 0){ whiteStep -= 1; rgbState[0] += 63; rgbState[1] += 63 ; rgbState[2] += 63 ; } }else if(rgb == true){ rgb2hsl(); if(luminSteps > 0){ luminSteps -= 1; hslState[2] += 100; } hsl2rgb(); printBack(); } }else{ command[fill] = serialBuffer; fill++; } } if(serialBuffer == '#'){ fill = 0; white = false; whiteStep = 0; rgb = true; rgbState[0] = 0; rgbState[1] = 0; rgbState[2] = 0; //red int r1 = (command[0]-48)*100; int r2 = (command[1]-48)*10; int r3 = command[2]-48; rgbState[0] = r1+r2+r3; rgbInit[0] = rgbState[0]; //green int g1 = (command[3]-48)*100; int g2 = (command[4]-48)*10; int g3 = command[5]-48; rgbState[1] = g1+g2+g3; rgbInit[1] = rgbState[1]; //blue int b1 = (command[6]-48)*100; int b2 = (command[7]-48)*10; int b3 = command[8]-48; rgbState[2] = b1+b2+b3; rgbInit[2] = rgbState[2]; printBack(); } } if(command[9] == 'r'){ OCR0A=255; //R OCR0B=255; //G OCR2B=255; //B } if(command[9] == 'd'){ OCR0A=255-rgbState[0]; //R OCR0B=255-rgbState[1]; //G OCR2B=255-rgbState[2]; //B } if(command[9] == 'f'){ if(millis() - previousMillis > 19) { previousMillis = millis(); counter -= 1; if(counter <0){ counter=255; state += 1; if(state > 7){state = 0;} } } switch(state){ case 0: //RGB off -> RGB on OCR0A=counter; //R OCR0B=counter; //G OCR2B=counter; //B break; case 1: //GB on -> R off OCR0A=255-counter; //R OCR0B=0; //G OCR2B=0; //B break; case 2: //RB on -> G off OCR0A=counter; //R OCR0B=255-counter; //G OCR2B=0; //B break; case 3: //RG on -> B off OCR0A=0; //R OCR0B=counter; //G OCR2B=255-counter; //B break; case 4: //R on -> GB off OCR0A=0; //R OCR0B=255-counter; //G OCR2B=255; //B break; case 5: //G on -> RB off OCR0A=255-counter; //R OCR0B=counter; //G OCR2B=255; //B break; case 6: //B on -> RG off OCR0A=255; //R OCR0B=255-counter; //G OCR2B=counter; //B break; case 7: //B on -> RGB off OCR0A=255; //R OCR0B=255; //G OCR2B=255-counter; //B break; }//end switch }//end if FLOAT }//end loop
I use 38400baud set to the BT module, and Arduino serial window settings: [x] autoscroll - no line end - 38400baud That is all. Hope to be in use for some beginner as me. And why I use inverted mode in PWM? That is because when you write in normal PWM mode 0, somehow still there is kind of led activity. In that way is fully off. | Използвам 38400baud за BT модула , както и Arduino настройка за прозореца: [x] autoscroll - no line end - 38400baud Te това е. Надявам се, да бъде от полза на хора начинаещи като мен. А защо таймерите са в инвертен режим? Това е така, тъй като при нормална работа ако се остави ШИМ на 0, все още има микро активно в диода и той мъждука. В този режим е напълно угасен. |
setup Android BT terminal APP function | настройка на Андроид приложението |
And links to app what I use | И връзки към приложенията които ползвах |