Bài 4. Điều khiển 8 LED với thanh ghi dịch

Trong bài này, chúng ta sẽ học cách sử dụng 8 LED mà không cần phải sử dụng đến 8 ngõ ra.

Mặc dù bạn có thể kết nối 8 LED với điện trở đến các chân của Arduino (tương tự như đối với LED RGB ở Bài 2), nhưng điều này sẽ làm bạn sử dụng hết số chân trên Arduino. Nếu bạn không cần thêm các ngõ các thì không vấn đề gì, tuy nhiên, đôi lúc bạn sẽ phải sử dụng các nút nhấn, cảm biến, servo, v.v… thì sẽ không còn chân để điều khiển. Do vậy, thay vì làm như vậy, chúng ta sẽ sử dụng một IC được gọi là Bộ chuyển đổi Serial (nối tiếp) sang Parallel (song song) 74HC595. IC này sẽ có 8 ngõ ra và ba ngõ vào.

IC này khiến việc điều khiển LED có phần chậm hơn (bạn chỉ có thể tác động thay đổi LED khoảng 500.000 lần mỗi giây thay vì 8.000.000 lần mỗi giây bằng Arduino) nhưng như vậy cũng thực sự rất nhanh rồi, nhanh hơn khả năng con người có thể phát hiện được, do vậy cũng không gặp vấn đề gì.

Linh kiện cần thiết

Để thực hành bài tập này, chúng ta cần sử dụng một số linh kiện như sau

STT Tên linh kiện SL Hình ảnh
1 Đèn LED 5mm 8

2 Điện trở 270
Ω
8

3 74HC595 1
4 Breadboard 1
5 Arduino UNO 1
6 Dây nối dạng cắm

Sơ đồ cắm chân breadboard

Vì chúng ta có 8 LED và 8 điện trở kết nối vào mạch, nên phải thực hiện hiện khá nhiều kết nối trên breadboard theo sơ đồ sau

Để đơn giản, ta cắm chip 74HC595 đầu tiên, vì có rất nhiều thứ kết nối với nó. Lắp sao cho đầu có phần U khuyết nằm hướng lên phía trên của breadboard. Chân số 1 của chip này sẽ nằm phía bên trái của của đầu này.

  • Chân 4 của arduino nối vào chân #14 của thanh ghi dịch
  • Chân 5 của arduino nối vào chân #12 của thanh ghi dịch
  • Chân 6 của arduino nối vào chân #11 của thanh ghi dịch

Hầu như các ngõ ra của thanh ghi dịch 74HC595 đều nằm bên trái (trừ một ngõ ra bên phải), đây là các ngõ nối vào LED, do đó khá dễ để kết nối chúng.

Sau mỗi ngõ ra, lắp vào một điện trở. Hãy để ý rằng các chân của điện trở không chạm vào các điện trở khác. Kiểm tra kĩ một lần nữa trước khi cấp nguồn cho Arduino. Sau đó, lắp LED lên breadboard. Chân dương của LED hướng vào IC.

Bây giờ, hãy kết nối các dây nối như sơ đồ ở trên. Đừng quên rằng có một kết nối từ chân số 8 của IC đến cột GND của breadboard.

Thanh ghi dịch 74HC595

Trước khi đến với phần mã lệnh, hãy xem qua IC ghi dịch này, từ đó hiểu được chúng ta phải điều khiển bằng lệnh như thế nào.

Loại IC này được gọi là thanh ghi dịch.

Thanh ghi dịch lưu trữ một kiểu dữ liệu mà ta có thể xem như là 8 ô nhớ, mỗi ô có một giá trị là 1 hoặc 0.

Để đặt mỗi giá trị đó là 1 hay 0 (tương ứng với bật hay tắt), chúng ta phải truyền vào một dữ liệu sử dụng chân ‘Clock’ và ‘Data’ của IC.

Chân ‘Clock’ được nhận 8 xung, tại thời điểm mỗi xung, nếu chân ‘Data’ ở mức cao, giá trị 1 sẽ được lưu vào thanh ghi dịch, ngược lại sẽ là 0. Khi tất cả tám xung được truyền vào, việc kích hoạt chân ‘Latch’ sẽ sao chép 8 giá trị đó vào thanh ghi ‘latch’. Điều này là cần thiết, nếu không các LED sẽ nhấp nháy khi dữ liệu được truyền vào thanh ghi dịch.

