
Witajcie moi drodzy
Przedstawię tutaj mój projekt zewnętrznego wyświetlacza temperatury procesora z komputera. Wyświetlacz pokazuje temperatury od 0 do 99C, jednocześnie odpowiednio dobierając swój kolor. Wyświetlacz zrobiony jest samodzielnie od 0 w oparciu o diody WS2812B, sterowany jest poprzez PIC18F67J60, a temperatury odbiera z komputera z systemem Windows poprzez Ethernet, a dokładniej HTTP. Wyświetlacz zasila się poprzez kabel USB z dowolnej ładowarki od telefonu. Projekt jest oparty przede wszystkim o druk 3D (obudowa, sam wyświetlacz) oraz moje własne, przygotowane wcześniej moduły.
Wstęp
Projekt złożyłem od 0 z samodzielnie przygotowanych wcześniej modułów (mój DIY wyświetlacz 7 segmentowy i moja płytka pod PIC18F67J60 obsługująca komunikacją Ethernet.
Firmware na PICa napisałem w Mikro C PRO for PIC, program na Windowsa (odczyt temperatury) w Visual Studio, C#.
Projekt obejmował:
- implementację obsługi wyświetlacza opartego na WS2812B dla PIC18F67J60
- implementację kontroli tego wyświetlacza poprzez HTTP na PIC18F67J60 (kontrola wyświetlanych znaków, 0-9 i abcdef, oraz kontrola koloru reprezentowanego poprzez wartość hue)
- projekt 3D i wydruk obudowy na termometr (zaprojektowana w Blenderze, wydrukowana białym filamentem PLA na drukarce 3D Ender 3 Pro)
- aplikację napisanę w C# na Windowsa która odczyta temperaturę procesora z wbudowanego sensora i wyśle ją po HTTP do PICa
Użyty wyświetlacz 7-segmentowy bazujący na WS2812B
W projekcie użyłem samodzielnie zrobionego dużego, kolorowego wyświetlacza opartego na WS2812B.
Opisany jest on szczegółowo tutaj:
https://www.elektroda.pl/rtvforum/topic3728082.html
Ale w dużym skrócie to, projekt płytki:

Lutowanie płytki wyświetlacza:

Plastikowa ramka - projekt w Blenderze:

Wydruk 3D (filament PLA na Ender 3 Pro):

Finalizacja:

Użyta płytka komunikacji Ethernet oparta na PIC18F67J60
Do projektu użyłem swojej płytki komunikacji Ethernet opartej o PIC18F67J60 który sam (bez zewnętrznych układów typu ENC28J600) wspiera komunikację Ethernet.
Projekt:

Wykonanie:

Na pokładzie jest PIC18F67J60 który obsługuje bezpośrednio komunikację Ethernetową. Obok niego jest złącze Magjack JXD0-0006NL. Dodatkowo jest tylko jeszcze stabilizator LDO TC1264 (zapewnia stabilne 3.3V z 5V z USB). Na płytce są jeszcze miejsca na pamięci 24AA256, ale nie są używane. No i rezonator kwarcowy 25MHz, dla PICa.
Obsługa mojego wyświetlacza WS2812B dla PIC18F67J60
Sam protokół sterowania WS2812B implementowałem jakiś czas temu dla PIC18F45K50:
https://www.elektroda.pl/rtvforum/topic3590731.html
Na szczęście nie było problemu z przeportowaniem tego na PIC18F67J60. Jednak obsługa protokołu WS2812B to tylko połowa sukcesu, trzeba jeszcze zamienić znaki na odpowiednie segmenty, tzn. PIC musi wiedzieć co wyświetla.
Chciałem to co można wyświetlać wygodnie na wyświetlaczu 7-segmentowym, czyli cyfry i litery abcdef.
W tym celu przygotowałem tablicę masek dla kolejnych kodów znaku (poszczególne bity każdej liczby określają czy dany segment jest zapalony):
Code: c
Następnym etapem była funkcja wyświetlająca dany znak na danej pozycji wyświetlacza. W jej nazwie zostało 'digit', choć wyświetla ona też wspierane litery.
Code: c
W powyższej funkcji mnożę pozycję cyfry razy 7, bo każda cyfra ma 7 segmentów. Potem kolejno badam kolejne bity wartości maski danej cyfry i sprawdzam który z 7 segmentów trzeba zapalić.
Potem zostało zrobić funkcję wyświetlającą cały ciąg znaków. Zakładam w niej, że przekazywana tablica zawiera 3 znaki.
Code: c
Do tego celu też potrzebowałem funkcji pomocniczej gdyż w ASCII niestety 'A' nie jest tuż po '9'. Funkcja poniżej zamienia kod ASCII znaku na indeks tablicy przedstawionej wcześniej:
Code: c
Firmware na PIC18F67J60 (komunikacja przez HTTP/TCP)
Program na PICa napisałem w Mikro C PRO for PIC i bazowałem go na HTTP Demo z przykładów kompilatora.
Program obsługuje prostą stronę internetową, która pośrednio bierze udział w sterowaniu wyświetlaczem.
Na stronie wyświetlany jest bieżący tekst w takim kolorze w jakim jest na wyświetlaczu:

Na stronie są też dostępne różne linki służące do testowania wyświetlacza. Część z tych linków po prostu ustawia wybrany kolor, część ustawia dany tekst, a część uruchamia testowe animacje WS2812B.
Tu macie wgląd w kod HTML strony (on jest częściowo generowany przez PICa):
Code: html
Zasadniczo to do sterowania wyświetlaczem używane są trzy rodzaje pakietów, oba oparte na HTTP GET.
- pakiet ustawienia koloru - 192.168.0.129/c/[R]/[G]/[ B ] - ustawia kolor o danym RGB
- pakiet ustawienia koloru - 192.168.0.129/h/[KOD_HUE] - ustawia kolor o danym hue (barwie)
- pakiet ustawienia tekstu - 192.168.0.129/v/[TEKST] - wyświetla dany tekst na wyświetlaczu
Takie pakiety można wysyłać z dowolnego źródła, też automatycznie z aplikacji na Windowsie. To właśnie robię, szczegóły w kolejnym akapicie.
Od strony PICa parsing pakietów wygląda bardzo prosto. Na przykład dla funkcji ustawiającej kolor:
Code: c
Funkcja parseInt bierze jako argumentów wskaźnik do wskaźnika na tekst i wczytuje z niego jedną liczbę, jednocześnie przesuwając wskaźnik (liczby oddzielone są ukośnikami):
Code: c
Software po stronie komputera (na Windowsa)
Software po stronie komputera ma za zadanie odczytanie temperatury procesora (jego obudowy, lub średniej z rdzeniów, dowolnie) i wysłanie jej poprzez TCP/HTTP do PICa.
Częstotliwość wysyłania temperatury można ustawić w kodzie, w tym momencie wysyłam ją co sekundę.
Do napisania tego programu użyłem Visual Studio i języka C#.
Niestety okazało się, że z odczytem temperatury procesora jest nieco problemów.
W sieci krąży na przykład taki fragment kodu:
Code: c
Niestety u mnie on nie działał, a próbowałem nawet w trybie Administratora. Ostatecznie rozwiązaniem dla mnie okazała się biblioteka OpenHardwareMonitor którą zainstalowałem poprzez NuGet Packages:

Jednak trzeba mieć na uwadze, że ona też nie wspiera wszystkich procesorów, więc ze wszystkim jest więcej kłopotów niż myślałem.
W załączonym kodzie (do pobrania) zaimplementowane jest więc kilka metod, zmienia się je #ifdef'em.
Do samego wysyłania temperatury używam klasy WebRequest.
Pierwsza wersja obudowy
Pierwszą wersję obudowy zaprojektowałem tak by była jak najmniejsza.
Nie miałem wtedy jeszcze całego konceptu wyświetlacza w głowie.
Płytkę z PIC dałem równolegle do wyświetlacza.
Model 3D (przód):

Widoczny gwint na śrubkę przedniego elementu:

Spód (dodatkowo jest tu miejsce na przykręcenie śrubkami złacza microUSB od zasilania):

Po wydrukowaniu i złożeniu, w trakcie programowania (PICKIT2 bezpośrednio podłączony do płytki z PIC):

Finalne składanie pierwszej wersji:


Pierwszy test przez Ethernet:



Jednak ta obudowa mi nie odpowiadała i zrobiłem potem ją od 0, inaczej.
Finalna wersja obudowy
Finalną wersję obudowy wykonałem zgodnie z tym co przedstawiłem w moim tutorialu modelowania obudowy w Blenderze:
https://www.elektroda.pl/rtvforum/topic3735510.html
Tylko odpowiednio zmodyfikowałem wymiary i dodałem otwory montażowe.



Wydruk podstawy:



Panel tylni:

Przedni panel:

Mocowanie wyświetlacza w przednim panelu za pomocą dodatkowych 'bloczków' wydrukowanych w 3D i śrubek:


Zamocowane:

Dodatkowo wyprowadzone złącze na ICSP w tylnym panelu (pasuje na ścisk):


W trakcie montażu:

Złącza z tyłu (potem przy pierwszym pinie ICSP zrobiłem kropkę markerem):

Podłączony już do zasilacza 5V z telefonu (złącze microUSB) i sieci Ethernet:

Całość złożona:

Filmik - testy wyświetlacza poprzez stronę internetową
Tutaj udało mi się wziąć w jeden kadr ekran monitora i gotowy wyświetlacz w obudowie. Na filmiku widać jak klikanie w kolejne linki na testowej stronie internetowej powoduje reakcje wyświetlacza, czyli taki ogólny test funkcjonalności.
Na stronie internetowej wyświetlany jest też bieżący napis z wyświetlacza wraz z odpowiednim kolorem.
Filmik - test kolorów/gradientu z poziomu Windowsa i C#
Kolor wyświetlacza zależy od temperatury jaka jest pokazywana. Im większa temperatura, tym cieplejszy kolor.
Kolor jest liczony po stronie aplikacji na Windowsa. Komputer wysyła do PICa dwa pakiety: jeden z tekstem do wyświetlenia, drugi określający jego kolor (jako liczbowa wartość hue).
Kod obliczania gradientu i wysyłania go wraz z kolorem:
Code: c
Dodatkowo zrobiłem funkcję służącą do przedstawiania działania gradientu, która nie odczytuje temperatury z procesora, tylko kolejno wyświetla dostępne wartości:
Code: c
Rezultat na filmie:
Wyświetlanie temperatury w normalnym trybie działa analogicznie, po prostu wtedy temperatura odzwierciedla temperaturę procesora na komputerze.
Pomiar prądu
Wyświetlacz zasilam z ładowarki 5V od starego telefonu. Podłączony do niej jest przez przedłużacz USB, bo stoi na szafce. W celu pomiaru prądu wpiąłem USB Doctor między przedłużacz a kabel microUSB:


(w trakcie pomiaru PIC ciągle odbierał nowe pakiety, wysyłane były kilka razy na sekundę)
Napięcie zasilania wynosi około 4.5V, a prąd zmienia się w zależności od tego co jest wyświetlane od około 0.15A do 0.2A. Czyli wyświetlacz pobiera około 1W.
Co można by zrobić lepiej
Projekt doprowadziłem do zadowalającego dla mnie stanu ale oczywiście dużo można by ulepszyć. Między innymi:
- można by nieco zmniejszyć wysokość panelu przedniego i tylnego ponieważ na skutek drobnych niedokładności wydruku górna i dolna połowa obudowy nie przylegają do siebie idealnie na ścisk (ale jest to wręcz niezauważalne)
- w kodzie C na PIC można by ulepszyć kilka rzeczy by było bardziej eleganckie, można by też poprawić kilka ryzykownych fragmentów kodu (można wywołać w pewnym miejscu przepełnienie bufora), ale jako, że jest to tylko wyświetlacz temperatury to tego nie robiłem
- na ten moment firmware PICa nie obsługuje sytuacji w której po prostu wyłączę komputer kontrolujący wyświetlacz, wtedy po prostu wyświetlacz cały czas pokazuje ostatnią zapamietaną temperaturę. W przyszłości być może dodam jakiś prosty timeout, że wyświetlacz gaśnie, jak nie otrzyma żadnych pakietów w ciągu np. 15 minut (to nie problem, wystarczy zliczać np. sekundy timerem i dodać ifa, że gdy ilość sekund bez pakietów przekroczy N to wtedy ... )
- można by nieco zmienić sposób wyświetlania temperatury, np. wyświetlać maksymalną wartość temperatur z rdzeniów procesora, a nie ich średnią...
Załączniki
Poniżej umieszczam do pobrania wszystkie pliki powiązane z projektem, zarówno projekt PCB jak i kody.
Nazwa | Format | Link |
Projekt PCB z PIC18F67J60 | Eagle .sch/.brd | |
Projekt PCB wyświetlacza 7seg | Eagle .sch/.brd | |
Firmware PIC18F67J60 | Projekt Mikro C, kody .c | |
Aplikacja na komputer | Projekt Visual Studio, kody .cs | |
Model obudowy (finalny) | Format Blendera (.blend) | |
Model obudowy (finalny) | Wyeksportowane STLe (.stl) | |
Model samego wyświetlacza (plastikowa nakładka na jego PCB) | Format Blendera (.blend) | |
Model obudowy (stary) | Format Blendera (.blend) |
Podsumowanie
Z mojego wyświetlacza jestem bardzo zadowolony. O dziwo okazał się on być bardziej praktyczny niż robienie kolejnego zegarka (choć zegarek też mam w planach).
Ustawiłem go na półce, dość daleko za komputerem, ale akurat mam tak ustawione meble, że mam go ciągle w polu widzenia i widzę jaka jest temperatura, zastępuje mi on zerkanie na temperatury na pasku zadań, zwłaszcza gdy włączone jest coś na pełny ekran.
Jeśli chodzi o "wystawanie" modułów samych wyświetlaczy, to jest to zgodne z moim projektem i zamysłem artystycznym na obudowę. Ale oczywiście można by przedłużyć obudowę o kilka mm lub więcej, schować wyświetlacze i dać nawet przed nimi nawet dociętą na wymiar szybkę.
Projekt ten pokazuje też jak bardzo dużo może wnieść do elektroniki druk 3D, bez niego byłoby trudniej wykonać obudowę na wymiar i sam wyświetlacz.