AskSin++
Lcd6749.h
1 //- -----------------------------------------------------------------------------------------------------------------------
2 // AskSin++
3 // 2016-10-31 papa Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
4 // LCD6749 class
5 // 2019-10-20 jp112sdl Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
6 //- -----------------------------------------------------------------------------------------------------------------------
7 
8 // https://www.pollin.de/p/lcd-modul-densitron-pc-6749-aaw-120818
9 // code based on https://www.mikrocontroller.net/topic/380929#4335859
10 
11 #ifndef __LCD6749_H__
12 #define __LCD6749_H__
13 
14 #define LCD6749_BUFSIZE 7
15 
16 namespace as {
17 
18  const struct seg16fonts {
19  char c;
20  uint16_t s;
21  } seg16font[65] PROGMEM = {
22  /* ABCDEFGHIJKLMNOP */
23  #ifdef LCDREVERSED
24  { '1', 0b0000011000000100 },
25  { '2', 0b1101110000111000 },
26  { '3', 0b1001111000111000 },
27  { '4', 0b0010011000111000 },
28  { '5', 0b1011101000111000 },
29  { '6', 0b1111101000111000 },
30  { '7', 0b0001100001111100 },
31  { '8', 0b1111111000111000 },
32  { '9', 0b1011111000111000 },
33  { '0', 0b1111111001010100 },
34  { '+', 0b0000000010111010 },
35  { '-', 0b0000000000111000 },
36  { '*', 0b0000000111111111 },
37  { '/', 0b0000000001010100 },
38  { '.', 0b0000100000000000 }, // no
39  { ')', 0b0000000001000001 },
40  { '$', 0b1011101010111010 },
41  { '(', 0b0000000100000100 },
42  { 'A', 0b0111111000111000 },
43  { 'B', 0b1111100100011100 },
44  { 'C', 0b1111100000000000 },
45  { 'D', 0b1111111000000000 }, // bad = O
46  { 'E', 0b1111100000011000 },
47  { 'F', 0b0111100000011000 },
48  { 'G', 0b1111101000100000 },
49  { 'H', 0b0110011000111000 },
50  { 'I', 0b1001100010010010 },
51  { 'J', 0b1000111000000000 },
52  { 'K', 0b0110000100011100 },
53  { 'L', 0b1110000000000000 },
54  { 'M', 0b0110011000010101 },
55  { 'N', 0b0110011100010001 },
56  { 'O', 0b1111111000000000 },
57  { 'P', 0b0111110000111000 },
58  { 'Q', 0b1111111100000000 },
59  { 'R', 0b0111000100001100 },
60  { 'S', 0b1011101000111000 },
61  { 'T', 0b0001100010010010 },
62  { 'U', 0b1110011000000000 },
63  { 'V', 0b0110100001010100 },
64  { 'W', 0b0110011101010000 },
65  { 'X', 0b0000000101010101 },
66  { 'Y', 0b0000000010010101 },
67  { 'Z', 0b1001100001010100 },
68  { '}', 0b0000000001011001 },
69  { '_', 0b1000000000000000 },
70  { '{', 0b0000000100110100 },
71  { 'b', 0b1110001000111000 },
72  { 'c', 0b1100000000111000 },
73  { 'd', 0b1100011000111000 },
74  { 'h', 0b0110001000111000 },
75  { 'l', 0b0110000000000000 },
76  { 'm', 0b0100001010111000 },
77  { 'n', 0b0100001000111000 },
78  { 'o', 0b1100001000111000 },
79  { 'r', 0b0100000000011000 },
80  { 't', 0b1110000000011000 },
81  { 'u', 0b1100001000000000 },
82  { 'v', 0b0100000001000000 },
83  { 'w', 0b1100001010000000 },
84  { '[', 0b1111100000000000 },
85  { '|', 0b0000000010010010 },
86  { ']', 0b1001111000000000 },
87 #else
88  { '1', 0b0110000001000000 },
89  { '2', 0b1101110000111000 },
90  { '3', 0b1111100000111000 },
91  { '4', 0b0000001010111010 },
92  { '5', 0b1011101000111000 },
93  { '6', 0b1011111000111000 },
94  { '7', 0b1000000001111010 },
95  { '8', 0b1111111000111000 },
96  { '9', 0b1111101000111000 },
97  { '0', 0b1111111001010100 },
98  { '+', 0b0000000010111010 },
99  { '-', 0b0000000000111000 },
100  { '*', 0b0000000111111111 },
101  { '/', 0b0000000001010100 },
102  { '.', 0b0000100000000000 },
103  { '(', 0b0000000001000001 },
104  { '$', 0b1011101010111010 },
105  { ')', 0b0000000100000100 },
106  { 'A', 0b1110011000111000 },
107  { 'B', 0b1111100010011010 },
108  { 'C', 0b1001111000000000 },
109  { 'D', 0b1111100010010010 },
110  { 'E', 0b1001111000110000 },
111  { 'F', 0b1000011000110000 },
112  { 'G', 0b1011111000001000 },
113  { 'H', 0b0110011000111000 },
114  { 'I', 0b1001100010010010 },
115  { 'J', 0b1000100010010010 },
116  { 'K', 0b0000000011010011 },
117  { 'L', 0b0001111000000000 },
118  { 'M', 0b0110011101010000 },
119  { 'N', 0b0110011100010001 },
120  { 'O', 0b1111111000000000 },
121  { 'P', 0b1100011000111000 },
122  { 'Q', 0b1111111000000001 },
123  { 'R', 0b1100011000110001 },
124  { 'S', 0b1011101000111000 },
125  { 'T', 0b1000000010010010 },
126  { 'U', 0b0111111000000000 },
127  { 'V', 0b0000011001010100 },
128  { 'W', 0b0110011000010101 },
129  { 'X', 0b0000000101010101 },
130  { 'Y', 0b0000000101010010 },
131  { 'Z', 0b1001100001010100 },
132  { '{', 0b0000000001011001 },
133  { '_', 0b0001100000000000 },
134  { '}', 0b0000000100110100 },
135  { 'b', 0b0011111000111000 },
136  { 'c', 0b0001110000111000 },
137  { 'd', 0b0111110000111000 },
138  { 'h', 0b0010011000111000 },
139  { 'l', 0b0000111000000000 },
140  { 'm', 0b0010010000101010 },
141  { 'n', 0b0010010000111000 },
142  { 'o', 0b0011110000111000 },
143  { 'r', 0b0000010000110000 },
144  { 't', 0b0001000010111010 },
145  { 'u', 0b0011110000000000 },
146  { 'v', 0b0000010000000100 },
147  { 'w', 0b0010010000000101 },
148  { '[', 0b1001111000000000 },
149  { '|', 0b0000000010010010 },
150  { ']', 0b1111100000000000 },
151 #endif
152  { ' ', 0b0000000000000000 },
153  { 0, 0xFFFF }
154  };
155 
156  const uint8_t segmap[3][16] PROGMEM= {
157 #ifdef LCDREVERSED
158  { 0x60, 0x62, 0x63, 0x53, 0x47, 0x46, 0x44, 0x50,
159  0x54, 0x61, 0x45, 0x51, 0x55, 0x52, 0x56, 0x57 },
160  { 0x40, 0x42, 0x43, 0x33, 0x27, 0x26, 0x24, 0x30,
161  0x34, 0x41, 0x25, 0x31, 0x35, 0x32, 0x36, 0x37 },
162  { 0x14, 0x16, 0x17, 0x07, 0x03, 0x02, 0x00, 0x04,
163  0x10, 0x15, 0x01, 0x05, 0x11, 0x06, 0x12, 0x13 }
164 #else
165  { 0x14, 0x16, 0x17, 0x07, 0x03, 0x02, 0x00, 0x04,
166  0x10, 0x15, 0x01, 0x05, 0x11, 0x06, 0x12, 0x13 },
167  { 0x40, 0x42, 0x43, 0x33, 0x27, 0x26, 0x24, 0x30,
168  0x34, 0x41, 0x25, 0x31, 0x35, 0x32, 0x36, 0x37 },
169  { 0x60, 0x62, 0x63, 0x53, 0x47, 0x46, 0x44, 0x50,
170  0x54, 0x61, 0x45, 0x51, 0x55, 0x52, 0x56, 0x57 }
171 #endif
172  };
173 
174 template<uint8_t CS, uint8_t WR, uint8_t DT>
175 class LCD6749 {
176 
177 public:
178  enum dots { NO_DOT, SINGLE_DOT, DOUBLE_DOT, BOTH_DOTS };
179 
180 private:
181  uint8_t _cs, _wr, _data, _lcdbuffer[LCD6749_BUFSIZE];
182 
183  void CS_low() { digitalWrite(_cs, LOW); delayMicroseconds(1); }
184  void CS_high() { delayMicroseconds(1); digitalWrite(_cs, HIGH); }
185  void DATA(uint8_t x) { if ((x)==0) digitalWrite(_data, LOW); else digitalWrite(_data, HIGH); }
186  void WR_pulse() { digitalWrite(_wr, LOW); delayMicroseconds(3); digitalWrite(_wr, HIGH); delayMicroseconds(3); }
187  void clearBuffer(void) { memset(_lcdbuffer, 0, LCD6749_BUFSIZE); }
188 
189 
190  uint16_t char2seg(char c) {
191  for (uint8_t j=0; pgm_read_byte(&(seg16font[j]).c); j++) {
192  if (pgm_read_byte(&(seg16font[j]).c) == c) {
193  return (pgm_read_word(&(seg16font[j]).s));
194  }
195  }
196  return 0;
197  }
198 
199  void updateDisplay(uint8_t dot) {
200  CS_low();
201  DATA(1); WR_pulse();
202  DATA(0); WR_pulse();
203  DATA(1); WR_pulse();
204 
205  for (uint8_t i = 0; i < 6; i++) { DATA(0); WR_pulse(); }
206 
207 #ifdef LCDREVERSED
208  if (dot & 0x01) _lcdbuffer[2]|=0b00000010;
209 #else
210  if (dot & 0x01) _lcdbuffer[2]|=0b00001000;
211 #endif
212  if (dot & 0x02) _lcdbuffer[2]|=0b00000110;
213  for (uint8_t i=0; i<LCD6749_BUFSIZE; i++) {
214  uint8_t mask= 0x01;
215  while (mask) {
216  DATA(_lcdbuffer[i] & mask);
217  WR_pulse();
218  mask<<=1;
219  }
220  }
221  DATA(1);
222  CS_high();
223  }
224 
225  void updateBuffer(uint8_t pos, char c) {
226  uint8_t segno= 0;
227  uint16_t mask= 0x8000;
228  for ( ; segno<16; segno++, mask>>=1) {
229  if (char2seg(c) & mask) {
230  uint8_t code= pgm_read_byte(&(segmap[pos][segno]));
231  _lcdbuffer[code>>4] |= 1<<(code&7);
232  }
233  }
234  }
235 
236  void sendCmd(uint8_t cmd) {
237  CS_low();
238  DATA(1); WR_pulse();
239  DATA(0); WR_pulse();
240  DATA(0); WR_pulse();
241  uint8_t mask= 0x80;
242  while (mask) {
243  DATA(cmd&mask);
244  WR_pulse();
245  mask>>=1;
246  }
247  DATA(1); WR_pulse();
248  CS_high();
249  }
250 
251 public:
252  LCD6749 () : _cs(0), _wr(0), _data(0) {}
253  virtual ~LCD6749() {}
254 
255  void init() {
256  _cs = CS;
257  _wr = WR;
258  _data= DT;
259  pinMode(_cs, OUTPUT);
260  pinMode(_wr, OUTPUT);
261  pinMode(_data, OUTPUT);
262 
263  sendCmd(0b00000001); // system enable
264  sendCmd(0b00101010); // 1/2 Bias, 4 commons
265  sendCmd(0b00000011); // turn on LCD
266 
267  clearBuffer();
268  }
269 
270  void clear() {
271  clearBuffer();
272  updateDisplay(NO_DOT);
273  }
274 
275  void printChar(uint8_t pos, char c, uint8_t dot) {
276  updateBuffer(pos, c);
277  updateDisplay(dot);
278  }
279 
280  void printV(uint8_t value) {
281  printWithUnit(value, SINGLE_DOT, 'V');
282  }
283 
284  void printWithUnit(uint8_t value, uint8_t dot, char c) {
285  clearBuffer();
286  char localBuffer[3];
287  snprintf(localBuffer, 3, "%2i", value);
288  updateBuffer(0, value < 10 ? '0' : localBuffer[0]);
289  updateBuffer(1,localBuffer[1]);
290  updateBuffer(2,c);
291  updateDisplay(dot);
292  }
293 
294  void printText(const char * t, uint8_t dot=NO_DOT) {
295  clearBuffer();
296 
297 #ifdef LCDREVERSED
298  if (strlen(t) > 2) {
299  if ( t[2]=='.' ) dot = SINGLE_DOT;
300  if ( t[2]==':' ) dot = DOUBLE_DOT;
301  }
302 #else
303  if (strlen(t) > 1) {
304  if ( t[1]=='.' ) dot = SINGLE_DOT;
305  if ( t[1]==':' ) dot = DOUBLE_DOT;
306  }
307 #endif
308 
309  uint8_t j = 0;
310  for (uint8_t i = 0; i < min(strlen(t), dot > NO_DOT ? 4 : 3); i++) {
311 #ifdef LCDREVERSED
312  if (dot > NO_DOT && i == 2) i++;
313 #else
314  if (dot > NO_DOT && i == 1) i++;
315 #endif
316  updateBuffer(j, t[i]);
317  j++;
318  }
319 
320  updateDisplay(dot);
321  }
322 
323  void printNumberAsFloat(int16_t number) {
324  if (number > 999) {
325  number = (number + 5) / 10;
326  printNumber(number, false, NO_DOT);
327  } else if (number < -99) {
328  number = (number - 5) / 10;
329  printNumber(number ,false, NO_DOT);
330  } else {
331  printNumber(number, false, SINGLE_DOT);
332  }
333  }
334 
335  void printNumber(int16_t number, bool leadingZero) {
336  printNumber(number, leadingZero, NO_DOT);
337  }
338 
339  void printNumber(int16_t number, bool leadingZero, uint8_t dot) {
340  clearBuffer();
341  char localBuffer[4]={};
342  snprintf(localBuffer, 4, "%3i", number);
343  for (uint8_t i = 0; i < strlen(localBuffer); i++) {
344  if (localBuffer[i] == 32 && leadingZero == true) localBuffer[i] = '0';
345  updateBuffer(i, localBuffer[i]);
346  }
347  updateDisplay(dot);
348  }
349 };
350 
351 }
352 
353 /*
354  //printWithUnit(24, LCD6749::NO_DOT, 'G'); // 2 4 G
355  //printWithUnit(24, LCD6749::SINGLE_DOT, 'G'); // 2.4 G
356  //printText("4:15"); // 4:1 5
357  //printNumberAsFloat(720); // 7.2 0
358  //printNumberAsFloat(4); // 0.0 4
359  //printV(19); // 1.9 V
360  //printNumber(14); // 1 4
361  //printNumber(14, true); //with leading zero // 0 1 4
362 */
363 
364 #endif
as::LCD6749
Definition: Lcd6749.h:175
as::seg16fonts
Definition: Lcd6749.h:18