/*------------------------------------------------------------------------- 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 . -------------------------------------------------------------------------*/ #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, 0x7F, 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, 0x76, 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, bool maintainCase) { if (letter >= '0' && letter <= '9') { init(DecodeNumbers[letter - '0'], brightness, defaultBrightness); } else if (letter >= 'a' && letter <= 'z') { uint8_t index = letter - 'a'; uint8_t bitmask = DecodeAlpha[index]; if (!bitmask && !maintainCase) { bitmask = DecodeAlphaCaps[index]; } init(bitmask, brightness, defaultBrightness); } else if (letter >= 'A' && letter <= 'Z') { uint8_t index = letter - 'A'; uint8_t bitmask = DecodeAlphaCaps[index]; if (!bitmask && !maintainCase) { bitmask = DecodeAlpha[index]; } init(bitmask, 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 static_cast(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; }