___________________________________________________________________________________________________________________________________________________________________________
___________________________________________________________________________________________________________________________________________________________________________

04 września 2026

MMDVM z emulatorem wświetlacza NEXTIN.

 

HotSpot podczas uruchamiania systemu (jeszcze bez obudowy).

    Podczas budowy mojego hotspotu MMDVM pojawiła się potrzeba zastosowania większego i bardziej czytelnego wyświetlacza niż typowy 0,96" ekran OLED. Zamiast kupować kolejny gotowy moduł (domyślnie Nextion), postanowiłem zbudować własny emulator wyświetlacza NEXTION, wykorzystujący kolorowy ekran TFT 320 × 240 pikseli oraz mikrokontroler ESP32.

    Urządzenie komunikuje się z hotspotem poprzez interfejs szeregowy dedykowany dla wyświetlacza NEXTION. Z punktu widzenia MMDVM mój emulator zachowuje się więc jak oryginalny wyświetlacz, ale cała grafika jest generowana bezpośrednio przez ESP32.

Złącze wyświetlacza NEXTION na płytce MMDVM DUAL
 

Co pokazuje wyświetlacz?

Podczas odbioru transmisji na ekranie prezentowane są najważniejsze informacje:

  • znak wywoławczy korespondenta,
  • imię operatora,
  • aktywna grupa TalkGroup,
  • poziom odbieranego sygnału RSSI,
  • wskaźnik jakości transmisji BER,
  • aktywny tryb DMR,
  • numer slotu /opcja/,
  • aktualny status RX/IDLE,
  • trzy ostatnio słyszane stacje (w czasie "oczekiwania").

Interfejs został zaprojektowany tak, aby najważniejsze informacje były widoczne z większej odległości. Zrezygnowałem więc z typowego „terminalowego” wyglądu na rzecz prostego, graficznego interfejsu.



Przykładowy ekran podczas normalnej pracy.
 

Wskaźnik poziomu sygnału

Dodatkowo wyświetlacz posiada graficzny wskaźnik poziomu sygnału. Jego wskazania są uzależnione od wartości RSSI otrzymywanej z MMDVM.

Im silniejszy sygnał, tym więcej aktywnych segmentów wskaźnika. Zastosowane zostało również kolorowe oznaczenie poziomu sygnału:

czerwony → żółty → zielony

Dzięki temu nie trzeba nawet odczytywać wartości liczbowej — jednym spojrzeniem można ocenić jakość odbioru.

Wskaźnik BER

Drugim ważnym parametrem jest BER, czyli Bit Error Rate. Na ekranie znajduje się zarówno wartość BER, jak i graficzny pasek.

Przy małym poziomie błędów pasek pozostaje krótki i zielony. Wraz ze wzrostem BER zmienia kolor na żółty, a przy większej liczbie błędów przechodzi w czerwony.

W przypadku cyfrowego DMR jest to bardzo przydatna informacja, ponieważ sam poziom RSSI nie zawsze mówi nam, czy transmisja będzie poprawnie odbierana.

Ekran oczekiwania

Gdy korespondent kończy nadawanie, wyświetlacz przechodzi w ekran oczekiwania na następnego korespondenta.

Gdy nie pojawia się nowy korespondent i grupa zostaje zamknięta znika sygnalizacja oczekiwania a jej miejsce zajmuje zegar.



 Dzięki temu od razu wiadomo, że hotspot pracuje, ale aktualnie nie odbiera żadnej transmisji.

 

Wygaszacz ekranu

Ponieważ wyświetlacz pracuje praktycznie przez cały czas, dodałem również prosty wygaszacz ekranu.

Po 5 minutach braku aktywności ekran zostaje wygaszony. Nie oznacza to oczywiście wyłączenia hotspotu — ESP32 oraz komunikacja z MMDVM nadal pracują. Opcjonalnie można wyłączyć programowo podświetlenie matrycy wyświetlacza. Ta funkcja jest ujęta w programie.

Pojawienie się nowej aktywności automatycznie wybudza ekran i ponownie pokazuje informacje o korespondencie.


 

ESP32 zamiast klasycznego NEXTION

Najciekawszą częścią projektu jest chyba właśnie sposób działania urządzenia.

Oryginalny wyświetlacz NEXTION posiada własny procesor i interpretuje polecenia przesyłane przez MMDVM. Tutaj jego rolę przejmuje ESP32.

