การใช้งาน LED Dot Matrix กับ Arduino

ทุกคนคงรู้จัก LED กัน เพราะทุกวันนี้ได้เข้ามาเกี่ยวข้องกับชีวิตประจำวันหลายอย่าง รอบๆ ตัวน่าจะพบเจอ LED กันหลายดวงเลย

ในการใช้งาน Arduino นั้น LED เป็น Output ที่สำคัญอย่างหนึ่ง เอาง่ายๆ แค่เริ่มใช้ เชื่อว่าทุกคนคงเคยรันโปรแกรม ไฟกระพริบเทพ กันมาแล้ว บางคนอาจเคยลองต่อ LED ข้างนอก สีต่างๆ หรืออาจเป็น RGB LED บางคนอาจเคยลองใช้ LED แบบ 7 ส่วน (7 Segment) แต่สำหรับวันนี้เราจะมาทดลองใช้ LED แบบ Dot Matrix กัน เพราะเอาไปทำอะไรได้หลายอย่าง

โดย LED Dot Matrix ที่จะใช้จะเป็นตามรูปนี้

จากรูปเป็น LED ขนาด 8x8 เรียงเป็น Matrix อยู่ในชิ้นส่วนเดียวกัน แต่เนื่องจากมี LED จำนวนมากถึง 64 ดวง การจะขับโดยใช้ขาของ Arduino แบบธรรมดา จะต้องใช้สายสัญญาณที่ใช้ขับจำนวนมาก ซึ่งไม่สะดวกต่อการใช้งาน

แสดงการต่อกับ LED Dot Matrix โดยตรง ซึ่งจะต้องใช้ขาและสายสัญญาณจำนวนมาก

จึงได้มีผู้ผลิตชิปที่ใช้สำหรับขับ LED โดยเฉพาะ นั่นก็คือ MAX7219 นั่นเอง ไอซีตัวนี้แต่เดิมสร้างขึ้นมาสำหรับใช้กับ LED 7 Segment กรณีที่ต่อใช้งานหลายหลัก (สูงสุด 8 หลัก) โดยการเชื่อมต่อระหว่าง MAX7219 กับ LED 7 Segment มีดังรูป

ในการต่อ MAX7219 เข้ากับ LED 7 Segment จะต่อขา SEG A-G,DP เข้ากับขา a-g ของแต่ละหลัก และต่อ DIG 0–7 เข้ากับแต่ละหลัก (ตามรูป) ในการทำงาน ไอซี MAX7219 จะส่งข้อมูลของแต่ละหลักไปเป็นครั้งๆ โดยส่งข้อมูลของหลักที่ 1 ในขณะที่ส่ง DIG 0 ออกไป ซึ่งจะทำให้หลักที่ 1 ติด จากนั้นทิ้งไว้ระยะหนึ่งแล้วจึงส่งหลักที่ 2–8 ในทำนองเดียวกัน ซึ่งเมื่อดำเนินการด้วยความเร็วที่เหมาะสม โดยอาศัยหลักของภาพติดตา เราจะเห็นเป็นว่าทุกหลักติดหมด

สำหรับ LED Dot Matrix ขนาด 8x8 ก็สามารถจะนำ MAX7219 มาใช้ได้พอดี โดยชิป 1 ตัวเมื่อนำมาใช้กับ LED แบบ Dot Matrix ก็เทียบเท่า 8x8 พอดี

ในการใช้งานชิปตัวนี้ จะใช้ 3 ขา คือ CLK ซึ่งเป็นสัญญาณ Clock สำหรับกำหนดความเร็วในการส่งข้อมูลเข้าสู่ชิป โดยความเร็วสูงสุดที่ใช้ได้คือ 10 MHz ขา CS และขา Data In (DIN) โดยเมื่อรวมกับขา Vcc และ Gnd ก็รวมกัน 5 ขาพอดี

ในการต่อกับ Arduino นั้นจะใช้การสื่อสารในแบบ SPI โดยจะต่อสายดังนี้

  • Vcc -> Vcc
  • Gnd -> Gnd
  • Din -> Pin 11 เป็นขาสำหรับข้อมูล
  • CS -> Pin 10 จะใช้บอกว่าจะโหลดข้อมูลเข้าสู่ชิปแล้ว
  • CLK -> Pin 13 เป็นขาคล็อกสำหรับ Sync ข้อมูล โดยคล็อก 1 สัญญาณจะหมายถึงข้อมูล 1 บิต

การส่งข้อมูลจะส่งเป็นชุด ชุดละ 16 บิต ขั้นตอนจะเริ่มจาก

  1. CS เป็น LOW
  2. ส่งสัญญาณ CLK
  3. ส่งข้อมูลทุกครั้งที่ขอบขาขึ้น จาก D15-> D0 (เส้นแดง)

