搜尋此網誌

2020年4月19日 星期日

Raspberry Pi4 輕鬆實作系列之 LED Matrix

在簡單的控制 LED 亮暗後,剛好手邊有一顆 8x8  LED Matrix ,當然就要拿來玩看看囉


先了解一下 LED Matrix 的資訊
這款有二種規格,一個為共陰,一個為共陽。
21588 是共陰,也就是陰極全部接在一起的意思,會以高電位來控制亮暗。
11588 是共陽,也就是陽極全部接在一起的意思,會以低電位來控制亮暗。
而控制上的差異主要在邏輯上的分別,共陰的控制比較直觀,控制線路高電位為亮,低電位為暗。而共陽在控制上相反。
不過,在 LED Matrix 來說,看起來是以 ROW 的角度來定義共陰或共陽。而在控制上基本上可以自己習慣的方式來設計。當然,若接外部電源或是外接 LED 驅動模組的話,就需要另外考慮。這次先以最簡單的 PI4 直推 LED 來做實驗。

底下是 11588 這顆的腳位配置圖


再來是這次實驗 11588 PI4 GPIO 的接線圖
一共用了 16 根 GPIO ,是比較直觀的用法。

整理一下 PIN 的對應關係

接完線路後的狀態


目前,硬體準備完畢,開始進行程式的開發。

由於會用到 16根 GPIO,所以先將會用到的 GPIO 定義好,方便後續使用


一開始當然是先驗証看看線路和硬體是否有問題,所以先寫了二個簡單的函數

主程式如下:

主要功能就是一顆一顆點亮,確認線路和 LED Matrix 是否有問題。

實際的影片如下:



在認硬體以及接線沒問題後,就可以進行顯示數字的功能了。
因為是點陣的方式來顯示,若要顯示數字的話,會需要把數字改成 8x8 的點陣方式,所以先進行數字圖像的轉換。
這裡是先以 excel 的格子來試畫,也方便轉成 byte 的方式來使用。

基於點陣資料,在程式內先定義每組數字圖像如下:

再設計主要顯示每組字元的方式

設計的邏輯是,同一時間只顯示單行,然後再順序顯示不同行,利用視覺暫留的特性,就能看到整個圖像的顯示。
實際的顯示流程如下:
在很快的顯示後,就會像8行疊在一起的結果


實際的影片如下:


本次實驗的完整程式如下:

from gpiozero import LED
from time import sleep

led_col = [LED(26), LED(4), LED(17), LED(6), LED(22), LED(13), LED(20), LED(21)]
led_row = [LED(5), LED(16), LED(9), LED(19), LED(2), LED(10), LED(3), LED(27)]
digital = [[0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C],  # 0
           [0x18, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x7E],  # 1
           [0x3C, 0x66, 0x42, 0x04, 0x08, 0x30, 0x60, 0x7E],  # 2
           [0x3C, 0x42, 0x02, 0x1C, 0x02, 0x02, 0x42, 0x3C],  # 3
           [0x0C, 0x14, 0x24, 0x44, 0x44, 0x7E, 0x04, 0x04],  # 4
           [0x7E, 0x40, 0x7C, 0x06, 0x02, 0x42, 0x66, 0x3C],  # 5
           [0x3C, 0x42, 0x40, 0x7C, 0x66, 0x42, 0x66, 0x3C],  # 6
           [0x7E, 0x42, 0x06, 0x04, 0x0C, 0x08, 0x18, 0x10],  # 7
           [0x3C, 0x42, 0x42, 0x3C, 0x42, 0x42, 0x42, 0x3C],  # 8
           [0x3C, 0x66, 0x42, 0x66, 0x3E, 0x02, 0x42, 0x3C]]  # 9
           
led_size_col = len(led_col)
led_size_row = len(led_row)

def clean_all():
  for col in range(led_size_col):
    led_col[col].on()
  for row in range(led_size_row):
    led_row[row].off()


def light_one(col, row):
  led_col[col].off()
  led_row[row].on()
  
count_col = 0
count_row = 0

def light_digital(num):
  digital_data = digital[num]
  for col in range(led_size_col):
    for row in range(led_size_row):
      light = (digital_data[col] >> row) & 0x01
      if light == 1:
        led_row[row].on()
      else:
        led_row[row].off()
    led_col[col].off()
    sleep(0.001)
    led_col[col].on()

count_num = 0
digital_num = 0

while True:
  # 測試每個點是否能正常顯示
#  clean_all()
#  sleep(0.1)
#  light_one(count_col,count_row)
#  sleep(0.1)
#  count_row = count_row + 1
#  if count_row >= led_size_row:
#    count_row = 0
#    count_col = count_col + 1
#    if count_col >= led_size_col:
#      count_col = 0
      
  # 進行數字圖像顯示
  light_digital(digital_num)
  count_num = count_num + 1
  if count_num > 50 :
    count_num = 0
    digital_num = digital_num + 1
    if digital_num >= 10:
      digital_num = 0



沒有留言:

張貼留言