-
Notifications
You must be signed in to change notification settings - Fork 0
/
sevenSegmentsFSM.h
137 lines (120 loc) · 5.2 KB
/
sevenSegmentsFSM.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <stdint.h>
// what character is being displayed
enum Phases
{
SevenSegDisplayType, // display either "P" (for percent) or "F" (for fault)
SevenSegDisplayValue, // display percentage or error code (the name of the constant is confusing but we use this state to display the whole number, another counter is used to track exactly the index of the current number to be displayed)
SevenSegDisplayFinlaBlank // display a blank character for 500ms (not to confuse with the 100ms flickering blank)
};
uint8_t SevenSegNumbers[] = {
// seven segments coded numbers
0b0111111, // 0
0b0000110, // 1
0b1011011, // 2
0b1001111, // 3
0b1100110, // 4
0b1101101, // 5
0b1111101, // 6
0b0000111, // 7
0b1111111, // 8
0b1101111 // 9
};
const uint8_t SevenSegP = 0b1110011; // letter "P" coded in seven segments
const uint8_t SevenSegF = 0b1110001; // letter "F" coded in...
// extract a digit form a number at a given index, then return its seven segment reperesentation
uint8_t extractSevenSegDigit(uint32_t value, uint8_t index)
{
for (int i = 0; i < index; i++)
value /= 10;
value %= 10;
return SevenSegNumbers[value]; // convert number into 7 seg representation
}
class SevenSegmentsFSM
{
private:
volatile Phases _phase;
volatile uint8_t _charIndex; // the index of a digit from the error code being displayed during SevenSegDisplayValue phase
volatile uint8_t _numberOfChars;
volatile uint8_t _flicker;
volatile uint8_t _endFlicker;
volatile uint8_t _result;
volatile uint8_t _type;
public:
volatile uint8_t value;
void (*OnFirstPhaseStarted)(); // event handler to be executed (if not 0) befor the first phase is started
void (*OnLastPhaseDone)(); // event handler to be executed (if not 0) after the last phase is done
uint8_t isFlickering() { return _flicker; }
uint8_t isFlickerDone(uint8_t clear)
{
uint8_t endFlicker = _endFlicker;
if (clear)
_endFlicker = 0;
return endFlicker;
}
SevenSegmentsFSM(uint8_t numberOfChars, uint8_t typeChar)
{
_numberOfChars = numberOfChars - 1;
_type = typeChar;
Reinit();
}
uint8_t LastResult() { return _result; }
Phases GetCurrentPhase() { return _phase; }
// returns 1 when the FSM ends, 0 otherwise
uint8_t Execute()
{
switch (_phase)
{
case SevenSegDisplayType: // just started displaying the error code
if (OnFirstPhaseStarted) // execute the event handler if existant
OnFirstPhaseStarted();
_charIndex = _numberOfChars; // reinit the index
_phase = SevenSegDisplayValue; // the next time this function is called it shall process SevenSegDisplayValue
_flicker = 1; // when SevenSegDisplayValue is being processed a short blank will be dispalyed
_result = _type; // the letter 'P' or 'F' (or anything intialized with) is to be displayed
break;
case SevenSegDisplayValue: // dispaly the error code
{
if (isFlickering()) // a flicker previously requested
{
_result = 0; // return blank character
_flicker = 0; // no more flicker
_endFlicker = 1; // tells "calculate7Seg" to display this charcter for only 100ms
}
else
{
_flicker = 1; // a character is being displayed now, so the next time flicker
// uint8_t value = errors[0]; // get the first error
_result = extractSevenSegDigit(value, _charIndex); // dispayed the digit with index of "_charIndex"
if (_charIndex == 0) // is it the last digit to display? then shift the errors stack
{
_phase = SevenSegDisplayFinlaBlank; // move to the next phase of display
_flicker = 0; // no flicker, the next phase is just blank character for 500ms
}
else
{
_charIndex--; // not the last digit? then move to the next one
}
}
}
break;
case SevenSegDisplayFinlaBlank: // display a blank character for 500ms
// StateOfSevenSeg = SevenSegDisplayingWaterLevel; // the last digit of this error is displayed, switching back to water level display, if another error is in stack "calculate7Seg" will call this again
// reset the state of PhaseOfSevenSeg
// PhaseOfSevenSeg = SevenSegDisplayType;
// SevenSegFlicker = 0;
Reinit(); // finalize, the result is a blank character
if (OnLastPhaseDone) // execute the event handler if existing
OnLastPhaseDone();
return 1; // tell that the machine finished executing all its states
break;
}
return 0; // still other states to be executed next
}
void Reinit()
{
_charIndex = _numberOfChars;
_flicker = _endFlicker = 0;
_phase = SevenSegDisplayType;
_result = 0;
}
};