IC này cũng có một chân OE (output enable), dùng để kích hoạt hoặc vô hiệu tất cả ngõ ra cùng một lúc. Bạn có thể kết nối chân này vào chân PWM của Arduino và dùng lệnh ‘analogWrite’ để điều khiển độ sáng của LED. Chân này được kích hoạt ở mức thấp, do vậy chúng ta kết nối nó với GND.

Mã chương trình Arduino

Arduino có một hàm đặc biệt gọi là ‘shiftOut’ dùng để gửi dữ liệu đến thanh ghi dịch. Dưới đây là toàn bộ mã lệnh của sketch, sau đó chúng ta sẽ thảo luận về cách chương trình này hoạt động.

/*
Bài 4. Điều khiển 8 LED với thanh ghi dịch
*/

int latchPin = 5;
int clockPin = 6;
int dataPin = 4;
byte leds = 0;

void setup()

{
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}

void loop()

{
  leds = 0;
  updateShiftRegister();
  delay(500);

  for (int i = 0; i < 8; i++)
  {
    bitSet(leds, i);
    updateShiftRegister();
    delay(500);
  }

}

void updateShiftRegister()

{
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, leds);
  digitalWrite(latchPin, HIGH);
}

Đầu tiên, chúng ta sẽ khai báo ba chân mà ta dự định sẽ sử dụng. Những chân này là các chân ngõ ra digital và được kết nối với chân latch, clock và data của 74HC595.

int latchPin = 5;
int clockPin = 6;
int dataPin = 4;

Tiếp theo đó, biến ‘leds’ sẽ được khai báo. Biến này sẽ giữ một mảng dữ liệu quy định LED nào sẽ tắt hoặc mở. Loại dữ liệu dạng ‘byte’ đại diện cho một bộ nhớ sử dụng 8 bit. Mỗi bit mang giá trị mở (on) hoặc tắt (off), do vậy đây là dạng dữ liệu thích hợp để theo dõi trạng thái của 8 LED.

byte leds = 0;

Hàm ‘setup’ chỉ đơn giản là thực hiện việc đặt ba chân chúng ta chọn làm ngõ ra digital.

void setup() 
{
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
}

Hàm ‘loop’ đầu tiên sẽ tắt tất cả các LED, bằng cách cho biến ‘leds’ giá trị bằng 0. Sau đó, nó gọi hàm ‘updateShiftRegister’ để gửi trạng thái của 8 led đến thanh ghi dịch, làm cho tất cả LED tắt. Chúng ta sẽ tìm hiểu hàm ‘updateShiftRegister’ làm việc như thế nào sau.

Tiếp theo, hàm loop sẽ dừng trong nửa giây và tiếp tục đến từ 0 đến 7 sử dụng vòng lặp ‘for’ với biến ‘i’. Mỗi lần, nó dùng hàm ‘bitSet’ của Arduino để đặt bit điều khiển LED tương ứng trong biến ‘leds’. Sau đó nó gọi ‘updateShiftRegister’ để cập nhật trạng thái của các đèn LED theo biến ‘leds’.

Có một khoảng dừng nửa giây trước khi biến ‘i’ tăng thêm một giá trị và đèn LED tiếp theo được bật sáng.

void loop() 
{
  leds = 0;
  updateShiftRegister();
  delay(500);
  for (int i = 0; i < 8; i++)
  {
    bitSet(leds, i);
    updateShiftRegister();
    delay(500);
  }
}

Hàm ‘updateShiftRegister’, đầu tiên sẽ đặt chân latchPin xuống mức thấp (LOW), sau đó gọi hàm Arduino ‘shiftOut’ trước khi đặt chân latchPin lên lại mức cao (HIGH).

