flycat gửi vào
- 32007 lượt xem
IC HC595 điều khiển 1 lúc được 8 đèn led (nâng cao hơn là 16 đèn và nhiều hơn nữa). Có bao giờ bạn tự hỏi muốn kiểm soát từng đèn thì làm sao? Ví dụ: tui chỉ muốn đèn thứ 5 sáng/tắt thì làm sao? Tui muốn đèn thứ 2 và 7 sáng/tắt thì làm sao? ...
Bài học này sẽ hướng dẫn "làm sao".
Ôn lại bài cũ
Đọc lại bài này http://arduino.vn/bai-viet/113-dieu-khien-8-den-led-sang-nhap-nhay-theo-y-muon-cua-ban-de-hay-kho
Mọi người chỉ cần làm tới bước điều khiển 8 đèn led với 1 IC 595 thôi nhé.
Và bài này nữa: http://arduino.vn/reference/for
Phân biệt số thập phân (Decimal number) và số nhị phân (Binary number)
Số thập phân bao gồm 10 chữ số: từ 0 đến 9. Nôm na dễ hiểu là các con số trong đời sống hằng ngày. Ví dụ: mấy bợn nợ mình 250k, bây giờ là 25 giờ, tui có 3 chân rất khỏe khắn , ...
Số nhị phân bao gồm 2 chữ số: 0 và 1. Và cũng là con số điều khiển đầu ra của IC HC595.
Bạn cần thành thạo đổi từ số thập phân sang số nhị phân và ngược lại. Nếu không biết thì sử dụng các trang web có sẵn http://www.convertworld.com/vi/chu-so/nhi-phan.html. Mình nghĩ nên tính tay sẽ thấy được điều kì diệu của số nhị phân .
Tiến hành nào
Các bạn nhớ chân kinh sau: Đèn sáng là số 1, đèn tắt là số 0. Chân kinh này sẽ xuyên suốt bài học.
Khi chưa nạp code vào board mạch Arduino, các đèn led ở trạng thái tắt => Tắt là số 0. Và có tổng cộng 8 đèn led => có 8 số 0.
Vị trí đèn | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
Trạng thái đèn | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Code chính của chương trình:
//chân ST_CP của 74HC595 int latchPin = 8; //chân SH_CP của 74HC595 int clockPin = 12; //Chân DS của 74HC595 int dataPin = 11; //Note 1: int a[] = { chuỗi số }; void setup() { pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); } void loop() { //Note 2: để ý số K ở i<K for (int i = 0;i<K;i++) { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, a[i]); //Note 3: MSBFIRST có thể đổi thành LSBFIRST và ngược lại. digitalWrite(latchPin, HIGH); delay(500); } }
Trong đoạn code trên, bạn cần lưu ý ở Note 1 và Note 2. Mục đích:
Note 1: dùng để cố định đèn led nào sẽ sáng. Cách này đơn giản dễ hiểu, nếu bạn phát triển lên thì bỏ Note 1, ghi code trực tiếp vào vòng FOR.
Note 2: xác định số vòng quay dựa vào Note 1
Vào phần chính của bài học:
Câu hỏi 1: Tui chỉ muốn đèn thứ 5 sáng/tắt thì làm sao?
Chỉ đèn thứ 5 sáng/ tắt tức là số 1, các đèn còn lại số 0
Vị trí đèn | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
Trạng thái đèn | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
Như vậy ta có 2 số nhị phân: 1 000 (dịch thuận, từ số 1 sang phải) và 10 000 (dịch ngược, từ số 1 sang trái). Lấy số nào mới đúng?
Nếu bạn làm đúng như bài học cũ thì lấy số 10 000. Nếu bạn không làm đúng như bài học cũ, sẽ ra số khác, nên cần phải kiểm soát việc sắp xếp đèn led.
Sau khi đã xác định được số nhị phân, tiến hành chuyển sang số thập phân. Tại sao ư? IC HC 595 nhận đầu vào là số thập phân, đầu ra là số nhị phân.
Số nhị phân | Số thập phân |
10 000 | 16 |
=> Note 1 sẽ là:
int a[] = {16};
Tiếp đến là Note 2: số K sẽ là số mấy? Nhìn vào kết quả Note 1, bạn sẽ thấy 1 số nên K = 1.
Câu hỏi đặt ra: Tui lấy số khác được không? Như K = 2, 3, 100 chẳng hạn?
Trả lời: Hoàn toàn được nhưng kết quả cho ra là số random.
Làm thử ví dụ với K = 1
Thứ tự vòng quay | Số đầu vào |
1 | 16 |
Đèn số 5 sẽ sáng/ tắt liên tục.
Với K = 2
Thứ tự vòng quay | Số đầu vào |
1 | 16 |
2 | 2 hoặc 4 hoặc 500 hoặc ... |
Đèn số 5 và (hoặc) đèn khác sáng/ tắt liên tục. Tương tự với K = 3, 100, ...
Code hoàn thiện của chương trình:
int latchPin = 8; int clockPin = 12; int dataPin = 11; int a[] = { 16 }; void setup() { pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); } void loop() { for (int i = 0;i<1;i++) { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, a[i]); digitalWrite(latchPin, HIGH); delay(500); } }
Câu hỏi 2: Tui muốn đèn thứ 2 và 7 sáng/tắt thì làm sao?
Có các trường hợp với bài toán này:
a) Đèn thứ 2 sáng, xong tắt đèn thứ 2. Đèn thứ 7 sáng, xong tắt đèn thứ 7
b) 2 đèn sáng/ tắt cùng lúc
c) d) e) Các bạn tự nghĩ ra tiếp :D
Với trường hợp a) Đèn thứ 2 sáng, xong tắt đèn thứ 2. Đèn thứ 7 sáng, xong tắt đèn thứ 7
Đèn thứ 2
Vị trí đèn | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
Trạng thái đèn | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Đèn thứ 7
Vị trí đèn | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
Trạng thái đèn | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
Đổi từ số nhị phân sang số thập phân
Số nhị phân | Số thập phân |
10 | 2 |
1 000 000 | 64 |
Code thay đổi:
int a[] = {2, 64}; K = 2;
Với trường hợp b) 2 đèn sáng/ tắt cùng lúc
Vị trí đèn | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
Trạng thái đèn | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 |
Số nhị phân | Số thập phân |
1 000 010 | 66 |
Code thay đổi:
int a[] = {66}; K = 1;
Câu hỏi 3: Ghép 2 (hoặc nhiều) code vào nhau như thế nào?
int latchPin = 8; int clockPin = 12; int dataPin = 11; int a[] = { 16 }; int b[] = {4, 64}; int c[] = {66}; void setup() { pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); } void loop() { //Chạy mảng a[] for (int i = 0;i<1;i++) { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, a[i]); digitalWrite(latchPin, HIGH); delay(500); } //Chạy mảng b[] for (int i = 0;i<2;i++) { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, b[i]); digitalWrite(latchPin, HIGH); delay(500); } //Chạy mảng c[] for (int i = 0;i<1;i++) { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, c[i]); digitalWrite(latchPin, HIGH); delay(500); } }
Các bạn tự làm thêm: 3 bóng đầu sáng/ tắt, 2 bóng cuối sáng/ tắt, bóng số lẻ sáng/ tắt, ...
Phát triển code thì đọc bài này http://arduino.vn/reference/bit-math-cac-phep-toan-thao-tac-tren-bit
Chúc các bạn thành công.