กลับไปหน้ารวมไฟล์
control-8-x-8-led-matrix-with-only-two-shift-registers-ca382e.md

ชื่อโปรเจกต์: ควบคุม 8 x 8 LED Matrix ด้วย Shift Register เพียงสองตัว


title: การควบคุม 8x8 LED Matrix ด้วย Shift Register และเทคนิคการเพิ่มประสิทธิภาพระดับต่ำ

เมื่อผมก้าวเข้าสู่โลกของ Arduino ด้วย Starter Kit พื้นฐาน และหลังจากเข้าใจตรรกะพื้นฐานแล้ว ผมก็ตัดสินใจว่าถึงเวลาที่จะสร้างโปรเจกต์ของตัวเอง

จุดเริ่มต้นของผมคือความต้องการที่จะสร้าง Sound Spectrum Analyzer เพื่อแสดงความถี่เสียงผ่าน LED Matrix อย่างไรก็ตาม ในระหว่างขั้นตอนการออกแบบ ผมได้พบกับความท้าทายทางวิศวกรรมที่สำคัญสามประการ:

  1. Pin Optimization (การจัดการ Pin): จะควบคุม LED จำนวนมาก (64 ดวง) ได้อย่างไรโดยไม่ใช้ Pin ทั้งหมดของ Arduino
  2. Performance (ประสิทธิภาพ): การแสดงผลจะต้องเร็วพอที่จะเหลือ CPU Cycles ให้ Arduino ประมวลผล FFT algorithm สำหรับการวิเคราะห์เสียง
  3. Power Management (การจัดการพลังงาน): จะควบคุมกระแสไฟเพื่อป้องกันระบบโอเวอร์โหลดได้อย่างไร

โปรเจกต์ที่ผมกำลังแบ่งปันนี้เป็นผลลัพธ์ของการแก้ปัญหาสองข้อแรก ซึ่งเป็นรากฐานสำคัญก่อนที่จะไปถึง Sound Analyzer ที่สมบูรณ์แบบ สิ่งนี้เกี่ยวข้องกับการควบคุม 8x8 LED Matrix โดยใช้ Shift Register เพียงสองตัวและ Pin น้อยที่สุด

แนวคิดและการทำงานของระบบ (สถาปัตยกรรมฮาร์ดแวร์)

แกนหลักของโปรเจกต์นี้คือการใช้ 74HC595 Shift Register สองตัวที่ทำงานร่วมกับเทคนิค Multiplexing

  • VCC Register (Anodes): ตัวแรกส่งสัญญาณบวก (High) ไปยัง Anode pin ของแต่ละคอลัมน์
  • GND Register (Cathodes): ตัวที่สองทำหน้าที่เป็นกราวด์ (Low) สำหรับ Cathode pin ของแต่ละแถว
แผนภาพวงจรพื้นฐานที่เชื่อมต่อ Arduino และ Shift Register

หมายเหตุ: แผนภาพด้านบนอาจมีการกลับขั้วในบางจุด แต่หลักการทางวิศวกรรมที่ถูกต้องสำหรับโปรเจกต์นี้คือ:

  • เชื่อมต่อ Pin บวก (Anode) ของ LED ในคอลัมน์เดียวกันเข้ากับ VCC Register
  • เชื่อมต่อ Pin ลบ (Cathode) ของ LED ในแถวเดียวกันเข้ากับ GND Register

การเพิ่มประสิทธิภาพด้วย SPI และ Direct Port Access

เพื่อให้ได้ความเร็วสูงสุด ผมไม่ได้ใช้ฟังก์ชัน shiftOut() หรือ digitalWrite() มาตรฐานของ Arduino เพราะฟังก์ชันเหล่านี้มีโอเวอร์เฮดสูง แต่ผมเลือกใช้วิธีการที่วิศวกร Embedded System นิยมใช้กัน:

  1. Hardware SPI: ใช้โมดูล SPI ภายในของชิป ATMega2560 (MOSI และ SCK pins) เพื่อส่งข้อมูลไปยัง Shift Register ด้วยความเร็วระดับ MHz
  2. Direct Port Access: ใช้คำสั่ง SET และ CLR ผ่าน Register PORTE เพื่อควบคุม Latch pins (Pin 2 และ 3 ของ Mega 2560) ซึ่งเร็วกว่า digitalWrite หลายสิบเท่า
void PutColumnVCC(unsigned char col) {
  CLR(PORTE, pe_vccs_latch); // Pull Latch pin Low with Direct Port Access
  SPI.transfer(col);         // Send data via Hardware SPI
  SET(PORTE, pe_vccs_latch); // Pull Latch pin High to display output
}

ตรรกะการเรนเดอร์

ในการแสดงภาพบน 8x8 Matrix เราไม่สามารถเปิด LED ทั้งหมดพร้อมกันได้ เพราะจะดึงกระแสไฟมากเกินไปและป้องกันการควบคุมลำดับภาพ ดังนั้น เราจึงใช้ Row Scanning (สแกนทีละแถว) โดยใช้ปรากฏการณ์ Persistence of Vision (POV)

ในโค้ดของผม ผมเลือกใช้ Loop Unrolling ในฟังก์ชัน Render() เพื่อลดภาระการคำนวณภายใน for loop:

