Skip to content

Commit 00bb2bf

Browse files
committed
Add 7seg driver
1 parent 645fd4d commit 00bb2bf

File tree

3 files changed

+222
-0
lines changed

3 files changed

+222
-0
lines changed

src/components/i2c/WipperSnapper_I2C.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,19 @@ bool WipperSnapper_Component_I2C::initI2CDevice(
865865
}
866866
_drivers_out.push_back(_charLcd);
867867
WS_DEBUG_PRINTLN("Char LCD Display Initialized Successfully!");
868+
} else if (strcmp("7seg", msgDeviceInitReq->i2c_device_name) == 0) {
869+
_sevenSeg = new WipperSnapper_I2C_Driver_Out_7Seg(this->_i2c, i2cAddress);
870+
_sevenSeg->ConfigureCharLcd(
871+
msgDeviceInitReq->i2c_output_add.config.char_lcd_config.rows,
872+
msgDeviceInitReq->i2c_output_add.config.char_lcd_config.columns, true);
873+
if (!_sevenSeg->begin()) {
874+
WS_DEBUG_PRINTLN("ERROR: Failed to initialize 7-Segement LED Matrix!");
875+
_busStatusResponse =
876+
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
877+
return false;
878+
}
879+
_drivers_out.push_back(_sevenSeg);
880+
WS_DEBUG_PRINTLN("7-Segement LED Matrix Initialized Successfully!");
868881
} else {
869882
WS_DEBUG_PRINTLN("ERROR: I2C device type not found!")
870883
_busStatusResponse =

src/components/i2c/WipperSnapper_I2C.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include "drivers/WipperSnapper_I2C_Driver_MS8607.h"
5252
#include "drivers/WipperSnapper_I2C_Driver_NAU7802.h"
5353
#include "drivers/WipperSnapper_I2C_Driver_Out.h"
54+
#include "drivers/WipperSnapper_I2C_Driver_Out_7Seg.h"
5455
#include "drivers/WipperSnapper_I2C_Driver_Out_CharLcd.h"
5556
#include "drivers/WipperSnapper_I2C_Driver_Out_QuadAlphaNum.h"
5657
#include "drivers/WipperSnapper_I2C_Driver_PCT2075.h"
@@ -201,6 +202,7 @@ class WipperSnapper_Component_I2C {
201202
WipperSnapper_I2C_Driver_ADT7410 *_adt7410 = nullptr;
202203
WipperSnapper_I2C_Driver_Out_QuadAlphaNum *_quadAlphaNum = nullptr;
203204
WipperSnapper_I2C_Driver_Out_CharLcd *_charLcd = nullptr;
205+
WipperSnapper_I2C_Driver_Out_7Seg *_sevenSeg = nullptr;
204206
};
205207
extern Wippersnapper WS;
206208

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
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

Comments
 (0)