Skip to content

Commit 16b5ac9

Browse files
author
mariuste
committed
Add IP address display functionality and configure button handling
1 parent 2861d1c commit 16b5ac9

4 files changed

Lines changed: 174 additions & 0 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"chat.tools.terminal.autoApprove": {
3+
"platformio": true
4+
}
5+
}

firmware/prusalink/lib/PrusaLinkAPI/PrusaLinkAPI.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,11 @@ String PrusaLinkApi::sendRequestToPrusaLink(String type, String command, const c
9797
}
9898

9999
now = millis();
100+
unsigned long lastDataAt = now;
100101
while (millis() - now < PLAPI_TIMEOUT) {
102+
bool gotData = false;
101103
while (_client->available()) {
104+
gotData = true;
102105
char c = _client->read();
103106

104107
if (_debug)
@@ -126,6 +129,22 @@ String PrusaLinkApi::sendRequestToPrusaLink(String type, String command, const c
126129
currentLineIsBlank = false;
127130
}
128131
}
132+
133+
if (gotData) {
134+
lastDataAt = millis();
135+
}
136+
137+
// Stop waiting once the response is fully read and no more data arrives.
138+
if (finishedHeaders && !gotData && (millis() - lastDataAt > 30)) {
139+
break;
140+
}
141+
142+
// Also stop if peer closed and no buffered data is left.
143+
if (!_client->connected() && !_client->available()) {
144+
break;
145+
}
146+
147+
delay(1);
129148
}
130149
} else {
131150
if (_debug) {

firmware/prusalink/platformio.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ build_flags =
1616
-I include
1717
-D WIFI_SSID_ENV=\"${sysenv.WIFI_SSID}\"
1818
-D WIFI_PASS_ENV=\"${sysenv.WIFI_PASS}\"
19+
-D IP_SHOW_BUTTON_PIN=7
1920

2021
[env:prusa_drucker_2]
2122
build_flags =

firmware/prusalink/src/main.cpp

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

97111
const int tempGood_T0 = 50; // below this temperature Nozzle is considered cool
98112
const 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();
105122
void displayPrinterPrinting(int time_left, float progress, int tool_temp, int bed_temp);
106123
void displayPrinterReady(int tool_temp, int bed_temp);
107124
void 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);
108128
bool isPrinterUnavailableState(const char *state);
129+
bool isIpShowButtonPressed();
109130
int scaleFloatToInteger(float progress);
110131
void 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
*/
161186
void 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

Comments
 (0)