การใช้งานโมดูล RGB LED#
บทความนี้กล่าวถึง การใช้งานโมดูล RGB LED ที่มีขาควบคุม 3 ขา เพื่อใช้ในการเปิด-ปิด หรือ ปรับค่าความสว่างด้วยสัญญาณ PWM
▷ RGB LED#
ไดโอดเปล่งแสงแบบ 3 สี (RGB LED) ประกอบด้วยวงจร LED ที่ให้แสงสีแดง (Red) สีเขียว (Green) และสีน้ำเงิน (Blue) แยกอิสระจากกัน แต่นำมาใส่ไว้ในตัวถังเดียวกัน และให้แสงที่มีสีเกิดจากการผสมของ 3 สี การใช้งาน RGB LED ก็เหมือน LED โดยทั่วไป แต่เนื่องจากว่า มีการนำ LED จำนวน 3 ดวง ที่ให้แสงสีที่แตกต่างกัน มาใส่ไว้ในตัวถังเดียวกัน จึงมีรูปแบบการต่อวงจรแบ่งได้เป็น 2 กรณี
- Common Anode (CA): มีการต่อขาแอโนด (Anode) ของ LED ทั้ง 3 ดวง ร่วมกัน ดังนั้นจะมีขา V=VCC เพื่อป้อนแรงดันไฟเลี้ยง
- Common Cathode (CC): มีการต่อขาแคโทด (Cathode) ของ LED ทั้ง 3 ดวง ร่วมกัน ดังนั้นจะมีขา GND เพื่อนำไปต่อกับ GND ของระบบ
รูป: ตัวอย่างโมดูล RGB แบบหลอด (Round Diffused Tri-Color LED) ที่มีทั้งขนาด 5mm หรือ 10mm และแบบ SMD 5050
รูป: ตัวอย่างโมดูล RGB ที่ได้เลือกมาใช้งาน
รูป: ตัวอย่างโมดูล RBG (active-low) แต่อาจมีการเรียงลำดับขาแตกต่างกันได้
รูป: ผังวงจรสำหรับโมดูล RGB LED (Common-Anode) ที่มีตัวต้านทาน 330 โอห์ม (Source: wiki.sunfounder.cc)
โมดูล RGB LED โดยทั่วไป มีการใส่ตัวต้านทานแบบอนุกรม จำนวน 3 ตัว ไว้เพื่อจำกัดปริมาณกระแส ตัวต้านทานเหล่านี้ อาจมีค่าความต้านทานเท่ากันหรือต่างกันก็ได้ แต่ถ้าแรงดันไบอัสตรง (Forward Voltage: ) ของ LED แต่ละสี มีค่าไม่เท่ากัน (เช่น R: 1.8V~2.4V, G: 2.8V~3.6V, B: 2.8V~3.6V) ดังนั้นถ้าใช้แรงดันไฟเลี้ยงเหมือนกัน ก็ควรจะใช้ตัวต้านทานที่มีค่าไม่เหมือนกัน ทั้งนี้ก็เพื่อให้ได้กระแสที่ผ่าน LED แต่ละดวงมีปริมาณใกล้เคียงกัน ปริมาณกระแสไฟฟ้าที่ไหลจะสัมพันธ์กับความสว่างของ LED
โมดูลของ KeyStudio มีการใช้ตัวต้านทานที่มีค่าแตกต่างกัน
(เช่น 331
, 102
และ 181
) ในขณะที่โมดูลของ Keyes มีตัวต้านทานที่มีค่า 331
เท่ากันทุกตัว
และโมดูล Keyes SMD-RGB CNT1 ที่มี RGB LED (Common Cathode)
ซึ่งมีแพ็กเกจแบบ SMD 5050 ไม่ได้ใส่ตัวต้านทานมาให้
ผู้ใช้งานจะต้องต่อตัวต้านทานเพิ่ม เพื่อจำกัดกระแสไม่ให้เกิน 30mA (โดยประมาณ)
▷ การเขียนโปรแกรมควบคุมโมดูล RGB LED#
การเขียนโปรแกรมควบคุมการทำงานของโมดูล RGB LED แบ่งเป็น 3 รูปแบบคือ
- การกำหนดสถานะติดหรือดับ (ON/OFF) ของ LED แต่ในดวง
- การสร้างสัญญาณ PWM (Pulse Width Modulation) ที่มีความถี่คงที่ แต่ปรับค่าความกว้างของพัลส์ หรือค่า Duty Cycle ของสัญญาณดังกล่าว ซึ่งจะทำให้สามารถปรับความสว่างของแต่ละสีของ RGB LED ได้
- การสร้างสัญญาณแบบแอนะล็อกเพื่อปรับระดับแรงดันไฟฟ้าของสัญญาณเอาต์พุตและนำไปใช้กับขาควบคุมของ RGB LED เช่น การใช้วงจร DAC (Digital-to-Analog Converter) เพื่อสร้างแรงดันไฟฟ้าที่ปรับระดับได้ แต่วิธีการนี้อาจไม่เป็นที่นิยม
นอกจากนั้นแล้ว จะต้องตรวจสอบด้วยว่า RGB LED เป็นแบบ Common-Anode (ทำงานแบบ Active-Low) หรือ Common-Cathode (ทำงานแบบ Active-High)
โค้ดตัวอย่างต่อไปนี้เป็น Arduino Sketch สาธิตการทำให้ RGB LED ติดและดับไปทีละสี โดยมีการเว้นระยะเวลาแล้วให้วนซ้ำไปเรื่อย ๆ และมีการเลือกใช้ขาของ Arduino Pins: {D11, D10, D9} สำหรับนำไปต่อกับขาของโมดูล RGB LED ที่ R, G และ B ตามลำดับ
// Arduino Sketch Demo (for Arduino Uno/Nano)
#define ACTIVE_LOW // Common-Anode RGB LED
#ifdef ACTIVE_LOW
#define LED_ON (LOW)
#else
#define LED_ON (HIGH)
#endif
#define LED_OFF (!LED_ON)
const int RGB_PINS[] = {11,10,9}; // R,G,B pins
const int DELAY_MS = 500; // delay time in msec.
void setup() {
for (int i=0; i < 3; i++) {
pinMode( RGB_PINS[i], OUTPUT );
digitalWrite( RGB_PINS[i], LED_OFF );
}
}
void loop() {
// This is a static local variable
// used to keep the selected pin index.
static int index = 0;
// Turn on the selected LED pin.
digitalWrite( RGB_PINS[index], LED_ON );
// Delay
delay( DELAY_MS );
// Turn off the selected LED.
digitalWrite( RGB_PINS[index], LED_OFF );
// Select the next LED control pin.
index = (index+1) % 3;
}
ตัวอย่างการเขียนโค้ดและจำลองการทำงานเสมือนจริง ด้วย Online Arduino Wokwi Simulator มีดังนี้
รูป: Wokwi Simulator - Arduino Nano + RGB LED (active-low, on/off)
รูป: Wokwi Simulator - Arduino Nano + RGB LED (active-high, on/off)
การตั้งค่าใช้งาน wokwi-rgb-led
(เช่น การกำหนดค่าของ Atribute
ที่มีชื่อว่า "common"
ให้เป็น "anode"
หรือ "cathode"
) สามารถดูได้จาก
https://docs.wokwi.com/parts/wokwi-rgb-led
ตัวอย่างถัดไปสาธิตการสร้างสัญญาณแบบ PWM สำหรับบอร์ด Arduino Uno/Nano
โดยใช้คำสั่ง analogWrite()
ของ Arduino API ซึ่งใช้ค่าเลขจำนวนเต็มในช่วง 0..255
ขาควบคุมของ RGB LED จะถูกเลือกไปทีละขา ดังนั้นสีของ LED ที่ตรงกับขาที่ถูกเลือก
จะเริ่มสว่างขึ้นและดับลง ไปตามลำดับ
#define ACTIVE_LOW
#ifdef ACTIVE_LOW
#define PWM_DC(x) (255-(x))
#else
#define PWM_DC(x) (x)
#endif
const int RGB_PINS[] = {11,10,9}; // R,G,B pins
const int DELAY_MS = 5;
void setup() {
Serial.begin(115200);
for (int i=0; i < 3; i++) {
pinMode( RGB_PINS[i], OUTPUT );
digitalWrite( RGB_PINS[i], PWM_DC(0) );
}
}
void loop() {
static int index = 0;
static String str;
for (int i=0; i < 512; i++) {
int value = (i >= 255) ? (511-i) : i;
value = PWM_DC(value);
// Update the PWM output.
analogWrite( RGB_PINS[index], value );
str = "value:";
str += value;
Serial.println( str.c_str() );
delay(DELAY_MS);
}
// Select the next LED control pin.
index = (index+1) % 3;
}
รูป: Wokwi Simulator - Arduino Nano + RGB LED (active-low, PWM-based)
ตัวอย่างโค้ดต่อไปนี้ สาธิตการกำหนดค่าสี (Color Code) แบบ 24 บิต (R, G, B อย่างละ 8 บิต)
ซึ่งมีการเก็บข้อมูลเป็นตัวเลขจำนวนเต็ม uint32_t
ในอาร์เรย์ COLORS
และมีการเปลี่ยนค่าสีไปตามลำดับ
// #define ACTIVE_LOW
#ifdef ACTIVE_LOW
#define PWM_DC(x) (255-(x))
#else
#define PWM_DC(x) (x)
#endif
const int RGB_PINS[] = {11,10,9}; // R,G,B pins
const int DELAY_MS = 500; // delay time in msec.
const uint32_t COLORS[] = {
0xff0000, 0x00ff00, 0x0000ff, 0xffff00,
0xff00ff, 0x00ffff, 0xffffff, 0x000000
};
const uint8_t NUM_COLORS = sizeof(COLORS)/sizeof(uint32_t);
void setup() {
for (int i=0; i < 3; i++) {
pinMode( RGB_PINS[i], OUTPUT );
analogWrite( RGB_PINS[i], PWM_DC(0) );
}
}
void loop() {
// A static local variable used to keep the current color index.
static int index = 0;
uint32_t color = COLORS[ index ];
for ( int i=2; i >= 0; i-- ) {
analogWrite( RGB_PINS[i], PWM_DC(color & 0xff) );
color >>= 8;
}
delay( DELAY_MS );
index = (index+1) % NUM_COLORS;
}
รูป: Wokwi Simulator - Arduino Nano + RGB LED (active-high, PWM-based)
ตัวอย่างการนำไปต่อวงจรโดยใช้บอร์ด Super-Mini ESP32C3 และเลือกใช้ขา GPIO-4 GPIO-2 และ GPIO-3 สำหรับโมดูล RGB LED (active-low)
ข้อสังเกต: การเรียงขาควบคุมของแต่ละโมดูล อาจแตกต่างกัน เช่น {V,R,G,B} หรือ {V,R,B,G}
รูป: แผนผังแสดงตำแหน่งขาของบอร์ด Super-Mini ESP32-C3
รูป: การทดลองใช้โมดูล RGB LED (OpenSmart, Black PCB) ร่วมกับบอร์ด ESP32-C3
รูป: การทดลองใช้โมดูล RGB LED (Keyes, Red PCB) ร่วมกับบอร์ด ESP32-C3
รูป: การทดลองใช้โมดูล RGB LED (White PCB) ร่วมกับบอร์ด ESP32-C3
โค้ดถัดไปสาธิตการเขียนโค้ด Arduino สำหรับ ESP32C3 ซึ่งสามารถใช้คำสั่งของ FreeRTOS API ได้ และในตัวอย่างนี้ ได้สาธิตการสร้างทาสก์ (Task) สำหรับ 3 สี และใช้งานไบนารีเซมาฟอร์ (Binary Semaphore) เพื่อทำให้ LED ของแต่ละสี มีการติดและดับไปตามลำดับ
#define ACTIVE_LOW
#ifdef ACTIVE_LOW
#define LED_ON (LOW)
#else
#define LED_ON (HIGH)
#endif
#define LED_OFF (!LED_ON)
const int NUM_TASKS = 3;
// Define LED pins
const int LED_PINS[] = {4,3,2};
// Define binary semaphore handles
SemaphoreHandle_t bin_semaphores[ NUM_TASKS ];
// Task entry function
void blinkLED(void *pvParameters) {
int index = (int)pvParameters;
int pin = LED_PINS[index];
pinMode( pin, OUTPUT );
digitalWrite( pin, LED_OFF );
SemaphoreHandle_t bin_sem;
while (1) {
bin_sem = bin_semaphores[index];
xSemaphoreTake( bin_sem, portMAX_DELAY); // Wait for semaphore
digitalWrite( pin, LED_ON ); // Turn on LED
vTaskDelay(1000 / portTICK_PERIOD_MS); // Delay for 1 second
digitalWrite( pin, LED_OFF ); // Turn off LED
bin_sem = bin_semaphores[(index+1)%NUM_TASKS];
xSemaphoreGive( bin_sem ); // Release semaphore for the next task
}
}
void setup() {
Serial.begin(115200); // Need to enable USB CDC on boot.
//while(!Serial);
delay(200);
sys_info();
// Create binary semaphores
for (int i=0; i < NUM_TASKS; i++) {
bin_semaphores[i] = xSemaphoreCreateBinary();
xSemaphoreTake( bin_semaphores[i], 0 /* not blocking*/ );
}
// Give a semaphore to the first task.
xSemaphoreGive( bin_semaphores[0] );
// Create FreeRTOS tasks
for (int i=0; i < NUM_TASKS; i++) {
xTaskCreate( blinkLED, "BlinkLED", 512, (void *)i, 1, NULL );
}
}
void loop() {
// empty for the main task
}
void sys_info() {
Serial.println("=========================================");
Serial.printf( "Arduino ESP32 Core v%u.%u.%u\n",
ESP_ARDUINO_VERSION_MAJOR,
ESP_ARDUINO_VERSION_MINOR,
ESP_ARDUINO_VERSION_PATCH );
Serial.flush();
Serial.printf("Espressif IDF: %s\n", ESP.getSdkVersion() );
Serial.printf("Chip Revision %lu\n", ESP.getChipRevision() );
Serial.printf("Cpu Freq. %lu MHz\n", ESP.getCpuFreqMHz() );
Serial.printf("Heap (total/free): %lu / %lu bytes\n",
ESP.getHeapSize(), ESP.getFreeHeap());
Serial.printf("PSRAM (toal/free): %lu / %lu bytes\n",
ESP.getPsramSize(), ESP.getFreePsram());
Serial.printf("Flash Size: %lu MB, Flash Speed: %lu MHz\n",
ESP.getFlashChipSize()/(1024*1024UL),
ESP.getFlashChipSpeed()/(uint32_t) 1e6 );
Serial.flush();
// more info...
Serial.printf("Espressif chip model: %s\n",
ESP.getChipModel() );
Serial.printf("Number of CPU Cores: %d\n",
ESP.getChipCores() );
String str;
switch(ESP.getFlashChipMode()) {
case FM_QIO: str = "QIO"; break;
case FM_QOUT: str = "QOUT"; break;
case FM_DIO: str = "DIO"; break;
case FM_DOUT: str = "DOUT"; break;
default: str = "Unknown"; break;
}
Serial.printf("Flash model: %s\n", str.c_str() );
Serial.println("=========================================\n");
Serial.flush();
}
รูป: ตัวอย่างข้อความเอาต์พุตจาก Arduino Serial Monitor
▷ กล่าวสรุป#
บทความนี้นำเสนอการใช้งานโมดูล RGB LED และตัวอย่างการเขียนโค้ด Arduino Sketch เพื่อกำหนดสถานะการติดหรือดับของ LED และการสร้างสัญญาณ PWM เพื่อปรับค่าความสว่างของ LED
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
Created: 2023-09-23 | Last Updated: 2023-09-24