หน้าเว็บ

วันศุกร์ที่ 29 สิงหาคม พ.ศ. 2557

[Warm-up] การใช้ภาษา C++ เพื่อควบ RGB LED ผ่านบอร์ด Arduino


        
           สำหรับในตอนนี้นั้น เราจะมาเขียนโค้ดภาษา C++ เพื่อใช้งานบอร์ด Arduino ในการควบคุม RGB LED โดยโปรแกรมและวงจรที่เราจะสร้างขึ้นมานั้นมีคุณสมบัติดังนี้
  • วงจรทำงานโดยใช้ระดับแรงดันสำหรับ I/O ที่ 5V
  • มีปุ่มกด 3 ปุ่มที่ทำงานแบบ Active Low โดยแต่ละปุ่มนั้นจะใช้ควบคุมความสว่างของแต่ละสี
  • มีเอาต์พุตจากบอร์ด Arduino 3 ขา ต่อกับวงจร RGB LED (ในที่นี้จะใช้แบบ common anode) พร้อมตัวต้านทานจำกัดกระแส 3 ตัว
  • เมื่อกดปุ่มแล้วปล่อยแต่ละครั้ง จะทำให้ค่า Duty Cycle ของสีนั้นเพิ่มขึ้น 8 ค่า เช่น เมื่อกดปุ่ม R ทำให้ค่า Duty Cycle ของสีแดงเพิ่มขึ้น 8 ค่า  และถ้าค่า Duty Cycle มีค่ามากกว่า 255 ให้กลับมาเริ่มที่ 0 ใหม่
       ในส่วนแรกนั้นเราจะสร้างไฟล์ชื่อ RGB_LED.h เพื่อเป็นการประกาศคลาสชื่อ RGB_LED  โดยมีสองส่วนคือ private และ public  ในส่วน private นั้นเราจะทำการประกาศตัวแปรต่างๆ ที่จะใช้งานภายในคลาส และในส่วน public นั้นเราจะประกาศ method ต่างๆ ที่ object ของคลาสนี้จะสามารถเรียกใช้งานได้
โค้ดที่ได้เป็นดังนี้

// class declaration
#ifndef RGB_LED_H
#define RGB_LED_H

#include <inttypes .h>

#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

class RGB_LED {
    private:
        int red_pin, green_pin, blue_pin;
        int red_duty, green_duty, blue_duty;
  
    public:
        RGB_LED(int red_pin, int green_pin, int blue_pin);
        void setRed(int duty_cycle);
        void setGreen(int duty_cycle);
        void setBlue(int duty_cycle);
  
