[PA-03b] Control RGB Led with slider Qt

I used the code of Mr.Vannevar Morgan and modified Arduino code in order to display RGB value on LCD I2C. Please check this link to see his youtube tutorial and github code
youtube: https://www.youtube.com/watch?v=5uuFlSzzYsc

github: https://github.com/vannevar-morgan/Qt-RGB-LED

The idea is similiar with the [PA-03a], you send command to Arduino and Arduino does correspondingly. Since we have 3 values of R-G-B so to discriminate them, we have to add prefix ‘r’ for Red, ‘g’ for Green and ‘b’ for Blue before brightness value. Here is my Arduino code:


/*
 * Date: Tue, 09/05/2017
 * Desc: Receive command from python to adjust RGB color
 * Convert message into integer, PWM on pin 9, 10, 11
 * Give feedback message syntax (R,G,B) displayed on LCD
 */
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR 0x3F 
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

#define red_led 9
#define green_led 10
#define blue_led 11
int rgb_val[3];

void setup()
{
 delay(1000);
 // Initialize pinMode
 pinMode(red_led, OUTPUT);
 pinMode(green_led, OUTPUT);
 pinMode(blue_led, OUTPUT);
 setPwmFrequency(red_led, 8); //Set pin 9's PWM frequency to 3906 Hz (31250/8 = 3906)
 setPwmFrequency(green_led, 8);
 setPwmFrequency(blue_led, 8);
 rgb_val[0] = 0; // This is the only way
 rgb_val[1] = 100;
 rgb_val[2] = 0;
 analogWrite(red_led, rgb_val[0]);
 analogWrite(green_led, rgb_val[1]);
 analogWrite(blue_led, rgb_val[2]);

// Initial LCD
 lcd.begin(16,2);
 lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
 lcd.setBacklight(HIGH);
 lcd_display_command(rgb_val);
 lcd.setCursor(0,0);
 lcd.print("Initial R-G-B ");
 
 // Initialize serial
 Serial.begin(9600);
}

void loop()
{
 if (Serial.available()){
 char led_specifier = Serial.read();
 int led_brightness = Serial.parseInt();
 write_leds(led_specifier, led_brightness);
 }
}

void write_leds(char led, int brightness)
{
 if (led == 'r'){
 analogWrite(red_led, brightness);
 rgb_val[0] = brightness;
 lcd_display_command(rgb_val);
 return;
 }
 if (led == 'g'){
 analogWrite(green_led, brightness);
 rgb_val[1] = brightness;
 lcd_display_command(rgb_val);
 return;
 }
 if (led == 'b'){
 analogWrite(blue_led, brightness);
 rgb_val[2] = brightness;
 lcd_display_command(rgb_val);
 return;
 } 
 return;
}

// change the frequency of PWM
void setPwmFrequency(int pin, int divisor) {
 byte mode;
 if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
 switch(divisor) {
 case 1: mode = 0x01; break;
 case 8: mode = 0x02; break;
 case 64: mode = 0x03; break;
 case 256: mode = 0x04; break;
 case 1024: mode = 0x05; break;
 default: return;
 }
 if(pin == 5 || pin == 6) {
 TCCR0B = TCCR0B & 0b11111000 | mode;
 } else {
 TCCR1B = TCCR1B & 0b11111000 | mode;
 }
 } else if(pin == 3 || pin == 11) {
 switch(divisor) {
 case 1: mode = 0x01; break;
 case 8: mode = 0x02; break;
 case 32: mode = 0x03; break;
 case 64: mode = 0x04; break;
 case 128: mode = 0x05; break;
 case 256: mode = 0x06; break;
 case 1024: mode = 0x07; break;
 default: return;
 }
 TCCR2B = TCCR2B & 0b11111000 | mode;
 }
}
// display on LCD 16x2
void lcd_display_command(int rgb_value[3]){
 lcd.clear();
 lcd.print("Color code R-G-B");
 lcd.setCursor(0,1);
 String content = String(rgb_value[0]) + "-" + String(rgb_value[1]) + "-" + String(rgb_value[2]);
 lcd.print(content);
}

There are some need-improve things. First, at the initializing state, if you are not happy with my R-G-B value = [0, 100, 0] and you want to change this, you have to change the initial value of the slider. So you need code to update the initial state at the beginning of Qt.

Second, the LCD seems to fade when you are dragging the slider (if you click, LCD displays quickly) so I think there is some uncertainty when you deal with the function slider_value_change. I will follow up this tutorial (maybe feedback message with time logging, yeah that is good, yay me)

Third, only one channel value (Red, Green or Blue) is sent at a time. It is not practical in the real life because you have to send a data block of 3 values. For example you have a color pallet and you pick a point on the pallet, the RGB value will change all of 3 value. I am thinking about sending a number (with binary from for enhancing transfer speed)


(256^2)*R + (256^1)*G + (256^0)*B


and a prefix (like modbus: one byte address, one byte value). So this tutorial will be suspended for further improvement.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s