Robot 7-segment Display, v1.1.0
Posted on

The library for controlling a 7-segment display.
Implementing controlling a multiplexed display.
Change Log
- structures:
- the
Characterstructure:- support transformation to the same character with a decimal point;
- increase usability;
- the
DisplaySelectorstructure controls a multiplexed display by switching its sub-displays, and keeps a set of pins using for this;
- the
- perform refactoring.
Features
- possibilities:
- controlling a single display;
- controlling a multiplexed display;
- structures:
- the
Characterstructure represents a character and keeps a set of specific segments that should be active for displaying this character:- supports transformation to the same character with a decimal point;
- the
Displaystructure represents a single display and keeps mapping between segments and pins to which they are connected; - the
DisplaySelectorstructure controls a multiplexed display by switching its sub-displays, and keeps a set of pins using for this.
- the
Examples
A multiplexed display stopwatch:
#include <Character.h>
#include <Display.h>
#include <PinForSegment.h>
#include <DisplaySelector.h>
#include <stdint.h>
using namespace irenica_ideas::robot_7_segment_display;
constexpr auto DISPLAY_QUANTITY = 4;
constexpr auto DECIMAL_POINT_INDEX = 1;
constexpr auto COUNTER_UPDATE_DELAY_IN_MS = 100;
constexpr auto DISPLAY_SELECTION_DELAY_IN_MS = 2;
const Character digits[] = {
Character(0x7e), // digit 0
Character(0x30), // digit 1
Character(0x6d), // digit 2
Character(0x79), // digit 3
Character(0x33), // digit 4
Character(0x5b), // digit 5
Character(0x5f), // digit 6
Character(0x70), // digit 7
Character(0x7f), // digit 8
Character(0x7b) // digit 9
};
// TODO: specify your own pin for every segment.
const auto display = Display(
PinForSegment<'a'>{2},
PinForSegment<'b'>{3},
PinForSegment<'c'>{5},
PinForSegment<'d'>{7},
PinForSegment<'e'>{11},
PinForSegment<'f'>{13},
PinForSegment<'g'>{17},
PinForSegment<'p'>{19}
);
// TODO: specify your own pin for every sub-display.
const auto selector = makeDisplaySelector(23, 29, 31, 37);
auto previousTime = 0ul;
uint8_t counterDigits[DISPLAY_QUANTITY] = {};
void setup() {
display.initialize();
selector.initialize();
}
void loop() {
// update the counter; about creating timers through the `millis()` function
// see: https://docs.arduino.cc/built-in-examples/digital/BlinkWithoutDelay
const auto currentTime = millis();
const auto elapsedTime = currentTime - previousTime;
if (elapsedTime > COUNTER_UPDATE_DELAY_IN_MS) {
auto willBeOverflowed = true;
for (
auto index = 0;
index < DISPLAY_QUANTITY && willBeOverflowed;
++index
) {
willBeOverflowed = counterDigits[index] == 9;
counterDigits[index] = willBeOverflowed ? 0 : counterDigits[index] + 1;
}
previousTime = currentTime;
}
// perform single update of the whole multiplexed display
for (auto index = 0; index < DISPLAY_QUANTITY; ++index) {
selector.selectDisplay(index);
// show the first character on the first sub-display, the second character
// on the second sub-display, etc.
auto digit = digits[counterDigits[index]];
if (index == DECIMAL_POINT_INDEX) {
digit = digit.withDecimalPoint();
}
digit.show(display);
delay(DISPLAY_SELECTION_DELAY_IN_MS);
}
}