Adafruit Library
dispDrvSt7789.h
Go to the documentation of this file.
1 
15 #ifndef WS_DISP_DRV_ST7789
16 #define WS_DISP_DRV_ST7789
17 
18 #include "dispDrvBase.h"
19 #include <Adafruit_ST7789.h>
20 
21 #define ST7789_STATUSBAR_HEIGHT 20
22 #define ST7789_STATUSBAR_ICON_SZ 16
23 #define ST7789_STATUSBAR_ICON_SPACING \
24  4
25 #define ST7789_STATUSBAR_ICON_MARGIN \
26  5
27 
28 
31 class dispDrvSt7789 : public dispDrvBase {
32 public:
48  dispDrvSt7789(int16_t cs, int16_t dc, int16_t mosi, int16_t sck,
49  int16_t rst = -1, int16_t miso = -1)
50  : dispDrvBase(cs, dc, mosi, sck, rst, miso), _display(nullptr) {}
51 
56  if (_display) {
57  // "Clear" the display before deleting
58  _display->fillScreen(ST77XX_BLACK);
59  delete _display;
60  _display = nullptr;
61  }
62 // Turn off backlight
63 #if defined(ARDUINO_FUNHOUSE_ESP32S2)
64  digitalWrite(TFT_BACKLIGHT, LOW);
65 #elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3_REVTFT) || \
66  defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3_TFT) || \
67  defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2_REVTFT) || \
68  defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2_TFT)
69  digitalWrite(TFT_BACKLITE, LOW);
70 #endif
71  }
72 
77  bool begin() override {
78 
79  _display = new Adafruit_ST7789(_pin_cs, _pin_dc, _pin_rst);
80  if (!_display)
81  return false;
82 
83  _display->init(_width, _height);
84  _display->setRotation(_rotation);
85  _display->fillScreen(ST77XX_BLACK);
86  _display->setTextColor(ST77XX_WHITE);
87  _display->setTextWrap(false);
88 
89  // Turn on backlight
90 #if defined(ARDUINO_FUNHOUSE_ESP32S2)
91  pinMode(TFT_BACKLIGHT, OUTPUT);
92  digitalWrite(TFT_BACKLIGHT, HIGH);
93 #elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3_REVTFT) || \
94  defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3_TFT) || \
95  defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2_REVTFT) || \
96  defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2_TFT)
97  pinMode(TFT_BACKLITE, OUTPUT);
98  digitalWrite(TFT_BACKLITE, HIGH);
99 #endif
100 
101  return true;
102  }
103 
110  static const unsigned char *batteryIcon(uint8_t bat) {
111  if (bat >= 75)
112  return epd_bmp_bat_full;
113  if (bat >= 50)
114  return epd_bmp_bat_75;
115  if (bat >= 25)
116  return epd_bmp_bat_50;
117  if (bat >= 10)
118  return epd_bmp_bat_25;
119  return epd_bmp_bat_empty;
120  }
121 
127  void drawBatteryIcon(uint8_t bat) override {
128  if (!_display)
129  return;
130 
131  // Clear and draw the new battery icon, based on battery level
132  _display->fillRect(_statusbar_icon_battery_x, _statusbar_icons_y,
134  ST77XX_WHITE);
135  _display->drawBitmap(_statusbar_icon_battery_x, _statusbar_icons_y,
137  ST7789_STATUSBAR_ICON_SZ, ST77XX_BLACK);
138  _statusbar_bat = bat;
139  }
140 
144  void showSplash() override {
145  if (!_display)
146  return;
147 
148  // Display the appropriate splash screen based on resolution
149  if (_width == 240 && _height == 240) {
150  _display->drawBitmap(0, 0, tft_bmp_logo_240240, 240, 240, ST77XX_WHITE);
151  } else if (_width == 135 && _height == 240) {
152  _display->drawBitmap(0, 0, tft_bmp_logo_240135, 240, 135, ST77XX_WHITE);
153  } else {
154  // Unsupported resolution detected, skip splash screen
155  return;
156  }
157 
158  delay(500);
159  }
160 
166  virtual void drawStatusBar(const char *io_username) override {
167  if (!_display)
168  return;
169 
170  // Clear the entire display buffer to remove splash screen
171  _display->fillScreen(ST77XX_BLACK);
172 
173  // Draw status bar
174  _display->fillRect(0, 0, _display->width(), ST7789_STATUSBAR_HEIGHT,
175  ST77XX_WHITE);
176 
177  // Draw username on left side of the status bar
178  _display->setTextSize(1);
179  _display->setTextColor(ST77XX_BLACK);
180  _display->setCursor(5, 6);
181  _display->print(io_username);
182 
183  // Calculate icon positions (rightmost side of status bar), center
184  // vertically
195  // Draw icons
196  _display->drawBitmap(_statusbar_icon_cloud_x, _statusbar_icons_y,
198  ST7789_STATUSBAR_ICON_SZ, ST77XX_BLACK);
199  _display->drawBitmap(_statusbar_icon_wifi_x, _statusbar_icons_y,
201  ST7789_STATUSBAR_ICON_SZ, ST77XX_BLACK);
203 
204  // Reset text color and size for main text area
205  _display->setTextColor(ST77XX_WHITE);
206  _display->setTextSize(_text_sz);
207  }
208 
219  void updateStatusBar(int8_t rssi, uint8_t bat, bool mqtt_status) override {
220  if (!_display)
221  return;
222 
223  // Only update wifi icon if the RSSI has changed significantly (+/-3dB)
224  bool update_rssi = abs(rssi - _statusbar_rssi) >= 3;
225  // Only update cloud icon if MQTT status has changed
226  bool update_mqtt = mqtt_status != _statusbar_mqtt_connected;
227  // Only update battery icon if the battery level crossed an icon threshold
228  bool update_battery = batteryIcon(bat) != batteryIcon(_statusbar_bat);
229 
230  // No need to update if nothing has changed
231  if (!update_rssi && !update_mqtt && !update_battery)
232  return;
233 
234  if (update_mqtt) {
235  // Clear and draw the new cloud icon, based on MQTT connection status
236  _display->fillRect(_statusbar_icon_cloud_x, _statusbar_icons_y,
238  ST77XX_WHITE);
239  if (mqtt_status) {
240  _display->drawBitmap(_statusbar_icon_cloud_x, _statusbar_icons_y,
242  ST7789_STATUSBAR_ICON_SZ, ST77XX_BLACK);
243  } else {
244  _display->drawBitmap(_statusbar_icon_cloud_x, _statusbar_icons_y,
246  ST7789_STATUSBAR_ICON_SZ, ST77XX_BLACK);
247  }
248  _statusbar_mqtt_connected = mqtt_status;
249  }
250 
251  // Update WiFi icon only if RSSI has changed significantly (+/-3dB)
252  if (update_rssi) {
253  const unsigned char *wifi_icon = epd_bmp_wifi_no_signal;
254  if (rssi >= -50) {
255  wifi_icon = epd_bmp_wifi_full;
256  } else if (rssi < -50 && rssi >= -60) {
257  wifi_icon = epd_bmp_wifi_fair;
258  } else if (rssi < -60 && rssi >= -70) {
259  wifi_icon = epd_bmp_wifi_weak;
260  } else if (rssi < -70 && rssi >= -80) {
261  wifi_icon = epd_bmp_wifi_no_signal;
262  } else {
263  wifi_icon = epd_bmp_wifi_no_signal;
264  }
265  // Clear and draw the new WiFi icon, based on RSSI
266  _display->fillRect(_statusbar_icon_wifi_x, _statusbar_icons_y,
268  ST77XX_WHITE);
269  _display->drawBitmap(_statusbar_icon_wifi_x, _statusbar_icons_y,
270  wifi_icon, ST7789_STATUSBAR_ICON_SZ,
271  ST7789_STATUSBAR_ICON_SZ, ST77XX_BLACK);
272  _statusbar_rssi = rssi;
273  }
274 
275  // Update battery icon only if the battery level crossed a threshold
276  if (update_battery)
277  drawBatteryIcon(bat);
278  }
279 
287  virtual void writeMessage(const char *message) override {
288  if (_display == nullptr)
289  return;
290 
291  // Clear only the area below the status bar
292  _display->fillRect(0, ST7789_STATUSBAR_HEIGHT, _display->width(),
293  _display->height() - ST7789_STATUSBAR_HEIGHT,
294  ST77XX_BLACK);
295  int16_t y_idx = ST7789_STATUSBAR_HEIGHT;
296 
297  // Calculate the line height based on the text size (NOTE: base height is
298  // 8px)
299  int16_t line_height = 8 * _text_sz;
300  uint16_t c_idx = 0;
301  size_t msg_size = strlen(message);
302  // Begin with a small offset from status bar
303  y_idx += 5;
304  _display->setCursor(0, y_idx);
305  for (size_t i = 0; i < msg_size && c_idx < msg_size; i++) {
306  if (y_idx + line_height > _height)
307  break;
308  if (message[i] == '\\' && i + 1 < msg_size &&
309  (message[i + 1] == 'n' || message[i + 1] == 'r')) {
310  // Handle \r\n sequence as a single newline
311  if (message[i + 1] == 'r' && i + 3 < msg_size &&
312  message[i + 2] == '\\' && message[i + 3] == 'n') {
313  // Skip to the next line
314  if (y_idx + line_height > _height)
315  break;
316  y_idx += line_height;
317  _display->setCursor(0, y_idx);
318  i += 3;
319  } else if (message[i + 1] == 'n') {
320  // Skip to the next line
321  if (y_idx + line_height > _height)
322  break;
323  y_idx += line_height;
324  _display->setCursor(0, y_idx);
325  i++;
326  }
327  } else if (message[i] == 0xC2 && message[i + 1] == 0xB0) {
328  // Degree symbol - tested on Feather RevTFT S3
329  _display->write(char(247));
330  i++;
331  } else {
332  _display->print(message[i]);
333  }
334  }
335  }
336 
337 private:
338  Adafruit_ST7789 *_display;
339 };
340 
341 #endif // WS_DISP_DRV_ST7789
static const unsigned char * batteryIcon(uint8_t bat)
Selects the battery icon for a battery level.
Definition: dispDrvSt7789.h:110
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: dispDrvSt7789.h:219
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:189
const unsigned char epd_bmp_wifi_fair[]
wifi-fair-thin-full icon from FontAwesome (16x16px)
Definition: icons.h:46
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:190
Driver for ST7789-based TFT displays.
Definition: dispDrvSt7789.h:31
const unsigned char epd_bmp_bat_25[]
battery-25-thin-full icon (16x16px)
Definition: icons.h:145
const unsigned char epd_bmp_wifi_no_signal[]
wifi-slash-thin-full icon from FontAwesome (16x16px)
Definition: icons.h:62
#define ST7789_STATUSBAR_ICON_MARGIN
Default margin from edge of display to status bar icons.
Definition: dispDrvSt7789.h:25
uint8_t _text_sz
Text size for displaying a message.
Definition: dispDrvBase.h:184
#define ST7789_STATUSBAR_HEIGHT
Default status bar height.
Definition: dispDrvSt7789.h:21
dispDrvSt7789(int16_t cs, int16_t dc, int16_t mosi, int16_t sck, int16_t rst=-1, int16_t miso=-1)
Constructor for the ST7789 display driver.
Definition: dispDrvSt7789.h:48
int8_t _statusbar_rssi
RSSI value for status bar.
Definition: dispDrvBase.h:193
#define ST7789_STATUSBAR_ICON_SZ
Default status bar icon size.
Definition: dispDrvSt7789.h:22
#define ST7789_STATUSBAR_ICON_SPACING
Default spacing between status bar icons.
Definition: dispDrvSt7789.h:23
uint8_t _rotation
Rotation of the display.
Definition: dispDrvBase.h:187
bool begin() override
Attempts to initialize the ST7789 TFT driver.
Definition: dispDrvSt7789.h:77
const unsigned char tft_bmp_logo_240240[]
Wippersnapper logo, 240x240px.
Definition: splash.h:365
int _statusbar_icon_cloud_x
X position of cloud icon.
Definition: dispDrvBase.h:192
int16_t _pin_rst
Reset pin.
Definition: dispDrvBase.h:177
void showSplash() override
Displays the splash screen on the display.
Definition: dispDrvSt7789.h:144
int16_t _width
Width of the display.
Definition: dispDrvBase.h:186
const unsigned char epd_bmp_wifi_full[]
wifi-thin-full icon from FontAwesome (16x16px)
Definition: icons.h:38
const unsigned char tft_bmp_logo_240135[]
Wippersnapper logo, 296x128px.
Definition: splash.h:22
virtual void writeMessage(const char *message) override
Writes a message to the display.
Definition: dispDrvSt7789.h:287
const unsigned char epd_bmp_bat_50[]
battery-50-thin-full icon (16x16px)
Definition: icons.h:120
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:185
bool _statusbar_mqtt_connected
MQTT connection status for the status bar.
Definition: dispDrvBase.h:195
Abstract base class for display drivers. This class provides a common interface for all display drive...
Definition: dispDrvBase.h:28
void drawBatteryIcon(uint8_t bat) override
Draws the battery icon based on the current battery level.
Definition: dispDrvSt7789.h:127
~dispDrvSt7789()
Destructor for the ST7789 display driver.
Definition: dispDrvSt7789.h:55
int16_t _pin_cs
Chip Select pin.
Definition: dispDrvBase.h:178
virtual void drawStatusBar(const char *io_username) override
Draws a status bar at the top of the display.
Definition: dispDrvSt7789.h:166
const unsigned char epd_bmp_wifi_weak[]
wifi-weak-thin-full icon from FontAwesome (16x16px)
Definition: icons.h:54
const unsigned char epd_bmp_bat_empty[]
battery-empty-thin-full icon (16x16px)
Definition: icons.h:170
int16_t _pin_dc
Data/Command pin.
Definition: dispDrvBase.h:176
uint8_t _statusbar_bat
Battery level (%) for the status bar.
Definition: dispDrvBase.h:194
const unsigned char epd_bmp_bat_75[]
battery-75-thin-full icon (16x16px)
Definition: icons.h:95
int _statusbar_icon_wifi_x
X position of WiFi icon.
Definition: dispDrvBase.h:191