Spisu treści:

Matryca LED RGB: 5 kroków
Matryca LED RGB: 5 kroków

Wideo: Matryca LED RGB: 5 kroków

Wideo: Matryca LED RGB: 5 kroków
Wideo: MATRYCA LED RGB WS2812b + sterownik bluetooth SP107e. Jakie efekty można uzyskać? | JAKIX 2024, Listopad
Anonim
Image
Image
Projektowanie sprzętu
Projektowanie sprzętu

Wyszukaj Instructable, a znajdziesz wiele projektów matryc LED. Żadna z nich nie była tym, czego chciałem, czyli zbadaniem interakcji sprzętu i oprogramowania, aby coś wyprodukować, i wytworzeniem produktu końcowego w zgrabnej płytce drukowanej ze sterownikiem, który pozwól mi narysować na „ekran LED” za pomocą wysokiego poziomu konstrukcje (np. rysowanie linii w przeciwieństwie do ustawiania określonych pikseli). Ta część była dla mnie ważna, ponieważ wiele sterowników matryc LED to gołe kości i nie zapewniają wiele w zakresie programowego tworzenia obrazu lub animacji. Nie oznacza to, że nie możesz tworzyć obrazów i animacji za pomocą innych sterowników, po prostu musiałbyś wykonywać bardziej powtarzalną pracę od projektu do projektu.

Więc postanowiłem zrealizować swoją wizję. Pierwszym krokiem było zaprojektowanie sprzętu. To było prawdopodobnie dla mnie największym wyzwaniem, ponieważ mam doświadczenie w programowaniu. Znowu było wiele gotowych projektów i z pewnością wykorzystałem je jako inspirację, ale chciałem uczyć się przez robienie, więc prototypowałem matrycę 4x4 na płytce prototypowej. Wiele się nauczyłem dzięki temu procesowi, ponieważ moje pierwsze kilka iteracji nie zadziałało. Ale zrobiłem projekt sprzętu, który zadziałał, co z kolei pozwoliło mi rozpocząć opracowywanie sterownika.

Wybrałem Arduino jako moją platformę sterowników, ponieważ jest powszechnie dostępny i ma wiele referencji w Internecie. Podczas gdy doświadczenie zawodowe pozwoliło mi dotrzeć do działającej wersji sterownika sprawniej niż moje wysiłki sprzętowe, wciąż było wiele iteracji, podczas gdy optymalizowałem wydajność sterownika dla mikrokontrolera ATMega i opracowałem interfejs programowania API, który mi się podobał.

Ten Instructuable dokumentuje projekt i niektóre kluczowe wnioski z mojego projektu. Więcej informacji na temat tego projektu można znaleźć na mojej stronie tutaj, w tym pełne zestawy, które można zakupić do zbudowania własnej matrycy LED RGB.

Krok 1: Projektowanie sprzętu

Podstawowym celem mojego projektu sprzętowego było stworzenie tablicy LED RGB, którą mógłbym zaprogramować, ale też nie chciałem wydawać dużo pieniędzy. Podejście, na które się zdecydowałem, polegało na użyciu rejestrów przesuwnych 74HC595 do sterowania diodami LED. Aby zminimalizować liczbę potrzebnych rejestrów przesuwnych, ułożyłem diody LED RGB w układ matrycy, w której wspólne anody zostały połączone w rzędy, a przewody czerwonej, zielonej i niebieskiej katody zostały połączone w kolumny. W przypadku matrycy 4x4 schemat obwodu wyglądał jak załączony schemat obwodu.

Jedną rzeczą, którą od razu zauważysz, jest to, że biorąc pod uwagę obwód matrycy, istnieją pewne konfiguracje oświetlenia LED, których nie można wykonać, gdy wszystkie pożądane diody LED są włączone w tym samym czasie. Na przykład matryca nie może jednocześnie zaświecić dwóch diod, które są przekątne względem siebie, ponieważ zasilanie zarówno rzędów, jak i kolumn spowoduje, że dwie przeciwległe diody zaświecą się po przekątnej prostopadłej do żądanych diod. Aby obejść ten problem, użyjemy multipleksowania do skanowania każdego wiersza. W sieci jest mnóstwo zasobów, które obejmują technikę multipleksowania, nie zamierzam tutaj ich powielać.