Hàm ‘shiftOut’ này có 4 tham số, hai tham số đầu theo thứ tự là chân Data và Clock. Tham số thứ ba chỉ ra vị trí của mảng dữ liệu mà chúng ta sẽ bắt đầu. Chúng ta sẽ bắt đầu từ bit ngoài cùng bên phải, được gọi là ‘Least Significant Bit’ (LSB).

Tham số thứ tư là dữ liệu mà chúng ta muốn đưa vào thanh ghi dịch, trong trường hợp này là biến ‘leds’.

void updateShiftRegister()
{
   digitalWrite(latchPin, LOW);
   shiftOut(dataPin, clockPin, LSBFIRST, leds);
   digitalWrite(latchPin, HIGH);
}

Nếu bạn muốn chuyển một LED nào đó sang trạng thái tắt, bạn có thể gọi một hàm Arduino tương tự (bitClear) với cách sử dụng tương tự như hàm ‘bitSet’. Hàm này sẽ đặt bit tương ứng trong biến ‘leds’ thành 0 và bạn phải sử dụng hàm ‘updateShiftRegister’ để cập nhật lại trạng thái các đèn LED.

Điều khiển độ sáng

Có một chân của 74HC595 mà chúng ta chưa đề cập đến là ‘Output Enable’. Đây là chân số 13 và trên breadboard, nó đang được kết nối với GND. Chân này đóng vai trò như một công tắc, có thể kích hoạt hay vô hiệu hóa các ngõ ra của IC – việc chúng ta làm là ‘kích hoạt mức thấp’ (kết nối và chân GND của Arduino để kích hoạt các ngõ ra). Do đó, nếu chúng ta kết nối vào chân 5V của Arduino, các ngõ ra sẽ bị vô hiệu hóa (tất cả LED sẽ tắt). Còn nếu ta kết nối vào GND, ngõ ra nào được đặt ON thì sẽ ON, ngõ ra nào đặt OFF sẽ OFF.

Chúng ta cũng có thể sử dụng chân này cùng với hàm ‘analogWrite’ như đã học trong bài 3, để điều khiển độ sáng của LED sử dụng phương pháp PWM (xem lại bài 3).

Để thực hiện điều này, tất cả những gì bạn cần, là thay đổi kết nối chân số 13 của 74HC595, từ chân GND sang chân số 3 của Arduino.

Sử dụng sketch bên dưới, sau khi tất cả các LED đều sáng, chúng ta tiếp tục làm các LED tối dần và tắt.

/*
Bài 4. Điều khiển 8 LED với thanh ghi dịch - Thay đổi độ sáng
*/
int latchPin = 5;
int clockPin = 6;
int dataPin = 4;

int outputEnablePin = 3;
byte leds = 0;

void setup() 
{
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
  pinMode(outputEnablePin, OUTPUT); 
}

void loop() 
{
  setBrightness(255);
  leds = 0;
  updateShiftRegister();
  delay(500);

  for (int i = 0; i < 8; i++)
  {
    bitSet(leds, i);
    updateShiftRegister();
    delay(500);
  }

  for (byte b = 255; b > 0; b--)
  {
    setBrightness(b);
    delay(50);
  }

}

void updateShiftRegister()
{
   digitalWrite(latchPin, LOW);
   shiftOut(dataPin, clockPin, LSBFIRST, leds);
   digitalWrite(latchPin, HIGH);
}

void setBrightness(byte brightness) // 0 to 255
{
  analogWrite(outputEnablePin, 255-brightness);
}

Bạn có thể làm gì hơn nữa

Một khi bạn đã biết cách sư dụng 74HC595, thì có nhiều thứ bạn có thể làm với rất nhiều LEDs. Bạn có thể thử tìm thêm các ứng dụng của nó từ Internet.

Một điều thú vụ nữa về 74HC595 là bạn có thể xâu chuỗi chúng để tăng số lượng LED mà bạn có thể điều khiển. Để làm điều này hoặc là sử dụng 74HC595 một cách chuyên nghiệp hơn, hãy xem qua tài liệu chính thức của Arduino cho hàm ‘shiftOut’ tại http://arduino.cc/en/Tutorial/ShiftOut.

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Website này sử dụng Akismet để hạn chế spam. Tìm hiểu bình luận của bạn được duyệt như thế nào.