ESP32:

  1. odbiera dane z interfejsu szeregowego MMDVM,

  2. analizuje polecenia przeznaczone dla NEXTION,

  3. wyodrębnia z nich informacje o korespondencie,

  4. rozpoznaje TalkGroup, RSSI i BER,

  5. generuje własny interfejs graficzny na ekranie TFT.

Dzięki temu wygląd wyświetlacza można zmieniać programowo bez ingerencji w konfigurację samego hotspotu.

 

Dlaczego właśnie tak?

    Projekt powstał przede wszystkim z ciekawości i chęci wykorzystania tego, co już miałem w warsztacie.

Zamiast ograniczać się do możliwości fabrycznego ekranu NEXTION, można stworzyć własny interfejs dokładnie taki, jaki jest potrzebny.

A ponieważ ESP32 ma znacznie większe możliwości niż klasyczny sterownik prostego wyświetlacza, pozostaje jeszcze sporo miejsca na dalszy rozwój programu.

Na tym etapie najważniejsze jest jednak to, że urządzenie działa stabilnie i spełnia swoją podstawową funkcję.

Reszta? Jak to zwykle w projektach krótkofalarskich bywa — skoro działa, to zawsze można jeszcze coś poprawić. 😉

 

Schemat połączeń (ESP32 <-> ST7789 & MMDVM)

Wyświetlacz ST7789 -> ESP32:

  • CS     -> GPIO 15
  • RST   -> GPIO 4
  • DC     -> GPIO 2
  • MOSI -> GPIO 23
  • SCLK  -> GPIO 18
  • VCC    -> 3.3V
  • GND   -> GND
  • BL       -> GPIO 32   /podświetlenie matrycy –opcja/

 

