___________________________________________________________________________________________________________________________________________________________________________
___________________________________________________________________________________________________________________________________________________________________________

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.

 

. 


31 lipca 2026

DMR Monitor na ESP32

 

 Prototyp monitora DMR na płytce uniwersalnej.

 

Po co powstał ten projekt?

Jeśli działasz w cyfrowym radiu DMR i chcesz mieć stały podgląd aktywności na wybranym kanale (TalkGroup) bez potrzeby odpalania komputera, ten projekt jest dla Ciebie.

Zbudowałem przenośny monitor DMR oparty o ESP32, który łączy się przez WiFi z siecią BrandMeister, wyświetla na kolorowym ekranie TFT 4″ aktualnie nadającego operatora, historię ostatnich transmisji, czas trwania nadawania i zapisuje logi na kartę SD. Wszystko w jednym, kompaktowym urządzeniu.


Co dokładnie robi ten program?

Program działa w pętli, nasłuchując na WebSocketach danych z BrandMeister i reagując na pojawiający się ruch w TalkGroup 260. Oto jego główne funkcjonalności:

📡 Łączność z BrandMeister przez WebSocket

  • Nawiązuje bezpieczne połączenie (SSL) z API BrandMeister.

  • Subskrybuje wszystkie zdarzenia (join everything).

  • Automatycznie wznawia połączenie w razie przerwania.

👤 Wyświetlanie aktywnego operatora

  • Pokazuje znak wywoławczy (np. SP5XYZ).

  • Wyświetla imię operatora lub alias TalkerAlias.

  • Podaje ID operatora oraz numer TalkGroup.

  • Mierzy i wyświetla czas trwania bieżącej transmisji (format MM:SS).

📜 Historia ostatnich operatorów

  • Przechowuje w pamięci ostatnich 4 operatorów (maksymalnie).

  • Wyświetla ich znak, nazwę, TG oraz godzinę transmisji.

  • Unika duplikowania tego samego operatora z rzędu – jeśli ten sam wraca, aktualizuje tylko znacznik czasu.

💾 Logowanie do pliku CSV na karcie SD

  • Każda zakończona transmisja jest zapisywana w pliku /dmr_log.csv na karcie SD.

  • Log zawiera: datę i godzinę rozpoczęcia, datę i godzinę zakończenia, znak, nazwę, ID, TG oraz czas trwania w sekundach.

  • Automatycznie tworzy nagłówek pliku, jeśli nie istnieje.

    Zapisane dane możemy odczytać w programie który czyta pliki *.csv.

     

    Przykładowe dane zapisane na karcie SD: 



🎨 Przyjazny interfejs użytkownika

  • Wyświetlacz TFT 4″ (480×320 px) z płynną obsługą graficzną.

  • Ikona radia zmienia kolor w zależności od stanu RX.

  • Wizualizacja trwania transmisji za pomocą animowanego paska (fale radiowe).

  • Zegar NTP (synchronizacja czasu z Internetu) w prawym górnym rogu.

  • Status połączenia z BrandMeister – zielone/czerwone kółko.

🔧 Konfiguracja z karty SD

  • Dane WiFi (SSID i hasło) są odczytywane z pliku config.txt na karcie SD – nie musisz ich hardkodować w programie. W ten sposób nie musisz ingerować w program by zalogować się do swojej sieci WiFi. Wystarczy zmienić dane na karcie SD.

  • Format pliku:

    SSID=moja_siec
    PASS=moje_haslo
    dane te zapisujemy na karcie SD w pliku o nazwie config.txt 

Co znajduje się w środku? – zaglądamy do kodu

Kod ma około 1800 linii i jest podzielony na logiczne sekcje. Oto najważniejsze fragmenty:

🔹 Komunikacja z BrandMeister