        void update_red(int width);
        void update_green(int width);
        void update_blue(int width);
};
#endif;
จากโค้ดด้านบน
        ในส่วน private เราได้ประกาศตัวแปรทั้งหมด 6 ตัวดังนี้

  1. int red_pin คือ ตัวเลขจำนวนเต็ม ของ pin บนบอร์ด arduino ที่ใช้งาน pwm ได้ สำหรับ RGB LED สีแดง
  2. int green_pin คือ ตัวเลขจำนวนเต็ม ของ pin บนบอร์ด arduino ที่ใช้งาน pwm ได้ สำหรับ RGB LED สีเขียว
  3. int blue_pin คือ ตัวเลขจำนวนเต็ม ของ pin บนบอร์ด arduino ที่ใช้งาน pwm ได้ สำหรับ RGB LED สีน้ำเงิน
  4. int red_duty คือ ตัวเลขจำนวนเต็ม สำหรับค่า Duty Cycle ของสีแดง
  5. int green_duty คือ ตัวเลขจำนวนเต็ม สำหรับค่า Duty Cycle ของสีเขียว
  6. int blue_duty คือ ตัวเลขจำนวนเต็ม สำหรับค่า Duty Cycle ของสีน้ำเงิน
        ในส่วน public เราได้ประกาศ method ทั้งหมด 7 method ดังนี้
  1. RGB_LED(int red_pin, int green_pin, int blue_pin)
    คือ constructor method โดยรับอาร์กิวเมนต์ red_pin, green_pin และ blue_pin เป็นข้อมูลแบบ int ซึ่งใช้สำหรับกำหนดหมายเลข pin เอาต์พุตบนบอร์ด arduino ที่สามารถใช้งาน pwm ได้
  2. void setRed(int duty_cycle)
    เป็นฟังก์ชันที่ใช้สำหรับกำหนดค่า duty cycle ให้กับสีแดงของ RGB LED โดยใช้คำสั่ง analogWrite() สำหรับบอร์ด arduino
  3. void setGreen(int duty_cycle)
    เป็นฟังก์ชันที่ใช้สำหรับกำหนดค่า duty cycle ให้กับสีเขียวของ RGB LED โดยใช้คำสั่ง analogWrite() สำหรับบอร์ด arduino
  4. void setBlue(int duty_cycle)
    เป็นฟังก์ชันที่ใช้สำหรับกำหนดค่า duty cycle ให้กับสีน้ำเงินของ RGB LED โดยใช้คำสั่ง analogWrite() สำหรับบอร์ด arduino
  5. void update_red(int width)
    เป็นฟังก์ชันที่ใช้สำหรับเปลี่ยนแปลงค่า duty cycle ของสีแดง เมื่อมีการกดปุ่มแต่ละครั้งค่า duty cycle จะเพิ่มขึ้น 8 ค่า และถ้ามีค่ามากกว่า 255 จะกลับมาเริ่มต้นใหม่ที่ 0
  6. void update_green(int width)
    เป็นฟังก์ชันที่ใช้สำหรับ เปลี่ยนแปลงค่า duty cycle ของสีเขียว เมื่อมีการกดปุ่มแต่ละครั้งค่า duty cycle จะเพิ่มขึ้น 8 ค่า และถ้ามีค่ามากกว่า 255 จะกลับมาเริ่มต้นใหม่ที่ 0
  7. void update_blue(int width)
    เป็นฟังก์ชันที่ใช้สำหรับ เปลี่ยนแปลงค่า duty cycle ของสีเขียว เมื่อมีการกดปุ่มแต่ละครั้งค่า duty cycle จะเพิ่มขึ้น 8 ค่า และถ้ามีค่ามากกว่า 255 จะกลับมาเริ่มต้นใหม่ที่ 0
     
       
       หลังจากที่เราได้ประกาศคลาส, ตัวแปร และ method ต่างๆ แล้ว เราจะสร้างไฟล์ใหม่ที่มีชื่อว่า RGB_LED.cpp เพื่อที่จะเขียนโค้ดกำหนดการทำงานของ method ต่างๆ ตามที่ได้ประกาศไว้ในไฟล์แรก 
โค้ดที่ได้เป็นดังนี้ 
#include "RGB_LED.h"
// class implementation
RGB_LED::RGB_LED(int red_pin, int green_pin, int blue_pin){
    this->red_pin = red_pin;
    this->green_pin = green_pin;
    this->blue_pin = blue_pin;
 
    this->red_duty = 0;
    this->green_duty = 0;
    this->blue_duty = 0;
 
    pinMode(red_pin, OUTPUT);
    pinMode(green_pin, OUTPUT);
    pinMode(blue_pin, OUTPUT);
 
    setRed(0);
    setGreen(0);
    setBlue(0);
}

void RGB_LED::setRed(int duty_cycle){
    analogWrite(red_pin, 255 - duty_cycle);
}

void RGB_LED::setGreen(int duty_cycle){
    analogWrite(green_pin, 255 - duty_cycle);
} 

void RGB_LED::setBlue(int duty_cycle){
    analogWrite(blue_pin, 255 - duty_cycle);
}

void RGB_LED::update_red(int width){
    red_duty += width;
    if (red_duty > 255) {
        red_duty = 0;
    }
    setRed(red_duty);
}

void RGB_LED::update_green(int width){
    green_duty += width;
    if (green_duty > 255) {
        green_duty = 0;
    }
    setGreen(green_duty);
}

