Arduino - Sử dụng chức năng PWM
Analog và Digital
Trước khi tìm hiểu về PWM, chúng ta nên bắt đầu với 1 khái niệm đơn giản
hơn nhưng vô cùng quan trọng trong điện tử, đó là Digital signal
và
Analog signal
.
Từ đầu cuốn sách đến giờ, chúng ta chỉ sử dụng các mức điện áp VCC hoặc
HIGH (mức 1) và 0V hoặc GND (mức 0). Trên thực tế, thế giới ta đang sống
hầu như là các tín hiệu Analog. Ví dụ như màu sắc, nhiệt độ, độ ẩm hay
cường độ ánh sáng của môi trường,…
Hiểu 1 cách đơn giản, Analog là những tín hiệu liên tục. Ví dụ trong dải
điện áp từ 0-5VDC, tại 1 thời điểm, giá trị điện áp có thể là 1 số bất
kì giữa 0 và 5 và thường được biểu diễn dưới giống như dạng sóng. Nó
hiện hữu trong đời sống như âm thanh ta nghe được, hình ảnh ta thấy… Với
Digital thì ngược lại, nó là những tín hiệu rời rạc. Ví dụ trong dải
điện áp từ 0-5VDC, tại 1 thời điểm, giá trị điện áp chỉ có thể là 0V
hoặc 5V, nó giống như 1 cái công tắc, 1 bức ảnh đen-trắng…
Trong máy tính, vi điều khiển hoặc các thiết bị điện tử, tín hiệu số
thường được sử dụng bởi nó có thể dễ dàng lưu trữ cũng như xử lí dữ
liệu. Để có thể xử lí, chuyển đổi dữ liệu tương tự sang dữ liệu số,
người ta thường chia nhỏ các phần của tín hiệu tương tự (quá trình này
gọi là lấy mẫu), sau đó các phần chia nhỏ này được gán cho các giá trị 0
hoặc 1.
Các vi điều khiển thường có bộ chuyển đổi dữ liệu tương tự sang dữ liệu
số gọi là ADC (Analog to Digital Converter) và 1 số vi điều khiển có
luôn 1 bộ chuyển đổi dữ liệu số sang tương tự (DAC).
PWM
PWM là chữ viết tắt của Pulse Width Modulation, dịch theo nghĩa
tiếng Việt có nghĩa là điều chế độ rộng xung. Đây là 1 công nghệ giúp
các tín hiệu số cho ra kết quả gần giống như tín hiệu tương tự. Tín hiệu
điều khiển số tạo ra bởi các xung (pulse), đó là sự lặp lại của việc
thay đổi điện áp giữa mức 0 và mức 1. Yếu tố đặc trưng của PWM là chu kì
và độ rộng xung.
Ví dụ, với 1 bóng LED, trong 1 chu kì sáng, nếu thời gian ở mức HIGH dài
hơn thời gian mức LOW thì đèn LED sẽ sáng mạnh, thời gian mức HIGH thấp
hơn thời gian mức LOW thì đèn sẽ sáng thấp hơn. Lợi dụng tính tăng này
ta có thể thay đổi thời gian mức HIGH và mức LOW để điều chỉnh cường độ
sáng của bóng LED. Tỉ số giữa thời gian của mức HIGH và mức LOW được gọi
là Duty cycle
.
Fade LED
Fade LED là 1 ví dụ cơ bản giúp chúng ta có thể sử dụng PWM trong
Arduino.
Yêu cầu
Tự động thay đổi cường độ sáng của bóng đèn LED.
Linh kiện cần dùng
Board Arduino Uno
Đèn LED
Điện trở 330Ω
Dây kết nối
Source code
int ledPin = 13; // Chân kết nối với LED
int brightness = 0; // Biến thiết lập cường độ sáng cho LED trên board
int fadeAmount = 15; // Biến thiết lập 1 bước thay đổi cường độ sáng.
void setup()
{
pinMode(ledPin, OUTPUT);
}
void loop()
{
analogWrite(ledPin, brightness);
brightness = brightness + fadeAmount;
if (brightness <= 0 || brightness >= 255) {
fadeAmount = -fadeAmount;
}
delay(30);
}
Giải thích source code
Biến
brightness
: Thiết lập cường độ sáng cho led,fadeAmount
là
1 bước thay đổi cường độ sáng. Sử dụng hàmanalogWrite()
nhằm set
giá trị cường độ sáng cho ledPin. LED sẽ sáng dần đến giá trị 255
sau đó sẽ tắt dần khi đến giá trị 0 và lặp đi lặp lại nhờ điều kiện
trong câu lệnh if.Giá trị từ 0 đến 255 tương ứng với Duty cycle từ 0% đến 100%.
Arduino không có bộ chuyển đổi DAC nhưng chúng ta có thể dùng PWM để có
thể cho ra tín hiệu ngõ ra ở dạng gần như Analog
, giá trị maximum =
255 là giá trị lớn nhất của chuyển đổi PWM chứ không liên quan đến bộ
ADC (10 bits) của chip Atmega328.
Điều khiển LED RGB
Giới thiệu
LED RGB là module LED có 3 chân tín hiệu điều khiển tương ứng với 3 màu
đỏ (Red), xanh lá (Green) và xanh dương (Blue). Chúng ta có thể phối hợp
giữa các màu để tạo ra các hiệu ứng màu sắc đẹp mắt.
Yêu cầu
Sử dụng button với 4 chế độ điều khiển:
Nhấn lần 1, LED sáng màu đỏ (Red).
Nhấn lần 2, LED sáng màu xanh lá (Green).
Nhấn lần 3, LED sáng màu xanh dương (Blue).
Nhấn lần 4, LED sáng cả 3 màu.
Nhấn lần 5, quay lại như lúc nhấn lần 1.
Linh kiện cần dùng
Board Arduino Uno
Module LED RGB
Nút nhấn
Điện trở 10KΩ
Dây kết nối
Đấu nối
Trên board Arduino Uno có các chân kí hiệu ~
đều có thể sử dụng chức
năng PWM.
Số thứ tự | Chân trên Module LED RGB | Chân trên board Arduino Uno |
---|---|---|
1 | R | 9 |
2 | G | 10 |
3 | B | 11 |
4 | V/G | 3.3V hoặc GND |
Bảng đấu nối chân của module LED RGB và board Arduino Uno
Source code
Nội dung source code đã được giải thích trong file.
#define pinLedRed 9 // Chân kết nối với pin R của module LED-RGB
#define pinLedGreen 10 // Chân kết nối với pin G của module LED-RGB
#define pinLedBlue 11 // Chân kết nối với pin B của module LED-RGB
#define pinButton 2 // Nút nhấn trên board
boolean lastPinButton = LOW; // Biến lưu trạng thái cuối của nút nhấn
boolean currentPinButton = LOW; // Biến lưu trạng thái hiện tại của nút nhấn
int ledMode = 0; // Các chế độ của nút nhấn.
void setup()
{
// Cài đặt các hướng của các chân
pinMode (pinLedRed, OUTPUT);
pinMode (pinLedGreen, OUTPUT);
pinMode (pinLedBlue, OUTPUT);
pinMode (pinButton, INPUT);
}
// Function chống dội phím khi nhấn (decoucing)
boolean debounce(boolean lastState)
{
boolean currentState; // Biến currentState chỉ có 2 trạng trái LOW hoặc HIGH, khai báo kiểu boolean nhằm tiết kiệm tài nguyên CPU.
currentState = digitalRead(pinButton); // Đọc trạng thái của button
if (lastState != currentState) { // Nếu nhấn Nút, chờ 20 mili giây, sau đó đọc lại trạng thái button 1 lần nữa.
delay(20);
currentState = digitalRead(pinButton);
}
return currentState; // Trả về trạng thái của button hiện tại
}
void setMode(int mode)
{
if (mode == 1) { // Màu đỏ: button nhấn lần 1
digitalWrite(pinLedBlue, HIGH);
digitalWrite(pinLedGreen, LOW);
digitalWrite(pinLedRed, LOW);
} else if (mode == 2) { // Màu xanh lá: button nhấn lần 2
digitalWrite(pinLedBlue, LOW);
digitalWrite(pinLedGreen, HIGH);
digitalWrite(pinLedRed, LOW);
} else if (mode == 3) { // Màu xanh dương: button nhấn lần 3
digitalWrite(pinLedBlue, LOW);
digitalWrite(pinLedGreen, LOW);
digitalWrite(pinLedRed, HIGH);
} else if (mode == 4) { // Sáng cả 3 màu: button nhấn lần 4
int fadeAmount = 0; // Bước thay đổi cường độ sáng
int brightness;
digitalWrite(pinLedBlue, LOW);
digitalWrite(pinLedGreen, LOW);
digitalWrite(pinLedRed, LOW);
for (fadeAmount = 0; fadeAmount < 255; fadeAmount += 10) {
brightness = fadeAmount;
analogWrite(pinLedBlue, brightness);
analogWrite(pinLedGreen, brightness);
analogWrite(pinLedRed, brightness);
delay(30); // delay 30 mili giây để hiển thị kết quả
}
}
}
void loop()
{
currentPinButton = debounce(lastPinButton); // Đọc trạng thái của nút nhấn ở function debounce()
if (lastPinButton == LOW && currentPinButton == HIGH) // Trạng thái nút nhấn đã thay đổi => đã nhấn phím
ledMode++;
lastPinButton = currentPinButton; // Reset lại trạng thái nút nhấn.
if (ledMode == 5) // Đang ở chế độ sáng 3 màu và nhấn button thì chuyển sang chế độ sáng màu đỏ (lặp lại chu kì)
ledMode = 1;
setMode(ledMode); // Đưa biến ledMode vào hàm setMode() để thực thi chế độ sáng tương ứng.
}
Với ledMode == 4
, chương trình sẽ chạy hết vòng lặp for mới kiểm tra
trạng thái của button. Ta có thể sử dụng interrupt để chương trình tối
ưu hơn.
Latest comments (0)