diff --git a/examples/sevensegment/NeoSegmentBus/NeoSegmentBus.ino b/examples/sevensegment/NeoSegmentBus/NeoSegmentBus.ino index 7ee1beb..05a160c 100644 --- a/examples/sevensegment/NeoSegmentBus/NeoSegmentBus.ino +++ b/examples/sevensegment/NeoSegmentBus/NeoSegmentBus.ino @@ -30,7 +30,7 @@ void loop() { delay(2000); - strip.RotateLeft(1); + strip.RotateRight(1); // reads right to left, so it is reversed strip.Show(); } diff --git a/examples/sevensegment/NeoSegmentFade/NeoSegmentFade.ino b/examples/sevensegment/NeoSegmentFade/NeoSegmentFade.ino index 98d9e59..588af8d 100644 --- a/examples/sevensegment/NeoSegmentFade/NeoSegmentFade.ino +++ b/examples/sevensegment/NeoSegmentFade/NeoSegmentFade.ino @@ -32,7 +32,7 @@ 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); + uint8_t bitfield = 1 << ( (uint8_t)(param.progress * LedSegment_G) % LedSegment_G); // instant a digit with that segment on SevenSegDigit digit(bitfield, brightness); // apply it to the strip @@ -126,7 +126,7 @@ void loop() brightness); // start the seconds fade animation - animations.StartAnimation(Animation_Fade, 1000, FadeAnimation); + animations.StartAnimation(Animation_Fade, 500, FadeAnimation); // start the cycle animation for the next second animations.StartAnimation(Animation_Cycle, 1000, CycleAnimation); diff --git a/src/internal/NeoSegmentFeatures.h b/src/internal/NeoSegmentFeatures.h index f0118f6..0198a83 100644 --- a/src/internal/NeoSegmentFeatures.h +++ b/src/internal/NeoSegmentFeatures.h @@ -84,8 +84,29 @@ public: typedef SevenSegDigit ColorObject; }; -// Abcdefg byte order -class NeoAbcdefgSegmentFeature : public Neo9Elements +class Neo9ElementsNoSettings : public Neo9Elements +{ +public: + typedef NeoNoSettings SettingsObject; + static const size_t SettingsSize = 0; + + static void applySettings(uint8_t*, const SettingsObject&) + { + } + + static uint8_t* pixels(uint8_t* pData) + { + return pData; + } + + static const uint8_t* pixels(const uint8_t* pData) + { + return pData; + } +}; + +// Abcdefgps byte order +class NeoAbcdefgSegmentFeature : public Neo9ElementsNoSettings { public: static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color) @@ -127,4 +148,69 @@ public: }; -typedef NeoAbcdefgSegmentFeature SevenSegmentFeature; // Abcdefg order is default \ No newline at end of file + +// BACEDF.G+ byte order +class NeoBacedfpgsSegmentFeature : public Neo9ElementsNoSettings +{ +public: + static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color) + { + uint8_t* p = getPixelAddress(pPixels, indexPixel); + + // Segment Digit is Abcdefgps order + *p++ = color.Segment[LedSegment_B]; + *p++ = color.Segment[LedSegment_A]; + *p++ = color.Segment[LedSegment_C]; + + *p++ = color.Segment[LedSegment_E]; + *p++ = color.Segment[LedSegment_D]; + *p++ = color.Segment[LedSegment_F]; + + *p++ = color.Segment[LedSegment_Decimal]; + *p++ = color.Segment[LedSegment_G]; + *p++ = color.Segment[LedSegment_Custom]; + } + + static ColorObject retrievePixelColor(const uint8_t* pPixels, uint16_t indexPixel) + { + ColorObject color; + const uint8_t* p = getPixelAddress(pPixels, indexPixel); + + color.Segment[LedSegment_B] = *p++; + color.Segment[LedSegment_A] = *p++; + color.Segment[LedSegment_C] = *p++; + + color.Segment[LedSegment_E] = *p++; + color.Segment[LedSegment_D] = *p++; + color.Segment[LedSegment_F] = *p++; + + color.Segment[LedSegment_Decimal] = *p++; + color.Segment[LedSegment_G] = *p++; + color.Segment[LedSegment_Custom] = *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); + + color.Segment[LedSegment_B] = pgm_read_byte(p++); + color.Segment[LedSegment_A] = pgm_read_byte(p++); + color.Segment[LedSegment_C] = pgm_read_byte(p++); + + color.Segment[LedSegment_E] = pgm_read_byte(p++); + color.Segment[LedSegment_D] = pgm_read_byte(p++); + color.Segment[LedSegment_F] = pgm_read_byte(p++); + + color.Segment[LedSegment_Decimal] = pgm_read_byte(p++); + color.Segment[LedSegment_G] = pgm_read_byte(p++); + color.Segment[LedSegment_Custom] = pgm_read_byte(p++); + + return color; + } + +}; + +typedef NeoBacedfpgsSegmentFeature SevenSegmentFeature; // Abcdefg order is default \ No newline at end of file diff --git a/src/internal/SegmentDigit.h b/src/internal/SegmentDigit.h index 826044c..32447e4 100644 --- a/src/internal/SegmentDigit.h +++ b/src/internal/SegmentDigit.h @@ -36,10 +36,26 @@ enum LedSegment LedSegment_E, LedSegment_F, LedSegment_G, - LedSegment_Decimal, + LedSegment_Decimal, // maybe jumpered to alternate custom segment + LedSegment_Custom, // generally not used but maybe connected to a custom segment LedSegment_COUNT }; +class NeoSevenSegCurrentSettings +{ +public: + NeoSevenSegCurrentSettings(uint16_t segments, uint16_t decimal, uint16_t special = 0) : + SegmentTenthMilliAmpere(segments), + DecimalTenthMilliAmpere(decimal), + SpecialTenthMilliAmpere(special) + { + } + + uint16_t SegmentTenthMilliAmpere; // in 1/10th ma + uint16_t DecimalTenthMilliAmpere; // in 1/10th ma + uint16_t SpecialTenthMilliAmpere; // in 1/10th ma +}; + // ------------------------------------------------------------------------ // SevenSegDigit represents a color object that is represented by the segments // of a 7 segment LED display digit. It contains helpful routines to manipulate @@ -51,6 +67,8 @@ enum LedSegment // ------------------------------------------------------------------------ struct SevenSegDigit { + typedef NeoSevenSegCurrentSettings SettingsObject; + // ------------------------------------------------------------------------ // Construct a SevenSegDigit using // the default brightness to apply to all segments @@ -134,8 +152,28 @@ struct SevenSegDigit // ------------------------------------------------------------------------ static SevenSegDigit LinearBlend(const SevenSegDigit& left, const SevenSegDigit& right, float progress); + + uint32_t CalcTotalTenthMilliAmpere(const SettingsObject& settings) + { + auto total = 0; + + for (uint8_t segment = LedSegment_A; segment < SegmentCount - 2; segment++) + { + total += Segment[segment] * settings.SegmentTenthMilliAmpere / Max; + } + + total += Segment[SegmentCount - 2] * settings.DecimalTenthMilliAmpere / Max; + total += Segment[SegmentCount - 1] * settings.SpecialTenthMilliAmpere / Max; + + return total; + } + template - static void SetString(T_SET_TARGET& target, uint16_t indexDigit, const char* str, uint8_t brightness, uint8_t defaultBrightness = 0) + static void SetString(T_SET_TARGET& target, + uint16_t indexDigit, + const char* str, + uint8_t brightness, + uint8_t defaultBrightness = 0) { if (str == nullptr) { @@ -146,7 +184,7 @@ struct SevenSegDigit const char* pIter = str; // digits are right to left - // so find the end + // so find the end and start there while (*pIter != '\0') { pIter++; @@ -157,25 +195,51 @@ struct SevenSegDigit while (pIter >= pFirst) { bool decimal = false; - char value = *pIter; + bool special = false; + char value = *pIter--; - // check if merging a decimal is required - if (pIter > pFirst && (*pIter == '.' || *pIter == ',')) + // must always be merged by previous char + // (the one to the right) + // so if repeated ignore it + // + if (value == ':' || value == ';') + { + continue; + } + + // check if merging a decimal with the next char is required + // (the one to the left) + // + if (pIter >= pFirst && (value == '.' || value == ',')) { // merge a decimal as long as they aren't the same - if (*(pIter - 1) != *pIter) + if (*(pIter) != value) { decimal = true; - pIter--; - value = *pIter; // use the next char + value = *pIter--; // use the next char } } + // check next char for colon + // + if (pIter >= pFirst && (*pIter == ':' || *pIter == ';')) + { + // the colon is custom extension using the decimal AND the special + // channels + special = true; + decimal = true; + pIter--; // skip colon + } + SevenSegDigit digit(value, brightness, defaultBrightness); if (decimal) { digit.Segment[LedSegment_Decimal] = brightness; } + if (special) + { + digit.Segment[LedSegment_Custom] = brightness; + } target.SetPixelColor(indexDigit, digit); indexDigit++; } @@ -188,6 +252,7 @@ struct SevenSegDigit static const uint8_t SegmentCount = 9; uint8_t Segment[SegmentCount]; + const static uint8_t Max = 255; // segment decode maps from ascii relative first char in map to a bitmask of segments //