void RGB_LED::update_blue(int width){
    blue_duty += width;
    if (blue_duty > 255) {
        blue_duty = 0;
    }
    setBlue(blue_duty);
}
หมายเหตุ: เนื่องจากเราใช้ RGB LED แบบ common anode จึงต้องใช้ค่า 255 - duty_cycle ในคำสั่ง analogWrite()

        
         หลังจากที่เราได้ประกาศและสร้างคลาสพร้อมทั้ง method ต่างๆ แล้ว  ต่อมาจะเป็นการนำคลาสที่เราสร้างมาใช้งานกับบอร์ด arduino โดยเขียนโค้ดภายในไฟล์ .ino ลองสร้าง object จากคลาสแล้วเรียกใช้งาน method ที่เราสร้าง เช่น เมื่อกดปุ่ม R แล้วปล่อยจะเรียกใช้งานฟังก์ชัน update_red(8) เพื่อให้ทำการเพิ่มค่า duty cycle ของสีแดงอีก 8 ค่า
โค้ดที่ได้เป็นดังนี้ 

#include "RGB_LED.h"

RGB_LED led(3, 5, 6);
int button_pin[] = {8, 9, 10};

void setup() {
    for(int i=0;i<3;i++){
        pinMode(button_pin[i], INPUT);
    }
}

void loop() {
    // if push then release red button
    if (digitalRead(button_pin[0]) == LOW) {
        delay(15);
        if (digitalRead(button_pin[0]) == HIGH){
            led.update_red(8);
        }
    }
  
    // if push and release green button
    if (digitalRead(button_pin[1]) == LOW) {
        delay(15);
        if (digitalRead(button_pin[1]) == HIGH){
            led.update_green(8);
        }
    }
  
    // if push and release blue button
    if (digitalRead(button_pin[2]) == LOW) {
        delay(15);
        if (digitalRead(button_pin[2]) == HIGH){
            led.update_blue(8);
        }
    }
}

จากโค้ดด้านบน
  • เราสร้าง object จากคลาส RGB_LED ชื่อว่า led โดยกำหนดเอาต์พุตของสีแดง, สีเขียว และสีน้ำเงิน เป็นหมายเลข pin คือ 3, 5 และ 6 ตามลำดับ
  • กำหนดหมายเลข pin คือ 8, 9 และ 10 เป็นอินพุตจากปุ่มกดสีแดง, สีเขียว และสีน้ำเงินตามลำดับ
  • เราใช้คำสั่ง delay(15); เพื่อช่วยในการ debounce ของปุ่มกด 
 
        หลังจากที่เขียนโค้ดทั้งหมดแล้ว  ต่อมาจะเป็นการนำโค้ดที่ได้มาใช้กับวงจรจริงโดยต่อวงจรตามภาพต่อไปนี้







ภาพแผนผังวงจร


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



         

        จากที่ผ่านมาเราต้องกดปุ่มแล้วปล่อยแต่ละครั้งเพื่อให้ค่า duty cycle ของสีใดสีหนึ่งเพิ่มขึ้นทีละ 8 ค่า  แต่ในตอนนี้เราต้องการให้ค่า duty cycle เพิ่มขึ้นทีละ 8 ค่า เมื่อกดปุ่มค้างไว้ทุกๆ 100 ms  ดังนั้นเราจะทำการแก้ไขโค้ดในไฟล์ .ino ดังต่อไปนี้

#include "RGB_LED.h"

RGB_LED led(3,5,6);
int button_pin[] = {8, 9, 10};

void setup() {
    for(int i=0;i<3;i++){
        pinMode(button_pin[i], INPUT);
    }
}

void loop() {
    // if press red button
    if (digitalRead(button_pin[0]) == LOW) {
        delay(100);
        led.update_red(8);
    }
  
    // if press green button
    if (digitalRead(button_pin[1]) == LOW) {
        delay(100);
        led.update_green(8);
    }
  
    // if press blue button
    if (digitalRead(button_pin[2]) == LOW) {
        delay(100);
        led.update_blue(8);
    }
}


ภาพตัวอย่างการทำงานของวงจร


ภาพตัวอย่างการทำงานของวงจร







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

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