@@ -62,6 +62,20 @@ uint8_t oePin = 14;
6262#define PIN_GREEN A2 // Green channel
6363#define PIN_BLUE A3 // Blue channel
6464
65+ #ifndef IP_SHOW_BUTTON_PIN
66+ #define IP_SHOW_BUTTON_PIN 0 // Fallback: BOOT/User button (active low)
67+ #endif
68+
69+ #ifndef IP_SHOW_BUTTON_ACTIVE_LOW
70+ #define IP_SHOW_BUTTON_ACTIVE_LOW 1
71+ #endif
72+
73+ #if defined(BUTTON_DOWN)
74+ #define IP_SHOW_BUTTON_ALT_PIN BUTTON_DOWN
75+ #elif defined(PIN_BUTTON_DOWN)
76+ #define IP_SHOW_BUTTON_ALT_PIN PIN_BUTTON_DOWN
77+ #endif
78+
6579#if HEIGHT == 16
6680#define NUM_ADDR_PINS 3
6781#elif HEIGHT == 32
@@ -96,6 +110,9 @@ bool prusaLinkWasOffline = false;
96110
97111const int tempGood_T0 = 50 ; // below this temperature Nozzle is considered cool
98112const int tempGood_Bed = 50 ; // below this temperature Bed is considered cool
113+ const unsigned long IP_BUTTON_AFTERGLOW_MS = 3000 ;
114+
115+ unsigned long showIpUntil = 0 ;
99116
100117
101118// --- Funktionsprototypen ---
@@ -105,7 +122,11 @@ void reconnectWiFi();
105122void displayPrinterPrinting (int time_left, float progress, int tool_temp, int bed_temp);
106123void displayPrinterReady (int tool_temp, int bed_temp);
107124void displayPrusaLinkOffline ();
125+ void displayIpAddress ();
126+ void drawTinyGlyph (char c, int x, int y, uint16_t color);
127+ void drawTinyText (const String &text, int x, int y, uint16_t color);
108128bool isPrinterUnavailableState (const char *state);
129+ bool isIpShowButtonPressed ();
109130int scaleFloatToInteger (float progress);
110131void printPrusaLinkDebug ();
111132// ---------------------------
@@ -126,6 +147,10 @@ void setup() {
126147 pinMode (PIN_RED , OUTPUT );
127148 pinMode (PIN_GREEN , OUTPUT );
128149 pinMode (PIN_BLUE , OUTPUT );
150+ pinMode (IP_SHOW_BUTTON_PIN , INPUT_PULLUP );
151+ #ifdef IP_SHOW_BUTTON_ALT_PIN
152+ pinMode (IP_SHOW_BUTTON_ALT_PIN , INPUT_PULLUP );
153+ #endif
129154
130155 // Start with the light off
131156 digitalWrite (PIN_RED , LOW );
@@ -160,6 +185,18 @@ void setup() {
160185 */
161186void loop () {
162187 unsigned long currentMillis = millis ();
188+
189+ // IP button: show IP while pressed and keep it visible for a short afterglow.
190+ if (isIpShowButtonPressed ()) {
191+ showIpUntil = currentMillis + IP_BUTTON_AFTERGLOW_MS ;
192+ }
193+
194+ if (currentMillis < showIpUntil) {
195+ displayIpAddress ();
196+ esp_task_wdt_reset ();
197+ return ;
198+ }
199+
163200 // Check the Wi-Fi connection and API status every second
164201 if (currentMillis - previousMillis >= CHECK_INTERVAL ) {
165202 previousMillis = currentMillis;
@@ -258,6 +295,27 @@ bool isPrinterUnavailableState(const char *state) {
258295 || (strcmp (state, " N/A" ) == 0 );
259296}
260297
298+ bool isIpShowButtonPressed () {
299+ int primaryState = digitalRead (IP_SHOW_BUTTON_PIN );
300+ #if IP_SHOW_BUTTON_ACTIVE_LOW
301+ bool primaryPressed = (primaryState == LOW );
302+ #else
303+ bool primaryPressed = (primaryState == HIGH );
304+ #endif
305+
306+ #ifdef IP_SHOW_BUTTON_ALT_PIN
307+ int altState = digitalRead (IP_SHOW_BUTTON_ALT_PIN );
308+ #if IP_SHOW_BUTTON_ACTIVE_LOW
309+ bool altPressed = (altState == LOW );
310+ #else
311+ bool altPressed = (altState == HIGH );
312+ #endif
313+ return primaryPressed || altPressed;
314+ #else
315+ return primaryPressed;
316+ #endif
317+ }
318+
261319/* *
262320 * @brief Handles the initial connection to the WiFi network.
263321 *
@@ -564,6 +622,97 @@ void displayPrusaLinkOffline() {
564622 matrix.show ();
565623}
566624
625+ /* *
626+ * @brief Displays the current LCD IP address while the user button is pressed.
627+ *
628+ * If Wi-Fi is connected, shows the local IP in one line using a tiny pixel
629+ * font so all octets fit on the 64x32 matrix.
630+ */
631+ void displayIpAddress () {
632+ matrix.fillScreen (0 );
633+ matrix.drawRect (0 , 0 , 64 , 32 , matrix.color565 (0 , 128 , 255 ));
634+
635+ if (WiFi.status () == WL_CONNECTED ) {
636+ String ip = WiFi.localIP ().toString ();
637+ int textWidth = ip.length () * 4 ; // 3 px glyph + 1 px spacing
638+ int x = (64 - textWidth) / 2 ;
639+ if (x < 1 ) {
640+ x = 1 ;
641+ }
642+ drawTinyText (ip, x, 13 , matrix.color565 (0 , 255 , 255 ));
643+ } else {
644+ drawTinyText (" NO WIFI" , 18 , 13 , matrix.color565 (255 , 180 , 0 ));
645+ }
646+
647+ matrix.show ();
648+ }
649+
650+ void drawTinyGlyph (char c, int x, int y, uint16_t color) {
651+ const uint8_t *rows = nullptr ;
652+
653+ static const uint8_t g0[5 ] = {0x7 , 0x5 , 0x5 , 0x5 , 0x7 };
654+ static const uint8_t g1[5 ] = {0x2 , 0x6 , 0x2 , 0x2 , 0x7 };
655+ static const uint8_t g2[5 ] = {0x7 , 0x1 , 0x7 , 0x4 , 0x7 };
656+ static const uint8_t g3[5 ] = {0x7 , 0x1 , 0x7 , 0x1 , 0x7 };
657+ static const uint8_t g4[5 ] = {0x5 , 0x5 , 0x7 , 0x1 , 0x1 };
658+ static const uint8_t g5[5 ] = {0x7 , 0x4 , 0x7 , 0x1 , 0x7 };
659+ static const uint8_t g6[5 ] = {0x7 , 0x4 , 0x7 , 0x5 , 0x7 };
660+ static const uint8_t g7[5 ] = {0x7 , 0x1 , 0x1 , 0x1 , 0x1 };
661+ static const uint8_t g8[5 ] = {0x7 , 0x5 , 0x7 , 0x5 , 0x7 };
662+ static const uint8_t g9[5 ] = {0x7 , 0x5 , 0x7 , 0x1 , 0x7 };
663+ static const uint8_t gd[5 ] = {0x0 , 0x0 , 0x0 , 0x2 , 0x2 }; // .
664+ static const uint8_t gn[5 ] = {0x5 , 0x7 , 0x7 , 0x7 , 0x5 }; // N
665+ static const uint8_t go[5 ] = {0x0 , 0x7 , 0x5 , 0x5 , 0x7 }; // O
666+ static const uint8_t gw[5 ] = {0x5 , 0x5 , 0x7 , 0x7 , 0x5 }; // W
667+ static const uint8_t gi[5 ] = {0x2 , 0x0 , 0x2 , 0x2 , 0x2 }; // I
668+ static const uint8_t gf[5 ] = {0x7 , 0x4 , 0x6 , 0x4 , 0x4 }; // F
669+
670+ switch (c) {
671+ case ' 0' : rows = g0; break ;
672+ case ' 1' : rows = g1; break ;
673+ case ' 2' : rows = g2; break ;
674+ case ' 3' : rows = g3; break ;
675+ case ' 4' : rows = g4; break ;
676+ case ' 5' : rows = g5; break ;
677+ case ' 6' : rows = g6; break ;
678+ case ' 7' : rows = g7; break ;
679+ case ' 8' : rows = g8; break ;
680+ case ' 9' : rows = g9; break ;
681+ case ' .' : rows = gd; break ;
682+ case ' N' : rows = gn; break ;
683+ case ' O' : rows = go; break ;
684+ case ' W' : rows = gw; break ;
685+ case ' I' : rows = gi; break ;
686+ case ' F' : rows = gf; break ;
687+ default : break ;
688+ }
689+
690+ if (rows == nullptr ) {
691+ return ;
692+ }
693+
694+ for (int row = 0 ; row < 5 ; row++) {
695+ for (int col = 0 ; col < 3 ; col++) {
696+ if (rows[row] & (1 << (2 - col))) {
697+ matrix.drawPixel (x + col, y + row, color);
698+ }
699+ }
700+ }
701+ }
702+
703+ void drawTinyText (const String &text, int x, int y, uint16_t color) {
704+ for (int i = 0 ; i < text.length (); i++) {
705+ char c = text[i];
706+ if (c >= ' a' && c <= ' z' ) {
707+ c = c - ' a' + ' A' ;
708+ }
709+ if (c != ' ' ) {
710+ drawTinyGlyph (c, x, y, color);
711+ }
712+ x += 4 ;
713+ }
714+ }
715+
567716/* *
568717 * @brief Displays a screen indicating WiFi is disconnected.
569718 *
0 commit comments