// Example of row-by-row scanning logic
PutRowGND(0xFE); // Activate row 1 (B11111110 - Active Low)
for (int col = 0; col < 8; col ++) {
  int reg = 1 << col;
  PutColumnVCC((unsigned char)(LEDS[0] & reg)); // Send column data for row 0
}
PutColumnVCC(0); // Clear column values to prevent "Ghosting"

ข้อมูลภาพจะถูกเก็บไว้ในอาร์เรย์ unsigned char LEDS[8] โดยที่ 1 Byte แทน 1 แถว และแต่ละ Bit ภายใน Byte นั้นแทน LED แต่ละดวงในแถวนั้น (คอลัมน์)

การจัดการเวลาแบบ Non-blocking

ปัญหาทั่วไปสำหรับผู้เริ่มต้นคือการใช้ delay() ซึ่งทำให้การสแกน LED หยุดชะงักและเกิดการกะพริบ ในโปรเจกต์นี้ ผมใช้ตัวแปร counter เพื่อสร้างระบบหน่วงเวลาแบบ Software Timer ซึ่งช่วยให้การสแกนแถวทำงานได้อย่างต่อเนื่อง ในขณะที่โปรแกรมเปลี่ยนเฟรมภาพตาม scroll_speed ที่กำหนดไว้

คุณสมบัติและการโต้ตอบ (User Interface)

ผมได้เพิ่มหน้าจอ LCD ขนาด 16x2 และปุ่มสี่ปุ่มเพื่อสร้างระบบเมนูที่ใช้งานได้จริง:

  • Page 1 (การเลือกโปรแกรม): เลือกจากรูปแบบการแสดงผลมากกว่า 20 รูปแบบ (เช่น Wave, Heart, Alphabet)
  • Page 2 (การตั้งค่าความเร็ว): ปรับความเร็วของแอนิเมชัน
  • Page 3 (ทิศทาง): สลับทิศทางการสแกนเพื่อทดสอบประสิทธิภาพของ Hardware

สรุปทางวิศวกรรม

การใช้ Shift Register สองตัวเพื่อควบคุม LED 64 ดวงด้วยเทคนิคนี้มีข้อดีที่ชัดเจน:

  1. Low Power Consumption (การใช้พลังงานต่ำ): เนื่องจาก LED จะติดทีละดวง (หรือทีละแถวด้วยอัตราการสแกนที่เร็วมาก) จึงใช้กระแสไฟน้อยมาก เทียบเท่ากับการเปิด LED เพียงดวงเดียว
  2. Pin Efficiency (ประสิทธิภาพการใช้ Pin): เราใช้ Pin หลักเพียง 4 Pin (2 Latch pins + 2 SPI pins) ทำให้มี Pin ประเภท PWM และ Analog เหลือเฟือสำหรับ Sensor อื่นๆ
  3. High Speed (ความเร็วสูง): การใช้ Hardware SPI และ Direct Port Access ทำให้ระบบนี้สามารถขยายไปเป็น Spectrum Analyzer ที่ต้องการการประมวลผลแบบ Real-time ได้อย่างง่ายดาย

แม้วงจรบน Breadboard อาจจะดูยุ่งเหยิงไปบ้าง แต่นี่เป็นก้าวแรกที่สำคัญในการทำความเข้าใจการทำงานระดับ Register ของ Microcontroller ซึ่งเป็นหัวใจสำคัญของการเป็นวิศวกร Embedded System มืออาชีพ!

ข้อมูล Frontmatter ดั้งเดิม

title: "Control 8 x 8 LED Matrix with Only Two Shift Registers"
description: "Control 8 x 8 (64) LEDs using two 74HC595 shift registers as fast as possible using SPI and PORT access. (Updated 19 Jan, 2019)"
author: "Jegqamas"
category: "Lights & LEDs"
tags:
  - "lights"
  - "spi"
  - "led"
  - "lcd"
  - "shiftregisters"
  - "port"
views: 28170
likes: 13
price: 1120
difficulty: "Intermediate"
components:
  - "1x Arduino Mega 2560"
  - "1x Standard LCD - 16x2 White on Blue"
  - "4x Pushbutton switch 12mm"
  - "2x Shift Register- Serial to Parallel"
  - "64x LED (generic)"
  - "1x Rotary potentiometer (generic)"
  - "8x Resistor 221 ohm"
tools: []
apps:
  - "1x Arduino IDE"
downloadableFiles:
  - "https://projects.arduinocontent.cc/b07644a8-d56d-4f4e-af9b-2c44b321f4c0.ino"
documentationLinks: []
passwordHash: "7c349559a0f5f41d8f0ccb56e72f8fcca57c89947f19bf656796e9b97d2b25c9"
encryptedPayload: "U2FsdGVkX1+6NyAzPpnpbYCsnGnuhH88igWSFEvQGmwXoJu+Qv7r7GoM05tSvWI+kUkkY4OJJUcUYzl4xMnieRVsKkm98A3LuYp20w/Skyc="
seoDescription: "Learn to control an 8 x 8 LED Matrix using two 74HC595 Shift Registers with SPI and PORT access for maximum speed and efficiency."
videoLinks: []
heroImage: "https://cdn.jsdelivr.net/gh/bigboxthailand/arduino-assets@main/images/projects/control-8-x-8-led-matrix-with-only-two-shift-registers-ca382e_cover.jpg"
lang: "th"