วันพฤหัสบดีที่ 28 สิงหาคม พ.ศ. 2557

RGB LED / PWM-based Dimming


คุณสมบัติของโค้ดสำหรับ Arduino และวงจร


  • วงจรทำงานโดยใช้ระดับแรงดันสำหรับ I/O ที่ 5V เท่านั้น
  • มีปุ่มกด 3 ปุ่ม (ให้ชื่อว่า R, G, B) ทำงานแบบ Pull-up (active-low) ให้ต่อวงจรปุ่มกดเอง เพื่อใช้งานกับบอร์ด Arduino
  • มีเอาต์พุต 3 ขา ต่อกับวงจร RGB LED (จะใช้แบบ Common-Anode หรือ Common-Cathode ก็ได้) พร้อมตัวต้านทานจำกัดกระแส 3 ตัว
  • เขียนโค้ดด้วยภาษา C++ สำหรับ Arduino เพื่อสร้าง Class ที่มีชื่อว่า "RGB_LED"
  • กำหนดให้ constructor สำหรับคลาส RGB_LED เป็นดังนี้                                                
    -  RGB_LED( int red_pin, int_green_pin, int blue_pin );                                  
    -  โดยรับค่ามาเป็นหมายเลขของ I/O pins สำหรับ 3 ขาของ Arduino ที่จะถูกใช้งานเป็นเอาต์พุตแบบ PWM
  • มีเมธอดอย่างเช่น                                                                                                      -  void setRed( int duty_cycle ), void setGreen( int duty_cycle ),                  
    -  void setBlue( int duty_cycle ) เพื่อใช้กำหนดค่า duty cycle ของขาเอาต์พุต PWM และใช้ในการกำหนดความสว่างของแต่ละสี ใช้คำสั่ง analogWrite() ในการกำหนดค่า
  • กำหนดสมาชิก instance members ตามความจำเป็น เช่น ค่า duty cycles สำหรับแต่ละสี
  • ใช้คลาสดังกล่าวในการเขียนโค้ด (สร้าง object จากคลาสดังกล่าวและเรียกใช้เมธอด) เพื่อสาธิตการทำงานร่วมกับฮาร์ดแวร์จริง
  • เมื่อกดปุ่ม R, G หรือ B แล้วปล่อยแต่ละครั้ง จะทำให้ค่า duty cycle ของสีดังกล่าวเพิ่มขึ้นทีละ 8 ถ้าค่า duty cycle เกิน 255 ให้วนกลับมาเริ่มที่ 0 ใหม่ (ค่าเริ่มต้นสำหรับ duty cycles เป็น 0)
  • เมื่อกดปุ่ม R, G หรือ B ค้างไว้อย่างน้อย 100 msec จะเพิ่มค่าขึ้นทีละ 8 (แล้วเริ่มนับเวลาใหม่) ถ้าค่า duty cycle เกิน 255 ให้วนกลับมาเริ่มที่ 0 ใหม่


อุปกรณ์ทดลอง (Apparatus) 



      อุปกรณ์     
         จำนวน         
RGB LED 5mm.
(Anode)
1


ตัวต้านทาน 330 โอห์ม 


(ส้ม ส้ม น้ำตาล ทอง)
6


BREADBOARD 


บอร์ดทดลองอิเล็กทรอนิกส์
1
Arduino Uno R3 
1
ปุ่มกด
3
สาย USB Cable
1
สายไฟต่อวงจร
-



ผังวงจร (Breadboard Layout)


ผังวงจร



รูปภาพจากการต่อวงจรจริง


Arduino Sketch


ข้อ1 : โค้ด Arduino สำหรับ เมื่อกดปุ่ม R, G หรือ B แล้วปล่อยแต่ละครั้ง จะทำให้ค่า duty cycle ของสีดังกล่าวเพิ่มขึ้นทีละ 8 ถ้าค่า duty cycle เกิน 255 ให้วนกลับมาเริ่มที่ 0 ใหม่ (ค่าเริ่มต้นสำหรับ duty cycles เป็น 0)