Ponieważ używam zwykłych diod LED anodowych, oznacza to, że rzędy dostarczają dodatnią moc, a kolumny opadają na ziemię. Dobrą wiadomością jest to, że rejestry przesuwne 74HC595 mogą zarówno pozyskiwać, jak i pobierać moc, ale złą wiadomością jest to, że mają limit mocy, jaką mogą pozyskiwać lub pobierać. Poszczególne piny 74HC595 mają maksymalny pobór prądu 70 mA, ale najlepiej trzymać mniej niż 20 mA. Poszczególne kolory w naszych diodach LED RGB mają pobór około 20 mA. Oznacza to, że 74HC595 nie może bezpośrednio zasilać całego rzędu diod LED, jeśli chcę je wszystkie włączyć.

Więc zamiast bezpośrednio zasilać rząd, 74HC595 będzie zamiast tego sterować tranzystorem dla każdego rzędu, a tranzystor będzie włączał lub wyłączał prąd zasilający rząd. Ponieważ projekt wykorzystuje zwykłe diody LED anodowe, tranzystorem przełączającym będzie PNP. Gdybyśmy używali wspólnej diody LED katodowej, tranzystorem przełączającym byłby NPN. Należy zauważyć, że przy użyciu tranzystora PNP do sterowania rzędem, ustawienie rejestru przesuwnego, aby go włączyć, staje się teraz niskie, ponieważ tranzystor PNP wymaga ujemnego napięcia między emiterem a bazą do włączenia, co pozwoli dodatniemu prądowi na przepływ do wiersz.

Jeszcze jedną rzeczą do rozważenia jest pożądany układ bitów rejestrów przesuwnych. To znaczy wśród rejestrów przesuwnych, które bity kontrolują, które wiersze lub kolumny w macierzy. Projekt, z którym wysłałem, to miejsce, w którym pierwszy bit lub "najbardziej znaczący bit", wysłany do rejestrów przesuwnych połączonych łańcuchowo, kontroluje kolumnę czerwonego elementu diod LED, drugi bit kontroluje zielony element pierwszej kolumny, trzeci bit kontroluje element pierwszej kolumny niebieski element, czwarty bit kontroluje czerwony element drugiej kolumny, … ten wzór jest powtarzany w kolumnach od lewej do prawej. Następnie następny wysłany bit steruje ostatnim lub dolnym wierszem, następny przedostatni wiersz, … to powtarzane aż do ostatniego wysłanego bitu lub „najmniej znaczącego bitu”, kontroluje pierwszy lub górny wiersz w macierzy.

Na koniec musiałem określić, jakich rezystorów użyję dla każdej z diod LED w LED RGB. Chociaż można użyć standardowego wzoru, który łączy napięcie przewodzenia i pożądany prąd, aby obliczyć wymagany rezystor, odkryłem, że ustawienie prądu każdej diody LED na 20 miliamperów skutkowało kolorem złamanej bieli, gdy wszystkie czerwone, zielone i niebieskie diody LED były włączone. Więc zacząłem się temu przyglądać. Za dużo czerwieni w bieli oznaczało zwiększenie rezystancji rezystora czerwonej diody LED w celu zmniejszenia prądu. Powtarzałem wymianę rezystorów o różnych omach, aż znalazłem kombinację, która dawała biały kolor, który uważałem za właściwy. Ostateczna kombinacja wynosiła 180 Ω dla czerwonej diody LED, 220 Ω dla zielonej diody i 100 Ω dla niebieskiej diody LED.

Krok 2: Budowa sprzętu - tablica do krojenia chleba

Budowa sprzętu - tablica do krojenia chleba
Budowa sprzętu - tablica do krojenia chleba
Budowa sprzętu - tablica do krojenia chleba
Budowa sprzętu - tablica do krojenia chleba

