├── LICENSE ├── README.md ├── extras ├── letters.png ├── photo.jpg ├── photo1.jpg └── segment-map.jpg └── src ├── HT1621.cpp └── HT1621.hpp /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 hedgehogV 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HT1621 7 segment LCD library 2 | Library for 7-segment lcds based on the HT1621 driver. Very often marked as PDC-6X1. 3 | 4 | photo 5 | 6 | Based on the bitbanging efforts by [anxzhu](https://github.com/anxzhu) (2016-2018). 7 | APIs rewritten in 2018 to follow the LiquidCrystal format by [valerio\new] 8 | (https://github.com/5N44P). 9 | 10 | Refactored. Removed dependency on any MCU hardware. Added SPI support and text support. 11 | By Viacheslav Balandin 12 | https://github.com/hedgehogV/HT1621-lcd 13 | 14 | 15 | ## APIs reference 16 | 17 | * `HT1621(pPinSet *pCs, pPinSet *pSck, pPinSet *pMosi, pPinSet *pBacklight)` 18 | Ctor. Starts the lcd with the pin assignment declared. The backlight pin is optional 19 | 20 | * `HT1621(pInterface *pSpi, pPinSet *pCs, pPinSet *pBacklight)` 21 | Starts the lcd with SPI interface. CS and backlight pins are optional. Tested with CPOL=LOW, EDGE=1 22 | 23 | * `void clear()` 24 | Clears the display 25 | 26 | * `void backlightOn()` 27 | Turns on the backlight 28 | 29 | * `void backlightOff()` 30 | Turns off the backlight 31 | 32 | * `void batteryLevel(uint8_t percents)` 33 | Accepts values from 0 to 100. Bigger values will be treated as 100. Battery charge represented by the rectangles above the battery symbol. 34 | 35 | * `void print(const char *str)` 36 | Print string (up to 6 characters) 37 | Allowed characters: letters, digits, space, minus, underscore. Not allowed characters will be displayed as spaces. 38 | See characters appearance in `Internal functioning` chapter 39 | 40 | * `void print(int32_t num)` 41 | Prints a signed integer between -99999 and 999999. Larger and smaller values will be displayed as -99999 and 999999 42 | 43 | * `void print(float num, int precision)` 44 | Prints a float with 0 to 3 decimals, based on the `precision` parameter. Default value is 3 45 | 46 | * `void print(int32_t multiplied_float, uint32_t multiplier)` 47 | Prints number with dot. Use it instead float. Float type usage may slow down many systems 48 | 49 | * `void displayOff()` 50 | Turns off the display (doesn't turn off the backlight) 51 | 52 | * `void displayOn()` 53 | Turns the display back on after it has been disabled by `noDisplay()` 54 | 55 | ## API usage 56 | 57 | To start display you have to call one of Ctors with pointers to toggle_Gpio or SpiTx functions. 58 | You may need a function wrapper. Wrapper example: 59 | 60 | ```cpp 61 | // spi wrapper 62 | void SpiTx(uint8_t *ptr, uint8_t size) 63 | { 64 | HAL_SPI_Transmit(&hspi2, ptr, size, 2000); 65 | } 66 | 67 | // cs wrapper 68 | void toggle_CS(bool b) 69 | { 70 | HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, b? GPIO_PIN_SET:GPIO_PIN_RESET); 71 | } 72 | 73 | // ctor call example 74 | HT1621 lcd = HT1621(&SpiTx, &toggle_CS); 75 | 76 | // prints "hello" on display 77 | lcd.print("HELLO"); 78 | ``` 79 | 80 | 81 | ## Internal functioning 82 | 83 | Letters example. Source: https://www.dcode.fr/7-segment-display 84 | Some of them looks a bit strange. But 7-segment display isn't 85 | the best thing to show letters 86 | 87 | photo 88 | 89 | ° -> 0x33 = 10 + 20 + 01 + 02 90 | C -> 0x1D = 10 + 01 + 04 + 08 91 | 92 | ``` 93 | ___10___ 94 | | | 95 | 01 20 96 | |___02___| 97 | | | 98 | 04 40 99 | |___08___| 100 | 101 | ``` 102 | 103 | -------------------------------------------------------------------------------- /extras/letters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hedgehogV/HT1621-lcd/4697885b1852f4c79a0aa011dbc322a42071858e/extras/letters.png -------------------------------------------------------------------------------- /extras/photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hedgehogV/HT1621-lcd/4697885b1852f4c79a0aa011dbc322a42071858e/extras/photo.jpg -------------------------------------------------------------------------------- /extras/photo1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hedgehogV/HT1621-lcd/4697885b1852f4c79a0aa011dbc322a42071858e/extras/photo1.jpg -------------------------------------------------------------------------------- /extras/segment-map.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hedgehogV/HT1621-lcd/4697885b1852f4c79a0aa011dbc322a42071858e/extras/segment-map.jpg -------------------------------------------------------------------------------- /src/HT1621.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Copyright 2016-2018 anxzhu (github.com/anxzhu) 3 | Copyright 2018 Valerio Nappi (github.com/5N44P) (changes) 4 | Based on segment-lcd-with-ht1621 from anxzhu (2016-2018) 5 | (https://github.com/anxzhu/segment-lcd-with-ht1621) 6 | 7 | Partially rewritten and extended by Valerio Nappi (github.com/5N44P) in 2018 8 | https://github.com/5N44P/ht1621-7-seg 9 | 10 | Refactored. Removed dependency on any MCU hardware by Viacheslav Balandin 11 | https://github.com/hedgehogV/HT1621-lcd 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal in 15 | the Software without restriction, including without limitation the rights to 16 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 17 | of the Software, and to permit persons to whom the Software is furnished to do 18 | so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 25 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 26 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 27 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 28 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | 30 | *******************************************************************************/ 31 | 32 | #include "HT1621.hpp" 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | /** 39 | * @brief CALCULATION DEFINES BLOCK 40 | */ 41 | constexpr int MAX_NUM = 999999; 42 | constexpr int MIN_NUM = -99999; 43 | 44 | constexpr size_t PRECISION_MAX_POSITIVE = 3; // TODO: find better names 45 | constexpr size_t PRECISION_MAX_NEGATIVE = 2; 46 | constexpr size_t PRECISION_MIN = 1; 47 | 48 | constexpr size_t BITS_PER_BYTE = 8; 49 | 50 | #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) 51 | #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) 52 | 53 | /** 54 | * @brief DISPLAY HARDWARE DEFINES BLOCK 55 | */ 56 | #define BIAS 0x52 //0b1000 0101 0010 1/3duty 4com 57 | #define SYSDIS 0x00 //0b1000 0000 0000 Turn off both system oscillator and LCD bias generator 58 | #define SYSEN 0x02 //0b1000 0000 0010 Turn on system oscillator 59 | #define LCDOFF 0x04 //0b1000 0000 0100 Turn off LCD bias generator 60 | #define LCDON 0x06 //0b1000 0000 0110 Turn on LCD bias generator 61 | #define XTAL 0x28 //0b1000 0010 1000 System clock source, crystal oscillator 62 | #define RC256 0x30 //0b1000 0011 0000 System clock source, on-chip RC oscillator 63 | #define TONEON 0x12 //0b1000 0001 0010 Turn on tone outputs 64 | #define TONEOFF 0x10 //0b1000 0001 0000 Turn off tone outputs 65 | #define WDTDIS1 0x0A //0b1000 0000 1010 Disable WDT time-out flag output 66 | 67 | #define MODE_CMD 0x08 68 | #define MODE_DATA 0x05 69 | 70 | #define BATTERY_SEG 0x80 71 | #define DOT_SEG 0x80 72 | 73 | static const char ascii[] = 74 | { 75 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 76 | /* ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '-' ' ' ' ' */ 77 | /*2*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 78 | /* '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' ' ' ' ' ' ' ' ' ' ' ' ' */ 79 | /*3*/ 0x7D, 0x60, 0x3e, 0x7a, 0x63, 0x5b, 0x5f, 0x70, 0x7f, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 80 | /* ' ' 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' */ 81 | /*4*/ 0x00, 0x77, 0x4f, 0x1d, 0x6e, 0x1f, 0x17, 0x5d, 0x47, 0x05, 0x68, 0x27, 0x0d, 0x54, 0x75, 0x4e, 82 | /* 'P' 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' ' ' ' ' ' ' ' ' '_' */ 83 | /*5*/ 0x37, 0x73, 0x06, 0x59, 0x0f, 0x6d, 0x23, 0x29, 0x67, 0x6b, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x08, 84 | /* ' ' 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' */ 85 | /*6*/ 0x00, 0x77, 0x4f, 0x1d, 0x6e, 0x1f, 0x17, 0x5d, 0x47, 0x05, 0x68, 0x27, 0x0d, 0x54, 0x75, 0x4e, 86 | /* 'P' 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' ' ' ' ' ' ' ' ' ' ' */ 87 | /*7*/ 0x37, 0x73, 0x06, 0x59, 0x0f, 0x6d, 0x23, 0x29, 0x67, 0x6b, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 88 | }; 89 | 90 | #define ASCII_SPACE_SYMBOL 0x00 91 | 92 | #if (('1234' >> 24) == '1') 93 | #ifndef LITTLE_ENDIAN 94 | #define LITTLE_ENDIAN 95 | #endif 96 | #elif (('4321' >> 24) == '1') 97 | #ifndef BIG_ENDIAN 98 | #define BIG_ENDIAN 99 | #endif 100 | #else 101 | #error "Unable to determine endian. Set it manually" 102 | #endif 103 | 104 | union tCmdSeq 105 | { 106 | struct __attribute__((packed)) 107 | { 108 | #if defined LITTLE_ENDIAN 109 | uint16_t padding : 4; 110 | uint16_t data : 8; 111 | uint16_t type : 4; 112 | #elif defined BIG_ENDIAN 113 | uint16_t type : 4; 114 | uint16_t data : 8; 115 | uint16_t padding : 4; 116 | #endif 117 | }; 118 | uint8_t arr[2]; 119 | }; 120 | 121 | union tDataSeq 122 | { 123 | struct __attribute__((packed)) 124 | { 125 | #if defined LITTLE_ENDIAN 126 | uint8_t padding : 7; 127 | uint16_t data2 : 16; 128 | uint16_t data1 : 16; 129 | uint16_t data0 : 16; 130 | uint8_t addr : 6; 131 | uint8_t type : 3; 132 | #elif defined BIG_ENDIAN 133 | uint8_t type : 3; 134 | uint8_t addr: 6; 135 | uint16_t data0 : 16; 136 | uint16_t data1 : 16; 137 | uint16_t data2 : 16; 138 | uint8_t padding : 7; 139 | #endif 140 | }; 141 | uint8_t arr[8]; 142 | }; 143 | 144 | 145 | HT1621::HT1621(pPinSet *pCs, pPinSet *pSck, pPinSet *pMosi, pPinSet *pBacklight) 146 | { 147 | pCsPin = pCs; 148 | pSckPin = pSck; 149 | pMosiPin = pMosi; 150 | pBacklightPin = pBacklight; 151 | 152 | wrCmd(BIAS); 153 | wrCmd(RC256); 154 | wrCmd(SYSDIS); 155 | wrCmd(WDTDIS1); 156 | wrCmd(SYSEN); 157 | wrCmd(LCDON); 158 | } 159 | 160 | HT1621::HT1621(pInterface *pSpi, pPinSet *pCs, pPinSet *pBacklight) 161 | { 162 | pSpiInterface = pSpi; 163 | pCsPin = pCs; 164 | pBacklightPin = pBacklight; 165 | 166 | wrCmd(BIAS); 167 | wrCmd(RC256); 168 | wrCmd(SYSDIS); 169 | wrCmd(WDTDIS1); 170 | wrCmd(SYSEN); 171 | wrCmd(LCDON); 172 | } 173 | 174 | void HT1621::backlightOn() 175 | { 176 | if (pBacklightPin) 177 | pBacklightPin(HIGH); 178 | } 179 | 180 | void HT1621::backlightOff() 181 | { 182 | if (pBacklightPin) 183 | pBacklightPin(LOW); 184 | } 185 | 186 | void HT1621::displayOn() 187 | { 188 | wrCmd(LCDON); 189 | } 190 | 191 | void HT1621::displayOff() 192 | { 193 | wrCmd(LCDOFF); 194 | } 195 | 196 | void HT1621::wrBytes(uint8_t *ptr, uint8_t size) 197 | { 198 | // probably need to use microsecond delays in this method 199 | // after every pin toggle function to give display 200 | // driver time for data reading. But current solution works for me 201 | 202 | // TODO: check wrong size 203 | // lcd driver expects data in reverse order 204 | std::reverse(ptr, ptr + size); 205 | 206 | if (pCsPin) 207 | pCsPin(LOW); 208 | 209 | if (pSpiInterface) 210 | pSpiInterface(ptr, size); 211 | else if (pSckPin && pMosiPin) 212 | { 213 | for (size_t k = 0; k < size; k++) 214 | { 215 | // send bits into display one by one 216 | for (size_t i = 0; i < BITS_PER_BYTE; i++) 217 | { 218 | pSckPin(LOW); 219 | pMosiPin((ptr[k] & (0x80 >> i))? HIGH : LOW); 220 | pSckPin(HIGH); 221 | } 222 | } 223 | } 224 | 225 | if (pCsPin) 226 | pCsPin(HIGH); 227 | } 228 | 229 | void HT1621::wrBuffer() 230 | { 231 | tDataSeq dataSeq = {}; 232 | dataSeq.type = MODE_DATA; 233 | dataSeq.addr = 0; 234 | // unable to use memcpy function with bit fields. So fill data manually 235 | dataSeq.data0 = (buffer[5] << 8) + buffer[4]; 236 | dataSeq.data1 = (buffer[3] << 8) + buffer[2]; 237 | dataSeq.data2 = (buffer[1] << 8) + buffer[0]; 238 | 239 | wrBytes(dataSeq.arr, sizeof(tDataSeq)); 240 | } 241 | 242 | void HT1621::wrCmd(uint8_t cmd) 243 | { 244 | tCmdSeq CommandSeq = {}; 245 | CommandSeq.type = MODE_CMD; 246 | CommandSeq.data = cmd; 247 | 248 | wrBytes(CommandSeq.arr, sizeof(tCmdSeq)); 249 | } 250 | 251 | void HT1621::batteryLevel(uint8_t percents) 252 | { 253 | batteryBufferClear(); 254 | 255 | if (percents > 75) 256 | { 257 | buffer[0] |= BATTERY_SEG; 258 | } 259 | if (percents > 50) 260 | { 261 | buffer[1] |= BATTERY_SEG; 262 | } 263 | if (percents > 25) 264 | { 265 | buffer[2] |= BATTERY_SEG; 266 | } 267 | wrBuffer(); 268 | } 269 | 270 | void HT1621::batteryBufferClear() 271 | { 272 | buffer[0] &= ~BATTERY_SEG; 273 | buffer[1] &= ~BATTERY_SEG; 274 | buffer[2] &= ~BATTERY_SEG; 275 | } 276 | 277 | void HT1621::dotsBufferClear() 278 | { 279 | buffer[3] &= ~DOT_SEG; 280 | buffer[4] &= ~DOT_SEG; 281 | buffer[5] &= ~DOT_SEG; 282 | } 283 | 284 | void HT1621::lettersBufferClear() 285 | { 286 | for (size_t i = 0; i < DISPLAY_SIZE; i++) 287 | { 288 | buffer[i] &= BATTERY_SEG | DOT_SEG; 289 | } 290 | } 291 | 292 | void HT1621::clear() 293 | { 294 | batteryBufferClear(); 295 | dotsBufferClear(); 296 | lettersBufferClear(); 297 | 298 | wrBuffer(); 299 | } 300 | 301 | void HT1621::bufferToAscii(const char *in, char *out) 302 | { 303 | for (size_t i = 0; i < MIN(DISPLAY_SIZE, strlen(in)); i++) 304 | { 305 | char c = in[i]; 306 | // Handle situation when char is out of displayable ascii table part. 307 | // Show space instead 308 | if (c < ' ') 309 | out[i] |= ASCII_SPACE_SYMBOL; 310 | else if (c - ' ' > (int)sizeof(ascii)) 311 | out[i] |= ASCII_SPACE_SYMBOL; 312 | else 313 | out[i] |= ascii[c - ' ']; 314 | } 315 | } 316 | 317 | void HT1621::print(const char *str) 318 | { 319 | dotsBufferClear(); 320 | lettersBufferClear(); 321 | bufferToAscii(str, buffer); 322 | wrBuffer(); 323 | } 324 | 325 | void HT1621::print(int32_t num) 326 | { 327 | if (num > MAX_NUM) 328 | num = MAX_NUM; 329 | if (num < MIN_NUM) 330 | num = MIN_NUM; 331 | 332 | dotsBufferClear(); 333 | lettersBufferClear(); 334 | 335 | char str[DISPLAY_SIZE + 1] = {}; 336 | snprintf(str, sizeof(str), "%6li", num); 337 | 338 | bufferToAscii(str, buffer); 339 | 340 | wrBuffer(); 341 | } 342 | 343 | void HT1621::print(float num, uint8_t precision) 344 | { 345 | if (num >= 0 && precision > PRECISION_MAX_POSITIVE) 346 | precision = PRECISION_MAX_POSITIVE; 347 | else if (num < 0 && precision > PRECISION_MAX_NEGATIVE) 348 | precision = PRECISION_MAX_NEGATIVE; 349 | 350 | int32_t integerated = (int32_t)(num * pow(10, precision)); 351 | 352 | if (integerated > MAX_NUM) 353 | integerated = MAX_NUM; 354 | if (integerated < MIN_NUM) 355 | integerated = MIN_NUM; 356 | 357 | print(integerated); 358 | decimalSeparator(precision); 359 | 360 | wrBuffer(); 361 | } 362 | 363 | // TODO: make multiplier more strict. 364 | void HT1621::print(int32_t multiplied_float, uint32_t multiplier) 365 | { 366 | uint8_t precision = 0; 367 | 368 | if (multiplier == 1000) 369 | precision = 3; 370 | else if (multiplier == 100) 371 | precision = 2; 372 | else if (multiplier == 10) 373 | precision = 1; 374 | 375 | if (multiplied_float > MAX_NUM) 376 | multiplied_float = MAX_NUM; 377 | if (multiplied_float < MIN_NUM) 378 | multiplied_float = MIN_NUM; 379 | 380 | print((int32_t)multiplied_float); 381 | decimalSeparator(precision); 382 | 383 | wrBuffer(); 384 | } 385 | 386 | void HT1621::decimalSeparator(uint8_t dpPosition) 387 | { 388 | dotsBufferClear(); 389 | 390 | if (dpPosition < PRECISION_MIN || dpPosition > PRECISION_MAX_POSITIVE) 391 | // selected dot position not supported by display hardware 392 | return; 393 | 394 | // the first three eights bits in the buffer are for the battery signs 395 | // the last three are for the decimal point 396 | buffer[DISPLAY_SIZE - dpPosition] |= DOT_SEG; 397 | } 398 | -------------------------------------------------------------------------------- /src/HT1621.hpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Copyright 2016-2018 anxzhu (github.com/anxzhu) 3 | Copyright 2018 Valerio Nappi (github.com/5N44P) (changes) 4 | Based on segment-lcd-with-ht1621 from anxzhu (2016-2018) 5 | (https://github.com/anxzhu/segment-lcd-with-ht1621) 6 | 7 | Partially rewritten and extended by Valerio Nappi (github.com/5N44P) in 2018 8 | https://github.com/5N44P/ht1621-7-seg 9 | 10 | Refactored. Removed dependency on any MCU hardware by Viacheslav Balandin 11 | https://github.com/hedgehogV/HT1621-lcd 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal in 15 | the Software without restriction, including without limitation the rights to 16 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 17 | of the Software, and to permit persons to whom the Software is furnished to do 18 | so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 25 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 26 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 27 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 28 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | 30 | *******************************************************************************/ 31 | 32 | #ifndef HT1621_H_ 33 | #define HT1621_H_ 34 | 35 | #include 36 | #include 37 | 38 | 39 | class HT1621 40 | { 41 | public: 42 | 43 | using pPinSet = void(bool); 44 | using pInterface = void(uint8_t *, uint8_t); 45 | 46 | /** 47 | * @brief Construct a new HT1621 object 48 | * 49 | * Starts the lcd with the pin assignment declared. The backlight pin is optional 50 | * 51 | * @param pCs - pointer to CS pin toggle function 52 | * @param pSck - pointer to SCK pin toggle function 53 | * @param pMosi - pointer to MOSI pin toggle function 54 | * @param pBacklight - pointer to backlight pin toggle function. Optional 55 | */ 56 | HT1621(pPinSet *pCs, pPinSet *pSck, pPinSet *pMosi, pPinSet *pBacklight = nullptr); 57 | 58 | /** 59 | * @brief Construct a new HT1621::HT1621 object 60 | * 61 | * Starts the lcd with SPI interface. CS and backlight pins are optional 62 | * 63 | * @param pSpi - pointer to SPI write function 64 | * @param pCs - pointer to CS pin toggle function. Optional if SPI has hardware CS configured 65 | * @param pBacklight - pointer to backlight pin toggle function. Optional 66 | */ 67 | HT1621(pInterface *pSpi, pPinSet *pCs = nullptr, pPinSet *pBacklight = nullptr); 68 | 69 | /** 70 | * @brief Turns on the display (doesn't affect the backlight) 71 | */ 72 | void displayOn(); 73 | 74 | /** 75 | * @brief Turns off the display (doesn't affect the backlight) 76 | */ 77 | void displayOff(); 78 | 79 | /** 80 | * @brief Turns on the backlight 81 | */ 82 | void backlightOn(); 83 | 84 | /** 85 | * @brief Turns off the backlight 86 | */ 87 | void backlightOff(); 88 | 89 | /** 90 | * @brief Show battery level. 91 | * 92 | * @param percents - battery charge state. May vary from 0 up to 100 93 | */ 94 | void batteryLevel(uint8_t percents); 95 | 96 | /** 97 | * @brief Print string (up to 6 characters) 98 | * 99 | * @param str String to be displayed. 100 | * Allowed: letters, digits, space, minus, underscore 101 | * Not allowed symbols will be displayed as spaces. See symbols appearance in README.md 102 | */ 103 | void print(const char *str); 104 | 105 | /** 106 | * @brief Prints a signed integer between -99999 and 999999. 107 | * Larger and smaller values will be displayed as -99999 and 999999 108 | * 109 | * @param num - number to be printed 110 | */ 111 | void print(int32_t num); 112 | 113 | /** 114 | * @brief Prints a float with 0 to 3 decimals, based on the `precision` parameter. Default value is 3 115 | * This method may be slow on many systems. Try to avoid float usage. 116 | * You may use `void print(int32_t multiplied_float, uint32_t multiplier)` instead 117 | * 118 | * @param num - number to be printed 119 | * @param precision - precision of the number 120 | */ 121 | void print(float num, uint8_t precision = 3); 122 | 123 | /** 124 | * @brief Prints number with dot. Use it instead float. Float type usage may slow down many systems 125 | */ 126 | void print(int32_t multiplied_float, uint32_t multiplier); 127 | 128 | /** 129 | * @brief Clears the display 130 | */ 131 | void clear(); 132 | 133 | private: 134 | 135 | static const size_t DISPLAY_SIZE = 6; // symbols on display 136 | char buffer[DISPLAY_SIZE] = {}; // buffer where display data will be stored 137 | 138 | // defines to set display pin to low or high level 139 | const bool LOW = 0; 140 | const bool HIGH = 1; 141 | 142 | pPinSet *pCsPin = nullptr; // SPI CS pin 143 | pPinSet *pSckPin = nullptr; // for display it is WR pin 144 | pPinSet *pMosiPin = nullptr; // for display it is Data pin 145 | pPinSet *pBacklightPin = nullptr; // display backlight pin 146 | pInterface *pSpiInterface = nullptr; // ptr to SPI_tx implementation 147 | 148 | // the most low-level function. Sends array of bytes into display 149 | void wrBytes(uint8_t* ptr, uint8_t size); 150 | // write buffer to the display 151 | void wrBuffer(); 152 | // write command sequence to display 153 | void wrCmd(uint8_t cmd); 154 | // set decimal separator. Used when print float numbers 155 | void decimalSeparator(uint8_t dpPosition); 156 | // takes the buffer and puts it straight into the driver 157 | void update(); 158 | // remove battery symbol from display buffer 159 | void batteryBufferClear(); 160 | // remove dot symbol from display buffer 161 | void dotsBufferClear(); 162 | // remove all symbols from display buffer except battery and dots 163 | void lettersBufferClear(); 164 | // coverts buffer symbols to format, which can be displayed by lcd 165 | void bufferToAscii(const char *in, char *out); 166 | }; 167 | 168 | #endif 169 | --------------------------------------------------------------------------------