Seven segment (#293)

This commit is contained in:
Michael Miller
2019-09-25 00:49:24 -07:00
committed by GitHub
parent 0177b8d519
commit 7c9ac59ddd
10 changed files with 760 additions and 13 deletions

View File

@@ -0,0 +1,36 @@
// NeoSegmentBus
// This example will demonstrate using the NeoSegmentBus which provides support for a
// seven segment LED digit driven by three WS2811; connected in series with other digits
//
// See https://shop.idlehandsdev.com/products/addressable-7-segment-display for a hardware example
//
// This example will print the string "3.14" and then rotate it through the available digits
//
#include <NeoPixelSegmentBus.h>
const uint16_t DigitCount = 4; // Max Digits, not segments, not pixels
const uint8_t BusPin = 2; // make sure to set this to the correct pin, ignored for Esp8266
#define brightness 128
NeoPixelSegmentBus<SevenSegmentFeature, Neo800KbpsMethod> strip(DigitCount, BusPin);
void setup()
{
strip.Begin();
strip.Show(); // clears all digits by default
delay(500);
strip.SetString(0, "3.14", brightness);
strip.Show();
}
void loop()
{
delay(2000);
strip.RotateLeft(1);
strip.Show();
}

View File

@@ -0,0 +1,144 @@
// NeoSegmentBus
// This example will demonstrate using the NeoSegmentBus which provides support for a
// seven segment LED digit driven by three WS2811; connected in series with other digits
//
// See https://shop.idlehandsdev.com/products/addressable-7-segment-display for a hardware example
//
// This example will print current seconds since start of the Arduino
// with a digit animating a circling path for each second
//
#include <NeoPixelSegmentBus.h>
#include <NeoPixelAnimator.h>
const uint16_t DigitCount = 5; // Max Digits, not segments, not pixels
const uint8_t BusPin = 2; // make sure to set this to the correct pin, ignored for Esp8266
const uint16_t CycleDigit = 0;
const uint16_t SecondsDigit = 1;
#define brightness 128
NeoPixelSegmentBus<SevenSegmentFeature, Neo800KbpsMethod> strip(DigitCount, BusPin);
enum Animation
{
Animation_Cycle, // animation for the cycle indicator
Animation_Fade, // animation for fade of seconds
Animation_COUNT
};
NeoPixelAnimator animations(Animation_COUNT);
void CycleAnimation(const AnimationParam& param)
{
// calculate which segment should be on using the animation progress
uint8_t bitfield = 1 << (uint8_t)(param.progress * LedSegment_F);
// instant a digit with that segment on
SevenSegDigit digit(bitfield, brightness);
// apply it to the strip
strip.SetPixelColor(CycleDigit, digit);
}
// for the animation of fading the new number in, we use
// two digit DIBs (Device Independant Bitmaps) of SevenSegDigit to blend with;
// each sized one less than the strip due to the first is a used for the cycle
// animation.
typedef NeoDib<SevenSegDigit> SevenSegDib;
SevenSegDib StartingDigits(DigitCount - 1);
SevenSegDib EndingDigits(DigitCount - 1);
// shader class that will do the "string" blending
//
class DigitBlendShader
{
public:
// this shader always renders and doesn't track a dirty state
bool IsDirty() const
{
return true;
}
void ResetDirty()
{
}
SevenSegDigit Apply(uint16_t indexDigit, SevenSegDigit digit)
{
// since we call EndingDigits.Render below, the digit argument is
// from the EndingDigits so no need to call GetPixelColor to get it
// create a digit that is a blend between the last seconds
// value and the next seconds value using the BlendAmount
SevenSegDigit blendDigit = SevenSegDigit::LinearBlend(
StartingDigits.GetPixelColor(indexDigit),
digit,
BlendAmount);
return blendDigit;
}
float BlendAmount;
};
// the instance of our shader class
DigitBlendShader blendShader;
void FadeAnimation(const AnimationParam& param)
{
// set the shader property BlendAmount to the animation progress
blendShader.BlendAmount = param.progress;
// apply it to the strip at the SecondsDigit location
EndingDigits.Render<SevenSegmentFeature, DigitBlendShader>(strip,
blendShader,
SecondsDigit);
}
uint32_t lastSeconds;
void setup()
{
lastSeconds = millis() / 1000;
strip.Begin();
strip.Show();
// init animation Dibs as cleared
StartingDigits.ClearTo(0);
EndingDigits.ClearTo(0);
}
void loop()
{
uint32_t seconds = millis() / 1000;
// when the seconds change, start animations for the update
//
if (seconds != lastSeconds)
{
// copy last animation ending digits as starting digits
StartingDigits = EndingDigits;
// format and display new value in ending digits dib
String display(seconds);
SevenSegDigit::SetString<SevenSegDib>(EndingDigits,
0,
display.c_str(),
brightness);
// start the seconds fade animation
animations.StartAnimation(Animation_Fade, 1000, FadeAnimation);
// start the cycle animation for the next second
animations.StartAnimation(Animation_Cycle, 1000, CycleAnimation);
lastSeconds = seconds;
}
if (animations.IsAnimating())
{
// the normal loop just needs these two to run the active animations
animations.UpdateAnimations();
strip.Show();
}
}

View File

@@ -153,7 +153,6 @@ private:
_duration = duration;
_remaining = duration;
_fnCallback = animUpdate;
}
void StopAnimation()