Sercem programu jest obsługa WebSocket. Funkcja webSocketEvent() odbiera dane JSON, które przychodzą w dwóch zagnieżdżonych warstwach – najpierw wyciąga właściwy payload, potem deserializuje go i sprawdza, czy DestinationID pasuje do monitorowanego TG (260). Jeśli tak – wywołuje nowaAktywnosc().

cpp
if (destinationID != MONITORED_TG) {
  break;
}

 

🔹 Logika końca transmisji

Funkcja sprawdzKoniecRX() sprawdza, czy od ostatniego odebranego pakietu minęło więcej niż 2500 ms. Jeśli tak – uznaje transmisję za zakończoną, zapisuje log na SD i przełącza ekran w stan czuwania.

🔹 Efektowny interfejs

Użyłem bibliotek Adafruit GFX i ST7796S do obsługi wyświetlacza. Funkcja rysujIkoneRadia() rysuje ikonę, która świeci na zielono podczas odbioru, a na ciemnoszaro w stanie czuwania. Animacja RX (animacjaRX()) to paski imitujące fale radiowe – odświeżane co 150 ms.

🔹 Historia i logika deduplikacji

dodajDoHistorii() przesuwa starsze wpisy w dół i wstawia nowego operatora na pierwszą pozycję. Co ważne – jeśli ten sam operator pojawia się ponownie, nie jest dodawany drugi raz, a jedynie aktualizowany jest jego znacznik czasu.


Jak uruchomić ten projekt na swoim ESP32?

Potrzebne elementy

  • ESP32 (np. Wemos D1 R32, NodeMCU-32S) Ja zrobiłem to na ESP32 WROOM-32U.

  • Wyświetlacz TFT z kontrolerem ST7796S (lub kompatybilny, 4″ 480×320 px SPI)

  • Karta microSD (do zapisu logów i konfiguracji)

  • Kabel USB, zasilanie 5V

    Nie zamieszczam schematu bo na podstawie definicji pinów można to zrobić bez problemu. 

     

Konfiguracja

  1. Sformatuj kartę SD jako FAT32.

  2. W katalogu głównym karty utwórz plik config.txt o zawartości:

    text
    SSID=TwojaNazwaWiFi
    PASS=TwojeHasloWiFi
  3. Zainstaluj wymagane biblioteki w Arduino IDE lub PlatformIO:

    • WiFi.h

    • WebSocketsClient.h

    • ArduinoJson.h (wersja 6.x)

    • Adafruit_GFX.h

    • Adafruit_ST7796S_kbv.h

    • SD.h

    • time.h

  4. Sprawdź piny w sekcji KONFIGURACJA SPRZETOWA – dopasuj do swojej płytki.

  5. Skompiluj i wgraj na ESP32.

    Niektóre piny są zdublowane dla wyświetlacza i karty SD. To nie jest błąd. TAK MA BYĆ! 


// ==================================
//                 KONFIGURACJA SPRZĘTOWA
// ==================================
// Piny wyświetlacza (VSPI)
#define TFT_CS 16
#define TFT_RST 4
#define TFT_DC 2
#define TFT_MOSI 23
#define TFT_SCLK 18
#define TFT_BACKLIGHT 17

// Piny karty SD (współdzielone z wyświetlaczem, różne CS)
#define SD_CS_PIN 21  
#define SD_MISO 19  
#define SD_MOSI 23
#define SD_SCLK 18
 
 

 

Dla kogo jest ten projekt?

  • Krótkofalowców i pasjonatów łączności cyfrowej DMR.

  • Twórców projektów IoT szukających ciekawego zastosowania dla ESP32.

  • Programistów embedded, którzy chcą zobaczyć, jak integrować WebSocket, JSON i wyświetlacz w jednym urządzeniu.


Podsumowanie

Projekt pokazuje, jak z pozornie prostego mikrokontrolera można zbudować zaawansowane urządzenie monitorujące z graficznym interfejsem, zapisem danych i komunikacją przez Internet. Kod jest napisany przejrzyście, z podziałem na funkcje, co ułatwia modyfikacje – na przykład można zmienić monitorowany TalkGroup, dodać więcej historii lub zintegrować z własnym API.



