Control Surface main
MIDI Control Surface library for Arduino
SevenSegmentDisplay.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <AH/STL/algorithm> // std::fill
6#include <Print.h>
7
9
10namespace MCU {
11
18template <uint8_t LENGTH>
20 : public MatchingMIDIInputElement<MIDIMessageType::CONTROL_CHANGE,
21 TwoByteRangeMIDIMatcher>,
22 public Printable {
23 public:
25 using Parent =
27
28 SevenSegmentDisplay(MIDIAddress address) : Parent({address, LENGTH}) {
30 }
31
32 void reset() override {
33 if (!ignoreReset) {
35 dirty = true;
36 }
37 }
38
39 protected:
41 void handleUpdate(typename Matcher::Result match) override {
42 uint8_t index = LENGTH - 1 - match.index;
43 // MIDI msg: character data → bits 0-5
44 // MIDI msg: decimal point → bit 6 set, no decimal point → bit 6 not set
45 // text: decimal point → bit 7 set, no decimal point → bit 7 not set
46 uint8_t decimalPt = (match.value & 0x40) << 1;
47 uint8_t chardata = match.value & 0x3F;
48 uint8_t character = chardata >= 0x20 ? chardata : chardata + 0x40;
49 character |= decimalPt;
50 dirty |= text[index] != character;
51 text[index] = character;
52 }
53
54 void fillWithSpaces() { std::fill(std::begin(text), std::end(text), ' '); }
55
56 public:
59
73 void getText(char *buffer, uint8_t offset = 0,
74 uint8_t length = LENGTH) const {
75 if (offset >= LENGTH)
76 offset = LENGTH - 1;
77 if (length > LENGTH - offset)
78 length = LENGTH - offset;
79 for (uint8_t i = 0; i < length; i++)
80 buffer[i] = getCharacterAt(i + offset);
81 buffer[length] = '\0';
82 }
83
88 char getCharacterAt(uint8_t index) const { return text[index] & 0x7F; }
89
97 void getDecimalPoints(bool *buffer) const {
98 for (uint8_t i = 0; i < LENGTH; i++)
99 buffer[i] = getDecimalPointAt(i);
100 }
101
106 bool getDecimalPointAt(uint8_t index) const { return text[index] & 0x80; }
107
109
112
114 size_t printTo(Print &printer) const override {
115 size_t s = 0;
116 for (uint8_t i = 0; i < LENGTH; i++) {
117 s += printer.print(getCharacterAt(i));
118 if (getDecimalPointAt(i))
119 s += printer.print('.');
120 }
121 return s;
122 }
123
125
128
131 bool getDirty() const { return dirty; }
133 void clearDirty() { dirty = false; }
134
136
137 private:
139 bool dirty = true;
140
141 public:
145 bool ignoreReset = true;
146};
147
148} // namespace MCU
149
#define END_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Class that receives and saves the text of a Mackie Control Universal 7-segment display like the assig...
void getDecimalPoints(bool *buffer) const
Copy the decimal points into the given buffer.
bool getDecimalPointAt(uint8_t index) const
Get the decimal point state at the given index.
bool ignoreReset
Don't reset the state when calling the reset method.
SevenSegmentDisplay(MIDIAddress address)
bool getDirty() const
Check if the value was updated since the last time the dirty flag was cleared.
char getCharacterAt(uint8_t index) const
Get the character at the given index.
void getText(char *buffer, uint8_t offset=0, uint8_t length=LENGTH) const
Copy the ASCII text into the given buffer.
size_t printTo(Print &printer) const override
Print out the text of the display to the given Print.
AH::Array< char, LENGTH > text
Non-ASCII and not null-terminated.
void handleUpdate(typename Matcher::Result match) override
Update a single character.
void reset() override
Reset the input element to its initial state.
void clearDirty()
Clear the dirty flag.
A type-safe utility class for saving a MIDI address consisting of a 7-bit address,...
The MIDIInputElement base class is very general: you give it a MIDI message, and it calls the updateW...
Matcher for MIDI messages with 2 data bytes, such as Note On/Off, Control Change, Key Pressure (but n...