สำหรับการสั่งงาน MAX7219 จะควบคุมผ่านรีจิสเตอร์ (Register) ขนาด 8 บิตจำนวน 14 ตัว ตามตารางด้านล่าง

  • Register 1–8 เก็บข้อมูลที่จะแสดง
  • Register 9 บอกว่าแต่ละหลักจะใช้ decode แบบ BCD หรือไม่
  • Register A ใช้กำหนดความสว่างโดยมี 15 ระดับ (00h-0Fh)
  • Register B ใช้กำหนดว่าแสดงหลักใดบ้าง (00h-07h)
  • Register C ค่า 1=ทำงานปกติ 0=หยุดทำงาน

ในการจะโปรแกรมลงรีจิสเตอร์ทั้ง 14 ตัว หรือ ตัวใดตัวหนึ่ง จะทำผ่านการสื่อสารแบบ SPI ตามที่ได้กล่าวไปก่อนหน้านี้ โดยรูปแบบของข้อมูลจะเป็นดังนี้ คือ 4 บิตแรกจะไม่ใช้งาน (ปกติจะให้ค่าเป็น 0) 4 บิตถัดมาจะเป็นค่าตำแหน่งของรีจิสเตอร์ที่ต้องการโปรแกรม จากนั้นอีก 8 บิตจึงเป็นข้อมูลที่จะโปรแกรมลงในรีจิสเตอร์

อ่านมาถึงตรงนี้ บางคนอาจจะเริ่มสงสัยว่า ต้องรู้กันขนาดนี้เลยเหรอ แค่จะแสดงผลบน LED Dot Matrix คำตอบคือ หากเราเข้าใจการทำงานของมันในระดับที่ลงลึกถึงฐานรากในแบบที่อธิบายไป ในการทำความเข้าใจกับโปรแกรมจะง่ายขึ้น

เอาละครับ! ตอนนี้เราก็พร้อมแล้ว ที่จะมาโปรแกรมกัน โดยโปรแกรมแสดงข้างล่าง

โปรแกรมจะเริ่มจาก include SPI.h เพื่อเรียกใช้ไลบรารีในการส่งข้อมูลตามรูปแบบ จากนั้นก็จะเป็นการกำหนดขา ของ LED ซึ่งจะตรงกับของ SPI พอดี

ในบรรทัดที่ 7–12 จะเป็นฟังก์ชัน MAX7219_write_reg ซึ่งจะใช้ในการเขียนค่าลงในรีจิสเตอร์ โดยจะรับค่าตำแหน่งรีจิสเตอร์และข้อมูลที่จะเขียนลงไป โดยจะเริ่มจากเซ็ทให้ CS_PIN เป็น Low และส่งข้อมูล เมื่อเสร็จแล้วก็กำหนด CS_PIN เป็น High ซึ่งจะสอดคล้องกับ Timing Diagram ที่ได้อธิบายไปก่อนหน้านี้

ในบรรทัดที่ 14–19 จะเป็นการกำหนดค่าของรีจิสเตอร์ทั้ง 13 ตัว

ในบรรทัดที่ 21–27 จะเป็นฟังก์ชัน MAX7219_init ซึ่งเป็นการกำหนดค่าเริ่มต้นสำหรับการทำงานให้กับไอซี MAX7219 โดยมีรายละเอียดดังนี้ 1) decode mode ใช้แบบ binary ตามปกติ 2) กำหนดความสว่างเป็นกลางๆ โดยใช้ค่า 7 3) การใช้งาน ใช้ทุกหลัก (กรณีนี้คือทุกแถว) 4) ทำงานในโหมดปกติ (no shutdown) และ 5) ไม่ทำ display test

ในบรรทัดที่ 29–37 จะเป็นส่วน setup ของโปรแกรม โดยเริ่มจากกำหนดให้เรียก SPI ให้ทำงาน กำหนด Bit Order จากนั้นกำหนดความเร็วในการส่งข้อมูล (ทำได้โดยใช้การหาร clock ของระบบ) กรณีนี้กำหนดค่าเป็นหารด้วย 16 ดังนั้น clock ของระบบ 16 MHz หารด้วย 16 เท่ากับ 1 MHz เสร็จแล้วกำหนดให้ SPI ทำงานในโหมด 0 (ต้องใช้โหมดนี้เท่านั้น) จากนั้นกำหนด CS_PIN เป็น Output และกำหนดเป็น HIGH เพื่อแสดงว่ายังไม่เริ่มทำงาน จากนั้นจึงเรียกใช้ MAX7219_init เพื่อตั้งค่าเริ่มต้นในการทำงาน