*********************************************************************

 NOWA WERSJA I NOWE MOŻLIWOŚCI

DMR Monitor HF5WWL - Wersja 4.3 MULTI  z obsługą wielu grup

 

Co nowego?

Najważniejszą zmianą w wersji 4.3 MULTI jest możliwość monitorowania wielu grup DMR jednocześnie. Dotychczas urządzenie śledziło wyłącznie polską grupę 260. Teraz możesz dowolnie konfigurować, które grupy chcesz obserwować.

Jak to działa?

Plik konfiguracyjny monitored_tg.txt

Na karcie SD wystarczy utworzyć plik monitored_tg.txt i wpisać w nim numery grup, które chcemy monitorować. Każda grupa w osobnej linii: 

260
26077
260042
1
2

Nowa funkcja: monitorowanie wszystkich grup z prefiksem 260

Jeśli chcesz śledzić wszystkie grupy zaczynające się od 260 (np. 260, 26077, 260042, 260123, itd.), wystarczy wpisać w pliku:

text
260*

To szczególnie przydatne, gdy interesują Cię wszystkie lokalne grupy w Twoim regionie.

Łączenie opcji

Możesz też łączyć oba sposoby:

# Wszystkie grupy z prefiksem 260
260*
# Dodatkowo inne grupy
1
2
3
 
Monitor oczekuje na aktywność na wybranych grupach:
 

Zmieniły się też zapisy w logu. Teraz wyglądają tak:

 

Co z dotychczasową funkcjonalnością?

  • Działanie z grupą 260 - jeśli brak pliku monitored_tg.txt, program domyślnie monitoruje grupę 260 (zgodnie z poprzednią wersją)

  • Logowanie do CSV - bez zmian, nadal zapisuje wszystkie aktywności

  • Wyświetlacz i interfejs - bez zmian, zachowano dotychczasowy wygląd

  • Połączenie z BrandMeister - bez zmian

Przykładowe zastosowania

  1. Monitorowanie lokalnych grup - wpisz wszystkie lokalne grupy w swoim regionie

  2. Śledzenie konkretnych rozmów - dodaj tylko interesujące Cię grupy

  3. Obserwacja ruchu w całym prefiksie 260 - użyj 260*

  4. Mieszane - monitoruj grupę 260, wszystkie podgrupy 260 i dodatkowe grupy zagraniczne

Wymagania

  • Karta SD z plikami:

    • config.txt - dane WiFi (SSID i hasło)

    • monitored_tg.txt - lista grup do monitorowania (opcjonalnie)

      Plik  dmr_log.csv zostanie utworzony automatycznie o ile go już nie utworzono.

Kompatybilność

Zmiany są w pełni kompatybilne wstecznie. Jeśli nie utworzysz pliku monitored_tg.txt, program zachowa się identycznie jak poprzednia wersja i będzie monitorować tylko grupę 260.

Podsumowanie

Nowa wersja DMR Monitora daje użytkownikowi pełną kontrolę nad tym, które grupy chce obserwować. To proste, ale bardzo użyteczne ulepszenie, które sprawia, że urządzenie staje się jeszcze bardziej wszechstronnym narzędziem do monitorowania ruchu DMR.

 

 Krótki filmik prezentujący pracę prototypu.

 

Cały kod w formacie *.bin możesz otrzymać bezpłatnie po kontakcie przez e-mail

  - Jeżeli do mnie napiszesz możesz dostać program z usuniętym moim znakiem (wpiszę Twój znak).


 

✍️ Autor: Robert HF5WWL
📅 Data projektu: Lipiec / 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) 
😊

 

#HamRadio
#DMRradio
#TalkGroup260
#AmateurRadio
#DigitalRadio
#RadioMonitor
#SP5WWL