View File

@@ -43,10 +43,12 @@ License along with NeoPixel. If not, see
#include "internal/HsbColor.h"
#include "internal/HtmlColor.h"
#include "internal/RgbwColor.h"
#include "internal/SegmentDigit.h"
#include "internal/NeoColorFeatures.h"
#include "internal/DotStarColorFeatures.h"
#include "internal/Lpd8806ColorFeatures.h"
#include "internal/NeoSegmentFeatures.h"
#include "internal/Layouts.h"
#include "internal/NeoTopology.h"

67
src/NeoPixelSegmentBus.h Normal file
View File

@@ -0,0 +1,67 @@
/*-------------------------------------------------------------------------
NeoPixelBus library wrapper template class that provides enhanced methods
for writing to segment based strips
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
-------------------------------------------------------------------------
This file is part of the Makuna/NeoPixelBus library.
NeoPixelBus is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
NeoPixelBus is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#pragma once
#include "NeoPixelBus.h"
template<typename T_COLOR_FEATURE, typename T_METHOD> class NeoPixelSegmentBus :
public NeoPixelBus<T_COLOR_FEATURE, T_METHOD>
{
public:
NeoPixelSegmentBus(uint16_t countPixels, uint8_t pin) :
NeoPixelBus<T_COLOR_FEATURE, T_METHOD>(countPixels, pin)
{
}
NeoPixelSegmentBus(uint16_t countPixels) :
NeoPixelBus<T_COLOR_FEATURE, T_METHOD>(countPixels)
{
}
void SetString(uint16_t indexDigit,
const char* str,
uint8_t brightness,
uint8_t defaultBrightness = 0)
{
T_COLOR_FEATURE::ColorObject::SetString(*this,
indexDigit,
str,
brightness,
defaultBrightness);
}
void SetString(uint16_t indexDigit,
const String& str,
uint8_t brightness,
uint8_t defaultBrightness = 0)
{
SetString(indexDigit, str.c_str(), brightness, defaultBrightness);
}
};

View File

@@ -45,9 +45,10 @@ public:
uint8_t* pEnd = pPixelDest + (count * PixelSize);
while (pPixelDest < pEnd)
{
*pPixelDest++ = pPixelSrc[0];
*pPixelDest++ = pPixelSrc[1];
*pPixelDest++ = pPixelSrc[2];
for (uint8_t iElement = 0; iElement < PixelSize; iElement++)
{
*pPixelDest++ = pPixelSrc[iElement];
}
}
}
@@ -57,8 +58,6 @@ public:
while (pPixelDest < pEnd)
{
*pPixelDest++ = *pPixelSrc++;
*pPixelDest++ = *pPixelSrc++;
*pPixelDest++ = *pPixelSrc++;
}
}
@@ -69,8 +68,6 @@ public:
while (pPixelDest < pEnd)
{
*pPixelDest++ = pgm_read_byte(pSrc++);
*pPixelDest++ = pgm_read_byte(pSrc++);
*pPixelDest++ = pgm_read_byte(pSrc++);
}
}
@@ -81,8 +78,6 @@ public:
while (pDestBack > pPixelDest)
{
*--pDestBack = *--pSrcBack;
*--pDestBack = *--pSrcBack;
*--pDestBack = *--pSrcBack;
}
}

View File

@@ -94,6 +94,25 @@ public:
free((uint8_t*)_pixels);
}
NeoDib& operator=(const NeoDib& other)
{
// check for self-assignment
if (&other == this)
{
return *this;
}
uint16_t copyCount = other.PixelCount() < PixelCount() ? other.PixelCount() : PixelCount();
for (uint16_t pixel = 0; pixel < copyCount; pixel++)
{
_pixels[pixel] = other.Pixels()[pixel];
}
Dirty();
return *this;
}
T_COLOR_OBJECT* Pixels() const
{
return _pixels;
@@ -144,8 +163,8 @@ public:
Dirty();
};
template <typename T_COLOR_FEATURE, typename T_SHADER> void Render(NeoBufferContext<T_COLOR_FEATURE> destBuffer,
T_SHADER& shader)
template <typename T_COLOR_FEATURE, typename T_SHADER>
void Render(NeoBufferContext<T_COLOR_FEATURE> destBuffer, T_SHADER& shader, uint16_t destIndexPixel = 0)
{
if (IsDirty() || shader.IsDirty())
{
@@ -159,7 +178,7 @@ public:
for (uint16_t indexPixel = 0; indexPixel < countPixels; indexPixel++)
{
T_COLOR_OBJECT color = shader.Apply(indexPixel, _pixels[indexPixel]);
T_COLOR_FEATURE::applyPixelColor(destBuffer.Pixels, indexPixel, color);
T_COLOR_FEATURE::applyPixelColor(destBuffer.Pixels, destIndexPixel + indexPixel, color);
}
shader.ResetDirty();

View File

@@ -0,0 +1,130 @@
/*-------------------------------------------------------------------------
NeoSegmentFeatures provides feature classes to describe seven segment display
elements for NeoPixelBus template class
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
-------------------------------------------------------------------------
This file is part of the Makuna/NeoPixelBus library.
NeoPixelBus is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
NeoPixelBus is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#pragma once
class Neo9Elements
{
public:
static const size_t PixelSize = 9; // three 3 element
static uint8_t* getPixelAddress(uint8_t* pPixels, uint16_t indexPixel)
{
return pPixels + indexPixel * PixelSize;
}
static const uint8_t* getPixelAddress(const uint8_t* pPixels, uint16_t indexPixel)
{
return pPixels + indexPixel * PixelSize;
}
static void replicatePixel(uint8_t* pPixelDest, const uint8_t* pPixelSrc, uint16_t count)
{
uint8_t* pEnd = pPixelDest + (count * PixelSize);
while (pPixelDest < pEnd)
{
for (uint8_t iElement = 0; iElement < PixelSize; iElement++)
{
*pPixelDest++ = pPixelSrc[iElement];
}
}
}
static void movePixelsInc(uint8_t* pPixelDest, const uint8_t* pPixelSrc, uint16_t count)
{
uint8_t* pEnd = pPixelDest + (count * PixelSize);
while (pPixelDest < pEnd)
{
*pPixelDest++ = *pPixelSrc++;
}
}
static void movePixelsInc_P(uint8_t* pPixelDest, PGM_VOID_P pPixelSrc, uint16_t count)
{
uint8_t* pEnd = pPixelDest + (count * PixelSize);
const uint8_t* pSrc = (const uint8_t*)pPixelSrc;
while (pPixelDest < pEnd)
{
*pPixelDest++ = pgm_read_byte(pSrc++);
}
}
static void movePixelsDec(uint8_t* pPixelDest, const uint8_t* pPixelSrc, uint16_t count)
{
uint8_t* pDestBack = pPixelDest + (count * PixelSize);
const uint8_t* pSrcBack = pPixelSrc + (count * PixelSize);
while (pDestBack > pPixelDest)
{
*--pDestBack = *--pSrcBack;
}
}
typedef SevenSegDigit ColorObject;
};
// Abcdefg byte order
class NeoAbcdefgSegmentFeature : public Neo9Elements
{
public:
static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color)
{
uint8_t* p = getPixelAddress(pPixels, indexPixel);
uint8_t commonSize = (PixelSize < color.SegmentCount) ? PixelSize : color.SegmentCount;
for (uint8_t iSegment = 0; iSegment < commonSize; iSegment++)
{
*p++ = color.Segment[iSegment];
}
}
static ColorObject retrievePixelColor(uint8_t* pPixels, uint16_t indexPixel)
{
ColorObject color;
uint8_t* p = getPixelAddress(pPixels, indexPixel);
uint8_t commonSize = (PixelSize < color.SegmentCount) ? PixelSize : color.SegmentCount;
for (uint8_t iSegment = 0; iSegment < commonSize; iSegment++)
{
color.Segment[iSegment] = *p++;
}
return color;
}
static ColorObject retrievePixelColor_P(PGM_VOID_P pPixels, uint16_t indexPixel)
{
ColorObject color;
const uint8_t* p = getPixelAddress((const uint8_t*)pPixels, indexPixel);
uint8_t commonSize = (PixelSize < color.SegmentCount) ? PixelSize : color.SegmentCount;
for (uint8_t iSegment = 0; iSegment < commonSize; iSegment++)
{
color.Segment[iSegment] = pgm_read_byte(p++);
}
return color;
}
};
typedef NeoAbcdefgSegmentFeature SevenSegmentFeature; // Abcdefg order is default

View File

@@ -0,0 +1,153 @@
/*-------------------------------------------------------------------------
SegmentDigit provides a color object that can be directly consumed by NeoPixelBus
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
-------------------------------------------------------------------------
This file is part of the Makuna/NeoPixelBus library.
NeoPixelBus is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
NeoPixelBus is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#include "SegmentDigit.h"
//
// https://en.wikichip.org/wiki/seven-segment_display/representing_letters
//
const uint8_t SevenSegDigit::DecodeNumbers[] = {
// 0 1 2 3 4 5 6 7 8 9
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F };
const uint8_t SevenSegDigit::DecodeAlphaCaps[] = {
// A B C D E F G
0x77, 0x00, 0x39, 0x00, 0x79, 0x71, 0x3D,
// H I J K L M N
0x76, 0x30, 0x1E, 0x00, 0x38, 0x00, 0x00,
// O P Q R S
0x3F, 0x73, 0x00, 0x00, 0x6D,
// T U V W X Y Z
0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00 };
const uint8_t SevenSegDigit::DecodeAlpha[] = {
// a b c d e f g
0x00, 0x7C, 0x58, 0x5E, 0x00, 0x00, 0x00,
// h i j k l m n
0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54,
// o p q r s
0x5C, 0x00, 0x67, 0x50, 0x00,
// t u v w x y z
0x78, 0x1C, 0x00, 0x00, 0x00, 0x6E, 0x00 };
const uint8_t SevenSegDigit::DecodeSpecial[] = {
// , - . /
0x80, 0x40, 0x80, 0x40 };
void SevenSegDigit::init(uint8_t bitmask, uint8_t brightness, uint8_t defaultBrightness)
{
for (uint8_t iSegment = 0; iSegment < SegmentCount; iSegment++)
{
Segment[iSegment] = (bitmask & 0x01) ? brightness : defaultBrightness;
bitmask >>= 1;
}
}
SevenSegDigit::SevenSegDigit(uint8_t bitmask, uint8_t brightness, uint8_t defaultBrightness)
{
init(bitmask, brightness, defaultBrightness);
};
SevenSegDigit::SevenSegDigit(char letter, uint8_t brightness, uint8_t defaultBrightness)
{
if (letter >= '0' && letter <= '9')
{
init(DecodeNumbers[letter - '0'], brightness, defaultBrightness);
}
else if (letter >= 'a' && letter <= 'z')
{
init(DecodeAlpha[letter - 'a'], brightness, defaultBrightness);
}
else if (letter >= 'A' && letter <= 'Z')
{
init(DecodeAlphaCaps[letter - 'A'], brightness, defaultBrightness);
}
else if (letter >= ',' && letter <= '/')
{
init(DecodeSpecial[letter - ','], brightness, defaultBrightness);
}
else
{
memset(Segment, defaultBrightness, sizeof(Segment));
}
};
uint8_t SevenSegDigit::CalculateBrightness() const
{
uint16_t sum = 0;
for (uint8_t iSegment = 0; iSegment < SegmentCount; iSegment++)
{
sum += Segment[iSegment];
}
return (uint8_t)(sum / SegmentCount);
}
void SevenSegDigit::Darken(uint8_t delta)
{
for (uint8_t iSegment = 0; iSegment < SegmentCount; iSegment++)
{
uint8_t element = Segment[iSegment];
if (element > delta)
{
element -= delta;
}
else
{
element = 0;
}
Segment[iSegment] = element;
}
}
void SevenSegDigit::Lighten(uint8_t delta)
{
for (uint8_t iSegment = 0; iSegment < SegmentCount; iSegment++)
{
uint8_t element = Segment[iSegment];
if (element < 255 - delta)
{
element += delta;
}
else
{
element = 255;
}
Segment[iSegment] = element;
}
}
SevenSegDigit SevenSegDigit::LinearBlend(const SevenSegDigit& left, const SevenSegDigit& right, float progress)
{
SevenSegDigit result;
for (uint8_t iSegment = 0; iSegment < SegmentCount; iSegment++)
{
result.Segment[iSegment] = left.Segment[iSegment] + ((right.Segment[iSegment] - left.Segment[iSegment]) * progress);
}
return result;
}

202
src/internal/SegmentDigit.h Normal file
View File

@@ -0,0 +1,202 @@
/*-------------------------------------------------------------------------
SegmentDigit provides a color object that can be directly consumed by NeoPixelBus
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
-------------------------------------------------------------------------
This file is part of the Makuna/NeoPixelBus library.
NeoPixelBus is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
NeoPixelBus is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#pragma once
#include <Arduino.h>
enum LedSegment
{
LedSegment_A,
LedSegment_B,
LedSegment_C,
LedSegment_D,
LedSegment_E,
LedSegment_F,
LedSegment_G,
LedSegment_Decimal,
LedSegment_COUNT
};
// ------------------------------------------------------------------------
// SevenSegDigit represents a color object that is represented by the segments
// of a 7 segment LED display digit. It contains helpful routines to manipulate
// and set the elements.
//
// The order represents the physical LED location starting at A, through to G, then
// ending at the decimal point
// "abcdefg."
// ------------------------------------------------------------------------
struct SevenSegDigit
{
// ------------------------------------------------------------------------
// Construct a SevenSegDigit using
// the default brightness to apply to all segments
// ------------------------------------------------------------------------
SevenSegDigit(uint8_t defaultBrightness)
{
memset(Segment, defaultBrightness, sizeof(Segment));
}
// ------------------------------------------------------------------------
// Construct a SevenSegDigit using
// a bitmask for the segment (bit order is ".gfedcba")
// the brightness to apply to them, (0-255)
// the default brightness to apply to those not set in the bitmask (0-255)
// ------------------------------------------------------------------------
SevenSegDigit(uint8_t bitmask, uint8_t brightness, uint8_t defaultBrightness = 0);
// ------------------------------------------------------------------------
// Construct a SevenSegDigit using
// a char that will get mapped to the segments,
// the brightness to apply to them, (0-255)
// the default brightness to apply to those not set in the bitmask (0-255)
// ------------------------------------------------------------------------
SevenSegDigit(char letter, uint8_t brightness, uint8_t defaultBrightness = 0);
// ------------------------------------------------------------------------
// Construct a SevenSegDigit that will have its values set in latter operations
// CAUTION: The members are not initialized and may not be consistent
// ------------------------------------------------------------------------
SevenSegDigit()
{
};
// ------------------------------------------------------------------------
// Comparison operators
// ------------------------------------------------------------------------
bool operator==(const SevenSegDigit& other) const
{
for (uint8_t iSegment = 0; iSegment < SegmentCount; iSegment++)
{
if (Segment[iSegment] != other.Segment[iSegment])
{
return false;
}
}
return true;
};
bool operator!=(const SevenSegDigit& other) const
{
return !(*this == other);
};
// ------------------------------------------------------------------------
// CalculateBrightness will calculate the overall brightness
// NOTE: This is a simple linear brightness
// ------------------------------------------------------------------------
uint8_t CalculateBrightness() const;
// ------------------------------------------------------------------------
// Darken will adjust the color by the given delta toward black
// NOTE: This is a simple linear change
// delta - (0-255) the amount to dim the segment
// ------------------------------------------------------------------------
void Darken(uint8_t delta);
// ------------------------------------------------------------------------
// Lighten will adjust the color by the given delta toward white
// NOTE: This is a simple linear change
// delta - (0-255) the amount to lighten the segment
// ------------------------------------------------------------------------
void Lighten(uint8_t delta);
// ------------------------------------------------------------------------
// LinearBlend between two colors by the amount defined by progress variable
// left - the segment to start the blend at
// right - the segment to end the blend at
// progress - (0.0 - 1.0) value where 0 will return left and 1.0 will return right
// and a value between will blend the brightness of each element
// weighted linearly between them
// ------------------------------------------------------------------------
static SevenSegDigit LinearBlend(const SevenSegDigit& left, const SevenSegDigit& right, float progress);
template <typename T_SET_TARGET>
static void SetString(T_SET_TARGET& target, uint16_t indexDigit, const char* str, uint8_t brightness, uint8_t defaultBrightness = 0)
{
if (str == nullptr)
{
return;
}
const char* pFirst = str;
const char* pIter = str;
// digits are right to left
// so find the end
while (*pIter != '\0')
{
pIter++;
}
pIter--;
while (pIter >= pFirst)
{
bool decimal = false;
char value = *pIter;
// check if merging a decimal is required
if (pIter > pFirst && (*pIter == '.' || *pIter == ','))
{
// merge a decimal as long as they aren't the same
if (*(pIter - 1) != *pIter)
{
decimal = true;
pIter--;
value = *pIter; // use the next char
}
}
SevenSegDigit digit(value, brightness, defaultBrightness);
if (decimal)
{
digit.Segment[LedSegment_Decimal] = brightness;
}
target.SetPixelColor(indexDigit, digit);
indexDigit++;
}
}
// ------------------------------------------------------------------------
// segment members (0-255) where each represents the segment location
// and the value defines the brightnes (0) is off and (255) is full brightness
// ------------------------------------------------------------------------
static const uint8_t SegmentCount = 9;
uint8_t Segment[SegmentCount];
// segment decode maps from ascii relative first char in map to a bitmask of segments
//
static const uint8_t DecodeNumbers[10]; // 0-9
static const uint8_t DecodeAlphaCaps[26]; // A-Z
static const uint8_t DecodeAlpha[26]; // a-z
static const uint8_t DecodeSpecial[4]; // , - . /
protected:
void init(uint8_t bitmask, uint8_t brightness, uint8_t defaultBrightness);
};