Adafruit Library
dispDrvThinkInkGrayscale4Eaamfgn.h
Go to the documentation of this file.
1 
16 #ifndef WS_DRV_THINKINK_GRAYSCALE4_EAAMFGN_H
17 #define WS_DRV_THINKINK_GRAYSCALE4_EAAMFGN_H
18 
19 #include "dispDrvBase.h"
20 
21 #define STATUS_BAR_HEIGHT \
22  20
23 #define STATUS_BAR_BORDER 1
24 #define STATUS_BAR_ICON_SZ 16
25 #define STATUS_BAR_ICON_SPACING \
26  4
27 #define STATUS_BAR_ICON_MARGIN \
28  5
29 
30 
34 public:
49  drvDispThinkInkGrayscale4Eaamfgn(int16_t dc, int16_t rst, int16_t cs,
50  int16_t sram_cs = -1, int16_t busy = -1)
51  : dispDrvBase(dc, rst, cs, sram_cs, busy), _display(nullptr) {}
52 
54  if (_display) {
55  // Clear the display buffer before deleting
56  _display->clearBuffer();
57  _display->display();
58  delete _display;
59  _display = nullptr;
60  }
61  }
62 
72  bool begin(thinkinkmode_t mode, bool reset = true) override {
73  _display = new ThinkInk_290_Grayscale4_EAAMFGN(_pin_dc, _pin_rst, _pin_cs,
75  if (!_display)
76  return false; // Allocation failed
77 
78  // Initialize the display
79  _display->begin(mode);
80  // Configure display settings
81  _display->setTextSize(_text_sz);
82  _display->setTextColor(EPD_BLACK);
83  _display->setTextWrap(false);
84  _height = _display->height();
85  _width = _display->width();
86  _display->clearBuffer();
87  return true;
88  }
89 
93  virtual void showSplash() override {
94  if (!_display)
95  return;
96  _display->drawBitmap(0, 0, epd_bitmap_ws_logo_296128, 296, 128, EPD_BLACK);
97  _display->display();
98  }
99 
105  virtual void drawStatusBar(const char *io_username) override {
106  if (!_display)
107  return;
108 
109  // Clear the entire display buffer to remove splash screen
110  _display->clearBuffer();
111 
112  // Draw status bar
113  _display->fillRect(0, 0, _display->width(), STATUS_BAR_HEIGHT, EPD_BLACK);
114  _display->fillRect(STATUS_BAR_BORDER, STATUS_BAR_BORDER,
115  _display->width() - (2 * STATUS_BAR_BORDER),
116  STATUS_BAR_HEIGHT - (2 * STATUS_BAR_BORDER), EPD_WHITE);
117 
118  // Draw username on left side of the status bar
119  _display->setTextSize(1);
120  _display->setTextColor(EPD_BLACK);
121  _display->setCursor(5, 6);
122  _display->print(io_username);
123 
124  // Calculate status bar icon positions and center vertically
129  _display->width() - STATUS_BAR_ICON_SZ - STATUS_BAR_ICON_MARGIN;
134  // Draw icons on right side of the status bar
135  _display->drawBitmap(_statusbar_icon_cloud_x, _statusbar_icons_y,
137  STATUS_BAR_ICON_SZ, EPD_BLACK);
138  _display->drawBitmap(_statusbar_icon_wifi_x, _statusbar_icons_y,
140  STATUS_BAR_ICON_SZ, EPD_BLACK);
141  _display->drawBitmap(_statusbar_icon_battery_x, _statusbar_icons_y,
143  STATUS_BAR_ICON_SZ, EPD_BLACK);
144  _display->display();
145  }
146 
157  void updateStatusBar(int8_t rssi, uint8_t bat, bool mqtt_status) override {
158  if (!_display)
159  return;
160 
161  // Only update wifi icon if the RSSI has changed significantly (+/- 5dB)
162  bool update_rssi = abs(rssi - _statusbar_rssi) >= 5;
163  // Only update cloud icon if MQTT status has changed
164  bool update_mqtt = mqtt_status != _statusbar_mqtt_connected;
165 
166  // No need to update if nothing has changed
167  if (!update_rssi && !update_mqtt)
168  return;
169 
170  if (update_mqtt) {
171  // updating the RSSI occurs too frequently to be practical
172  _display->fillRect(_statusbar_icon_cloud_x, _statusbar_icons_y,
174  if (mqtt_status) {
175  _display->drawBitmap(_statusbar_icon_cloud_x, _statusbar_icons_y,
177  STATUS_BAR_ICON_SZ, EPD_BLACK);
178  } else {
179  _display->drawBitmap(_statusbar_icon_cloud_x, _statusbar_icons_y,
181  STATUS_BAR_ICON_SZ, EPD_BLACK);
182  }
183  _statusbar_mqtt_connected = mqtt_status;
184  }
185 
186  // Update WiFi icon only if RSSI has changed significantly (+/-3dB)
187  if (update_rssi) {
188  const unsigned char *wifi_icon = epd_bmp_wifi_no_signal;
189  if (rssi >= -50) {
190  wifi_icon = epd_bmp_wifi_full;
191  } else if (rssi < -50 && rssi >= -60) {
192  wifi_icon = epd_bmp_wifi_fair;
193  } else if (rssi < -60 && rssi >= -70) {
194  wifi_icon = epd_bmp_wifi_weak;
195  } else if (rssi < -70 && rssi >= -80) {
196  wifi_icon = epd_bmp_wifi_no_signal;
197  } else {
198  wifi_icon = epd_bmp_wifi_no_signal;
199  }
200  // Clear and draw the new WiFi icon, based on RSSI
201  _display->fillRect(_statusbar_icon_wifi_x, _statusbar_icons_y,
203  _display->drawBitmap(_statusbar_icon_wifi_x, _statusbar_icons_y,
205  EPD_BLACK);
206  _statusbar_rssi = rssi;
207  }
208 
209  _display->display();
210  }
211 
219  virtual void writeMessage(const char *message) override {
220  if (_display == nullptr)
221  return;
222 
223  // Clear only the area below the status bar
224  _display->fillRect(0, STATUS_BAR_HEIGHT, _display->width(),
225  _display->height() - STATUS_BAR_HEIGHT, EPD_WHITE);
226  // Add padding between status bar and text content
227  int16_t y_idx = STATUS_BAR_HEIGHT + 4;
228  _display->setCursor(0, y_idx);
229 
230  // Calculate the line height based on the text size (NOTE: base height is
231  // 8px)
232  int16_t line_height = 8 * _text_sz;
233  uint16_t c_idx = 0;
234  size_t msg_size = strlen(message);
235 
236  // Reset the text size to the configured value before we write
237  _display->setTextSize(_text_sz);
238 
239  for (size_t i = 0; i < msg_size && c_idx < msg_size; i++) {
240  if (y_idx + line_height > _height)
241  break;
242  if (message[i] == '\\' && i + 1 < msg_size &&
243  (message[i + 1] == 'n' || message[i + 1] == 'r')) {
244  // Handle \r\n sequence as a single newline
245  if (message[i + 1] == 'r' && i + 3 < msg_size &&
246  message[i + 2] == '\\' && message[i + 3] == 'n') {
247  // Skip to the next line
248  if (y_idx + line_height > _height)
249  break;
250  y_idx += line_height;
251  _display->setCursor(0, y_idx);
252  i += 3;
253  } else if (message[i + 1] == 'n') {
254  // Skip to the next line
255  if (y_idx + line_height > _height)
256  break;
257  y_idx += line_height;
258  _display->setCursor(0, y_idx);
259  i++;
260  }
261  } else if (message[i] == 0xC2 && message[i + 1] == 0xB0) {
262  // Degree symbol
263  _display->write(char(247));
264  i++;
265  } else {
266  _display->print(message[i]);
267  }
268  }
269  _display->display();
270  }
271 
272 private:
273  ThinkInk_290_Grayscale4_EAAMFGN *_display;
274 };
275 
276 #endif // WS_DRV_THINKINK_GRAYSCALE4_EAAMFGN_H
const unsigned char epd_bmp_bat_full[]
battery-full-thin-full icon from FontAwesome (16x16px)
Definition: icons.h:70
int _statusbar_icons_y
Y position of status bar icons.
Definition: dispDrvBase.h:178
#define STATUS_BAR_ICON_MARGIN
Margin from edge of display to status bar icons in pixels.
Definition: dispDrvThinkInkGrayscale4Eaamfgn.h:27
const unsigned char epd_bmp_wifi_fair[]
wifi-fair-thin-full icon from FontAwesome (16x16px)
Definition: icons.h:46
drvDispThinkInkGrayscale4Eaamfgn(int16_t dc, int16_t rst, int16_t cs, int16_t sram_cs=-1, int16_t busy=-1)
Constructor for the ThinkInk Grayscale 4-level EAAMFGN display driver.
Definition: dispDrvThinkInkGrayscale4Eaamfgn.h:49
const unsigned char epd_bmp_cloud_offline[]
cloud-xmark-thin-full icon from FontAwesome (16x16px)
Definition: icons.h:30
int _statusbar_icon_battery_x
X position of battery icon.
Definition: dispDrvBase.h:179
virtual void drawStatusBar(const char *io_username) override
Draws a status bar at the top of the display.
Definition: dispDrvThinkInkGrayscale4Eaamfgn.h:105
const unsigned char epd_bmp_wifi_no_signal[]
wifi-slash-thin-full icon from FontAwesome (16x16px)
Definition: icons.h:62
uint8_t _text_sz
Text size for displaying a message.
Definition: dispDrvBase.h:173
bool begin(thinkinkmode_t mode, bool reset=true) override
Attempts to initialize the ThinkInk Grayscale 4-level EAAMFGN display driver.
Definition: dispDrvThinkInkGrayscale4Eaamfgn.h:72
int8_t _statusbar_rssi
RSSI value for status bar.
Definition: dispDrvBase.h:182
#define STATUS_BAR_ICON_SZ
Size of status bar icons in pixels.
Definition: dispDrvThinkInkGrayscale4Eaamfgn.h:24
#define STATUS_BAR_BORDER
Border around the status bar in pixels.
Definition: dispDrvThinkInkGrayscale4Eaamfgn.h:23
int16_t _pin_sram_cs
Optional EPD SRAM chip select pin.
Definition: dispDrvBase.h:169
Driver for a ThinkInk 2.9" Grayscale 4-level EAAMFGN display.
Definition: dispDrvThinkInkGrayscale4Eaamfgn.h:33
virtual void writeMessage(const char *message) override
Writes a message to the display.
Definition: dispDrvThinkInkGrayscale4Eaamfgn.h:219
int _statusbar_icon_cloud_x
X position of cloud icon.
Definition: dispDrvBase.h:181
int16_t _pin_rst
Reset pin.
Definition: dispDrvBase.h:166
int16_t _width
Width of the display.
Definition: dispDrvBase.h:175
#define STATUS_BAR_ICON_SPACING
Spacing between status bar icons in pixels.
Definition: dispDrvThinkInkGrayscale4Eaamfgn.h:25
const unsigned char epd_bmp_wifi_full[]
wifi-thin-full icon from FontAwesome (16x16px)
Definition: icons.h:38
virtual void showSplash() override
Displays a splash screen.
Definition: dispDrvThinkInkGrayscale4Eaamfgn.h:93
#define STATUS_BAR_HEIGHT
Height of the status bar in pixels, assumes 16px icons.
Definition: dispDrvThinkInkGrayscale4Eaamfgn.h:21
const unsigned char epd_bmp_cloud_online[]
cloud-thin-full icon from FontAwesome (16x16px)
Definition: icons.h:22
int16_t _height
Height of the display.
Definition: dispDrvBase.h:174
bool _statusbar_mqtt_connected
MQTT connection status for the status bar.
Definition: dispDrvBase.h:185
void updateStatusBar(int8_t rssi, uint8_t bat, bool mqtt_status) override
Updates the status bar with current information (battery level, connectivity status, etc).
Definition: dispDrvThinkInkGrayscale4Eaamfgn.h:157
int16_t _pin_busy
Optional Busy pin.
Definition: dispDrvBase.h:168
Abstract base class for display drivers. This class provides a common interface for all display drive...
Definition: dispDrvBase.h:28
int16_t _pin_cs
Chip Select pin.
Definition: dispDrvBase.h:167
const unsigned char epd_bmp_wifi_weak[]
wifi-weak-thin-full icon from FontAwesome (16x16px)
Definition: icons.h:54
int16_t _pin_dc
Data/Command pin.
Definition: dispDrvBase.h:165
int _statusbar_icon_wifi_x
X position of WiFi icon.
Definition: dispDrvBase.h:180