-
Notifications
You must be signed in to change notification settings - Fork 0
/
BikeNavi.ino
451 lines (391 loc) · 10.5 KB
/
BikeNavi.ino
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
#include <inttypes.h>
#include <ctype.h>
/**************
Libs
*************/
#include <SPI.h>
#include <FLASH.h>
#include <EPD2.h>
#include <BinaryLine.h>
#include <Wire.h>
#include <LM75.h>
/**************
FONT
*************/
#include <Fonts.h> // this is just an empty file
#define MY_FONT calibri_14pt_bitmap
#define MY_FONT_WIDTH calibri_14pt_width
#define MY_FONT_INDEX calibri_14pt_index
#define FONT_CHARACTER_HEIGHT 17
PROGMEM
#define unsigned
#define char uint8_t
#include "calibri.c"
#undef char
#undef unsigned
PROGMEM
#include "calibri_width.c"
#include "calibri_index.c"
/****************
RENDERER
***************/
#define LINE_WIDTH 264
#define TOTAL_LINES 176
#define REPEAT 3
#define STEP 2
#define BLOCK 16
/****************
IMAGES
***************/
#include <Images.h> // this is just an empty file
#define IMG_ARROW_WIDTH 32
#define IMG_ARROW_HEIGHT 40
#define IMG_NORTH_WIDTH 16
#define IMG_NORTH_HEIGHT 16
#define LEFT_IMG arrow_left_bits
#define RIGHT_IMG arrow_right_bits
#define STRAIGHT_IMG arrow_straight_bits
#define NORTH_IMG_0 n_0_bits
#define NORTH_IMG_45 n_45_bits
#define NORTH_IMG_90 n_90_bits
PROGMEM const
#define unsigned
#define char uint8_t
#include "left.xbm"
#undef char
#undef unsigned
PROGMEM const
#define unsigned
#define char uint8_t
#include "right.xbm"
#undef char
#undef unsigned
PROGMEM const
#define unsigned
#define char uint8_t
#include "straight.xbm"
#undef char
#undef unsigned
PROGMEM const
#define unsigned
#define char uint8_t
#include "n_0.xbm"
#undef char
#undef unsigned
PROGMEM const
#define unsigned
#define char uint8_t
#include "n_45.xbm"
#undef char
#undef unsigned
PROGMEM const
#define unsigned
#define char uint8_t
#include "n_90.xbm"
#undef char
#undef unsigned
/************************
RENDER-UTILITY
************************/
unsigned char mapPoints[400] = {
184, 94,
180, 94,
179, 93,
178, 93,
176, 92,
174, 91,
170, 89,
166, 87,
161, 85,
157, 83,
154, 80,
153, 80,
151, 79,
150, 78,
147, 74,
143, 70,
139, 67,
136, 65,
133, 63,
130, 61,
127, 59,
124, 57,
121, 55,
119, 53,
116, 51,
113, 49,
111, 48,
108, 48,
106, 47,
103, 47,
101, 47,
99, 47,
94, 48,
89, 49,
88, 49,
81, 50,
74, 52,
70, 53,
68, 53,
63, 54,
59, 56,
53, 58,
49, 59,
43, 61,
37, 64,
36, 65,
31, 67,
27, 70,
24, 72,
21, 74,
19, 76,
18, 77,
16, 78,
16, 78,
15, 78,
15, 78,
15, 77,
15, 77,
16, 75,
16, 74,
17, 73,
18, 72,
19, 70,
20, 68,
21, 66,
22, 64,
24, 61,
25, 58,
27, 56,
29, 53,
30, 52,
32, 49,
34, 43,
35, 42,
35, 41,
36, 40,
38, 39,
40, 38,
42, 36,
46, 33,
53, 28,
60, 22,
65, 18,
70, 13,
74, 10,
77, 7,
79, 6,
80, 4,
81, 3,
81, 2,
82, 1,
0x00
}; //200 possilbe points
/***************************
Arduino IO layout
***************************/
//#define Pin_TEMPERATURE = A0; // Temperature is handled by LM75 over I2C and not an analog pin
#define Pin_MICROSD_CS 3
#define Pin_PANEL_ON 5
#define Pin_BORDER 10
#define Pin_DISCHARGE 4
//#define Pin_PWM 5 // Not used by COG v2
#define Pin_RESET 6
#define Pin_BUSY 7
#define Pin_EPD_CS 8
#define Pin_FLASH_CS 9
#define Pin_SW2 12
#define Pin_RED_LED 13
// LED anode through resistor to I/O pin
// LED cathode to Ground
#define LED_ON HIGH
#define LED_OFF LOW
// I/O setup
void setup() {
Serial.begin(9600);
Serial.println("Ia");
pinMode(Pin_RED_LED, OUTPUT);
//pinMode(Pin_SW2, INPUT);
//pinMode(Pin_TEMPERATURE, INPUT);
//pinMode(Pin_PWM, OUTPUT);
pinMode(Pin_BUSY, INPUT);
pinMode(Pin_RESET, OUTPUT);
pinMode(Pin_PANEL_ON, OUTPUT);
pinMode(Pin_DISCHARGE, OUTPUT);
pinMode(Pin_BORDER, OUTPUT);
pinMode(Pin_EPD_CS, OUTPUT);
pinMode(Pin_FLASH_CS, OUTPUT);
pinMode(Pin_MICROSD_CS, OUTPUT);
Serial.println("Pin Modes defined");
digitalWrite(Pin_RED_LED, LOW);
//digitalWrite(Pin_PWM, LOW); // not actually used - set low so can use current eval board unmodified
digitalWrite(Pin_RESET, LOW);
digitalWrite(Pin_PANEL_ON, LOW);
digitalWrite(Pin_DISCHARGE, LOW);
digitalWrite(Pin_BORDER, LOW);
digitalWrite(Pin_EPD_CS, LOW);
digitalWrite(Pin_FLASH_CS, HIGH);
digitalWrite(Pin_MICROSD_CS, HIGH);
Serial.println("Initial Pin values Set");
FLASH.begin(Pin_FLASH_CS);
if (FLASH.available()) {
Serial.println("FLASH chip detected OK");
} else {
uint8_t maufacturer;
uint16_t device;
FLASH.info(&maufacturer, &device);
Serial.print("unsupported FLASH chip: MFG: 0x");
Serial.print(maufacturer, HEX);
Serial.print(" device: 0x");
Serial.print(device, HEX);
Serial.println();
}
// configure temperature sensor
Wire.begin();
LM75.begin();
}
// main loop
void loop() {
char description[] = "Leicht links abbiegen auf Berndshöfer";
char distance_1[] = "2.3km";
char distance_2[] = "975.5m";
unsigned char descriptionLength = sizeof(description) / sizeof(unsigned char) - 1;
unsigned char distance_1_length = sizeof(distance_1) / sizeof(unsigned char) - 1;
unsigned char distance_2_length = sizeof(distance_2) / sizeof(unsigned char) - 1;
unsigned short angle = 315;
render(description, descriptionLength, distance_1, distance_1_length, distance_2, distance_2_length, angle);
// flash LED for 5 seconds
for (unsigned char x = 0; x < 50; ++x) {
digitalWrite(Pin_RED_LED, LED_ON);
delay(50);
digitalWrite(Pin_RED_LED, LED_OFF);
delay(50);
}
}
void render(const char *description, unsigned char descriptionLength, const char *distance_1, unsigned char distance_1_length, const char *distance_2, unsigned char distance_2_length, unsigned short angle)
{
// define the E-Ink display
EPD_Class EPD(EPD_2_7, Pin_PANEL_ON, Pin_BORDER, Pin_DISCHARGE, Pin_RESET, Pin_BUSY, Pin_EPD_CS);
BinaryLine line(MY_FONT, MY_FONT_INDEX, MY_FONT_WIDTH);
short temperature = LM75.read();
digitalWrite(Pin_MICROSD_CS, HIGH);
EPD.begin(); // power up the EPD panel
if (!EPD) {
Serial.print("EPD error = ");
Serial.print(EPD.error());
Serial.println("");
return;
}
EPD.setFactor(temperature); // adjust for current temperature
EPD.clear();
for (short n = 0; n < REPEAT; ++n) {
short BLOCK_begin = 0;
unsigned char BLOCK_end = 0;
while (BLOCK_begin < TOTAL_LINES) {
BLOCK_end += STEP;
BLOCK_begin = BLOCK_end - BLOCK;
if (BLOCK_begin < 0) {
BLOCK_begin = 0;
}
else if (BLOCK_begin >= TOTAL_LINES) {
break;
}
bool full_BLOCK = (BLOCK_end - BLOCK_begin == BLOCK);
for (unsigned char lineIndex = BLOCK_begin; lineIndex < BLOCK_end; ++lineIndex) {
if (lineIndex >= TOTAL_LINES) {
break;
}
if (full_BLOCK && (lineIndex < (BLOCK_begin + STEP))) {
EPD.line(lineIndex, 0, 0x00, false, EPD_normal);
}
else {
//Clear Line
line.clear();
//Description
renderText(description, descriptionLength, 0, 0, &line, lineIndex);
renderHorizontallLine(1 + FONT_CHARACTER_HEIGHT, 88, LINE_WIDTH, &line, lineIndex);
//Direction 1
renderImage(LEFT_IMG, IMG_ARROW_WIDTH, IMG_ARROW_HEIGHT, 25, 25, &line, lineIndex);
renderText(distance_1, distance_1_length, 0, 80, &line, lineIndex);
renderHorizontallLine(97, 0, 88, &line, lineIndex); //Direction Seperator
//Direction 2
renderImage(RIGHT_IMG, IMG_ARROW_WIDTH, IMG_ARROW_HEIGHT, 25, 105, &line, lineIndex);
renderText(distance_2, distance_2_length, 0, 160, &line, lineIndex);
//Map
renderVerticalLine(80, 1 + FONT_CHARACTER_HEIGHT, TOTAL_LINES, &line, lineIndex);
renderCompas(100, 25, angle, &line, lineIndex);
if (lineIndex > 19)
line.insertMap(mapPoints, lineIndex - 19, 81);
//Map Center
if (lineIndex >= 95 && lineIndex <= 99)
{
line.insertByte(0xF0, 168);
line.insertByte(0x01, 176);
}
line.render(&EPD, lineIndex);
}
}
}
}
EPD.end(); // power down the EPD panel
}
void renderHorizontallLine(unsigned short y, BinaryLine *line, unsigned char currentLineIndex)
{
renderHorizontallLine(y, 0, LINE_WIDTH, line, currentLineIndex);
}
void renderHorizontallLine(unsigned short y, unsigned short startX, unsigned short endX, BinaryLine *line, unsigned char currentLineIndex)
{
//TODO auch innerhalb eines bytes anfangen
if (currentLineIndex == y) {
unsigned short startByte = startX / 8;
unsigned short endByte = endX / 8;
for (unsigned short index = startByte; index < endByte; index++) {
line->insertByte(0xFF, index*8);
}
}
}
void renderCompas(unsigned short x, unsigned short y, unsigned short angle, BinaryLine *line, unsigned char currentLineIndex)
{
if (currentLineIndex > y && currentLineIndex < y + IMG_NORTH_HEIGHT)
{
unsigned char *img = NORTH_IMG_0;
bool flipVertical = false;
bool flipHorizontal = false;
if((angle > 22 && angle <=67) ||
(angle > 112 && angle <= 157) ||
(angle > 202 && angle <= 247) ||
(angle > 292 && angle <= 337))
{
img = NORTH_IMG_45;
}
if((angle > 67 && angle <=112) ||
(angle > 247 && angle <= 292))
{
img = NORTH_IMG_90;
}
if(angle > 112 && angle <=247)
flipHorizontal = true;
if(angle > 202 && angle <=337)
flipVertical = true;
line->insertImg(img, currentLineIndex - y, IMG_NORTH_WIDTH, IMG_NORTH_HEIGHT, x, flipHorizontal, flipVertical);
}
}
void renderVerticalLine(unsigned short x, BinaryLine *line, unsigned char currentLineIndex)
{
renderVerticalLine(x, 0, TOTAL_LINES, line, currentLineIndex);
}
void renderVerticalLine(unsigned short x, unsigned short startY, unsigned short endY, BinaryLine *line, unsigned char currentLineIndex)
{
if (currentLineIndex >= startY && currentLineIndex <= endY)
line->insertByte(0x80, x);
}
void renderImage(unsigned char * img, unsigned int imgWidth, unsigned int imgHeight, unsigned short x, unsigned short y, BinaryLine *line, unsigned char currentLineIndex)
{
if (currentLineIndex >= y && currentLineIndex < y + imgHeight)
line->insertImg(img, currentLineIndex - y, imgWidth, imgHeight, x ,false, false);
}
void renderText(unsigned char* text, unsigned char textLength, unsigned short x, unsigned short y, BinaryLine *line, unsigned char currentLineIndex)
{
if (currentLineIndex >= y && currentLineIndex < y + FONT_CHARACTER_HEIGHT)
line->insertText(text, textLength, currentLineIndex - y, 0);
}