Projekt umożliwia interakcje z panelem LED. Pozwala on na wyświetlanie dowolnego tekstu na matrycy, zrobienia z panelu zegara pokazującego aktualną godzinę, bądź wyświetlanie dowolnych kształtów przez zapalanie konkretnych diod.
- Płytka ESP Wroom 32
- 32x16 RGB LED Matrix Panel
- ESP32_MINI_P3_P4_HUB75
- Kabel sygnałowy
- Kabel zasilający
- Komputer z zainstalowanym Thonny’m.
Program pozwala na wyświetlanie różnych liter, cyfr oraz kształtów przez zapalenie konkretnych diod. Dodatkowo można zmieniać barwę diod na siedem różnych kolorów, które są mieszanką czerwonego, zielonego oraz niebieskiego. Wyświetlanie tekstu polega na zmianie pliku z rozszerzeniem „.txt” znajdującego się na płytce, korzystając z bibliotek z cyframi i literami. Aktualna godzina do zegara jest pobierana z komputera. Korzystając z tych funkcji, mamy sporo możliwości. Można zrobić własny napis i go zaanimować, żeby się przesuwał w różne kierunki jak np. na sklepach napis „OPEN”. Możliwe jest wyświetlanie dowolnych kształtów. Sterowanie matrycą przebiega przez wiersz poleceń (wtedy użytkownik sam prowadza komendy), lub po przez wpisanie komend do programu głównego na samym jego końcu.
Główne elementy programu:
- „Cyfry.py”
Biblioteka odpowiadająca za cyfry wyświetlane na ekranie przy włączonym zegarze. Mają one wymiar 7x4 pikseli.
- „Litery.py”
Biblioteka odpowiadająca za litery wyświetlane na ekranie. Mają wymiar 5x5 pikseli.
- „Message.txt”
Plik przechowujący wiadomość do wyświetlenia na matrycy. Należy go wgrać na płytkę.
- „Program.py”
Główny program z wszystkimi funkcjami sterującymi.
Opis działania wybranych funkcji
- Turn_on_led – włącza poszczególną diodę na matrycy w wybranym kolorze
- Display_frame – wyświetla pojedyńczą klatkę programu
- Draw_digit – rysuje cyfrę z biblioteki „cyfry”
- Draw_letter – rysuje literę z biblioteki „litery”
- Draw_text – wyświetla tekst
- Zegar – zaczyna wyświetlać aktualną godzinę na matrycy
- Wyświetl_tekst – wyświetla tekst z pliku „message.txt” na wyświetlaczu
- Wylacz – gasi wszystkie ledy
Wszystkie funkcje są opisane w programie. Kolory w jakich można zapalać diody to: niebieski, zielony, czerwony, turkusowy, żółty, różowy oraz biały.
from machine import Pin
import time
from cyfry import CYFRY # Importuj bibliotekę z cyframi
from litery import LITERY # Importuj bibliotekę z literami
from time import localtime # Importuje funkcję do odczytywania aktualnej godziny
# Konfiguracja pinów GPIO dla macierzy LED RGB
DATA_PINS = {
'R1': Pin(26, Pin.OUT),
'G1': Pin(18, Pin.OUT),
'B1': Pin(19, Pin.OUT),
'R2': Pin(23, Pin.OUT),
'G2': Pin(14, Pin.OUT),
'B2': Pin(5, Pin.OUT)
}
ADDRESS_PINS = [Pin(13, Pin.OUT), Pin(21, Pin.OUT), Pin(17, Pin.OUT), Pin(12, Pin.OUT)]
LATCH_PIN = Pin(4, Pin.OUT)
CLK_PIN = Pin(16, Pin.OUT)
OE_PIN = Pin(2, Pin.OUT)
# Parametry macierzy
ROWS = 16 # Liczba rzędów
COLS = 32 # Liczba kolumn
#Kolory
niebieski=0b100
zielony=0b010
czerwony=0b001
turkusowy=0b110
zolty=0b011
bialy=0b111
rozowy=0b101
# Funkcja ustawiająca adres wiersza
def set_row_address(row):
for i in range(4): # 4 bity adresu
ADDRESS_PINS[i].value((row >> i) & 1)
# Funkcja przesyłająca dane do wiersza
def send_row_data(row_data_upper, row_data_lower):
for col in range(COLS):
# Wyciągnij dane dla każdego koloru (górny wiersz)
DATA_PINS['R1'].value((row_data_upper[col] >> 0) & 1)
DATA_PINS['G1'].value((row_data_upper[col] >> 1) & 1)
DATA_PINS['B1'].value((row_data_upper[col] >> 2) & 1)
# Wyciągnij dane dla każdego koloru (dolny wiersz)
DATA_PINS['R2'].value((row_data_lower[col] >> 0) & 1)
DATA_PINS['G2'].value((row_data_lower[col] >> 1) & 1)
DATA_PINS['B2'].value((row_data_lower[col] >> 2) & 1)
# Wygeneruj impuls zegara
CLK_PIN.value(1)
CLK_PIN.value(0)
# Funkcja wyświetlająca pojedynczą klatkę
def display_frame(frame_buffer):
for row in range(ROWS // 2):
# Ustaw adres wiersza
set_row_address(row)
# Prześlij dane dla dwóch wierszy (górny i dolny)
send_row_data(frame_buffer[row], frame_buffer[row + (ROWS // 2)])
# Zablokuj dane
LATCH_PIN.value(1)
time.sleep_us(1) # Dodano krótkie opóźnienie
LATCH_PIN.value(0)
# Włącz wyświetlanie
OE_PIN.value(0) # Upewnij się, że ten pin jest ustawiony na 0, by włączyć wyświetlanie
time.sleep_us(512)
# Wyłącz wyświetlanie, aby zapobiec duchom
OE_PIN.value(1)
# Funkcja generująca pustą ramkę
def create_frame_buffer():
return [[0 for _ in range(COLS)] for _ in range(ROWS)]
# Funkcja rysująca cyfrę w buforze
def draw_digit(frame_buffer, digit, x_offset, y_offset, color):
# Pobierz odpowiednią macierz dla cyfry
digit_matrix = CYFRY.get(digit)
# Rysowanie cyfry na macierzy LED w odpowiednich pozycjach
for y in range(7): # Cyfry mają wysokość 7
for x in range(4): # Cyfry mają szerokość 4
if (digit_matrix[y] >> (3 - x)) & 1: # Sprawdź, czy dioda powinna być zapalona
turn_on_led(frame_buffer, x_offset + x, y_offset + y, color) # Zapal diodę na pozycji
# Funkcja rysująca litere w buforze
def draw_letter(frame_buffer, letter, x_offset, y_offset, color):
if letter not in LITERY:
return # Jeśli litera nie jest w słowniku, nie rysujemy
# Pobierz reprezentację litery
letter_matrix = LITERY[letter]
# Rysowanie litery na macierzy LED w odpowiednich pozycjach
for y in range(5): # Wysokość litery (5 wiersze)
for x in range(5): # Szerokość litery (5 kolumn)
if (letter_matrix[y] >> (4 - x)) & 1: # Sprawdź, czy dioda powinna być zapalona
turn_on_led(frame_buffer, x_offset + x, y_offset + y, color) # Zapal diodę na pozycji
# Funkcja zapalająca wybraną diodę na matrycy
def turn_on_led(frame_buffer, x, y, color):
if 0 <= x < COLS and 0 <= y < ROWS:
frame_buffer[y][x] = color # Ustaw kolor na pozycji (x, y)
# Funkcja do wyświetlania aktualnej godziny
def get_current_time():
current_time = localtime()
hours = current_time[3]
minutes = current_time[4]
seconds = current_time[5]
return f'{hours:02}:{minutes:02}:{seconds:02}' # Formatowanie godziny HH:MM:SS
# Funckja do wyświetlania tekstu z pliku
def draw_text(frame_buffer, text, x_offset, y_offset, color):
x=x_offset
for char in text:
if char != ' ': # Ignoruj spacje
if char == '<NEWLINE>':
y_offset+=6
x=x_offset
continue
draw_letter(frame_buffer, char, x, y_offset, color) # Rysuj literę
x += 5 # Przesuwamy pozycję na następną literę (5 to szerokość jednej litery)
# Funkcja do wyświetlania godziny
def draw_time(frame_buffer,color1,color2):
current_time = get_current_time()
x_offset = 1
i=0
y_offset=5
for char in current_time:
if char != ':': # Ignoruj dwukropek
if i==2:
x_offset -= 1
draw_digit(frame_buffer,':',x_offset,y_offset,color2)
x_offset += 3
i=0
draw_digit(frame_buffer, char, x_offset, y_offset,color1) # Rysuj cyfrę na pozycji x_offset
x_offset += 4 # Przesuń o 5, by zostawić miejsce między cyframi
i=i+1
# Funkcja do zerowania regionu macierzy bufora
def zero_region_buffera(frame_buffer, x, y, width, height):
for i in range(x, x + width):
for j in range(y, y + height):
if 0 <= i < COLS and 0 <= j < ROWS:
frame_buffer[j][i] = 0 # Zerowanie wartości w buforze
# Funkcja wyswietlania aktualnej godziny
def zegar(color1,color2):
# Przygotuj bufor ramki
frame_buffer = create_frame_buffer()
# Pobierz aktualną godzinę
current_time = get_current_time()
start=time.ticks_ms()
# Wyświetlaj klatkę w pętli
while True:
czas=(time.ticks_ms()-start)
if czas>990:
frame_buffer = create_frame_buffer() # Zresetuj bufor
# Rysuj każdą cyfrę godziny na matrycy LED
draw_time(frame_buffer, color1,color2) # Rysuj czas
start=time.ticks_ms()
# Wyświetlaj klatkę w pętli
display_frame(frame_buffer) # Wyświetlanie bez kontroli jasności
# Czekaj 1 sekundę, aby zaktualizować czas
# Funkcja odczytywania tekstu z pliku
def odczyt_tekstu_z_pliku(file_path):
with open(file_path, "r") as file:
content = file.read()
result = []
for char in content:
if char == '\n':
result.append("<NEWLINE>")
else:
result.append(char)
return result
# Funkcja wyświetlania tekstu z pliku
def wyswietl_tekst_z_pliku(frame_buffer,file_path,x_offset,y_offset,color):
text=odczyt_tekstu_z_pliku(file_path)
y=y_offset
if text:
draw_text(frame_buffer, text, x_offset,y,color)
else:
print("Brak tekstu do wyświetlenia")
# Funkcja wyświetlania tekstu z pliku
def wyswietl_tekst(color,x_offset,y_offset):
frame_buffer = create_frame_buffer()
file_path="message.txt"
frame_buffer=create_frame_buffer()
wyswietl_tekst_z_pliku(frame_buffer,file_path,x_offset,y_offset,color)
while True:
display_frame(frame_buffer)
# Funkcja do wyłączenia ledów
def wylacz():
frame_buffer=create_frame_buffer()
display_frame(frame_buffer)
def szyld():
frame_buffer=create_frame_buffer()
text='LEDS'
paser=0
kolor=zielony
start=time.ticks_ms()
while True:
frame_buffer=create_frame_buffer()
for x in range(32):
for y in range(4):
if kolor==zielony:
turn_on_led(frame_buffer,x,y,kolor)
turn_on_led(frame_buffer,x,y+12,kolor)
kolor=niebieski
else:
turn_on_led(frame_buffer,x,y,kolor)
turn_on_led(frame_buffer,x,y+12,kolor)
kolor=zielony
draw_text(frame_buffer,text,paser,5,czerwony)
t=time.ticks_ms()
elapsed=t-start
if (elapsed>300):
start=time.ticks_ms()
paser+=1
if paser>32:
paser=-16
display_frame(frame_buffer)
szyld()