ในบรรทัดที่ 39–45 จะเป็นฟังก์ชัน test_mode ซึ่งจะเป็นการสั่งให้ MAX7219 เข้าสู่โหมด display test ซึ่งจะเป็นการสั่งให้ LED ทุกดวงติดทั้งหมด จากนั้นก็ออกจากโหมด display test ซึ่งจะเป็นผลให้ LED ดับ

ในบรรทัดที่ 48–67 จะเป็น Pattern ของการแสดงผลที่เราต้องการจะให้นำไปแสดงบนจอ LED ซึ่งกรณีนี้จะแสดงเป็นตัวอักษร ‘C’ กับ ‘E’

ในบรรทัดที่ 69–80 จะเป็น loop หลักของการทำงาน โดยจะเรียก test_mode 1 ครั้ง จากนั้นก็กำหนดให้ทำงานในโหมดปกติ และแสดงตัว CE

ในโปรแกรมข้างต้นจะเห็นได้ว่าเราสามารถแสดงผลบนจอ LED ได้แล้ว แต่จะแสดงผลอะไรจะต้องดำเนินการเองทั้งหมด ซึ่งนับว่าไม่ค่อยสะดวกสักเท่าไร จึงได้มีผู้พัฒนาไลบรารีต่อยอดขึ้นไปอีก เพื่อให้การใช้งานสามารถทำได้ง่ายขึ้น โดยในที่นี่จะแนะนำให้ใช้ไลบรารีที่ชื่อว่า LedControl และโชคดีที่เราสามารถติดตั้งไลบรารีตัวนี้ผ่าน Arduino ได้เลย โดยไม่ต้องโหลดมาติดตั้งเอง โดยเข้าไปที่ Manage Libraries แล้ว search คำว่า ledcontrol ตามรูป แล้วติดตั้งแค่นั้น

จากนั้นก็ลองโหลดโปรแกรม demo มารัน ตามรูปด้านล่าง

จากนี้จะอธิบายโปรแกรม ในบรรทัดที่ 12

LedControl lc=LedControl(11,13,10,1);

บรรทัดนี้จะเป็นการสร้าง Object ที่ชื่อ lc ซึ่งต่อไปจะหมายถึงโมดูล LEDพารามิเตอร์ 3 ตัวแรก จะหมายถึง ขาที่ต่อกับ Din, Clk และ CS ตามลำดับ สำหรับพารามิเตอร์ตัวสุดท้าย จะหมายถึงจำนวนโมดูลของ LED (เนื่องจากโมดูล LED Dot Matrix นี้ สามารถต่อกันไปเรื่อยๆ ได้

ในส่วนของ setup จะประกอบด้วย

lc.shutdown(0,false);
/* Set the brightness to a medium values */
lc.setIntensity(0,8);
/* and clear the display */
lc.clearDisplay(0);

ซึ่งเนื่องจากเราเข้าใจการทำงานของ MAX7219 แล้ว ดังนั้นเราจึงบอกได้ว่า คำสั่งแรกคือการสั่งให้ทำงานตามปกติ (shutdown = false) คำสั่งที่ 2 คือการกำหนดความสว่างที่ระดับ 8 จาก 15 และคำสั่งที่ 3 เป็นคำสั่งให้ล้างหน้าจอ

สำหรับในไลบรารีนี้ ก็มีฟังก์ชันหลักอยู่ 3 ฟังก์ชันด้วยกัน คือ

  • ฟังก์ชัน setLed(addr,row,col,T/F)จะรับข้อมูลประกอบด้วย addr คือ โมดูล row,col ค่าแถวและคอลัมน์ และ T/F คือ ให้ติดหรือดับ
  • ฟังก์ชัน setRow(addr,row,value) จะรับข้อมูลประกอบด้วย addr คือ โมดูล row คือ แถวที่จะแสดง และ value คือค่า 8 บิตที่จะให้แสดง
  • ฟังก์ชัน setColumn(int addr, int col, byte value) ใช้งานเช่นเดียวกับ setRow

เมื่อดูโปรแกรมประกอบก็คิดว่าคงจะเข้าใจกันเพิ่มขึ้นนะครับ สุดท้ายนี้ขอแถมโปรแกรมเกมงูเอาไว้เล่นสักเกม

โปรแกรมข้างต้นดัดแปลงจาก https://www.instructables.com/id/Arduino-Dot-Matrix-Game-Console/ โดยปรับปุ่มให้ตรงกับ Joy Stick Shield คือ ถ้ามี Joy Stick Shield ก็เล่นได้เลยครับ

ก็หวังว่าบทความนี้คงจะทำให้ผู้ที่จะใช้งาน LED Dot Matrix เข้าใจการทำงานมากขึ้นและสามารถนำไปใช้งานกัน

Like what you read? Give Thana Hongsuwan a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.