Bài 6: Bật tắt đèn tự động bằng cảm biến ánh sáng sử dụng Arduino
Mục tiêu
Qua chuỗi 5 bài trước, các bạn đã cùng mình đi qua từng bước tiếp cận những kiến thức Điện tử và kỹ thuật Lập trình Arduino cơ bản nhất rồi.
- Từ bài này, chúng ta hãy thử vận dụng những gì đã học được để làm những dự án nhỏ thật tế nhé.
- Mục tiêu bài này là làm một "Bộ bật tắt đèn tự động" đơn giản, có thể lắp đặt ở nhiều nơi, như: cầu thang, tủ quần áo, phòng ngủ, bàn làm việc, ...
- Các bạn đã sẵn sàng chưa, cùng đi nào!
Kiến thức cơ bản
Cảm biến Quang trở?
- Quang trở (Photoresistor) là một loại linh kiện có chức năng khá giống Biến trở. Nó có thể thay đổi giá trị Trở kháng (Ω) theo Cường độ ánh sáng chiếu vào nó.
- Nó có thiết kế "Hình đĩa" và ra hai đầu dẫn, được cấu tạo chủ yếu từ thành phần chính là "Cadmium Sulfide" (một chất bán dẫn). Nên khi có ánh sáng chiếu vào bề mặt đĩa, chất này tiếp xúc với ánh sáng làm cho nhiều hạt Electron bị kích thích chuyển sang trạng thái tự do và có thể tham gia vào quá trình dẫn điện. → Kết quả là Trở kháng giữa hai đầu dẫn cảm biến sẽ giảm đi.
- Về nguyên tắc, bất kỳ Điện trở nào trong mạch đều có thể được thay thế bằng Quang trở. Vậy nên để biến đổi cường độ ánh sáng thành Điện áp cho Vi điều khiển đọc được dưới dạng tín hiệu Analog. Một Quang trở có thể mắc nối tiếp với một Điện trở thông thường, tạo thành một Bộ phân áp.
- Có 2 cách để thực hiện việc này theo hình dưới đây. Sơ đồ bên trái, khi chiếu ánh sáng vào sẽ làm điện áp đầu ra tăng. Còn sơ đồ bên phải, khi chiếu ánh sáng vào sẽ làm điện áp đầu ra giảm.
- Để dễ hiểu, các bạn hãy xem Quang trở như Nút nhấn. Khi có ánh sáng chiếu vào sẽ làm nó giảm Trở kháng và dễ dẫn điện hơn, khi ấy ta có thể xem như đang NHẤN NÚT. Cho nên ngược lại, khi không có ánh sáng chiếu vào, ta có thể xem như đang NHẢ NÚT.
Serial Plotter?
- Serial Plotter là một trong những công cụ trong Arduino IDE. Nó có thể nhận dữ liệu từ bo Arduino và hiển thị lên màn hình máy tính dưới dạng Sóng (Wave) thay vì văn bản thuần như Serial Monitor.
- Nó có thể trực quan hóa không chỉ một dữ liệu đơn lẻ mà còn nhiều dữ liệu trong cùng một đồ thị. Trong đó, Trục tung (X) thể hiện "biên độ" dữ liệu, còn Trục hoành (Y) cập nhập dữ liệu liên tục theo "thời gian".
- Và để Serial Plotter biểu diễn đồ thị đúng ý mình, ta sẽ cần tuân theo một số quy tắc trong việc gửi dữ liệu từ bo Arduino lên máy tính, để phần mềm có thể diễn giải đúng được. Bài hướng dẫn chi tiết, mình có để link ở mục Tìm hiểu thêm!
Phần mềm
Arduino
Trước khi bắt đầu:
|
Phần cứng
Danh sách thiết bị
Tên sản phẩm | Số lượng |
---|---|
Mạch Vietduino Uno (Arduino Uno Compatible) | 1 |
Mạch Arduino MakerEDU Shield | 1 |
Cảm biến ánh sáng quang trở MKL-S02 LDR light sensor | 1 |
Mạch led đơn MKL-M01 10mm single LED module [Trắng (White)] | 1 |
Cáp Micro USB | 1 |
Cáp Kết Nối MakerEDU XH2.54 3Wires 20cm Cable [XH2.54 - XH2.54] | 2 |
Hướng dẫn kết nối
- Gắn Shield "Arduino MakerEDU" lên bo Vietduino.
- Kết nối Module Quang trở với Shield bằng dây "XH2.54 3Wires" vào Port A1.
- Kết nối Module LED với Shield bằng dây "XH2.54 3Wires" vào Port D9.
- Kết nối bo Vietduino với máy tính thông qua cáp MicroUSB.
Code
- Mở Arduino IDE.
- Vào
File -> New
(hoặc Ctrl+N) tạo 1 file Arduino mới và đặt tên là ...\Smart_Light.ino
- Vào
Tool
để cấu hình Board:... và Port:... đúng tương ứng với bo Arduino bạn đang dùng. - Copy đoạn Code sau và nhấp vào Verify (Ctrl+R) để IDE kiểm tra lỗi cú pháp.
- Sau khi IDE kiểm tra không có lỗi trong Code, lúc này bạn có thể nhấp Upload (Ctrl+U) để nạp Code vào bo Arduino.
Code Example
Giải thích Code
#define /*** TIỀN XỬ LÝ ***/
Chức năng:
- Đây cũng là 1 lệnh chỉ thị dành cho Tiền xử lý.
Nó cho phép lập trình viên đặt tên (MACRO) cho một Giá trị không đổi (Constant) trước khi chương trình được biên dịch. Và khi bắt đầu quá trình biên dịch, trước tiên Tiền xử lý sẽ thực hiện "ánh xạ" (làm thay đổi văn bản Code) trên các MACRO này bằng các giá trị được xác định trước.
MACRO?
|
Cú pháp:
- #define Constant_Name Value
Tham số:
- Constant_Name - tên của MACRO được xác định.
- Value - giá trị để "gán" cho MACRO đó.
const /*** ĐỊNH TÍNH ***/
Chức năng:
- Là một Định tính (Qualifier) cho biến, làm sửa đổi hành vi của biến.
Nó làm cho một biến trở thành loại "chỉ đọc", như Hằng số (Constant).
Điều này có nghĩa là biến có thể được sử dụng giống như bất kỳ biến nào khác cùng loại, nhưng giá trị của nó không thể thay đổi. Trình biên dịch sẽ báo lỗi nếu phát hiện bạn cố gắng thay đổi giá trị của biến trong chương trình.
Cú pháp:
- const type var = val;
Tham số:
- type - các "kiểu dữ liệu".
- var - tên biến.
- val - giá trị bạn "gán cố định luôn" cho biến đó.
#define và const:
|
byte /*** KIỂU DỮ LIỆU ***/
Chức năng:
- Tạo một biến có kiểu dữ liệu là SỐ NGUYÊN KHÔNG DẤU để lưu trữ.
KHÔNG DẤU (Unsigned) nghĩa là biến này chỉ có thể lưu trữ Số Nguyên Dương.
Với 1 Byte = 8 bit, nó có thể lưu trữ một Số Nguyên trong phạm vi từ 0 đến 255 (28-1).
Cú pháp:
- byte var = val;
- byte var;
Tham số:
- var - tên biến.
- val - giá trị bạn "gán" cho biến đó.
if(condition) { // statement(s) } else { // statement(s) }
Chức năng:
- Câu lệnh
if
kiểm tra một Điều kiện (Condition) và thực hiện một câu lệnh hoặc tập hợp các câu lệnh của nó, nếu điều kiện làtrue
.
Ngược lại, điều kiện làfalse
thì sẽ thực hiện một câu lệnh hoặc tập hợp các câu lệnh của phần mở rộngelse
.
Tham số:
- condition - một biểu thức Boolean (có thể là
true
hoặcfalse
).
Serial.print(); /*** HÀM ***/
Chức năng:
- In dữ liệu vào cổng Serial Port dưới dạng văn bản ASCII mà con người có thể đọc được.
Lệnh này có thể nhận nhiều định dạng kiểu dữ liệu (như: kí tự, chuỗi, số nguyên, số thực, ...) tương tự giống với lệnhSerial.println()
.
Cú pháp:
- Serial.print(val);
Tham số:
- val - giá trị để in (cho phép bất kì kiểu dữ liệu nào).
Kiểu dữ liệu trả về:
- Trả về số Byte được in ra (kiểu dữ liệu
size_t
).
Chức năng này là tùy chọn, bạn có thể đọc hoặc không đọc cũng được.
> /*** TOÁN TỬ ***/ >= /*** TOÁN TỬ ***/ <= /*** TOÁN TỬ ***/ < /*** TOÁN TỬ ***/
Chức năng:
- Là các Toán tử So sánh có 2 Toán hạng.
Nó giúp "so sánh" Biến ở bên trái với Biến hoặc Hằng số ở bên phải của toán tử.
Cú pháp:
- x > y; // kết quả là
true
nếu x lớn hơn y vàfalse
nếu x nhỏ hơn bằng y - x >= y; // kết quả là
true
nếu x lớn hơn bằng y vàfalse
nếu x nhỏ hơn y - x <= y; // kết quả là
true
nếu x nhỏ hơn bằng y vàfalse
nếu x lớn hơn y - x < y; // kết quả là
true
nếu x nhỏ hơn y vàfalse
nếu x lớn hơn bằng y
Tham số: → cả 2 toán hạng đều có thể là bất kì kiểu dữ liệu nào.
- x - là Biến (toán hạng bên phải).
- y - là Biến hoặc Hằng số (toán hạng bên trái).
?: /*** TOÁN TỬ ***/
Chức năng:
- Là một Toán tử Điều kiện có tận 3 Toán hạng.
Nó có chức năng tương tự như câu lệnhif-else
nhưng lại chiếm ít không gian hơn và giúp viết câu lệnhif-else
theo cách ngắn nhất có thể.
Cú pháp:
- var = exp1 ? exp2 : exp3; // tương tự cấu trúc if (exp1) {var = exp2} else {var = exp3}
- exp1 ? exp2 : exp3; // tương tự cấu trúc if (exp1) {exp2} else {exp3}
Tham số:
- var - tên biến.
- exp1 - là biểu thức được đánh giá.
- exp2 - là biểu thức trả về hoặc câu lệnh được thực hiện nếu exp1 đánh giá là
true
. - exp3 - là biểu thức trả về hoặc câu lệnh được thực hiện nếu exp1 đánh giá là
false
.
Lưu đồ (Flow Chart)
Chương trình này hoạt động như thế nào?
Trước khi thật sự bắt đầu hoạt động.
- Ta sẽ cần đọc giá trị Analog từ cảm biến Quang trở lần đầu tiên để lấy mẫu.
- Từ giá trị Analog đọc được, ta chuyển đổi sang thang đo mới, với đơn vị (%).
- Và lần nữa chuyển đổi tiếp sang thang đo khác, chỉ còn 2 giá trị là
HIGH
vàLOW
. Nhờ giá trị (%) nên ta dễ dàng xác định trạng thái của Quang trở qua điểm SetPoint. - Sau khi đã xác định được trạng thái của Quang trở rồi, ta có thể quyết định bật LED hay tắt LED tùy theo nhu cầu sử dụng.
Kể từ lần lấy mẫu đầu tiên, chương trình mới thực sự bắt đầu hoạt động.
- Từ những lần sau quá trình cứ lặp lại như trên. Nhưng sẽ có thêm một quy tắc để tránh trường hợp mỗi khi giá trị đọc từ cảm biến dao động nhỏ quanh điểm SetPoint, làm đèn LED bật tắt liên tục.
- Để khắc phục ta sử dụng thêm giá trị Delta kết hợp với luật: "Là chỉ chấp nhận trạng thái mới của Quang trở (tức thay đổi trạng thái LED) chỉ khi giá trị (%) vượt quá khoảng Delta của ngưỡng trên hoặc dưới tính từ điểm SetPoint".
Kết quả Demo
Nếu mình đã cấp đủ nguồn rồi, thì ...
Các bạn có thể xem chương trình sẽ hoạt động như thế nào theo video dưới đây nhé.
!!! nhúng 1 clip youtube, để xem video trực tiếp trên trang này. Dùng extension <iframe> cho MediaWiki.
Gợi ý mở rộng
- _ Ta có thể thay đèn LED bằng Relay → để bật tắt các bóng đèn điện hay các thiết bị điện trong nhà.
- _ Kết hợp thêm Module RealTime → để tự động tinh chỉnh thông số sao cho hoạt động phù hợp với từng khung giờ sinh hoạt trong ngày.
- _ Kết hợp các thiết bị như Dimmer -> để theo dõi độ sáng của đèn bàn học hay góc làm việc từ đó điều chỉnh độ sáng đèn tự động ở một mức độ ổn định → giúp mắt mình đỡ mỏi, dễ chịu hơn.
- _ Làm ứng dụng theo dõi cường độ ánh sáng trong phòng → từ đó điều chỉnh rèm cửa tự động hay cửa miệng giếng trời → giúp luôn duy trì một lượng ánh sáng ổn định cho cả căn nhà.
- _ Làm hệ thống ánh sáng sân vườn tự động → bật đèn dần khi trời tối và tắt đèn dần khi trời sáng.
- _ Làm hệ thống theo dõi hướng mặt trời, để điều chỉnh hướng nhận được ánh sáng nhiều nhất có thể → cho các tấm pin năng lượng mặt trời, từ đó giúp tối ưu hiệu suất tạo năng lượng. Hay điều chỉnh hướng thấu kính tự động → để làm bộ đun nước nóng bằng mặt trời.
- _ ...
Tìm hiểu thêm
Về Quang trở và các Cảm biến tương tự khác: | Photoresistor VS Photodiode VS Phototransistor.
Về cách sử dụng đồ thị Serial Plotter: | Arduino - Serial Plotter.
Ngôn ngữ lập trình Arduino: | Language - Arduino Reference.