-
Notifications
You must be signed in to change notification settings - Fork 1
/
BigNum.h
151 lines (128 loc) · 4.66 KB
/
BigNum.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
138
139
140
141
142
143
144
145
146
147
148
149
150
#pragma once
#define ORIGINAL_FONT 0
// BigNum -----------------------------------------------
// Draw a large character over 2 lines on the LCD display
// Marco Colli July 2016
// PROGMEM Font definitions for big characters
//
#if ORIGINAL_FONT
// Character elements defined in the user chars in numerical order
// 0: 1: _ 2: _ 3: 4: _ 5: _ 6: 7: _
// | | | _| |_| |_ |_| _| |
// Definitions for the number of characters and their size
static const uint8_t NUM_ELEMENTS = 8; // elements required
static const uint8_t ELEMENT_SIZE = 8; // bytes per element
// Two types of fonts are defined - single and double stroke widths
// Single width strokes
const PROGMEM uint8_t fontSingle[NUM_ELEMENTS][ELEMENT_SIZE] =
{
{ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, // 0
{ 0x1f, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 }, // 1
{ 0x1f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1f }, // 2
{ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f }, // 3
{ 0x1f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1f }, // 4
{ 0x1f, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f }, // 5
{ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1f }, // 6
{ 0x1f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 } // 7
};
const PROGMEM uint8_t fontDouble[NUM_ELEMENTS][ELEMENT_SIZE] =
{
{ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, // 0
{ 0x1f, 0x1f, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 }, // 1
{ 0x1f, 0x1f, 0x01, 0x01, 0x01, 0x01, 0x1f, 0x1f }, // 2
{ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f, 0x1f }, // 3
{ 0x1f, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x1f, 0x1f }, // 4
{ 0x1f, 0x1f, 0x11, 0x11, 0x11, 0x11, 0x1f, 0x1f }, // 5
{ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0f, 0x1f }, // 6
{ 0x1f, 0x1f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 } // 7
};
#else
// Character elements defined in the user chars in numerical order
// 0: _ 1: 2: _ 3: _ 4: _ 5: 6: _ 7: not used
// | | |_| _| |_ |_| | |
// Definitions for the number of characters and their size
static const uint8_t NUM_ELEMENTS = 7; // elements required
static const uint8_t ELEMENT_SIZE = 8; // bytes per element
// Only one font is defined but it takes on less user defined character
// Single width strokes
const PROGMEM uint8_t fontSingle[NUM_ELEMENTS][ELEMENT_SIZE] =
{
{ 0x1f, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 }, // 0
{ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f }, // 1
{ 0x1f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1f }, // 2
{ 0x1f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1f }, // 3
{ 0x1f, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f }, // 4
{ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, // 5
{ 0x1f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, // 6
};
#endif
class BigNum
{
protected:
LiquidCrystal *_lcd;
public:
BigNum(LiquidCrystal *lcd) : _lcd(lcd)
{ };
void begin(void)
{
setSingleFont();
}
void setSingleFont(void)
{
uint8_t c[NUM_ELEMENTS];
for (uint8_t i = 0; i < NUM_ELEMENTS; i++)
{
memcpy_P(c, &fontSingle[i][0], ELEMENT_SIZE*sizeof(fontSingle[0][0]));
_lcd->createChar(i, c);
}
};
void setDoubleFont(void)
{
uint8_t c[NUM_ELEMENTS];
for (uint8_t i = 0; i < NUM_ELEMENTS; i++)
{
#if ORIGINAL_FONT
memcpy_P(c, &fontDouble[i][0], ELEMENT_SIZE*sizeof(fontDouble[0][0]));
#else
memcpy_P(c, &fontSingle[i][0], ELEMENT_SIZE*sizeof(fontSingle[0][0]));
#endif
_lcd->createChar(i, c);
}
};
void writeNumber(uint8_t row, uint8_t col, uint16_t num, uint8_t digits, bool leadZero = false)
// write number num at top left coordinate (row, col) in a space 3 digits in size
// with leading zero if requested
{
for (int8_t i = digits; i > 0; i--)
{
uint8_t d = num % 10;
// draw the digit depeding on zero or not and, if zero, position in the number or not
if ((d != 0) || leadZero || (d == 0 && i == digits) || (d == 0 && num != 0))
writeDigit(row, col + i - 1, d);
else
{
_lcd->setCursor(col, row);
_lcd->write(' ');
_lcd->setCursor(col, row + 1);
_lcd->write(' ');
}
num /= 10;
}
}
void writeDigit(uint8_t row, uint8_t col, uint8_t digit)
{
// Define the elements for the top and bottom for each digit
#if ORIGINAL_FONT
static const uint8_t top[10] = { 1, 0, 7, 7, 3, 4, 4, 7, 1, 1 };
static const uint8_t bot[10] = { 3, 0, 4, 2, 0, 6, 3, 0, 5, 2 };
#else
static const uint8_t top[10] = { 0, 5, 2, 2, 1, 3, 3, 6, 4, 4 };
static const uint8_t bot[10] = { 1, 5, 3, 2, 6, 2, 4, 5, 4, 2 };
#endif // ORIGINAL_FONT
if (digit > 9) return;
_lcd->setCursor(col, row);
_lcd->write((char)top[digit]);
_lcd->setCursor(col, row+1);
_lcd->write((char)bot[digit]);
};
};