Pierwszą fazą konstruktora sprzętu była deska do chleba. Tutaj zrobiłem matrycę 4x4 z diodami RGB. Ta macierz wymagałaby 16 bitów do sterowania, 12 dla kolumn RGB i 4 dla każdego wiersza. Dwa rejestry przesuwne 74HC595 poradzą sobie z tym wszystkim. Najpierw zbadałem i zaprojektowałem obwód, o którym myślałem, że będzie działał, a następnie zbudowałem go na płytce prototypowej.

Prawdopodobnie największym wyzwaniem przy budowie płytki stykowej było zarządzanie wszystkimi przewodami. Wziąłem wstępnie uformowany zestaw do płytek do krojenia chleba, ale wtedy był trochę nieporęczny. Sztuczka, która okazała się pomocna, polegała na stworzeniu „portu” do połączenia z płytą Arduino. Oznacza to, że zamiast podłączać piny Arduino bezpośrednio do różnych pinów IC na płytce prototypowej, przeznacz kilka rzędów na płytce prototypowej jako punkt połączenia Arduino, a następnie podłącz odpowiednie piny ID do tych rzędów. Do tego projektu potrzebujesz tylko pięciu połączeń do Arduino: +5V, masy, danych, zegara i zatrzasku.

Po zakończeniu budowy płytki prototypowej musiałem ją przetestować. Jednak bez jakiegoś sterownika, który wysyłałby odpowiednie sygnały do rejestrów przesuwnych, nie byłem w stanie sprawdzić, czy układ sprzętowy działa.

Krok 3: Projektowanie oprogramowania sterownika

Image
Image

Biorąc pod uwagę moje własne doświadczenie zawodowe związane z tworzeniem oprogramowania, była to część projektu, którą prawdopodobnie najwyraźniej wybrałem. Sprawdziłem wiele innych sterowników matryc LED opartych na Arduino. Chociaż z pewnością dostępne są dobre sterowniki, żaden z nich nie miał takiego projektu, jakiego chciałem. Moje cele projektowe sterownika to:

  • Zapewnij interfejs API wysokiego poziomu, aby móc programowo tworzyć obrazy i animacje. Większość sterowników, które widziałem, była bardziej skoncentrowana na zakodowanych na sztywno obrazach. Ponadto, ponieważ z zawodu jestem programistą C++, chciałem wykorzystać dobry projekt obiektowy do implementacji i zarządzania czynnościami rysowania na matrycy LED.
  • Użyj podwójnego buforowania do zarządzania obrazem na ekranie. Jeden bufor jest tym, do którego program zostaje wciągnięty, podczas gdy drugi reprezentuje stan pikseli matrycy w danym momencie. Zaletą tego podejścia jest to, że nie jest wymagane całkowite renderowanie następnej aktualizacji ramki dla ekranu pomiędzy cyklami aktualizacji multipleksowania.
  • Użyj PWM, aby zezwolić na więcej niż siedem prymitywnych kolorów, które RGB może renderować za pomocą prostych kombinacji elementów czerwonego, zielonego i niebieskiego.
  • Napisz sterownik tak, aby „po prostu działał” z różnymi rozmiarami matryc LED RGB, które były zgodne z moim ogólnym podejściem do projektowania matryc. Zauważ, że podczas gdy mój projekt sprzętu używa rejestrów przesuwnych 74HC595, spodziewałbym się, że mój sterownik będzie działał z dowolnym mechanizmem włączania/wyłączania rejestru przesuwnego, który jest ułożony przy użyciu podobnego układu bitów, jak mój projekt sprzętu. Na przykład spodziewałbym się, że mój sterownik będzie pracował ze sprzętem, który używał chipów DM13A do sterowania kolumnami i chipa 74HC595 do sterowania rzędami.

Jeśli chcesz od razu spojrzeć na kod sterownika, możesz go znaleźć na GitHub tutaj.

