1+ /* !
2+ * @file drvOut7Seg.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 DRV_OUT_7SEG_H
22+ #define DRV_OUT_7SEG_H
23+
24+ #include " drvOutputBase.h"
25+ #include < Adafruit_LEDBackpack.h>
26+ #include < Arduino.h>
27+
28+ #define LED_BACKPACK_ALIGNMENT_UNSPECIFIED 0
29+ #define LED_BACKPACK_ALIGNMENT_LEFT 1
30+ #define LED_BACKPACK_ALIGNMENT_RIGHT 2
31+ #define LED_BACKPACK_ALIGNMENT_DEFAULT LED_BACKPACK_ALIGNMENT_LEFT
32+ #define LED_MAX_CHARS 4
33+
34+ /* !
35+ @brief Class that provides a driver for an Adafruit 7-Segment LED matrix
36+ w/I2C backpack.
37+ */
38+ class drvOut7Seg : public drvOutputBase {
39+ public:
40+ /* !
41+ @brief Constructor for an Adafruit 7-Segment LED matrix w/I2C backpack.
42+ @param i2c
43+ The I2C interface.
44+ @param sensorAddress
45+ 7-bit device address.
46+ @param mux_channel
47+ The I2C multiplexer channel.
48+ @param driver_name
49+ The name of the driver.
50+ */
51+ drvOut7Seg (TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel,
52+ const char *driver_name)
53+ : drvOutputBase(i2c, sensorAddress, mux_channel, driver_name) {
54+ // Initialization handled by drvBase constructor
55+ }
56+
57+ /* !
58+ @brief Destructor for an Adafruit 7-Segment LED matrix w/I2C backpack.
59+ */
60+ ~drvOut7Seg () {
61+ if (_matrix) {
62+ delete _matrix;
63+ _matrix = nullptr ;
64+ }
65+ }
66+
67+ /* !
68+ @brief Initializes the 7-segment LED matrix and begins I2C
69+ communication.
70+ @returns True if initialized successfully, False otherwise.
71+ */
72+ bool begin () override {
73+ _matrix = new Adafruit_7segment ();
74+ bool did_begin = _matrix->begin (0x70 , _i2c);
75+ return did_begin;
76+ }
77+
78+ /* !
79+ @brief Configures the LED matrix's I2C backpack.
80+ @param brightness
81+ The brightness of the i2c backpack (0-15).
82+ @param alignment
83+ The alignment of the i2c backpack's LED matrix (left/right).
84+ */
85+ void ConfigureI2CBackpack (int32_t brightness, uint32_t alignment) {
86+ if (alignment == LED_BACKPACK_ALIGNMENT_RIGHT) {
87+ _alignment = LED_BACKPACK_ALIGNMENT_RIGHT;
88+ } else {
89+ _alignment = LED_BACKPACK_ALIGNMENT_DEFAULT;
90+ }
91+
92+ // Note: Adafruit_LEDBackpack normalizes only > 15, but not < 0,
93+ // so, here we're normalizing < 0 to 8 (median brightness)
94+ if (brightness < 0 ) {
95+ brightness = 8 ; // Set to median brightness if out of range
96+ }
97+ }
98+
99+ /* !
100+ @brief Sets the brightness of the LED backpack.
101+ @param b
102+ The brightness value, from 0 (off) to 15 (full brightness).
103+ */
104+ void SetLedBackpackBrightness (uint8_t b) {
105+ if (_matrix == nullptr ) {
106+ return ;
107+ }
108+ _matrix->setBrightness (b);
109+ }
110+
111+ /* !
112+ @brief Writes the first four characters of a message to the Adafruit
113+ 7-segment LED matrix.
114+ @param message
115+ The message to be displayed.
116+ */
117+ void WriteMessage (const char *message) {
118+ if (_matrix == nullptr || message == nullptr ) {
119+ return ;
120+ }
121+
122+ // Clear before writing
123+ _matrix->clear ();
124+
125+ // Calculate the number of characters to display
126+ size_t len_display = min (strlen (message), (size_t )LED_MAX_CHARS);
127+
128+ // Set the starting position based on alignment
129+ int pos_start;
130+ if (_alignment == LED_BACKPACK_ALIGNMENT_LEFT) {
131+ pos_start = 0 ; // start at the leftmost position of the display
132+ } else {
133+ // Exclude decimal points from the character count because those get
134+ // displayed on a "special" segment of the LED display
135+ int seg_chars = 0 ;
136+ for (size_t i = 0 ; i < len_display; i++) {
137+ if (message[i] != ' .' ) {
138+ seg_chars++;
139+ }
140+ }
141+ // start at the rightmost position of the display
142+ pos_start = LED_MAX_CHARS - seg_chars;
143+ }
144+
145+ // Write to the display's buffer
146+ int cur_idx = pos_start;
147+ for (size_t i = 0 ; i < len_display; i++) {
148+ // skip position 2
149+ if (cur_idx == 2 ) {
150+ cur_idx++;
151+ }
152+ // Save the character because if there's a decimal, we need to skip it in
153+ // the buffer
154+ char ch = message[i];
155+
156+ // Look-ahead for a decimal point to attach to the current character
157+ bool display_dot = false ;
158+ if (i + 1 < len_display && message[i + 1 ] == ' .' ) {
159+ display_dot = true ;
160+ i++;
161+ len_display++;
162+ }
163+
164+ // Write the character to the display buffer
165+ _matrix->writeDigitAscii (cur_idx, ch, display_dot);
166+ cur_idx++;
167+ }
168+ // Issue the buffered data in RAM to the display
169+ _matrix->writeDisplay ();
170+ }
171+
172+ /* !
173+ @brief Writes a floating point value to the Adafruit 7-segment LED
174+ matrix.
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), " %.5f" , value);
182+ WriteMessage (message);
183+ }
184+
185+ /* !
186+ @brief Writes an integer value to the Adafruit 7-segment LED matrix.
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 // DRV_OUT_7SEG_H
0 commit comments