class RGB_LED{
  public:
    //constructor
    RGB_LED( int red_pin, int green_pin, int blue_pin );
    //variable
    int duty_red,duty_blue,duty_green,_R,_G,_B;
    //methode
    void setRed(int duty_cycle);
    void setGreen(int duty_cycle);
    void setBlue(int duty_cycle);
};

RGB_LED::RGB_LED( int red_pin, int green_pin, int blue_pin ){                                      
  duty_red = 255;
  duty_blue = 255;
  duty_green = 255;
  _R = red_pin;
  _G = green_pin;
  _B = blue_pin;
  pinMode(_R,OUTPUT); // use as output
  pinMode(_G,OUTPUT); // use as output
  pinMode(_B,OUTPUT); // use as output
}

void RGB_LED :: setRed(int duty_cycle){
  duty_red = duty_cycle;
  duty_red -= 8;
  if(duty_red<0){
    duty_red = 255;
  }
  analogWrite(_R,duty_red);
  analogWrite(_G,duty_green);
  analogWrite(_B,duty_blue);
}

void RGB_LED :: setGreen(int duty_cycle){
  duty_green = duty_cycle;
  duty_green -= 8;
  if(duty_green<0){
    duty_green = 255;
  }
  analogWrite(_R,duty_red);
  analogWrite(_G,duty_green);
  analogWrite(_B,duty_blue);
}

void RGB_LED :: setBlue(int duty_cycle){
  duty_blue = duty_cycle;
  duty_blue -= 8;
  if(duty_blue <0){
    duty_blue = 255;
  }
  analogWrite(_R,duty_red);
  analogWrite(_G,duty_green);
  analogWrite(_B,duty_blue);
}

     เป็นสร้างคลาส RGB_LED โดยมี constructor ที่มีพารามีเตอร์ 3 ตัว ซึ่งคือ output ของวงจรนี้ ไปต่อกับ RGB LED และมี method ซึ่งจะทำการเพิ่มค่าสีของแต่ละขาที่ออกจากวงจร โดยเมื่อขาของoutput ที่ไปต่อกับ RGB LED สว่างมากที่สุดแล้ว จะทำการรีเซตค่าให้เป็นค่าตั้งต้นในขานั้นๆ 


RGB_LED led = RGB_LED(9,10,11);  //call class RGB_LED                                               
const int R = 2; // input of button red
const int G = 4; // input of button green
const int B = 7; // input of button blue
int a=0;
int b=0;
int c=0;
int red_State = 1; 
int green_State = 1; 
int blue_State = 1;

void setup(){
  pinMode(R,INPUT);
  pinMode(G,INPUT);
  pinMode(B,INPUT);
}

void loop(){
  red_State = digitalRead(R);
  green_State = digitalRead(G);
  blue_State = digitalRead(B);
  // button_red
  if(red_State == LOW){ //active-low
    a = 1;
  }
  if(green_State == LOW){ //active-low
    b = 1;
  }
  if(blue_State == LOW){ //active-low
    c = 1;
  }
  
  if(a == 1 && red_State == HIGH){
    a = 0;
    led.setRed(led.duty_red);
  }else if(b == 1 && green_State == HIGH){
    b = 0;
    led.setGreen(led.duty_green);
  }else if(c == 1 && blue_State == HIGH){
    c = 0;
    led.setBlue(led.duty_blue);
  }
}


     โดยประกาศ object ของคลาส RGB_LED และกำหนดค่าคงที่ซึ่งใช้เป็น input ในการรับเข้ามา และกำหนดค่าต่างๆที่ใช้ในcode ด้วย สำหรับ void setup() เป็นการกำหนดให้เป็น input ของวงจร ส่วน void loop() เป็นการกำหนดให้มีการกดปุ่มแล้วปล่อยถึงจะทำการเพิ่มสีของขานั้นๆ

ผลการทดลองข้อ1






