muwerk mupplet Display Library
muwerk applets; mupplets: functional units that support specific hardware or reusable applications
Loading...
Searching...
No Matches
ht162x_digits.h
1// ht162x_digits.h - 7/16 segment digits controlled by HT1621 (7 seg) or HT1622 (16 seg)
2
3#pragma once
4
5
6namespace ustd {
7
8
9
10/* leo stuff:
11static const uint8_t digitTable7Seg[] PROGMEM = {B01111110, B00110000, B01101101, B01111001,
12 B00110011, B01011011, B01011111, B01110000,
13 B01111111, B01111011};
14
15static const uint8_t charTable7Seg[] PROGMEM = {
16 B01110111, B00011111, B00001101, B00111101, B01001111, B01000111, B01011110,
17 B00110111, B00000110, B00111100, B00000111, B00001110, B01110110, B00010101,
18 B00011101, B01100111, B11101110, B00000101, B01011011, B01000110, B00111110,
19 B00011100, B00011100, B01001001, B00100111, B01101101};
20*/
25class Ht162xDigits : public Print {
26 private:
27 static const uint8_t digitTable7Seg[]={0b10111110, 0b00000110, 0b01111100, 0b01011110, 0b11000110,
28 0b11011010, 0b11111010, 0b00001110, 0b11111110, 0b11011110};
29
30 static const uint8_t charTable7Seg[]={
31 // A
32 0b11101110, 0b11110010, 0b01110000, 0b01110110, 0b11111000, 0b11101000,
33 // G
34 0b10111010, 0b11100110, 0b00000010, 0b00110110, 0b11100101, 0b10110000,
35 // M
36 0b10101110, 0b01100010, 0b01110010, 0b11101100, 0b11001111, 0b01100000,
37 // S
38 0b11011010, 0b11110000, 0b10110110, 0b00110010, 0b10110111, 0b11100110,
39 //Y
40 0b11100100, 0b01111100 };
41 // See command summary, datasheet p.13:
42 // cmd prefix command comment
43 // --- ----------- ------------
44 static const uint8_t cmdBIAS = 0x52; // 100 | 0 010a bXcX, ab=10 4 commons option, c=1 1/3 cmdcmdBIAS option
45 static const uint8_t cmdSYS_DIS = 0X00; // 100 | 0 0000 000X, Turn off both system oscillator and LCD bias generator
46 static const uint8_t cmdSYS_EN = 0X02; // 100 | 0 0000 001X, Turn on system oscillator
47 static const uint8_t cmdLCD_OFF = 0X04; // 100 | 0 0000 010X, Turn off LCD bias generator
48 static const uint8_t cmdLCD_ON = 0X06; // 100 | 0 0000 011X, Turn on LCD bias generator
49 static const uint8_t cmdWDT_DIS = 0X0A; // 100 | 0 0000 101X, Disable WDT time-out flag output
50 static const uint8_t cmdRC_256K = 0X30; // 100 | 0 0011 0XXX, System clock source, on-chip RC oscillator
51
52 // device configuration
53 LcdType lcdType;
54 uint8_t csPin;
55 uint8_t wrPin;
56 uint8_t dataPin;
57 uint8_t lcdBacklightPin;
58 uint8_t pwmIndexEsp32;
59
60 int digitCnt;
61 int digitRawCnt;
62 int segmentCnt;
63 bool isActive;
64
65 static const long clearDelayMs = 2;
66 static const long printDelayMs = 2;
67 static const long writeDelayUs = 4;
68
69 // runtime - pixel and module logic
70 uint8_t length;
71 uint8_t bitmapSize;
72 uint8_t *bitmap;
73 uint8_t *outputBuffer;
74 int16_t _width;
75 int16_t _height;
76 int16_t cursor_x;
77 int16_t cursor_y;
78 bool wrap;
79
80 public:
81 enum LcdType {lcd12digit_7segment, lcd10digit_16segment};
82 static const uint8_t frameBufferSize=12; // 12 positions of 8bit used for HT1621, 11 positions of 16bit used for HT1622
83 uint16_t frameBuffer[frameBufferSize]; // cache for segment state: only rewrite segments on content change
84
85 Ht162xDigits(LcdType lcdType, uint8_t csPin, uint8_t wrPin, uint8_t dataPin, uint8_t lcdBacklightPin=-1, uint8_t pwmIndexEsp32=-1)
86 : name(name), lcdType(lcdType), csPin(csPin), wrPin(wrPin), dataPin(dataPin), lcdBacklightPin(lcdBacklightPin), pwmIndexEsp32(pwmIndexEsp32) {
94 switch (lcdType) {
95 case LcdType::lcd12digit_7segment:
96 digitCnt=12;
97 digitRawCnt=13; // Chinese phone-booth title snips at display top
98 segmentCnt=8;
99 isActive=true;
100 break;
101 case LcdType::lcd10digit_16segment:
102 digitCnt=10;
103 digitRawCnt=12; // Special case last digits encodes 9 decimal dots
104 segmentCnt=17;
105 isActive=true;
106 break;
107 default:
108 isActive=false;
109 break;
110 }
111 }
112
115 void begin() {
116 if (isActive) {
117 pinMode(csPin, OUTPUT);
118 pinMode(wrPin, OUTPUT);
119 pinMode(dataPin, OUTPUT);
120 if (lcdBacklightPin!=-1) pinMode(lcdBacklightPin, OUTPUT);
121
122 switch (lcdType) {
123 case LcdType::lcd12digit_7segment:
124 writeCmd(cmdBIAS); // set LCD bias
125 writeCmd(cmdRC_256K); // use internal clock
126 writeCmd(cmdSYS_DIS); // disable all generators
127 writeCmd(cmdWDT_DIS); // disable watchdog timer output bitj
128 writeCmd(cmdSYS_EN); // enable generators
129 setDisplay(true); // switch on display
130 clear(); // Clear display
131 break;
132 case LcdType::lcd10digit_16segment:
133 writeCmd(cmdBIAS); // set LCD bias
134 writeCmd(cmdRC_256K); // use internal clock
135 writeCmd(cmdSYS_DIS); // disable all generators
136 writeCmd(cmdWDT_DIS); // disable watchdog timer output bitj
137 writeCmd(cmdSYS_EN); // enable generators
138 setDisplay(true); // switch on display
139 clear(); // Clear display
140 break;
141 default:
142 isActive=false;
143 break;
144 }
145 }
146 return isActive;
147 }
148
153 inline void setPowerSave(bool powersave) {
154 driver.setPowerSave(powersave);
155 }
156
160 inline void setIntensity(uint8_t intensity) {
161 driver.setIntensity(intensity);
162 }
163
168 inline void setTestMode(bool testmode) {
169 driver.setTestMode(testmode);
170 }
171
176 void setCursor(int16_t x, int16_t y) {
177 cursor_x = x;
178 cursor_y = y;
179 }
180
184 inline void setCursorX(int16_t x) {
185 cursor_x = x;
186 }
187
191 inline void setCursorY(int16_t y) {
192 cursor_y = y;
193 }
194
199 void setTextWrap(bool w) {
200 wrap = w;
201 }
202
211 void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint8_t pattern = B00000000) {
212 x = x < 0 ? 0 : x >= _width ? _width - 1 : x;
213 y = y < 0 ? 0 : y >= _height ? _height - 1 : y;
214 w = w < 0 ? 0 : w >= _width - x ? _width - x : w;
215 h = h < 0 ? 0 : h >= _height - y ? _height - y : h;
216
217 for (int16_t yy = y; yy < y + h; yy++) {
218 memset(bitmap + yy * _width + x, pattern, w);
219 }
220 }
221
235 bool printFormatted(int16_t x, int16_t y, int16_t w, int16_t align, String content) {
236 uint8_t shadowBuffer[8];
237 x = x < 0 ? 0 : x >= _width ? _width - 1 : x;
238 y = y < 0 ? 0 : y >= _height ? _height - 1 : y;
239 w = w < 0 ? 0 : w >= _width - x ? _width - x : w;
240 memset(bitmap + y * _width + x, B00000000, w);
241 uint8_t *pDst = shadowBuffer;
242 const unsigned char *pSrc = (unsigned char *)content.c_str();
243 while (pDst < shadowBuffer + 8 && *pSrc) {
244 if (*pSrc < 32) {
245 pDst--;
246 } else if (*pSrc == '.' || *pSrc == ',') {
247 if (pDst == shadowBuffer) {
248 *pDst = B10000000;
249 } else {
250 pDst--;
251 *pDst |= B10000000;
252 }
253 } else if (*pSrc == ' ') {
254 *pDst = B00000000;
255 } else if (*pSrc == '-') {
256 *pDst = B00000001;
257 } else if (*pSrc == '_') {
258 *pDst = B00001000;
259 } else if (*pSrc == '=') {
260 *pDst = B00001001;
261 } else if (*pSrc >= '0' && *pSrc <= '9') {
262 *pDst = pgm_read_byte_near(digitTable7Seg + *pSrc - '0');
263 } else if (*pSrc >= 'A' && *pSrc <= 'Z') {
264 *pDst = pgm_read_byte_near(charTable7Seg + *pSrc - 'A');
265 } else if (*pSrc >= 'a' && *pSrc <= 'z') {
266 *pDst = pgm_read_byte_near(charTable7Seg + *pSrc - 'a');
267 } else {
268 *pDst = B00001000;
269 }
270 pSrc++;
271 pDst++;
272 }
273 int16_t size = pDst - shadowBuffer;
274 int16_t offs = 0;
275 pDst = bitmap + (y * length) + x; // fist position of the destination slot
276 switch (align) {
277 default:
278 case 0:
279 // left
280 memcpy(pDst, shadowBuffer, min(w, size));
281 break;
282 case 1:
283 // center
284 if (w < size) {
285 // string is larger than slot size - display only middle part
286 offs = (size - w) / 2;
287 memcpy(pDst, shadowBuffer + offs, w);
288 } else {
289 // string is smaller than slot size - display center aligned
290 offs = (w - size) / 2;
291 memcpy(pDst + offs, shadowBuffer, size);
292 }
293 break;
294 case 2:
295 // right
296 if (w < size) {
297 // string is larger than slot size - display only last part
298 offs = size - w;
299 memcpy(pDst, shadowBuffer + offs, w);
300 } else {
301 // string is smaller than slot size - display right aligned
302 offs = w - size;
303 memcpy(pDst + offs, shadowBuffer, size);
304 }
305 break;
306 }
307 return *pSrc == 0 && size <= w;
308 }
309
316 void write() {
317 if (bitmap != nullptr) {
318 for (uint8_t digit = 0; digit < length; digit++) {
319 uint16_t endOffset = digit;
320 uint16_t startOffset = bitmapSize + endOffset;
321 uint8_t *pPtr = outputBuffer;
322 do {
323 startOffset -= length;
324 pPtr[0] = Max72XX::digit0 + length - digit - 1;
325 pPtr[1] = bitmap[startOffset];
326 pPtr += 2;
327 } while (startOffset > endOffset);
328 driver.sendBlock(outputBuffer, pPtr - outputBuffer);
329 }
330 }
331 }
332
336 virtual void fillScreen(uint8_t pattern) {
337 if (bitmap != nullptr) {
338 memset(bitmap, pattern, length * driver.getChainLen());
339 cursor_x = 0;
340 cursor_y = 0;
341 }
342 }
343
347 inline int16_t width() const {
348 return _width;
349 };
350
354 inline int16_t height() const {
355 return _height;
356 }
357
361 inline bool getTextWrap() const {
362 return wrap;
363 }
364
368 inline int16_t getCursorX() const {
369 return cursor_x;
370 }
371
375 inline int16_t getCursorY() const {
376 return cursor_y;
377 };
378
383 uint8_t getCharLen(unsigned char c, bool firstChar = false) {
384 if (c < 32) {
385 return 0;
386 } else if (c == '.' || c == ',') {
387 return firstChar ? 1 : 0;
388 }
389 return 1;
390 }
391
392 protected:
393 virtual size_t write(uint8_t c) {
394 if (c == '\r') {
395 cursor_x = 0;
396 } else if (c == '\n') {
397 cursor_x = 0;
398 cursor_y++;
399 }
400 if (wrap && cursor_x >= _width) {
401 cursor_x = 0;
402 cursor_y++;
403 }
404 if (cursor_x >= _width || cursor_y >= _height) {
405 // out of viewport
406 return 1;
407 }
408 if (cursor_x < 0 || cursor_y < 0) {
409 // out of viewport but we must increment when char is prinatble
410 cursor_x += getCharLen(c, cursor_x == 0);
411 return 1;
412 }
413 uint8_t index = cursor_y * _width + cursor_x;
414 if (c < 32) {
415 return 1;
416 } else if (c == '.' || c == ',') {
417 if (cursor_x == 0) {
418 bitmap[index] = B10000000;
419 } else {
420 bitmap[index - 1] |= B10000000;
421 cursor_x--;
422 }
423 } else if (c == ' ') {
424 bitmap[index] = B00000000;
425 } else if (c == '-') {
426 bitmap[index] = B00000001;
427 } else if (c == '_') {
428 bitmap[index] = B00001000;
429 } else if (c == '=') {
430 bitmap[index] = B00001001;
431 } else if (c >= '0' && c <= '9') {
432 bitmap[index] = pgm_read_byte_near(digitTable7Seg + c - '0');
433 } else if (c >= 'A' && c <= 'Z') {
434 bitmap[index] = pgm_read_byte_near(charTable7Seg + c - 'A');
435 } else if (c >= 'a' && c <= 'z') {
436 bitmap[index] = pgm_read_byte_near(charTable7Seg + c - 'a');
437 } else {
438 bitmap[index] = B00001000;
439 }
440 cursor_x++;
441 return 1;
442 }
443};
444
445} // namespace ustd
The HT162X Digits Display Class.
Definition: ht162x_digits.h:25
int16_t getCursorY() const
Definition: ht162x_digits.h:375
void setCursorX(int16_t x)
Definition: ht162x_digits.h:184
int16_t height() const
Definition: ht162x_digits.h:354
int16_t getCursorX() const
Definition: ht162x_digits.h:368
virtual void fillScreen(uint8_t pattern)
Definition: ht162x_digits.h:336
void begin()
Definition: ht162x_digits.h:115
int16_t width() const
Definition: ht162x_digits.h:347
void setIntensity(uint8_t intensity)
Definition: ht162x_digits.h:160
void setCursorY(int16_t y)
Definition: ht162x_digits.h:191
void setCursor(int16_t x, int16_t y)
Definition: ht162x_digits.h:176
void setTextWrap(bool w)
Definition: ht162x_digits.h:199
void setPowerSave(bool powersave)
Definition: ht162x_digits.h:153
bool printFormatted(int16_t x, int16_t y, int16_t w, int16_t align, String content)
Definition: ht162x_digits.h:235
void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint8_t pattern=B00000000)
Definition: ht162x_digits.h:211
Ht162xDigits(LcdType lcdType, uint8_t csPin, uint8_t wrPin, uint8_t dataPin, uint8_t lcdBacklightPin=-1, uint8_t pwmIndexEsp32=-1)
Definition: ht162x_digits.h:85
void setTestMode(bool testmode)
Definition: ht162x_digits.h:168
uint8_t getCharLen(unsigned char c, bool firstChar=false)
Definition: ht162x_digits.h:383
void write()
Definition: ht162x_digits.h:316
bool getTextWrap() const
Definition: ht162x_digits.h:361
@ digit0
Digit 0.
Definition: max72xx.h:24
The muwerk namespace.
Definition: display_digits_max72xx.h:10