1
+ /* !
2
+ * @file WipperSnapper_I2C_Driver_Out_7Seg.h
3
+ *
4
+ * Device driver designed specifically to work with the Adafruit LED 7-Segment
5
+ * I2C backpacks:
6
+ * ----> http://www.adafruit.com/products/881
7
+ * ----> http://www.adafruit.com/products/880
8
+ * ----> http://www.adafruit.com/products/879
9
+ * ----> http://www.adafruit.com/products/878
10
+ *
11
+ * Adafruit invests time and resources providing this open source code,
12
+ * please support Adafruit and open-source hardware by purchasing
13
+ * products from Adafruit!
14
+ *
15
+ * Copyright (c) Brent Rubell for Adafruit Industries 2025
16
+ *
17
+ * MIT license, all text here must be included in any redistribution.
18
+ *
19
+ */
20
+
21
+ #ifndef WIPPERSNAPPER_I2C_DRIVER_OUT_7SEG_H
22
+ #define WIPPERSNAPPER_I2C_DRIVER_OUT_7SEG_H
23
+
24
+ #include " WipperSnapper_I2C_Driver_Out.h"
25
+ #include < Adafruit_LEDBackpack.h>
26
+ #include < Arduino.h>
27
+
28
+ #define LED_BACKPACK_ALIGNMENT_UNSPECIFIED 0 // /< Unspecified alignment
29
+ #define LED_BACKPACK_ALIGNMENT_LEFT 1 // /< Left alignment
30
+ #define LED_BACKPACK_ALIGNMENT_RIGHT 2 // /< Right alignment
31
+ #define LED_BACKPACK_ALIGNMENT_DEFAULT \
32
+ LED_BACKPACK_ALIGNMENT_LEFT // /< Default alignment
33
+ #define LED_MAX_CHARS \
34
+ 4 // /< Maximum number of characters to display on the alphanumeric display
35
+
36
+
37
+ /* !
38
+ @brief Class that provides a driver interface for 7-Segment
39
+ Displays w/I2C Backpack
40
+ */
41
+ class WipperSnapper_I2C_Driver_Out_7Seg : public WipperSnapper_I2C_Driver_Out {
42
+
43
+ public:
44
+ /* ******************************************************************************/
45
+ /* !
46
+ @brief Constructor for a 7-Segment display driver.
47
+ @param i2c
48
+ The I2C interface.
49
+ @param sensorAddress
50
+ 7-bit device address.
51
+ */
52
+ /* ******************************************************************************/
53
+ WipperSnapper_I2C_Driver_Out_7Seg (TwoWire *i2c, uint16_t sensorAddress) : WipperSnapper_I2C_Driver_Out(i2c, sensorAddress) {
54
+ _i2c = i2c;
55
+ _sensorAddress = sensorAddress;
56
+ }
57
+
58
+ /* !
59
+ @brief Destructor for a 7-Segment display driver.
60
+ */
61
+ ~WipperSnapper_I2C_Driver_Out_7Seg () {
62
+ if (_matrix != nullptr ) {
63
+ delete _matrix;
64
+ _matrix = nullptr ;
65
+ }
66
+ }
67
+
68
+ /* !
69
+ @brief Initializes the 7-segment LED matrix and begins I2C
70
+ communication.
71
+ @returns True if initialized successfully, False otherwise.
72
+ */
73
+ bool begin () {
74
+ _matrix = new Adafruit_7segment ();
75
+ bool did_begin = _matrix->begin (_sensorAddress, _i2c);
76
+ return did_begin;
77
+ }
78
+
79
+ /* !
80
+ @brief Configures the LED matrix's I2C backpack.
81
+ @param brightness
82
+ The brightness of the i2c backpack (0-15).
83
+ @param alignment
84
+ The alignment of the i2c backpack's LED matrix (left/right).
85
+ */
86
+ void ConfigureI2CBackpack (int32_t brightness, uint32_t alignment) {
87
+ if (alignment == LED_BACKPACK_ALIGNMENT_RIGHT) {
88
+ _alignment = LED_BACKPACK_ALIGNMENT_RIGHT;
89
+ } else {
90
+ _alignment = LED_BACKPACK_ALIGNMENT_DEFAULT;
91
+ }
92
+
93
+ // Note: Adafruit_LEDBackpack normalizes only > 15, but not < 0,
94
+ // so, here we're normalizing < 0 to 8 (median brightness)
95
+ if (brightness < 0 ) {
96
+ brightness = 8 ; // Set to median brightness if out of range
97
+ }
98
+ }
99
+
100
+ /* !
101
+ @brief Sets the brightness of the LED backpack.
102
+ @param b
103
+ The brightness value, from 0 (off) to 15 (full brightness).
104
+ */
105
+ void SetLedBackpackBrightness (uint8_t b) {
106
+ if (_matrix == nullptr ) {
107
+ return ;
108
+ }
109
+ _matrix->setBrightness (b);
110
+ }
111
+
112
+ /* !
113
+ @brief Writes the first four characters of a message to the Adafruit
114
+ 7-segment LED matrix.
115
+ @param message
116
+ The message to be displayed.
117
+ */
118
+ void WriteMessage (const char *message) {
119
+ if (_matrix == nullptr || message == nullptr ) {
120
+ return ;
121
+ }
122
+
123
+ // Clear before writing
124
+ _matrix->clear ();
125
+
126
+ // Calculate the number of characters to display
127
+ size_t len_display = min (strlen (message), (size_t )LED_MAX_CHARS);
128
+
129
+ // Set the starting position based on alignment
130
+ int pos_start;
131
+ if (_alignment == LED_BACKPACK_ALIGNMENT_LEFT) {
132
+ pos_start = 0 ; // start at the leftmost position of the display
133
+ } else {
134
+ // Exclude decimal points from the character count because those get
135
+ // displayed on a "special" segment of the LED display
136
+ int seg_chars = 0 ;
137
+ for (size_t i = 0 ; i < len_display; i++) {
138
+ if (message[i] != ' .' ) {
139
+ seg_chars++;
140
+ }
141
+ }
142
+ // start at the rightmost position of the display
143
+ pos_start = LED_MAX_CHARS - seg_chars;
144
+ }
145
+
146
+ // Write to the display's buffer
147
+ int cur_idx = pos_start;
148
+ for (size_t i = 0 ; i < len_display; i++) {
149
+ // skip position 2
150
+ if (cur_idx == 2 ) {
151
+ cur_idx++;
152
+ }
153
+ // Save the character because if there's a decimal, we need to skip it in
154
+ // the buffer
155
+ char ch = message[i];
156
+
157
+ // Look-ahead for a decimal point to attach to the current character
158
+ bool display_dot = false ;
159
+ if (i + 1 < len_display && message[i + 1 ] == ' .' ) {
160
+ display_dot = true ;
161
+ i++;
162
+ len_display++;
163
+ }
164
+
165
+ // Write the character to the display buffer
166
+ _matrix->writeDigitAscii (cur_idx, ch, display_dot);
167
+ cur_idx++;
168
+ }
169
+ // Issue the buffered data in RAM to the display
170
+ _matrix->writeDisplay ();
171
+ }
172
+
173
+ /* !
174
+ @brief Writes a floating point value to the 7-segment display.
175
+ @param value
176
+ The value to be displayed. Only the first four digits are
177
+ displayed.
178
+ */
179
+ void WriteValue (float value) {
180
+ char message[8 + 1 ];
181
+ snprintf (message, sizeof (message), " %.2f" , value); // Less precision for 7-segment
182
+ WriteMessage (message);
183
+ }
184
+
185
+ /* !
186
+ @brief Writes an integer value to the 7-segment display.
187
+ @param value
188
+ The value to be displayed. Only the first four digits are
189
+ displayed.
190
+ */
191
+ void WriteValue (int32_t value) {
192
+ char message[LED_MAX_CHARS + 1 ];
193
+ snprintf (message, sizeof (message), " %ld" , value);
194
+ WriteMessage (message);
195
+ }
196
+
197
+ protected:
198
+ Adafruit_7segment *_matrix =
199
+ nullptr ; // /< ptr to a 7-segment LED matrix object
200
+ int32_t _brightness; // /< Brightness of the LED backpack, from 0 (off) to 15
201
+ // /< (full brightness)
202
+ uint32_t _alignment =
203
+ LED_BACKPACK_ALIGNMENT_DEFAULT; // /< Determines L/R alignment of the
204
+ // /< message displayed
205
+ };
206
+
207
+ #endif // WIPPERSNAPPER_I2C_DRIVER_OUT_7SEG_H
0 commit comments