1+ /* !
2+ * @file src/components/display/drivers/dispDrvSsd1306.h
3+ *
4+ * Driver for SSD1306-based OLED displays.
5+ *
6+ * Adafruit invests time and resources providing this open source code,
7+ * please support Adafruit and open-source hardware by purchasing
8+ * products from Adafruit!
9+ *
10+ * Copyright (c) Brent Rubell 2025 for Adafruit Industries.
11+ *
12+ * BSD license, all text here must be included in any redistribution.
13+ *
14+ */
15+ #ifndef WS_DISP_DRV_SSD1306
16+ #define WS_DISP_DRV_SSD1306
17+
18+ #include " dispDrvBase.h"
19+ #include < Arduino.h>
20+ #include < Adafruit_SSD1306.h>
21+
22+ #define WS_SSD1306_DEFAULT_WIDTH \
23+ 128 // /< Default width for a ssd1306 128x64 display
24+ #define WS_SSD1306_DEFAULT_HEIGHT \
25+ 64 // /< Default height for a ssd1306 128x64 display
26+
27+
28+ /* !
29+ @brief Driver for SSD1306-based TFT displays.
30+ */
31+ class dispDrvSsd1306 : public dispDrvBase {
32+ public:
33+ /* !
34+ @brief Constructor for the SSD1306 display driver.
35+ */
36+ dispDrvSsd1306 (TwoWire *i2c, uint16_t sensorAddress) : dispDrvBase(i2c, sensorAddress), _display(nullptr ) {
37+ _i2c = i2c;
38+ _sensorAddress = sensorAddress;
39+ _width = WS_SSD1306_DEFAULT_WIDTH;
40+ _height = WS_SSD1306_DEFAULT_HEIGHT;
41+ }
42+
43+ ~dispDrvSsd1306 () {
44+ if (_display) {
45+ _display->clearDisplay ();
46+ _display->display ();
47+ _display->ssd1306_command (SSD1306_DISPLAYOFF);
48+ delete _display;
49+ _display = nullptr ;
50+ }
51+ }
52+
53+ /* !
54+ @brief Attempts to initialize the SSD1306 display driver.
55+ @return True if the display was initialized successfully, false otherwise.
56+ */
57+ bool begin () override {
58+ if (_i2c == nullptr )
59+ return false ;
60+ // Attempt to create and allocate a SSD1306 obj.
61+ _display = new Adafruit_SSD1306 (_width, _height, _i2c);
62+ if (!_display->begin (SSD1306_SWITCHCAPVCC, _sensorAddress))
63+ return false ;
64+ // Configure the rotation, text size and color
65+ _display->setRotation (_rotation);
66+ _display->setTextSize (_text_sz);
67+ _display->setTextColor (SSD1306_WHITE);
68+ // Use full 256 char 'Code Page 437' font
69+ _display->cp437 (true );
70+ // Clear the buffer
71+ _display->clearDisplay ();
72+ _display->display ();
73+ return true ;
74+ }
75+
76+ /* !
77+ @brief Sets the text size for the display.
78+ @param s
79+ The text size to set.
80+ @note This method overrides the base class method to provide specific
81+ functionality for the SSD1306 driver.
82+ */
83+ void setTextSize (uint8_t s) override {
84+ if (!_display)
85+ return ;
86+ _text_sz = s;
87+ _display->setTextSize (s);
88+ }
89+
90+ /* !
91+ @brief Writes a message to the display.
92+ @param message
93+ The message to write to the display.
94+ @note This method overrides the base class method to provide specific
95+ functionality for the SSD1306 driver.
96+ */
97+ virtual void writeMessage (const char *message) override {
98+ if (_display == nullptr )
99+ return ;
100+
101+ // Start with a fresh display buffer
102+ // and settings
103+ int16_t y_idx = 0 ;
104+ _display->clearDisplay ();
105+ _display->setTextSize (_text_sz);
106+ _display->setTextColor (SSD1306_WHITE);
107+ _display->setCursor (0 , y_idx);
108+ _display->display ();
109+
110+ // Calculate the line height based on the text size (NOTE: base height is
111+ // 8px)
112+ int16_t line_height = 8 * _text_sz;
113+ uint16_t c_idx = 0 ;
114+ size_t msg_size = strlen (message);
115+ for (size_t i = 0 ; i < msg_size && c_idx < msg_size; i++) {
116+ if (message[i] == ' \\ ' && i + 1 < msg_size &&
117+ (message[i + 1 ] == ' n' || message[i + 1 ] == ' r' )) {
118+ // Handle \r\n sequence as a single newline
119+ if (message[i + 1 ] == ' r' && i + 3 < msg_size &&
120+ message[i + 2 ] == ' \\ ' && message[i + 3 ] == ' n' ) {
121+ // Skip to the next line
122+ y_idx += line_height;
123+ _display->setCursor (0 , y_idx);
124+ i += 3 ;
125+ } else if (message[i + 1 ] == ' n' ) {
126+ // Skip to the next line
127+ y_idx += line_height;
128+ _display->setCursor (0 , y_idx);
129+ i++;
130+ }
131+ } else if (message[i] == 0xC2 && message[i + 1 ] == 0xB0 ) {
132+ _display->write (char (248 ));
133+ _display->display ();
134+ i++;
135+ } else {
136+ _display->print (message[i]);
137+ _display->display ();
138+ }
139+ }
140+ }
141+
142+ private:
143+ Adafruit_SSD1306 *_display;
144+ };
145+
146+ #endif // WS_DISP_DRV_SSD1306
0 commit comments