Sterowanie panelami LED z poziomu mikrokontrolera pyMCU

Matryce LED są dość popularne. Za ich pomocą można tworzyć panele i banery reklamowe z np. animowanym tekstem. Włączanie bądź wyłączanie diody LED przez mikrokontroler to nie problem. Gdy diod będzie 64 albo i więcej to efektywne zarządzanie wszystkimi diodami LED stanie się problematyczne. Rozwiązaniem tego problemu są jednak sterowniki diod LED, które zmniejszają drastycznie ilość pinów potrzebnych do zarządzania panelem. Niektóre z nich obsługują także np. przewijanie tekstu. W tym artykule przedstawię układ z matrycą LED 8x8 i sterownikiem MAX7219.

Moduł matrycy LED 8x8 ze sterownikiem MAX7219

Wspomniany moduł można tanio nabyć w dx.com, hobbycomponents.com, czy w Polsce w electropark.pl, czy czasami także na Allegro. Cena 16-22 PLN za sztukę.

Moduły te można łączyć ze sobą w dłuższe łańcuchy (o czym za chwilę). Komunikacja odbywa się poprzez interfejs SPI - szeregowy interfejs urządzeń peryferyjnych, co sprowadza kontrolowanie matrycy LED do 3 pinów (plus dwa na zasilanie). W sieci dostępne są gotowe przykłady dla Arduino jak i dla Raspberry Pi. Dostępne są także inne płytki z tym sterownikiem - ogólnie to całkiem przydatny układ.

Podłączenie modułu

Żeby podłączyć moduł do naszego mikrokontrolera musimy wiedzieć które piny obsługują komunikację poprzez SPI. W przypadku pyMCU zegar (SCK, SCLK) to cyfrowy pin 11, wejście SDI (MISO) - pin 4, a wyjście SDO (MOSI) pin 5. Moduł posiada pięć pinów: VCC (+), GND (-), DIN (pin 5), CS (pin 4) oraz CLK - pin 11. Jeden panel może być zasilany przez pyMCU. Większa ich ilość wymagać będzie własnego zasilania.

Moduły te można łączyć ze sobą. Po przeciwnej stronie modułu mamy kolejne pięć pinów, które do tego służą. Podpięcie kolejnego modułu do nich spowoduje że oba będą na raz wyświetlać to samo. Żeby ułożyć układy w linie wszystkie łączymy do tych samych pinów mikrokontrolera - za wyjątkiem pinu DIN. Pin DIN pierwszej płytki łączymy normalnie do pinu 5 pyMCU, natomiast piny DIN kolejnych płytek do pinu DOUT poprzedzającej go płytki (ta sama pozycja, tyle że z tych "na górze"). Przykład znajdziemy na arduinobymyself.blogspot.com.br.

moduł LED podłączony do pyMCU
piny do komunikacji SPI oraz zasilania

Skryptowanie modułu LED

Dla Raspberry Pi mamy gotowy kod napisany w Pythonie. Na potrzeby pyMCU sforkowałem repozytorium i zmieniłem interfejs SPI z Raspberry na pyMCU.

Kod działa, choć w odróżnieniu od Raspberry Pi musi sobie utworzyć instancję pyMCU co może gryźć się z bardziej złożonym kodem operującym także na innych elementach podłączonych do mikrokontrolera. Postaram się z czasem przepisać ten kod na klasy przyjmujące jako parametr instancję pyMCU.

Tymczasem można pobawić się modułem i wyświetlać na nim jakiś tekst

import max7219.led as led
import max7219.transitions as transitions

led.init()
led.show_message("Hello world!", transition = transitions.left_scroll)

Słów kilka o SPI

Żeby porozumiewać się z układem za pomocą protokołów SPI, czy I2C musimy mieć ich dokumentację - żeby wiedzieć pod jakie adresy jakie dane wysyłać. W przypadku pyMCU musimy na początku włączyć komunikację po protokole SPI:

mb = pymcu.mcuModule()
mb.spiEnable(1, 1000, 0, 0)

Gdzie poszczególne argumenty to polaryzacja zegara, jego częstotliwość i dwa parametry określające kiedy dane są wysyłane i odbierane z modułu (dokumentacja opisuje, którą z kombinacji obsługuje). Więcej szczegółów w dokumentacji biblioteki pyMCU.

Przesyłanie danych wygląda prosto - mb.spiTransfer(DANE), gdzie dane to liczba, łańcuch lub lista liczb. W dokumentacji danego modułu znajdziemy heksadecymalne adresy, bądź i wartości, jakie będzie rozumiał ów moduł. W przypadku MAX7219 Wysyłamy dwuelementową listę zawierającą rejestr i dane. Kod dla Rasperry na tym kończy, lecz w przypadku pyMCU trzeba zrobić coś jeszcze. Raspberry pewnie robi to samo w tle, lecz dla pyMCU trzeba jawnie spełnić wymagania z dokumentacji MAX7219:

Serial data is loaded into the shift register while CS is low. The last 16 bits of serial data are latched on CS’s rising edge.
Dane do modułu ładowane są gdy CS jest w stanie niskim, a "wykonane" gdy stan rośnie z niskiego do wysokiego. Dla pyMCU to kwestia wykonania pinLow i pinHigh:
def send_byte(register, data):
    mb.pinLow(4)
    mb.spiTransfer([register, data])
    mb.pinHigh(4)

Różne moduły wykorzystujące SPI, czy I2C potrafią mieć swoje specyficzne spojrzenie na tą komunikację, przez co nie zawsze próba ich oskryptowania będzie miła i przyjemna. Tak, czy owak ten moduł działa i jest całkiem fajny.

RkBlog

Elektronika i Python, 29 September 2013

Comment article
Comment article RkBlog main page Search RSS Contact