Pierwsza iteracja mojego sterownika była lekką krzywą uczenia się możliwości platformy Arduino. Najbardziej oczywistym ograniczeniem jest pamięć RAM, czyli 2K bajtów dla Arduino Uno i Nano. Używanie obiektów C++ w takim scenariuszu często nie jest zalecane ze względu na obciążenie pamięci obiektów. Jednak czułem, że jeśli zostanie to zrobione dobrze, korzyści z obiektów w C++ przewyższają ich koszt (w pamięci RAM).

Drugim poważnym wyzwaniem było zastanowienie się, jak zaimplementować modulację szerokości impulsu za pomocą rejestrów przesuwnych, abym mógł wygenerować więcej niż siedem prymitywnych kolorów LED RGB. Programując przez wiele lat na platformach Linux, byłem przyzwyczajony do używania konstrukcji takich jak wątki do zarządzania procesami, które wymagają spójnego timingu. Czas operacji aktualizacji rejestru przesuwnego jest dość krytyczny przy tworzeniu sterownika dla matrycy LED, która wykorzystuje multipleksowanie. Powodem jest to, że chociaż multipleksowanie odbywa się tak szybko, że twoje oczy nie widzą migających i wyłączających się poszczególnych diod LED, twoje oczy mogą wychwycić różnice w całkowitym łącznym czasie, w którym którakolwiek z diod LED jest włączona. Jeśli jeden rząd diod LED jest stale włączony przez dłuższy czas niż pozostałe, podczas multipleksowania będzie wyglądał jaśniej. Może to prowadzić do nierównomiernej jasności matrycy lub okresowego strobowania matrycy jako całości (ma to miejsce, gdy jeden cykl aktualizacji trwa dłużej niż pozostałe).

Ponieważ potrzebowałem spójnego mechanizmu czasowego, aby spowodować, że aktualizacje rejestru przesuwnego będą zgody, ale Arduino formalnie nie obsługuje wątku, musiałem stworzyć własny mechanizm podobny do wątków. Moją pierwszą iteracją było po prostu utworzenie timera pętli, który zależał od funkcji Arduino loop() i uruchamiałby akcję, gdy upłynie określony czas od ostatniego uruchomienia akcji. Jest to forma „współpracy wielozadaniowej”. Brzmi dobrze, ale w praktyce okazało się to niespójne, gdy szybkość strzelania była mierzona w mikrosekundach. Powodem tego jest to, że gdybym miał uruchomione dwa z tych liczników pętli, jedna z ich akcji często trwała wystarczająco długo, aby druga akcja została uruchomiona później niż było to pożądane.

Odkryłem, że rozwiązaniem tego problemu jest użycie natywnego mechanizmu przerwania zegara Arduino. Ten mechanizm pozwala uruchamiać niewielki fragment kodu w bardzo spójnych odstępach czasu. Tak więc zaprojektowałem kod sterownika wokół elementu projektowego polegającego na użyciu przerwania zegara do wyzwalania kodu do wysłania rejestrów przesuwnych macierzy do następnej aktualizacji w cyklu multipleksowania. Aby to zrobić i umożliwić aktualizowanie obrazu na ekranie, aby nie zakłócało aktywnego zrzutu do rejestrów przesuwnych (coś, co nazwalibyśmy „warunkiem wyścigu”), zastosowałem podejście polegające na posiadaniu podwójnych buforów dla bitów rejestru przesuwnego, jeden do pisania i jeden do czytania. Gdy użytkownik aktualizuje obraz macierzy, te operacje są wykonywane w buforze zapisu. Kiedy te operacje są zakończone, przerwania są tymczasowo zawieszane (oznacza to, że przerwanie zegara nie może zostać uruchomione), a bufor zapisu jest zamieniany na poprzedni bufor odczytu i nie jest to nowy bufor odczytu, a następnie interpretacje są ponownie włączane. Następnie, gdy odpala przerwanie zegara wskazujące, że nadszedł czas, aby wysłać następną konfigurację bitową do rejestrów przesuwnych, informacja ta jest odczytywana z bieżącego bufora odczytu. W ten sposób nigdy nie dochodzi do zapisu do bufora, który może być aktualnie odczytywany podczas przerwania zegara, co mogłoby uszkodzić informacje wysyłane do rejestrów przesuwnych.

