Lumitronix_Iflex_Pro_Workshop
Library to interact with the iFlexPro
SegmentDigit.h
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2 SegmentDigit provides a color object that can be directly consumed by LumitronixIFlexBus
3 
4 Written by Michael C. Miller.
5 
6 I invest time and resources providing this open source code,
7 please support me by dontating (see https://github.com/Makuna)
8 
9 -------------------------------------------------------------------------
10 This file is part of the LUMITRONIX_iFlex_Workshop library.
11 
12 LumitronixIFlexBus is free software: you can redistribute it and/or modify
13 it under the terms of the GNU Lesser General Public License as
14 published by the Free Software Foundation, either version 3 of
15 the License, or (at your option) any later version.
16 
17 LumitronixIFlexBus is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU Lesser General Public License for more details.
21 
22 You should have received a copy of the GNU Lesser General Public
23 License along with LumitronixIFlex. If not, see
24 <http://www.gnu.org/licenses/>.
25 -------------------------------------------------------------------------*/
26 #pragma once
27 
29 {
37  LedSegment_Decimal, // maybe jumpered to alternate custom segment
38  LedSegment_Custom, // generally not used but maybe connected to a custom segment
40 };
41 
43 {
44 public:
45  NeoSevenSegCurrentSettings(uint16_t segments, uint16_t decimal, uint16_t special = 0) :
46  SegmentTenthMilliAmpere(segments),
47  DecimalTenthMilliAmpere(decimal),
49  {
50  }
51 
52  uint16_t SegmentTenthMilliAmpere; // in 1/10th ma
53  uint16_t DecimalTenthMilliAmpere; // in 1/10th ma
54  uint16_t SpecialTenthMilliAmpere; // in 1/10th ma
55 };
56 
57 // ------------------------------------------------------------------------
58 // SevenSegDigit represents a color object that is represented by the segments
59 // of a 7 segment LED display digit. It contains helpful routines to manipulate
60 // and set the elements.
61 //
62 // The order represents the physical LED location starting at A, through to G, then
63 // ending at the decimal point
64 // "abcdefg."
65 // ------------------------------------------------------------------------
67 {
69 
70  // ------------------------------------------------------------------------
71  // Construct a SevenSegDigit using
72  // the default brightness to apply to all segments
73  // ------------------------------------------------------------------------
74  SevenSegDigit(uint8_t defaultBrightness)
75  {
76  memset(Segment, defaultBrightness, sizeof(Segment));
77  }
78 
79  // ------------------------------------------------------------------------
80  // Construct a SevenSegDigit using
81  // a bitmask for the segment (bit order is ".gfedcba")
82  // the brightness to apply to them, (0-255)
83  // the default brightness to apply to those not set in the bitmask (0-255)
84  // ------------------------------------------------------------------------
85  SevenSegDigit(uint8_t bitmask, uint8_t brightness, uint8_t defaultBrightness = 0);
86 
87  // ------------------------------------------------------------------------
88  // Construct a SevenSegDigit using
89  // a char that will get mapped to the segments,
90  // the brightness to apply to them, (0-255)
91  // the default brightness to apply to those not set in the bitmask (0-255)
92  // ------------------------------------------------------------------------
93  SevenSegDigit(char letter, uint8_t brightness, uint8_t defaultBrightness = 0, bool maintainCase = false);
94 
95  // ------------------------------------------------------------------------
96  // Construct a SevenSegDigit that will have its values set in latter operations
97  // CAUTION: The members are not initialized and may not be consistent
98  // ------------------------------------------------------------------------
100  {
101  };
102 
103  // ------------------------------------------------------------------------
104  // Comparison operators
105  // ------------------------------------------------------------------------
106  bool operator==(const SevenSegDigit& other) const
107  {
108  for (uint8_t iSegment = 0; iSegment < Count; iSegment++)
109  {
110  if (Segment[iSegment] != other.Segment[iSegment])
111  {
112  return false;
113  }
114  }
115  return true;
116  };
117 
118  bool operator!=(const SevenSegDigit& other) const
119  {
120  return !(*this == other);
121  };
122 
123  // ------------------------------------------------------------------------
124  // operator [] - readonly
125  // access elements in order of the Segments
126  // see static Count for the number of elements
127  // ------------------------------------------------------------------------
128  uint8_t operator[](size_t idx) const
129  {
130  return Segment[idx];
131  }
132 
133  // ------------------------------------------------------------------------
134  // operator [] - read write
135  // access elements in order by index rather than R,G,B
136  // see static Count for the number of elements
137  // ------------------------------------------------------------------------
138  uint8_t& operator[](size_t idx)
139  {
140  return Segment[idx];
141  }
142 
143  // ------------------------------------------------------------------------
144  // CalculateBrightness will calculate the overall brightness
145  // NOTE: This is a simple linear brightness
146  // ------------------------------------------------------------------------
147  uint8_t CalculateBrightness() const;
148 
149  // ------------------------------------------------------------------------
150  // Dim will return a new SevenSegDigit that is blended to off with the given ratio
151  // ratio - (0-255) where 255 will return the original brightness and 0 will return off
152  //
153  // NOTE: This is a simple linear blend
154  // ------------------------------------------------------------------------
155  SevenSegDigit Dim(uint8_t ratio) const;
156 
157  // ------------------------------------------------------------------------
158  // Brighten will return a new SevenSegDigit that is blended to full bright with the given ratio
159  // ratio - (0-255) where 255 will return the original brightness and 0 will return full brightness
160  //
161  // NOTE: This is a simple linear blend
162  // ------------------------------------------------------------------------
163  SevenSegDigit Brighten(uint8_t ratio) const;
164 
165  // ------------------------------------------------------------------------
166  // Darken will adjust the color by the given delta toward black
167  // NOTE: This is a simple linear change
168  // delta - (0-255) the amount to dim the segment
169  // ------------------------------------------------------------------------
170  void Darken(uint8_t delta);
171 
172  // ------------------------------------------------------------------------
173  // Lighten will adjust the color by the given delta toward white
174  // NOTE: This is a simple linear change
175  // delta - (0-255) the amount to lighten the segment
176  // ------------------------------------------------------------------------
177  void Lighten(uint8_t delta);
178 
179  // ------------------------------------------------------------------------
180  // LinearBlend between two colors by the amount defined by progress variable
181  // left - the segment to start the blend at
182  // right - the segment to end the blend at
183  // progress - (0.0 - 1.0) value where 0 will return left and 1.0 will return right
184  // and a value between will blend the brightness of each element
185  // weighted linearly between them
186  // ------------------------------------------------------------------------
187  static SevenSegDigit LinearBlend(const SevenSegDigit& left, const SevenSegDigit& right, float progress);
188  // progress - (0 - 255) value where 0 will return left and 255 will return right
189  // and a value between will blend the color weighted linearly between them
190  // ------------------------------------------------------------------------
191  static SevenSegDigit LinearBlend(const SevenSegDigit& left, const SevenSegDigit& right, uint8_t progress);
192 
193 
194  uint32_t CalcTotalTenthMilliAmpere(const SettingsObject& settings)
195  {
196  auto total = 0;
197 
198  for (uint8_t segment = LedSegment_A; segment < Count - 2; segment++)
199  {
200  total += Segment[segment] * settings.SegmentTenthMilliAmpere / Max;
201  }
202 
203  total += Segment[Count - 2] * settings.DecimalTenthMilliAmpere / Max;
204  total += Segment[Count - 1] * settings.SpecialTenthMilliAmpere / Max;
205 
206  return total;
207  }
208 
209  template <typename T_SET_TARGET>
210  static void SetString(T_SET_TARGET& target,
211  uint16_t indexDigit,
212  const char* str,
213  uint8_t brightness,
214  uint8_t defaultBrightness = 0)
215  {
216  if (str == nullptr)
217  {
218  return;
219  }
220 
221  const char* pFirst = str;
222  const char* pIter = str;
223 
224  // digits are right to left
225  // so find the end and start there
226  while (*pIter != '\0')
227  {
228  pIter++;
229  }
230  pIter--;
231 
232 
233  while (pIter >= pFirst)
234  {
235  bool decimal = false;
236  bool special = false;
237  char value = *pIter--;
238 
239  // must always be merged by previous char
240  // (the one to the right)
241  // so if repeated ignore it
242  //
243  if (value == ':' || value == ';')
244  {
245  continue;
246  }
247 
248  // check if merging a decimal with the next char is required
249  // (the one to the left)
250  //
251  if (pIter >= pFirst && (value == '.' || value == ','))
252  {
253  // merge a decimal as long as they aren't the same
254  if (*(pIter) != value)
255  {
256  decimal = true;
257  value = *pIter--; // use the next char
258  }
259  }
260 
261  // check next char for colon
262  //
263  if (pIter >= pFirst && (*pIter == ':' || *pIter == ';'))
264  {
265  // the colon is custom extension using the decimal AND the special
266  // channels
267  special = true;
268  decimal = true;
269  pIter--; // skip colon
270  }
271 
272  SevenSegDigit digit(value, brightness, defaultBrightness);
273  if (decimal)
274  {
275  digit.Segment[LedSegment_Decimal] = brightness;
276  }
277  if (special)
278  {
279  digit.Segment[LedSegment_Custom] = brightness;
280  }
281  target.SetPixelColor(indexDigit, digit);
282  indexDigit++;
283  }
284  }
285 
286  // ------------------------------------------------------------------------
287  // segment members (0-255) where each represents the segment location
288  // and the value defines the brightnes (0) is off and (255) is full brightness
289  // ------------------------------------------------------------------------
290  static const uint8_t Count = 9;
291  uint8_t Segment[Count];
292 
293  const static uint8_t Max = 255;
294 
295  // segment decode maps from ascii relative first char in map to a bitmask of segments
296  //
297  static const uint8_t DecodeNumbers[10]; // 0-9
298  static const uint8_t DecodeAlphaCaps[26]; // A-Z
299  static const uint8_t DecodeAlpha[26]; // a-z
300  static const uint8_t DecodeSpecial[4]; // , - . /
301 
302 protected:
303  void init(uint8_t bitmask, uint8_t brightness, uint8_t defaultBrightness);
304 
305  inline static uint8_t _elementDim(uint8_t value, uint8_t ratio)
306  {
307  return (static_cast<uint16_t>(value) * (static_cast<uint16_t>(ratio) + 1)) >> 8;
308  }
309 
310  inline static uint8_t _elementBrighten(uint8_t value, uint8_t ratio)
311  {
312  uint16_t element = ((static_cast<uint16_t>(value) + 1) << 8) / (static_cast<uint16_t>(ratio) + 1);
313 
314  if (element > Max)
315  {
316  element = Max;
317  }
318  else
319  {
320  element -= 1;
321  }
322  return element;
323  }
324 };
325 
LedSegment
Definition: SegmentDigit.h:29
@ LedSegment_COUNT
Definition: SegmentDigit.h:39
@ LedSegment_E
Definition: SegmentDigit.h:34
@ LedSegment_G
Definition: SegmentDigit.h:36
@ LedSegment_D
Definition: SegmentDigit.h:33
@ LedSegment_F
Definition: SegmentDigit.h:35
@ LedSegment_Custom
Definition: SegmentDigit.h:38
@ LedSegment_B
Definition: SegmentDigit.h:31
@ LedSegment_C
Definition: SegmentDigit.h:32
@ LedSegment_Decimal
Definition: SegmentDigit.h:37
@ LedSegment_A
Definition: SegmentDigit.h:30
Definition: SegmentDigit.h:43
uint16_t SegmentTenthMilliAmpere
Definition: SegmentDigit.h:52
uint16_t SpecialTenthMilliAmpere
Definition: SegmentDigit.h:54
uint16_t DecimalTenthMilliAmpere
Definition: SegmentDigit.h:53
NeoSevenSegCurrentSettings(uint16_t segments, uint16_t decimal, uint16_t special=0)
Definition: SegmentDigit.h:45
Definition: SegmentDigit.h:67
static const uint8_t Max
Definition: SegmentDigit.h:293
SevenSegDigit()
Definition: SegmentDigit.h:99
static uint8_t _elementDim(uint8_t value, uint8_t ratio)
Definition: SegmentDigit.h:305
uint8_t & operator[](size_t idx)
Definition: SegmentDigit.h:138
uint32_t CalcTotalTenthMilliAmpere(const SettingsObject &settings)
Definition: SegmentDigit.h:194
SevenSegDigit(uint8_t defaultBrightness)
Definition: SegmentDigit.h:74
uint8_t Segment[Count]
Definition: SegmentDigit.h:291
static const uint8_t DecodeNumbers[10]
Definition: SegmentDigit.h:297
void Darken(uint8_t delta)
Definition: SegmentDigit.cpp:145
void Lighten(uint8_t delta)
Definition: SegmentDigit.cpp:162
uint8_t operator[](size_t idx) const
Definition: SegmentDigit.h:128
static const uint8_t Count
Definition: SegmentDigit.h:290
bool operator==(const SevenSegDigit &other) const
Definition: SegmentDigit.h:106
static const uint8_t DecodeAlpha[26]
Definition: SegmentDigit.h:299
static uint8_t _elementBrighten(uint8_t value, uint8_t ratio)
Definition: SegmentDigit.h:310
bool operator!=(const SevenSegDigit &other) const
Definition: SegmentDigit.h:118
static SevenSegDigit LinearBlend(const SevenSegDigit &left, const SevenSegDigit &right, float progress)
Definition: SegmentDigit.cpp:179
SevenSegDigit Brighten(uint8_t ratio) const
Definition: SegmentDigit.cpp:134
NeoSevenSegCurrentSettings SettingsObject
Definition: SegmentDigit.h:68
SevenSegDigit Dim(uint8_t ratio) const
Definition: SegmentDigit.cpp:123
static const uint8_t DecodeAlphaCaps[26]
Definition: SegmentDigit.h:298
uint8_t CalculateBrightness() const
Definition: SegmentDigit.cpp:111
static const uint8_t DecodeSpecial[4]
Definition: SegmentDigit.h:300
void init(uint8_t bitmask, uint8_t brightness, uint8_t defaultBrightness)
Definition: SegmentDigit.cpp:61
static void SetString(T_SET_TARGET &target, uint16_t indexDigit, const char *str, uint8_t brightness, uint8_t defaultBrightness=0)
Definition: SegmentDigit.h:210