ข้อ2 : โค้ด Arduino สำหรับ เมื่อกดปุ่ม R, G หรือ B ค้างไว้อย่างน้อย 100 msec จะเพิ่มค่าขึ้นทีละ 8 (แล้วเริ่มนับเวลาใหม่) ถ้าค่า duty cycle เกิน 255 ให้วนกลับมาเริ่มที่ 0 ใหม่
RGB_LED led = RGB_LED(9,10,11);                                                                               
const int R = 2; // input of button red
const int G = 4; // input of button green
const int B = 7; // input of button blue
int a=0;
int b=0;
int c=0;
int red_State = 1;
int green_State = 1;
int blue_State = 1;
unsigned long time00,time01,time10,time11,time20,time21;

void setup(){
  pinMode(R,INPUT);
  pinMode(G,INPUT);
  pinMode(B,INPUT);
  Serial.begin(9600);
}

void loop(){
  red_State = digitalRead(R);
  green_State = digitalRead(G);
  blue_State = digitalRead(B);
  // button_red
  if(red_State == LOW){ //active-low
    time01=millis();
    if(a == 0){
      time00 = time01;
      a = 1;
    }
    if(time01-time00 >= 100  ){
      led.setRed(led.duty_red);
      Serial.println(time01);
      time00 = 0;
    }
  }
  if(green_State == LOW){ //active-low
    time11=millis();
    if(b == 0){
      time10 = time11;
      b = 1;
    }
    if(time11-time10 >= 100  ){
      led.setGreen(led.duty_green);
      Serial.println(time11);
      time10 = 0;
    }
  }
  if(blue_State == LOW){ //active-low
    time21=millis();
    if(c == 0){
      time20 = time21;
      c = 1;
    }
    if(time21-time20 >= 100  ){
      led.setBlue(led.duty_blue);
      Serial.println(time21);
      time20 = 0;
    }
  }
}

     มีการเปลี่ยนแปลง code จากข้อ 1 แค่ในส่วนที่ไม่ใช่ class เท่านั้น ดังนี้ ใช้ millis() ในการแสดงค่าของเวลาในช่วงที่กดปุ่ม แล้วเช็คไปเรื่อยๆว่าปุ่มนั้นๆมีการกดเกิน 100 ms หรือยัง ถ้าเกินแล้ว ก็จะให้แสดงไฟในขานั้นๆสว่างมากขึ้น 



ผลการทดลองข้อ2





ทฤษฎี (Theory)

Pulse Width Modulation (PWM) เป็นเทคนิคในการควบคุมกำลังไฟฟ้า เป็นสัญญาณดิจิตอลแบบมีคาบ ในที่นี้ใช้ควบคุมความสว่างของหลอดไฟ แผนภาพด้านล่างแสดงให้เห็นสัญญาณ PWM ใน arduino
รูปจาก : https://learn.adafruit.com/adafruit-arduino-lesson-3-rgb-leds/theory-pwm

ทุกๆ 1/500 วินาที สัญญาณเอาต์พุท PWM จะสร้างสัญญาณพัลส์ ซึ่งความกว้างของสัญญาณพัลส์นี้จะถูกควบคุมโดยฟังก์ชัน "analogWrite" ดังนั้น "analogWrite(0)" จะไม่สร้างสัญญาณพัลส์ มีค่าลอจิกเป็น LOW และ "analogWrite(255)" จะสร้างสัญญาณพัลส์ที่มีค่าลอจิกเป็น HIGH ตลอดสัญญาณ


ต้องกำหนดค่าใน analogWrite เป็นค่าตั้งแต่ 0 ถึง 255 จึงจะสร้างสัญญาณพัลส์ได้ 


ความถี่ 1 Hz หทายถึง สัญญาณ Pulse 1 ลูก ในเวลา 1 วินาที ฉะนั้น ความถี่ 100 Hz ก็คือ สัญญาณ Pulse 100 ลูก ในเวลา 1 วินาที

ไม่มีความคิดเห็น:

แสดงความคิดเห็น