Projektowanie reszty sterownika było stosunkowo prostym przypadkiem projektowania zorientowanego obiektowo. Na przykład stworzyłem obiekt do zarządzania obrazem bitowym rejestru przesuwnego dla dowolnego stanu ekranu. Dzięki enkapsulacji kodu odnoszącego się do zarządzania obrazem bitowym, stworzenie wspomnianego wyżej podejścia do podwójnych buforów było samo w sobie prostym ćwiczeniem. Ale nie napisałem tego Instruktażu, aby wychwalać zalety projektowania zorientowanego obiektowo. Inne elementy projektu obejmują koncepcję glifu i obrazu RGB. Glif to podstawowa konstrukcja obrazu, która nie ma wrodzonej informacji o kolorze. Możesz myśleć o tym jako o czarno-białym obrazie. Gdy glif jest rysowany na ekranie LED, podawane są informacje o kolorze, aby wskazać, jak powinny być pokolorowane „białe” piksele. Obraz RGB to obraz, w którym każdy piksel ma swoją własną informację o kolorze.

Zachęcam do przejrzenia przykładowych szkiców Arduino i przejrzenia dokumentacji nagłówka sterownika, aby zapoznać się ze sposobem wykorzystania sterownika do tworzenia obrazów i animacji na matrycy LED RGB.

Krok 4: Upiorne diody LED

Zjawisko LED
Zjawisko LED
Zjawisko LED
Zjawisko LED

W matrycy LED „ghosting” to zjawisko świecenia diody LED w matrycy, gdy nie jest to pożądane, zwykle o bardzo niskim poziomie. Mój oryginalny projekt sprzętu był podatny na efekt ghostingu, zwłaszcza w ostatnim rzędzie. Przyczyną tego są dwie rzeczy: tranzystory nie wyłączają się od razu oraz pasożytnicza pojemność w diodach RGB.

Gdy skanujemy wiersze, ponieważ tranzystory nie wyłączają się natychmiast, poprzedni wiersz w cyklu skanowania jest nadal częściowo zasilany po włączeniu następnego wiersza. Jeśli dana kolumna, która była wyłączona w poprzednim rzędzie, zostanie ponownie włączona, gdy nowy rząd zostanie zasilony, dioda LED tej kolumny w poprzednim rzędzie zaświeci się na chwilę, podczas gdy tranzystor przełączający poprzedniego rzędu nadal się włącza wyłączony. To, co powoduje, że wyłączanie tranzystora zajmuje zauważalną ilość czasu, to nasycenie bazy tranzystora. Powoduje to, że ścieżka kolektor-emiter tranzystora nadal przewodzi, gdy prąd jest usuwany z bazy, przynajmniej do momentu zaniku nasycenia. Biorąc pod uwagę, że nasz cykl aktualizacji multipleksowania powoduje, że rzędy są celowo włączone przez okres czasu mierzony w mikrosekundach, czas, w którym nasycony tranzystor poprzedniego rzędu pozostaje przewodzący, może być zauważalną częścią tego. W rezultacie twoje oko może dostrzec bardzo krótki czas, w którym włączona jest dioda LED poprzedniego rzędu.

Aby rozwiązać problem nasycenia tranzystora, można dodać diodę Schottky'ego do tranzystora między bazą a kolektorem, aby spowodować niewielki prąd wsteczny do bazy, gdy tranzystor jest włączony, zapobiegając nasyceniu tranzystora. To z kolei spowoduje szybsze wyłączenie tranzystora, gdy prąd zostanie usunięty z bazy. Zobacz ten artykuł, aby uzyskać szczegółowe wyjaśnienie tego efektu. Jak widać na rysunku w tej sekcji, bez diody zjawy są dość zauważalne, ale dodanie diody do obwodu dla każdego rzędu znacznie usuwa zjawy.

