/
ePaper.cpp
executable file
·502 lines (433 loc) · 11.8 KB
/
ePaper.cpp
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
// Include the standard types
#include <Arduino.h>
#include <ePaper.h>
// Character definitions
// abcdefghijklmnop
uint16_t aChar = 0b1011100001011100;
uint16_t bChar = 0b0001101101011101;
uint16_t cChar = 0b1000001001010101;
uint16_t dChar = 0b1010101111000001;
uint16_t eChar = 0b1000001001011101;
uint16_t fChar = 0b1000000001011100;
uint16_t gChar = 0b1001101001010101;
uint16_t hChar = 0b0011100000011100;
uint16_t iChar = 0b1000001111000001;
uint16_t jChar = 0b1000000111000101;
uint16_t kChar = 0b0100010000011100;
uint16_t lChar = 0b0000001000010101;
uint16_t mChar = 0b0110100000110100;
uint16_t nChar = 0b0010110000110100;
uint16_t oChar = 0b1010101001010101;
uint16_t pChar = 0b1011000001011100;
uint16_t qChar = 0b1010111001010101;
uint16_t rChar = 0b1011010001011100;
uint16_t sChar = 0b1001101001100001;
uint16_t tChar = 0b1000000111000000;
uint16_t uChar = 0b0010101000010101;
uint16_t vChar = 0b0100000000010110;
uint16_t wChar = 0b0010110000010110;
uint16_t xChar = 0b0100010000100010;
uint16_t yChar = 0b0100000010100000;
uint16_t zChar = 0b1100001001000011;
uint16_t zeroChar = 0b1010101001010101;
uint16_t oneChar = 0b0000000110000000;
uint16_t twoChar = 0b1011001001001101;
uint16_t threeChar = 0b1101101001000001;
uint16_t fourChar = 0b0011100000011000;
uint16_t fiveChar = 0b1001101001011001;
uint16_t sixChar = 0b1001101001011101;
uint16_t sevenChar = 0b1100000001000010;
uint16_t eightChar = 0b1011101001011101;
uint16_t nineChar = 0b1011101001011001;
// abcdefghijklmnop
uint16_t commaChar = 0b0000000000000010;
uint16_t dashChar = 0b0001000000001000;
uint16_t uscorChar = 0b0000001000000001;
uint16_t oparnChar = 0b0100010000000000;
uint16_t cparnChar = 0b0000000000100010;
uint16_t hashChar = 0b0011101110001001;
uint16_t dolarChar = 0b1001101111011001;
uint16_t prcntChar = 0b0101101111011010;
uint16_t starChar = 0b0101010000101010;
uint16_t plusChar = 0b0001000110001000;
uint16_t questChar = 0b1011000011010000;
uint16_t quoteChar = 0b0000000100010000;
uint16_t slashChar = 0b0100000000000010;
uint16_t equalChar = 0b0001001000001001;
uint16_t toBits(char ch) {
// turn a character into 16 bits of segment data
switch (ch)
{
case 'A':
case 'a':
return aChar;
case 'B':
case 'b':
return bChar;
case 'C':
case 'c':
return cChar;
case 'D':
case 'd':
return dChar;
case 'E':
case 'e':
return eChar;
case 'F':
case 'f':
return fChar;
case 'G':
case 'g':
return gChar;
case 'H':
case 'h':
return hChar;
case 'I':
case 'i':
return iChar;
case 'J':
case 'j':
return jChar;
case 'K':
case 'k':
return kChar;
case 'L':
case 'l':
return lChar;
case 'M':
case 'm':
return mChar;
case 'N':
case 'n':
return nChar;
case 'O':
case 'o':
return oChar;
case 'P':
case 'p':
return pChar;
case 'Q':
case 'q':
return qChar;
case 'R':
case 'r':
return rChar;
case 'S':
case 's':
return sChar;
case 'T':
case 't':
return tChar;
case 'U':
case 'u':
return uChar;
case 'V':
case 'v':
return vChar;
case 'W':
case 'w':
return wChar;
case 'X':
case 'x':
return xChar;
case 'Y':
case 'y':
return yChar;
case 'Z':
case 'z':
return zChar;
case '0':
return zeroChar;
case '1':
return oneChar;
case '2':
return twoChar;
case '3':
return threeChar;
case '4':
return fourChar;
case '5':
return fiveChar;
case '6':
return sixChar;
case '7':
return sevenChar;
case '8':
return eightChar;
case '9':
return nineChar;
case ',':
case '.':
return commaChar;
case '-':
return dashChar;
case '_':
return uscorChar;
case '(':
case '<':
return oparnChar;
case ')':
case '>':
return cparnChar;
case '#':
return hashChar;
case '$':
return dolarChar;
case '%':
return prcntChar;
case '*':
return starChar;
case '+':
return plusChar;
case '?':
return questChar;
case '"':
return quoteChar;
case '/':
return slashChar;
case '=':
return equalChar;
default:
return 0;
}
}
uint16_t reverse(uint16_t x) {
// reverse all bits in two bytes
x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
//x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
return ((x >> 8) | (x << 8));
}
uint16_t* reverseData(uint16_t *data, uint16_t characterData[]) {
// reverse all elements, causing it to be upside down
for (int i=0; i<10; i++) {
data[i] = reverse(characterData[i]);
}
return data;
}
uint16_t* flipData(uint16_t *data, uint16_t characterData[]) {
// cause text to flow in the other direction
for (int i=0; i<10; i++)
data[9-i] = characterData[i];
return data;
}
Changes* newData(Changes *ch, uint16_t data[]) {
// generate a Changes structure where all input bits are added,
// all others removed, and the negative is precalculated too.
for(int i=0; i<10; i++) {
ch->add[i] = data[i];
ch->del[i] = ~(data[i]);
ch->addNeg[i] = ch->del[i];
ch->delNeg[i] = ch->add[i];
ch->addDel[i] = 0xFFFF;
ch->addDelNeg[i] = 0;
}
return ch;
}
Changes* changedData(Changes *ch, uint16_t oldData[], uint16_t data[]) {
// Generate a Canges structure with all the bits
// that are in new but not in old,
// all the bits that are in old but now in new,
// and the negative of both
for(int i=0; i<10; i++) {
ch->add[i] = (oldData[i] ^ data[i]) & data[i];
ch->del[i] = (oldData[i] ^ data[i]) & ~(data[i]);
ch->addNeg[i] = ~(ch->add[i]);
ch->delNeg[i] = ~(ch->del[i]);
ch->addDel[i] = ch->add[i] | ch->del[i];
ch->addDelNeg[i] = ~(ch->addDel[i]);
}
return ch;
}
// Constructor
ePaper::ePaper(int XCK, int LATCH, int SLPB, int DI0, int EN, int VCC){
_XCK = XCK;
_LATCH = LATCH;
_SLPB = SLPB;
_DI0 = DI0;
_EN = EN;
_VCC = VCC;
pinMode(_XCK, OUTPUT);
pinMode(_LATCH, OUTPUT);
pinMode(_SLPB, OUTPUT);
pinMode(_DI0, OUTPUT);
pinMode(_EN, OUTPUT);
pinMode(_VCC, OUTPUT);
// Initial Pin Configurations -----------------------
digitalWrite(_SLPB, LOW); // Sleep high turns the display on
digitalWrite(_DI0, LOW);
digitalWrite(_XCK, LOW);
digitalWrite(_LATCH, LOW);
digitalWrite(_EN, LOW);
digitalWrite(_VCC, LOW);
_topChanges = (Changes*)malloc(sizeof(Changes));
_bottomChanges = (Changes*)malloc(sizeof(Changes));
// --------------------------------------------------
//delay(100);
}
void ePaper::shiftBits(uint8_t nbits, uint16_t val) {
// write N bits in val to the data and clock lines
uint8_t i;
for (i = 0; i < nbits; i++) {
// Little endian
//digitalWrite(_DI0, !!(val & (1 << i)));
// Big endian
digitalWrite(_DI0, !(val & (1 << (nbits - 1 - i))));
digitalWrite(_XCK, HIGH);
digitalWrite(_XCK, LOW);
}
}
void ePaper::print(uint16_t data[], int bw, int com){
// uint16 data[] - 10*16=160 bits of segment data
// int bw - This should be a 1 or a 0, and will decide whether the BW (the fist bit) bit is set or not.
// int com - This should be a 1 or a 0, and will decide whether the COM (the last bit) bit is set or not.
shiftBits(1, bw);
for(int i=0; i<10; i++) {
shiftBits(16, data[i]);
}
shiftBits(1, com);
}
void ePaper::printAll(uint16_t topData[], uint16_t bottomData[], int bw, int com) {
// print both displays and throw the latch
print(bottomData, bw, com);
print(topData, bw, com);
latch();
}
void ePaper::zeroOut() {
uint16_t empty[10] = {0,0,0,0,0,0,0,0,0,0};
printAll(empty, empty, 0, 0);
}
void ePaper::latch() {
// latch(): Simple function to activate and deactivate the latch
digitalWrite(_LATCH, HIGH);
digitalWrite(_LATCH, LOW);
}
void ePaper::wakeup() {
// power the chip and display and wake it from sleep
digitalWrite(_VCC, HIGH);
delay(50);
digitalWrite(_EN, HIGH);
digitalWrite(_SLPB, HIGH);
delay(100);
latch(); // do we need this?
}
void ePaper::shutdown() {
// put all pins to LOW
digitalWrite(_SLPB, LOW);
digitalWrite(_DI0, LOW);
digitalWrite(_XCK, LOW);
digitalWrite(_LATCH, LOW);
digitalWrite(_EN, LOW);
delay(50);
digitalWrite(_VCC, LOW);
}
void ePaper::completeData(char *top, char *bottom) {
// write a full display update to memory, updates all segments
for (int i=0; i<10; i++) {
_topData[i] = reverse(toBits(top[i]));
_bottomData[9-i] = toBits(bottom[i]);
}
newData(_topChanges, _topData);
newData(_bottomChanges, _bottomData);
}
void ePaper::incrementalData(char *top, char *bottom) {
// write an incrementl display update to memory, updates only changed segments
uint16_t topData[10];
uint16_t bottomData[10];
for (int i=0; i<10; i++) {
topData[i] = reverse(toBits(top[i]));
bottomData[9-i] = toBits(bottom[i]);
}
changedData(_topChanges, _topData, topData);
changedData(_bottomChanges, _bottomData, bottomData);
for (int i=0; i<10; i++) {
_topData[i] = topData[i];
_bottomData[i] = bottomData[i];
}
}
void ePaper::writeSimple(int up, int bw) {
// a simple update that fades sooner than the 7-5-7 but looks better
wakeup();
// added = 1
// deleted = 0
// unchanged = 1
printAll(_topChanges->delNeg, _bottomChanges->delNeg, up ? !bw : 1, 1);
delay(1400);
// added = 1
// deleted = 1
// unchanged = 0
printAll(_topChanges->addDel, _bottomChanges->addDel, up ? 1 : 0, 0);
delay(1400);
// added = 0
// deleted = 1
// unchanged = 1
printAll(_topChanges->addNeg, _bottomChanges->addNeg, up ? bw : 1, 1);
delay(1400);
zeroOut();
shutdown();
}
void ePaper::write757(int up, int bw) {
// write a 7-5-7 waveform to the display
// this is ugly and takes longer, but doesn't fade away as quickly
wakeup();
// added = 1
// deleted = 0
// unchanged = 1
printAll(_topChanges->delNeg, _bottomChanges->delNeg, up ? !bw : 1, 1);
delay(250);
// added = 1
// deleted = 0
// unchanged = 0
printAll(_topChanges->add, _bottomChanges->add, up ? !bw : 0, 0);
delay(250);
int x;
for(x=0; x<7; x++) {
delay(100);
// added = 1
// deleted = 0
// unchanged = 0
printAll(_topChanges->add, _bottomChanges->add, up ? !bw : 0, 0);
delay(100);
// added = 1
// deleted = 0
// unchanged = 1
printAll(_topChanges->delNeg, _bottomChanges->delNeg, up ? !bw : 1, 1);
}
for(x=0; x<5; x++) {
delay(200);
// added = 1
// deleted = 1
// unchanged = 0
printAll(_topChanges->addDel, _bottomChanges->addDel, up ? 1 : 0, 0);
delay(200);
// added = 0
// deleted = 0
// unchanged = 1
printAll(_topChanges->addDelNeg, _bottomChanges->addDelNeg, up ? 0 : 1, 1);
}
// added = 0
// deleted = 1
// unchanged = 0
printAll(_topChanges->del, _bottomChanges->del, up ? bw : 0, 0);
delay(250);
// added = 0
// deleted = 1
// unchanged = 1
printAll(_topChanges->addNeg, _bottomChanges->addNeg, up ? bw : 1, 1);
delay(250);
for(x=0; x<7; x++) {
delay(100);
// added = 0
// deleted = 1
// unchanged = 0
printAll(_topChanges->del, _bottomChanges->del, up ? bw : 0, 0);
delay(100);
// added = 0
// deleted = 1
// unchanged = 1
printAll(_topChanges->addNeg, _bottomChanges->addNeg, up ? bw : 1, 1);
}
zeroOut();
shutdown();
}