Połączenie z Pi-Star (UART):

  • RX2 (GPIO 16) ESP32 -> TX z płyty MMDVM / Raspberry Pi (3.3V Logic)

    TX2 (GPIO 17) ESP32 -> RX z płyty MMDVM / Raspberry Pi (3.3V Logic)

    (GND ESP32 -> GND Raspberry Pi / MMDVM  (WAŻNE!

 
  • Zwróćcie uwagę, że do wyświetlacza z tego złącza wysyłane są dane (Rx i Tx) oraz masa i +5V. Tak więc łączymy go z Vin ESP32 i nie potrzebujemy dodatkowego (osobnego) zasilania do modułu wyświetlacza.

    Należy też pamiętać, że zasilając wyświetlacz przez gniazdo USB modułu ESP32 zasilamy też moduł MMDV i Raspberry Pi. Tak więc zasilanie z gniazda Raspberry należy wcześniej wyłączyć.

     

Konfiguracja w programie Pi-Star

Aby emulator działał poprawnie, w panelu Pi-Star Configuration należy zmienić ustawienia w sekcji MMDVM Display Driver:

  • MMDVM Display Type: Nextion

  • Port: Modem (lub /dev/ttyAMA0 w zależności od połączenia)

  • Nextion Layout: G4KLX


     

✅ Podsumowanie

Mój emulator NEXTION jest więc niewielkim, samodzielnym terminalem informacyjnym dla hotspotu MMDVM.

ESP32 + TFT 320 × 240 + interfejs NEXTION/MMDVM pozwalają uzyskać czytelny, kolorowy ekran prezentujący najważniejsze informacje o aktualnej pracy hotspotu.

Projekt pokazuje również, że nie zawsze trzeba korzystać z gotowych rozwiązań. Czasami wystarczy mikrokontroler, wyświetlacz i trochę wolnego czasu, aby zrobić urządzenie dokładnie dopasowane do własnych potrzeb.

 

  

⚠️   Jeszcze jeden "drobiazg" na który proponuję zwrócić uwagę: Fabryczne "anteny" które były dołączone do MMDVM. Rezonans na częstotliwości 424 MHz. Może tylko mi się takie trafiły? :) Co prawda nadajnik ma około 15 mW ale tak być nie powinno. Proponuję sprawdzić co otrzymaliście w zestawie.



 

📜   Jeśli zainteresował Cię ten projekt i chciałbyś do niego program - napisz.    Z pewnością Ci go wyślę.

 

EDIT 05.07.2026 r. 

 W nowej wersji oprogramowania dodałem prosty interfejs WWW. Teraz można oglądać pracę HotSpota na ekranie komputera, laptopa lub tabletu. Jest to prosty interfejs ale możliwy do rozbudowania. Na tą chwilę tyle wystarcza. Tak to wygląda na ekranie komputera:




 
 
 
A tak teraz wygląda nowy ekran emulatora:
 


 

✍️ Autor: Robert HF5WWL
📅 Data projektu: sierpień 2026 r.
 📍 Lokalizacja: Wołomin, POLSKA
📁 Coś nie jasne? Pytaj poprzez e-mail (hf5wwl@gmail.com) lub w komentarzu 
🛠️ Poziom trudności: Łatwy  (jak się ma oprogramowanie) 
😊

 

 

 #DIY #DoItYourself #HAMRadio #HamTech #ESP32 #MMDVM #DMR #RadioAmatorskie #Krótkofalarstwo #Homebrew #Electronics #Maker #TechProject #DigitalRadio #DMRMonitor

 


03 września 2026

Tester rozdzielczości i offsetów wyświetlaczy z rodziny ST77xx

 


Odbicie "lustrzane".
Prawidłowy obraz w pozytywie.



 

 

 

 

 

 

 

Wstęp

    Kiedy kupujemy wyświetlacz TFT z rodziny ST77xx (ST7789, ST7735, ST7796 itp.) — zwłaszcza na portalach aukcyjnych, bez dokładnej dokumentacji — często nie wiemy, jaką ma prawdziwą rozdzielczość ani jakie są jego offsety (colstart / rowstart). Biblioteki Adafruit domyślnie zakładają konkretne wartości, a gdy się pomylimy, efekt jest natychmiastowy:

  • obraz jest przesunięty, ucięty na krawędzi,

  • widać „duchy" pikseli poza obszarem rysowania,

  • tekst jest lustrzany lub do góry nogami,

  • kolory są odwrócone (negatyw),

  • podświetlenie nie działa.


    Błąd przesunięcia H.
        
    Błąd przesunięcia H i V.

     

     

     

     

 

 

 

 

    Zamiast metodą prób i błędów modyfikować docelowy projekt — można użyć dedykowanego testera. Poniżej opisuję program, który napisałem na ESP32 z myślą o szybkiej kalibracji dowolnego panelu z rodziny ST77xx.


 

Co potrafi tester

    Program obsługuje się wyłącznie z Serial Monitora (115200 baud, Newline) — nie trzeba podłączać żadnych przycisków, enkoderów ani potencjometrów. Po wgraniu na ESP32 i podłączeniu wyświetlacza wystarczy otworzyć Serial Monitor i wydawać komendy.

Wzorzec testowy

Na ekranie rysowany jest czytelny wzorzec referencyjny:

  • Biała ramka dokładnie na krawędziach zadeklarowanego obszaru W × H — od razu widać, czy rozdzielczość jest poprawna.

  • Siatka co 20 px (ciemnoszara) — ułatwia ocenę przesunięcia.

  • Dwie przekątne (cyjan) — przecinają się w geometrycznym środku.

  • 4 kolorowe znaczniki w rogach:

    • czerwony — lewy-górny,

    • zielony — prawy-górny,

    • niebieski — lewy-dolny,

    • żółty — prawy-dolny.

    Dzięki nim od razu widać orientację i ewentualne lustro. Czerwony znacznik zawsze musi trafić w lewy-górny róg czytelnego obrazu.

  • Na środku ekranu wyświetlane są: aktualne W × H, colstart/rowstart, rotacja oraz status INV / MX / MY.

Gotowe profile

Program zawiera kilkanaście wpisanych profili najpopularniejszych paneli — m.in.:

ProfilRozdzielczośćUwagi
ST7789 240×2401.3" / 1.54"klasyk prosto z AliExpress
ST7789 240×3202.0" / 2.4"najczęstszy „2.4 cala"
ST7789 135×2401.14"mały IPS
ST7789 170×3201.9"
ST7789 172×3201.47"
ST7789 240×2801.69"
ST7789 240×2961.72"
ST7789P3 76×282pasekaktywny LOW, rotacja 1
ST7735 128×1601.8"
ST7735 128×1280.96" / 1.44"
ST7735 80×1600.96" mini
ST7796 320×4803.5"

Plus osobny profil „MANUAL / nieznany" — do kalibracji od zera.

Sterowanie z Serial Monitora

n / p    - następny / poprzedni gotowy profil
w / W    - width -1 / +1
h / H    - height -1 / +1
x / X    - colstart -1 / +1
y / Y    - rowstart -1 / +1
r        - rotacja 0 -> 1 -> 2 -> 3 -> 0
v        - przełącz negatyw / pozytyw
m        - lustro w poziomie (bit MX w MADCTL)
M        - lustro w pionie   (bit MY w MADCTL)
f        - cykl przez 4 kombinacje MX/MY (naprawa lustrzanego obrazu)
c        - wyczyść CAŁY obszar GRAM (480×480)
B        - przełącz polaryzację podświetlenia (HIGH/LOW)
i        - wymuś ponowną inicjalizację i przerysowanie
s        - zapisz konfigurację do NVS i wypisz gotowy kod
l        - lista wbudowanych profili z numerami
g<nr>    - skocz bezpośrednio do profilu o numerze <nr>, np. "g3"
a        - włącz / wyłącz auto-cykl (zmiana profilu co 8 s)
b        - mignij podświetleniem (test przewodu BL)
?        - pomoc

Po zmianie dowolnego parametru ekran jest natychmiast czyszczony i rysowany od nowa — efekt widoczny od razu, bez restartu ESP32.

Zapis i eksport gotowego kodu

Komenda s zapisuje aktualną konfigurację do NVS (pamięci nieulotnej ESP32) — po restarcie program startuje z tymi samymi ustawieniami. Co ważniejsze, na Serial wypisuje gotowy kod do wklejenia w docelowym projekcie:

cpp
class ST77xxDisplay : public Adafruit_ST7789 {
public:
  ST77xxDisplay(int8_t cs, int8_t dc, int8_t rst) : Adafruit_ST7789(cs, dc, rst) {}
  void setOffsets(int8_t col, int8_t row) { setColRowStart(col, row); }
};
ST77xxDisplay tft(TFT_CS, TFT_DC, TFT_RST);

pinMode(TFT_BL, OUTPUT);
digitalWrite(TFT_BL, HIGH);  // podświetlenie aktywne HIGH
tft.init(240, 320);
tft.setOffsets(0, 0);
tft.setRotation(0);
tft.invertDisplay(false);
{ uint8_t m = 0xC0; tft.sendCommand(0x36, &m, 1); }  // rot=0 MX=0 MY=0

Wklejasz, kompilujesz, działa.


Ostatnia poprawka do starej wersji: pełne czyszczenie GRAM

Problem

    Podczas kalibracji zmienia się rozdzielczość, offsety, rotację i inwersję dziesiątki razy. Standardowa funkcja fillScreen() czyści tylko obszar bieżącego W × H — więc jeśli wcześniej testowałeś panel 320×480, a teraz przeskakujesz na 135×240, to poza nowym oknem adresowym zostają śmieci z poprzedniego profilu. Utrudnia to ocenę, czy np. colstart jest już ustawiony dobrze, bo widać „duchy" pikseli w miejscach, których nowy obraz nie zdołał zamalować.

Dodatkowo okazuje się, że Adafruit_ST7789::setAddrWindow() automatycznie dodaje offsety colstart / rowstart do podanych współrzędnych. Więc próba wyczyszczenia ekranu przez setAddrWindow(0, 0, 480, 480) przy profilu z colstart = 80 adresuje w rzeczywistości 80..559 × 80..559 — sterownik zawija licznik GRAM, część ekranu pozostaje nietknięta, a inne piksele są zapisywane wielokrotnie.

Rozwiązanie

W wersji v1.6 funkcja clearScreen() wysyła surowe komendy CASET / RASET / RAMWR bezpośrednio przez sendCommand(), z pełnym zakresem 0..479 i bez offsetów:

cpp
void clearScreen() {
  uint8_t caset[4] = { 0x00, 0x00, (uint8_t)((CLEAR_MAX_W - 1) >> 8), (uint8_t)((CLEAR_MAX_W - 1) & 0xFF) };
  uint8_t raset[4] = { 0x00, 0x00, (uint8_t)((CLEAR_MAX_H - 1) >> 8), (uint8_t)((CLEAR_MAX_H - 1) & 0xFF) };

  tft.sendCommand(ST77XX_CASET, caset, 4);
  tft.sendCommand(ST77XX_RASET, raset, 4);
  tft.sendCommand(ST77XX_RAMWR, (const uint8_t *)NULL, 0);

  tft.startWrite();
  tft.writeColor(ST77XX_BLACK, (uint32_t)CLEAR_MAX_W * CLEAR_MAX_H);
  tft.endWrite();
}

Ta funkcja jest wywoływana automatycznie w applyProfile(), przed narysowaniem wzorca. Efekt: po każdej zmianie profilu / rozdzielczości / offsetów / rotacji / inwersji / lustra ekran jest w 100% czysty — żadnych „duchów" po poprzednich próbach.


Jak używać — krok po kroku

  1. Podłącz wyświetlacz zgodnie z pinami zdefiniowanymi na górze pliku (TFT_CS=15, TFT_DC=2, TFT_RST=4, TFT_MOSI=23, TFT_SCLK=18, TFT_BL=32).

  2. Wgraj program na ESP32 (Arduino IDE, płytka ESP32 Dev Module).

  3. Otwórz Serial Monitor — 115200 baud, Newline.

  4. Wpisz l, żeby zobaczyć listę profili.

  5. Wybierz profil komendą g<nr> — np. g1 dla ST7789 240×320.

  6. Dostrajaj: w/W, h/H, x/X, y/Y — aż biała ramka pokryje się z krawędziami ekranu, a czerwony znacznik będzie w lewym-górnym rogu czytelnego obrazu.

  7. Jeśli obraz jest lustrzany — wciskaj f, aż tekst będzie czytelny.

  8. Jeśli kolory są odwrócone — wciśnij v.

  9. Jeśli podświetlenie nie działa — wciśnij B i/lub b.

  10. Wpisz s — konfiguracja trafia do NVS i na Serial wypisuje się gotowy kod do wklejenia w projekcie docelowym.

Kalibruj w rotacji 0 (pionowej) — dopiero po ustaleniu offsetów i rozdzielczości przechodź na inne rotacje.


Pod maską — ciekawe rozwiązania

  • ST77xxTester jako podklasa Adafruit_ST7789 — setColRowStart() bywa oznaczone jako protected w niektórych wersjach biblioteki. Utworzenie podklasy z publicznym wrapperem setOffsets(col, row) obchodzi ten problem czysto, bez modyfikowania biblioteki.

  • Ręczne wysyłanie MADCTL po setRotation() — init() resetuje rejestr MADCTL, więc ustawienia lustra trzeba nakładać po każdej inicjalizacji. Program robi to w applyMADCTL().

  • Obszar czyszczenia 480×480 — pokrywa wszystkie panele z listy profili (w tym ST7796 320×480). Nadmiarowe adresy po prostu zawijają licznik GRAM, a ponieważ piszemy wszędzie czarny — efekt jest dokładnie taki, jak trzeba.

  • Rzutowanie (const uint8_t *)NULL — bez tego kompilator nie wie, które przeciążenie sendCommand wybrać (z uint8_t* czy const uint8_t*), bo NULL pasuje do obu.


Wnioski

    Tester skrócił mi czas kalibracji nowego panelu z nawet godzin (metodą prób i błędów w docelowym projekcie) do kilku minut w dedykowanym narzędziu. Kluczowe okazały się:

  1. Natychmiastowa reakcja na każdą zmianę — czysty ekran i świeżo narysowany wzorzec po każdym naciśnięciu klawisza.

  2. Czytelny wzorzec — kolorowe znaczniki w rogach od razu pokazują orientację i ewentualne lustro.

  3. Eksport gotowego kodu — komenda s eliminuje przepisywanie parametrów do projektu ręcznie.

  4. Pełne czyszczenie GRAM — bez tego połowa czasu kalibracji schodzi na odróżnianie śmieci od rzeczywistych artefaktów nowego ustawienia.

Program jest dostępny na licencji otwartej — wystarczy wkleić do Arduino IDE, wgrać na ESP32 i cieszyć się szybką kalibracją kolejnych egzotycznych paneli z rodziny ST77xx. Miło by było gdybyś pamiętał o jego autorze i włożonej przez niego pracy 😊.


 

Na koniec kilka fotek z kalibrowania:

Źle dobrana rozdzielczość i rotacja.

Źle dobrana rozdzielczość. Rotacja OK.

 

 

 

 

 

 

 

 

Jeszcze zła rozdzielczość i rotacja.


Poprawna rozdzielczość, zła rotacja.

 

 

 

 

 

 

 

Poprawna rozdzielczość i rotacja.

 

 

Po włączeniu negacji widać 

przesunięcie krawędzi.


 

 

 

 

 

 

 

Teraz jest poprawnie. Tak można zapisać -> [s].


 

 

  

 

 

 

 

 

 

 

 Przepraszam za jakość zdjęć ale tak mój telefon widzi ekran wyświetlacza.

 

 Miłego kalibrowania!



✍️ Autor: Robert HF5WWL
📅 Data projektu: wrzesień 2026 r.
 📍 Lokalizacja: Wołomin, POLSKA
📁 Coś nie jasne? Pytaj poprzez e-mail (hf5wwl@gmail.com) lub w komentarzu 
🛠️ Poziom trudności: Łatwy  (jak się wie co się robi) 
😊

📜 Program jest dostępny za darmo /aktualna wersja/. Wystarczy poprosić via e-mail.

 

.