Skip to content

Commit 75deb6b

Browse files
committed
Draw and update status bar, show splash
1 parent bf1e68c commit 75deb6b

File tree

10 files changed

+1509
-1053
lines changed

10 files changed

+1509
-1053
lines changed

src/Wippersnapper.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2914,5 +2914,9 @@ ws_status_t Wippersnapper::run() {
29142914
WS._uartComponent->update();
29152915
WS.feedWDT();
29162916

2917+
// Process display controller events, if initialized
2918+
WS._displayController->update();
2919+
WS.feedWDT();
2920+
29172921
return WS_NET_CONNECTED; // TODO: Make this funcn void!
29182922
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#ifndef _ICONS_H_
2+
#define _ICONS_H_
3+
#include <Arduino.h>
4+
5+
const unsigned char epd_bmp_cloud [] PROGMEM = {
6+
// 'cloud-thin-full, 16x16px
7+
0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0d, 0xc0, 0x18, 0x78, 0x10, 0x0c, 0x30, 0x04, 0x70, 0x0c,
8+
0xc0, 0x06, 0xc0, 0x03, 0xc0, 0x03, 0x40, 0x03, 0x70, 0x06, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00
9+
};
10+
11+
const unsigned char epd_bmp_wifi [] PROGMEM = {
12+
// 'wifi-thin-full, 16x16px
13+
0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x3c, 0x3c, 0x70, 0x0e, 0xc0, 0x03, 0x03, 0xc0, 0x0f, 0xf0,
14+
0x1c, 0x38, 0x18, 0x18, 0x00, 0x00, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00
15+
};
16+
17+
18+
const unsigned char epd_bmp_bat_full [] PROGMEM = {
19+
// 'battery-full-thin-full, 16x16px
20+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0xc0, 0x06, 0xff, 0xfa, 0xf0, 0x0b, 0xf0, 0x0b,
21+
0xf0, 0x0b, 0xf0, 0x0b, 0xff, 0xfa, 0xc0, 0x06, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
22+
};
23+
24+
#endif // _ICONS_H_

src/components/display/assets/splash.h

Lines changed: 1355 additions & 1007 deletions
Large diffs are not rendered by default.

src/components/display/controller.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,16 @@ bool DisplayController::Handle_Display_Write(
129129
WS_DEBUG_PRINTLN(msgWrite->message);
130130
display->writeMessage(msgWrite->message);
131131
return true;
132+
}
133+
134+
void DisplayController::update() {
135+
// if _hw_instances is empty, early out
136+
if (_hw_instances.size() == 0)
137+
return;
138+
139+
// Get the driver instance for the display
140+
DisplayHardware *display = nullptr;
141+
for (auto &hw_instance : _hw_instances) {
142+
hw_instance->updateStatusBar(WS.getRSSI(), 100, WS.networkStatus());
143+
}
132144
}

src/components/display/controller.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class DisplayController {
3535
wippersnapper_display_v1_DisplayAddOrReplace *msgAdd);
3636
bool Handle_Display_Remove(wippersnapper_display_v1_DisplayRemove *msgRemove);
3737
bool Handle_Display_Write(wippersnapper_display_v1_DisplayWrite *msgWrite);
38+
void update();
3839

3940
private:
4041
std::vector<DisplayHardware *>

src/components/display/drivers/dispDrvBase.h

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
#ifndef WS_DISP_DRV_BASE_H
1616
#define WS_DISP_DRV_BASE_H
1717

18+
#include "../assets/icons.h"
19+
#include "../assets/splash.h"
1820
#include "Adafruit_ThinkInk.h"
1921
#include "Wippersnapper.h"
20-
#include "../assets/splash.h"
2122

2223
/*!
2324
@brief Abstract base class for display drivers.
@@ -125,32 +126,54 @@ class dispDrvBase {
125126
*/
126127
virtual void setTextSize(uint8_t s) { _text_sz = s; }
127128

128-
129129
/*!
130130
@brief Displays a splash screen on the display.
131131
@note This method can be overridden by derived classes to provide
132132
specific functionality.
133133
*/
134-
virtual void showSplash() { // No-op for base class
134+
virtual void showSplash() { // No-op for base class
135+
}
136+
137+
/*!
138+
@brief Draws a status bar at the top of the display.
139+
@param io_username
140+
The username to display on the status bar.
141+
@note This method can be overridden by derived classes to provide
142+
specific functionality.
143+
*/
144+
virtual void drawStatusBar(const char *io_username) {
145+
// No-op for base class
135146
}
136147

137-
virtual void drawStatusBar() {
148+
/*!
149+
@brief Updates the status bar with current information (battery level,
150+
connectivity status, etc).
151+
@note This method can be overridden by derived classes to provide
152+
specific functionality.
153+
*/
154+
virtual void updateStatusBar(int8_t rssi, uint8_t bat,
155+
ws_status_t mqtt_connected) {
138156
// No-op for base class
139157
}
140158

141159
protected:
142-
int16_t _pin_dc; ///< Data/Command pin
143-
int16_t _pin_rst; ///< Reset pin
144-
int16_t _pin_cs; ///< Chip Select pin
145-
int16_t _pin_busy; ///< Optional Busy pin
146-
int16_t _pin_sram_cs; ///< Optional EPD SRAM chip select pin
147-
uint16_t _pin_mosi; ///< Optional MOSI pin for SPI TFT displays
148-
uint16_t _pin_miso; ///< Optional MISO pin for SPI TFT displays
149-
uint16_t _pin_sck; ///< Optional SCK pin for SPI TFT displays
150-
uint8_t _text_sz = 1; ///< Text size for displaying a message
151-
int16_t _height; ///< Height of the display
152-
int16_t _width; ///< Width of the display
153-
uint8_t _rotation; ///< Rotation of the display
160+
int16_t _pin_dc; ///< Data/Command pin
161+
int16_t _pin_rst; ///< Reset pin
162+
int16_t _pin_cs; ///< Chip Select pin
163+
int16_t _pin_busy; ///< Optional Busy pin
164+
int16_t _pin_sram_cs; ///< Optional EPD SRAM chip select pin
165+
uint16_t _pin_mosi; ///< Optional MOSI pin for SPI TFT displays
166+
uint16_t _pin_miso; ///< Optional MISO pin for SPI TFT displays
167+
uint16_t _pin_sck; ///< Optional SCK pin for SPI TFT displays
168+
uint8_t _text_sz = 1; ///< Text size for displaying a message
169+
int16_t _height; ///< Height of the display
170+
int16_t _width; ///< Width of the display
171+
uint8_t _rotation; ///< Rotation of the display
172+
int8_t _statusbar_rssi; ///< RSSI value for status bar
173+
uint8_t
174+
_statusbar_bat; ///< Battery level, as a percentage, for the status bar
175+
ws_status_t
176+
_statusbar_mqtt_connected; ///< MQTT connection status for the status bar
154177
};
155178

156179
#endif // WS_DISP_DRV_BASE_H

src/components/display/drivers/dispDrvThinkInkGrayscale4Eaamfgn.h

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ class drvDispThinkInkGrayscale4Eaamfgn : public dispDrvBase {
7979
/*!
8080
@brief Displays a splash screen
8181
*/
82-
virtual void showSplash() override {
83-
if (! _display)
82+
virtual void showSplash() override {
83+
if (!_display)
8484
return;
8585
_display->drawBitmap(0, 0, epd_bitmap_ws_logo_296128, 296, 128, EPD_BLACK);
8686
_display->display();
@@ -90,32 +90,68 @@ class drvDispThinkInkGrayscale4Eaamfgn : public dispDrvBase {
9090
/*!
9191
@brief Draws a status bar at the top of the display.
9292
*/
93-
virtual void drawStatusBar() override {
93+
virtual void drawStatusBar(const char *io_username) override {
9494
if (!_display)
9595
return;
96-
_display->clearBuffer();
97-
_display->fillScreen(EPD_WHITE);
98-
99-
int barHeight = 15;
96+
97+
// Draw status bar
98+
int barHeight = 20; // Assumes 16x16 icons
10099
int borderWidth = 1;
101-
// Black rect outline
102-
_display->fillRect(0, 0, _width, barHeight, EPD_BLACK);
103-
// White rect inside for icons/text
104-
_display->fillRect(borderWidth, borderWidth,
105-
_width - (2 * borderWidth),
106-
barHeight - (2 * borderWidth),
107-
EPD_WHITE);
108-
109-
// Vertically center text in the bar
110-
_display->setTextSize(1); // Text size 1 = 8 pixels tall
111-
int textHeight = 8;
112-
int usableHeight = barHeight - (2 * borderWidth); // 13px usable
113-
int textY = borderWidth + (usableHeight - textHeight) / 2; // = 1 + (13-8)/2 = 3
114-
// Draw status text
100+
_display->fillRect(0, 0, _display->width(), barHeight, EPD_BLACK);
101+
_display->fillRect(borderWidth, borderWidth,
102+
_display->width() - (2 * borderWidth),
103+
barHeight - (2 * borderWidth), EPD_WHITE);
104+
105+
// Draw username on left side of the status bar
106+
_display->setTextSize(1);
115107
_display->setTextColor(EPD_BLACK);
116-
_display->setCursor(5, textY);
117-
_display->print("[IO] OK|[WiFi] OK|[Bat] 100%");
118-
_display->display();
108+
_display->setCursor(5, 6);
109+
_display->print(io_username);
110+
111+
// Calculate icon positions and center vertically
112+
int iconSize = 16;
113+
int iconSpacing = 4;
114+
int rightMargin = 5;
115+
int iconY = borderWidth + ((barHeight - 2 * borderWidth - iconSize) / 2);
116+
int batteryX = _display->width() - iconSize - rightMargin;
117+
int wifiX = batteryX - iconSize - iconSpacing;
118+
int cloudX = wifiX - iconSize - iconSpacing;
119+
// Draw icons on right side of the status bar
120+
_display->drawBitmap(cloudX, iconY, epd_bmp_cloud, iconSize, iconSize,
121+
EPD_BLACK);
122+
_display->drawBitmap(wifiX, iconY, epd_bmp_wifi, iconSize, iconSize,
123+
EPD_BLACK);
124+
_display->drawBitmap(batteryX, iconY, epd_bmp_bat_full, iconSize, iconSize,
125+
EPD_BLACK);
126+
}
127+
128+
/*!
129+
@brief Updates the status bar with current information (battery level,
130+
connectivity status, etc).
131+
@param rssi
132+
The current RSSI value to display.
133+
@param bat
134+
The current battery level (0-100) to display.
135+
@param mqtt_connected
136+
The current MQTT connection status to display.
137+
*/
138+
void updateStatusBar(int8_t rssi, uint8_t bat,
139+
ws_status_t mqtt_connected) override {
140+
if (!_display)
141+
return;
142+
143+
if (bat != _statusbar_bat) {
144+
// Update battery icon
145+
_statusbar_bat = bat;
146+
}
147+
if (rssi != _statusbar_rssi) {
148+
// Update WiFi icon
149+
_statusbar_rssi = rssi;
150+
}
151+
if (mqtt_connected != _statusbar_mqtt_connected) {
152+
// Update cloud icon
153+
_statusbar_mqtt_connected = mqtt_connected;
154+
}
119155
}
120156

121157
/*!

src/components/display/hardware.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,14 +262,22 @@ bool DisplayHardware::beginEPD(
262262

263263
void DisplayHardware::showSplash() {
264264
if (!_drvDisp)
265-
return;
265+
return;
266266
_drvDisp->showSplash();
267267
}
268268

269-
void DisplayHardware::drawStatusBar() {
270-
_drvDisp->drawStatusBar();
269+
void DisplayHardware::drawStatusBar(const char *io_username) {
270+
if (!_drvDisp)
271+
return;
272+
_drvDisp->drawStatusBar(const char *io_username);
271273
}
272274

275+
void DisplayHardware::updateStatusBar(int8_t rssi, uint8_t bat,
276+
ws_status_t mqtt_connected) {
277+
if (!_drvDisp)
278+
return;
279+
_drvDisp->updateStatusBar(rssi, bat, mqtt_connected);
280+
}
273281

274282
/*!
275283
@brief Removes a suffix from the hardware instance name, if it exists.

src/components/display/hardware.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ class DisplayHardware {
4444
bool beginTft(wippersnapper_display_v1_TftConfig *config,
4545
wippersnapper_display_v1_TftSpiConfig *spi_config);
4646

47-
4847
void showSplash();
49-
void drawStatusBar();
48+
void drawStatusBar(const char *io_username);
49+
void updateStatusBar(int8_t rssi, uint8_t bat, ws_status_t mqtt_connected);
5050
//
5151
// API for Adafruit_GFX that abstracts hardware functionality
5252
// NOTE: These methods are meant to be implemented within dispDrvBase and

src/network_interfaces/Wippersnapper_ESP32.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* please support Adafruit and open-source hardware by purchasing
99
* products from Adafruit!
1010
*
11-
* Copyright (c) Brent Rubell 2020-2024 for Adafruit Industries.
11+
* Copyright (c) Brent Rubell 2020-2025 for Adafruit Industries.
1212
*
1313
* MIT license, all text here must be included in any redistribution.
1414
*

0 commit comments

Comments
 (0)