1+ /* !
2+ * @file WipperSnapper_I2C_Driver_Out_SH1107.h
3+ *
4+ * Device driver for a SH1107 OLED Display
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 for Adafruit Industries 2025
11+ *
12+ * MIT license, all text here must be included in any redistribution.
13+ *
14+ */
15+
16+ #ifndef WIPPERSNAPPER_I2C_DRIVER_OUT_SH1107_H
17+ #define WIPPERSNAPPER_I2C_DRIVER_OUT_SH1107_H
18+
19+ #include " WipperSnapper_I2C_Driver_Out.h"
20+ #include < Adafruit_SH110x.h>
21+ #include < Arduino.h>
22+
23+ #define DEFAULT_WIDTH 128 // /< Default width for a sh1107 128x64 display
24+ #define DEFAULT_HEIGHT 64 // /< Default height for a sh1107 128x64 display
25+
26+ /* !
27+ @brief Class that provides a driver interface for a SH1107
28+ OLED Display
29+ */
30+ class WipperSnapper_I2C_Driver_Out_SH1107
31+ : public WipperSnapper_I2C_Driver_Out {
32+
33+ public:
34+ /* ******************************************************************************/
35+ /* !
36+ @brief Constructor for a SH1107 OLED display.
37+ @param i2c
38+ The I2C interface.
39+ @param sensorAddress
40+ 7-bit device address.
41+ */
42+ /* ******************************************************************************/
43+ WipperSnapper_I2C_Driver_Out_SH1107 (TwoWire *i2c, uint16_t sensorAddress)
44+ : WipperSnapper_I2C_Driver_Out(i2c, sensorAddress) {
45+ _i2c = i2c;
46+ _sensorAddress = sensorAddress;
47+ _width = DEFAULT_WIDTH;
48+ _height = DEFAULT_HEIGHT;
49+ }
50+
51+ /* !
52+ @brief Destructor for a SH1107 OLED display.
53+ */
54+ ~WipperSnapper_I2C_Driver_Out_SH1107 () {
55+ if (_display != nullptr ) {
56+ _display->clearDisplay ();
57+ _display->display ();
58+ _display->sh1107_command (SH1107_DISPLAYOFF);
59+ delete _display;
60+ _display = nullptr ;
61+ }
62+ }
63+
64+ /* !
65+ @brief Initializes the SH1107 display and begins I2C.
66+ @returns True if initialized successfully, False otherwise.
67+ */
68+ bool begin () {
69+ // Attempt to create and allocate a SH1107 obj.
70+ _display = new Adafruit_SH1107 (_width, _height, _i2c);
71+ if (!_display->begin (_sensorAddress, true ))
72+ return false ;
73+ // Configure the text size and color
74+ _display->setTextSize (_text_sz);
75+ _display->setTextColor (SH1107_WHITE);
76+ // Use full 256 char 'Code Page 437' font
77+ _display->cp437 (true );
78+ // Clear the buffer
79+ _display->clearDisplay ();
80+ _display->display ();
81+ return true ;
82+ }
83+
84+ /* !
85+ @brief Configures a SH1107 OLED display. Must be called before driver
86+ begin()
87+ @param width
88+ The width of the display in pixels.
89+ @param height
90+ The height of the display in pixels.
91+ @param text_size
92+ The magnification factor for the text size.
93+ */
94+ void ConfigureSH1107 (uint8_t width, uint8_t height, uint8_t text_size) {
95+ _width = width;
96+ _height = height;
97+ _text_sz = text_size;
98+ }
99+
100+ /* !
101+ @brief Writes a message to the SH1107 display.
102+ @param message
103+ The message to be displayed.
104+ */
105+ void WriteMessageSH1107 (const char *message) {
106+ if (_display == nullptr )
107+ return ;
108+
109+ // Start with a fresh display buffer
110+ // and settings
111+ int16_t y_idx = 0 ;
112+ _display->clearDisplay ();
113+ _display->setTextSize (_text_sz);
114+ _display->setTextColor (SH1107_WHITE);
115+ _display->setCursor (0 , y_idx);
116+ _display->display ();
117+
118+ // Calculate the line height based on the text size (NOTE: base height is
119+ // 8px)
120+ int16_t line_height = 8 * _text_sz;
121+ uint16_t c_idx = 0 ;
122+ size_t msg_size = strlen (message);
123+ for (size_t i = 0 ; i < msg_size && c_idx < msg_size; i++) {
124+ if (message[i] == ' \\ ' && i + 1 < msg_size &&
125+ (message[i + 1 ] == ' n' || message[i + 1 ] == ' r' )) {
126+ // Handle \r\n sequence as a single newline
127+ if (message[i + 1 ] == ' r' && i + 3 < msg_size &&
128+ message[i + 2 ] == ' \\ ' && message[i + 3 ] == ' n' ) {
129+ // Skip to the next line
130+ y_idx += line_height;
131+ _display->setCursor (0 , y_idx);
132+ i += 3 ;
133+ } else if (message[i + 1 ] == ' n' ) {
134+ // Skip to the next line
135+ y_idx += line_height;
136+ _display->setCursor (0 , y_idx);
137+ i++;
138+ }
139+ } else if (message[i] == 0xC2 && message[i + 1 ] == 0xB0 ) {
140+ _display->write (char (248 ));
141+ _display->display ();
142+ i++;
143+ } else {
144+ _display->print (message[i]);
145+ _display->display ();
146+ }
147+ }
148+ }
149+
150+ protected:
151+ Adafruit_SH1107 *_display =
152+ nullptr ; // /< Pointer to the Adafruit_SH1107 object
153+ uint8_t _width; // /< Width of the display in pixels
154+ uint8_t _height; // /< Height of the display in pixels
155+ uint8_t _text_sz; // /< Text size of the display
156+ };
157+
158+ #endif // WIPPERSNAPPER_I2C_DRIVER_OUT_SH1107_H
0 commit comments