Diody LED RGB są podatne na inne zjawisko zwane pojemnością pasożytniczą. Podstawową przyczyną tego jest fakt, że każda z trzech kolorowych diod LED w jednostce LED RGB ma różne napięcia przewodzenia. Ta różnica napięć przewodzenia może powodować efekt pojemności elektrycznej pomiędzy poszczególnymi kolorami diod LED. Ponieważ ładunek elektryczny jest gromadzony w jednostce LED podczas zasilania, po odłączeniu zasilania pasożytnicza pojemność musi zostać rozładowana. Jeśli ta kolumna LED jest w inny sposób włączona dla zasilania innego rzędu, pasożytniczy ładunek rozładuje się przez tę diodę LED kolumny i spowoduje jej krótkie zaświecenie. Ten efekt ładnie wyjaśniono w tym artykule. Rozwiązaniem jest dodanie ścieżki rozładowania dla tego pasożytniczego ładunku innego niż przez samą diodę LED, a następnie danie jej czasu na rozładowanie przed ponownym zasileniem kolumny. W moim projekcie sprzętowym osiąga się to poprzez dodanie rezystora do linii zasilającej każdego rzędu, który łączy siłę z uziemieniem. Spowoduje to pobranie większej ilości prądu, gdy rząd jest zasilany, ale zapewnia ścieżkę rozładowania dla pojemności pasożytniczej, gdy rząd nie jest zasilany.

Warto jednak zauważyć, że w praktyce efekt pojemności pasożytniczej jest dla mnie ledwo zauważalny (jeśli się go poszuka, można go znaleźć), dlatego dodanie tego dodatkowego rezystora uważam za opcjonalne. Efekt spowolnienia dla tranzystorów nasyconych jest znacznie silniejszy i zauważalny. Niemniej jednak, jeśli obejrzysz trzy zdjęcia przedstawione w tej sekcji, zobaczysz, że rezystory całkowicie usuwają wszelkie zjawy, które nadal występują poza czasem powolnego wyłączania tranzystora.

Krok 5: Ostateczna produkcja i kolejne kroki

Image
Image

Ostatnią fazą tego projektu było dla mnie stworzenie płytki drukowanej (PCB). Użyłem programu open source Fritzing do zaprojektowania mojej płytki drukowanej. Chociaż było wiele powtarzalnych zadań do wykonania, aby rozmieścić 100 diod LED na tablicy 10x10, ta faza projektu była dla mnie dziwnie satysfakcjonująca. Ustalenie, w jaki sposób zostanie ułożona każda ścieżka elektryczna, było jak układanka, a rozwiązanie tej układanki stworzyło poczucie spełnienia. Ponieważ nie jestem skonfigurowany do produkcji płytek drukowanych, skorzystałem z jednego z wielu zasobów internetowych, które wykonują małe serie niestandardowych płytek drukowanych. Lutowanie części było dość proste, ponieważ mój projekt wykorzystywał wszystkie części z otworami przelotowymi.

W chwili pisania tej instrukcji mam następujące plany dotyczące moich projektów RGB LED Matrix:

  1. Kontynuuj ulepszanie sterownika w warstwie API, aby umożliwić programiście bardziej zaawansowane funkcje, w szczególności przewijanie tekstu.
  2. Twórz większe projekty macierzy, takie jak 16x16 lub nawet 16x32.
  3. Eksploruj użycie tranzystorów MOSFET zamiast BJT do przełączania zasilania w rzędzie
  4. Eksploruj, używając sterowników stałoprądowych DM13A zamiast 74HC595 do przełączania kolumn
  5. Twórz sterowniki dla innych platform mikrokontroli, takich jak Teensy, ODROID C2 lub Raspberry Pi.

Zwróć uwagę, że zarówno projekt sprzętu, jak i sterownik zostały wydane na licencji open source GPL v3 w tym repozytorium GitHub. Co więcej, chociaż producenci PCB wykonują „małe serie” moich projektów PCB, wciąż dostaję znacznie więcej, niż osobiście potrzebuję. Sprzedaję więc pełne zestawy do moich różnych projektów matryc LED RGB (płytka drukowana i wszystkie części w zestawie) z mojej strony internetowej tutaj.

Zalecana: