- Giá trị: biến số (variable) và hằng số (constant) (hằng, biến số, kiểu dữ liệu...)
- Cấu trúc (structure) cấu trúc tuần tự (if, for, while,..), phép toán, toán tử,...
- Hàm và thủ tục (function)
Ở phần 1 và 2 hoàn toàn là ngôn ngữ C nên các bạn tham khảo các bài viết về ngôn ngữ C tại Serial về lập trình C. Chỉ riêng phần 3 là Hàm và thủ tục là các hàm dành riêng cho ngôn ngữ lập trình trên Arduino nên các bạn chỉ cần học them phần này sẽ lập trình được. Lưu ý những hàm giới thiệu bên dưới là những gì cơ bản nhất.
==========================================================================
2. Nhập xuất Analog (Analog I/O)
2.1 analogReference()
Giới thiệu
Hàm analogReference() có nhiệm vụ đặt lại mức (điện áp) tối đa khi đọc tín hiệu analogRead. Ứng dụng như sau, giả sử bạn đọc một tín hiệu dạng analog có hiệu điện thế từ 0-1,1V. Nhưng mà nếu dùng mức điện áp tối đa mặc định của hệ thống (5V) thì khoảng giá trị sẽ ngắn hơn => độ chính xác kém hơn => hàm này ra đời để giải quyết việc đó!
Cú pháp
analogReference(type)
type: một trong các kiểu giá trị sau: DEFAULT, INTERNAL, INTERNAL1V1, INTERNAL2V56, hoặc EXTERNAL
Kiểu
|
Nhiệm vụ đảm nhiệm
|
Ghi chú
|
DEFAULT
|
Đặt mức điện áp tối đa là 5V (nếu trên mạch dùng nguồn 5V làm nuôi chính) hoặc là 3,3V (nếu trên mạch dùng nguồn 3,3V làm nguồn nuôi chính)
| |
INTERNAL
|
Đặt lại mức điện áp tối đa là 1,1 V (nếu sử dụng vi điều khiển ATmega328 hoặc ATmega168)
Đặt lại mức điện áp tối đa là 2,56V (nếu sử dụng vi điều khiển ATmega8) | |
INTERNAL1V1
|
Đặt lại mức điện áp tối đa là 1,1 V
|
Chỉ có trên Arduino Mega
|
INTERNAL2V56
|
Đặt lại mức điện áp tối đa là 2,56 V
|
Chỉ có trên Arduino Mega
|
EXTERNAL
|
Đặt lại mức điện áp tối đa BẰNG với mức điện áp được cấp vào chân AREF
|
Chỉ được cấp vào chân AREF một điện áp nằm trong khoảng 0-5V
|
Trả về
khôngCảnh báo
NẾU bạn sử dụng kiểu EXTERNAL cho hàm analogReference thì bạn BUỘC phải cấp nó một nguồn nằm trong khoảng từ 0-5V, và nếu bạn đã cấp một nguồn điện thỏa mãn điều kiện trên vào chân AREF thì bạn BUỘC phải gọi dòng lệnh analogReference(EXTERNAL) trước khi sử dụng analogRead() [NẾU KHÔNG MẠCH BẠN SẼ "die"]
Ngoài ra, bạn có thể sử dụng một điện trở 5kΩ đặt trước chân AREF rồi đặt nguồn điện ngoài (điện áp bạn muốn cấp vào chân AREF). Vì sao lại làm như vậy? Bời vì sao chỗ gắn chân AREF có một nội điện trở (điện trở có sẵn trong mạch) khoảng 32kΩ => sẽ tạo ra mạch giảm áp phiên bản dễ nhất => giảm điện thế gắn vào chân AREF => không hư nếu bạn có lỡ gắn nguồn hơn 5V . Nếu bạn chưa hiểu rõ, bạn có thể xem hình sau.
2.2 analogRead()
Giới thiệu
Nhiệm vụ của analogRead() là đọc giá trị điện áp từ một chân Analog (ADC). Trên mạch Arduino UNO có 6 chân Analog In, được kí hiệu từ A0 đến A5. Trên các mạch khác cũng có những chân tương tự như vậy với tiền tố "A" đứng đầu, sau đó là số hiệu của chân.
analogRead() luôn trả về 1 số nguyên nằm trong khoảng từ 0 đến 1023 tương ứng với thang điện áp (mặc định) từ 0 đến 5V. Bạn có thể điều chỉnh thang điện áp này bằng hàm analogReference().
Hàm analogRead() cần 100 micro giây để thực hiện.
Khi người ta nói "đọc tín hiệu analog", bạn có thể hiểu đó chính là việc đọc giá trị điện áp.
Cú pháp
analogRead([chân đọc điện áp]);
Ví dụ
int voltage = analogRead(A0);
Trong đó A0 là chân dùng để đọc điện áp.
Nếu bạn chưa kết nối chân đọc điện áp, hàm analogRead() sẽ trả về một giá trị ngẫu nhiên trong khoảng từ 0 đến 1023. Để khắc phục điều này, bạn phải mắc thêm một điện trở có trị số lớn (khoảng 10k ohm trở lên) hoặc một tụ điện 104 từ chân đọc điện áp xuống GND.
2.3 analogWrite()
Giới thiệu
analogWrite() là lệnh xuất ra từ một chân trên mạch Arduino một mức tín hiệu analog (phát xung PWM). Người ta thường điều khiển mức sáng tối của đèn LED hay hướng quay của động cơ servo bằng cách phát xung PWM như thế này.Bạn không cần gọi hàm pinMode() để đặt chế độ OUTPUT cho chân sẽ dùng để phát xung PWM trên mạch Arduino.
Cú pháp
analogWrite([chân phát xung PWM], [giá trị xung PWM]);
Giá trị mức xung PWM nằm trong khoảng từ 0 đến 255, tương ứng với mức duty cycle từ 0% đến 100%Ví dụ
int led = 11;
void setup() {
}
void loop() {
for (int i = 0; i <= 255; i++) {
analogWrite(led,i);
delay(20);
}
}
Đoạn code trên có chức năng làm sáng dần một đèn LED được kết nối vào chân số 11 trên mạch Arduino.2.4 PWM
Kiến thức cơ bản
Xung là các trạng thái cao / thấp (HIGH/LOW) về mức điện áp được lặp đi lặp lại. Đại lượng đặc trưng cho 1 xung PWM (Pulse Width Modulation) bao gồm tần số (frequency) và chu kì xung (duty cycle).
Tần số là gì?
Tần số là số lần lặp lại trong 1 đơn vị thời gian. Đơn vị tần số là Hz, tức là số lần lặp lại dao động trong 1 giây.
Lấy ví dụ, 1Hz = 1 dao động trong 1 giây. 2Hz = 2 dao động trong 1 giây. 16MHz = 16 triệu dao động trong 1 giây.
Như vậy theo quy tắc tam suất: 16 triệu dao động - 1 giây --> 1 dao động tốn 1/16.000.000 (giây) = 0,0625 (micro giây)
Cách xác định 1 dao động như thế nào? Đa phần các bạn mới nghiên cứu điện tử thường mắc sai lầm ở việc xác định 1 dao động. Dao động được xác định từ trạng thái bắt đầu và kết thúc ngay trước khi trạng thái bắt đầu được lặp lại.
Cách xác định 1 dao động
Như vậy thông thường, 1 dao động sẽ bao gồm 2 trạng thái điện: mức cao (x giây) và mức thấp (y giây). Tỉ lệ phần trăm thời gian giữa 2 trạng thái điện này chính là chu kì xung.
Với x/y = 0% ta có xung chứa toàn bộ điện áp thấp (khái niệm xung nên hiểu mở rộng)
Với x/y = 50% thì 50% thời gian đầu, xung có điện áp cao, 50% sau xung có điện áp thấp.
Với x/y=100% ta có xung chứa toàn bộ điện áp cao.
Tóm lại, với 1 xung ta có:
- Tần số: để tính toán ra được thời gian của 1 xung
- Chu kì xung: bao nhiêu thời gian xung có mức áp cao, bao nhiêu thời gian xung có mức áp thấp.
Liên hệ với Arduino
Với kiến thức cơ bản về xung, các bạn sẽ hiểu rõ hơn về xung trong thực tế như thế nào.
Xung khi sử dụng với hàm analogWrite trong Arduino
Giữa 2 vạch màu xanh lá cây là 1 xung.
analogWrite | tỉ lệ | chu kì xung |
analogWrite(0) | 0/255 | 0% |
analogWrite(64) | 64/255 | 25% |
analogWrite(127) | 127/255 | 50% |
analogWrite(191) | 191/255 | 75% |
analogWrite(255) | 255/255 | 100% |
Hàm analogWrite() trong Arduino giúp việc tạo 1 xung dễ dàng hơn. Hàm này truyền vào tham số cho phép thay đổi chu kì xung, bạn có thể tính toán ra được chu kì xung như ở bảng trên. Tần số xung được Arduino thiết lập mặc định.
Đối với board Arduino Uno, xung trên các chân 3,9,10,11 có tần số là 490Hz, xung trên chân 5,6 có tần số 980Hz. Làm thế nào để tạo ra các xung có tần số nhanh hơn? Bạn có thể tham khảo thêm các thư viện riêng hỗ trợ việc này. Trong mã nguồn Arduino gốc không hỗ trợ phần này.
Bài này giới thiệu về xung PPM (Pulse Position Modulation) được sử dụng để điều khiển servo. Về bản chất PPM cũng là một xung, do vậy bạn cần tham khảo về xung trong bài xung PWM trước khi đọc tiếp nội dung của bài này.
Xung PPM khác với PWM ở chỗ:
- tần số thông thường có giá trị trong khoảng 50Hz (20 mili giây), không quan trọng
- thời gian xung ở mức cao chỉ từ 1ms đến 2ms, rất quan trọng.
- có thể có nhiều hơn 1 sự thay đổi trạng thái điện cao/thấp
Nắm bắt được 2 ý trên ta đã có thể phân biệt được xung PPM và xung PWM giống nhau và khác nhau như thế nào.
Thời gian xung ở mức cao quy định góc quay của RC servo.
Với thời gian 1ms mức cao, góc quay của servo là 0, 1.5ms góc quay 90 và 2ms góc quay là 180. Các góc khác từ 0-180 được xác định trong khoảng thời gian 1-2ms.
Lưu ý: có thể ghép nhiều xung trong cùng 1 thời gian là 20ms để xác định vị trí góc của nhiều servo cùng 1 lúc. Tối đa là 10 servo.
Điều khiển 3 servo cùng lúc