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