-
Notifications
You must be signed in to change notification settings - Fork 4
/
charlieplex.ino
138 lines (116 loc) · 3.44 KB
/
charlieplex.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
// where does our characterMap start in the ASCII code
#define MAP_START 32
#define DISPLAY_WIDTH 4
#define DISPLAY_HEIGHT 5
// "pixels" per second
#define SPEED 10
// the text to display
#define DISPLAY_STRING "HELLO WORLD!"
// maps characters to their 4x5 grid
unsigned long characterMap[59];
// set up a character in the characterMap
void Chr(char theChar, unsigned long value) {
characterMap[theChar - MAP_START] = value;
}
// The offset of our string in the display
int offset = 0;
unsigned long lastMillis = 0;
unsigned long currentMillis = 0;
unsigned int timeout;
char myString[] = DISPLAY_STRING;
int length = sizeof(myString);
// render the string on the given offset
void renderString(char *theString, int offset) {
int index = 0;
while (theString[index]) {
renderCharacter(theString[index], offset - index * (DISPLAY_WIDTH + 1));
index++;
}
}
// render a character on the given offset
void renderCharacter(char theChar, int charOffset) {
if (charOffset <= -DISPLAY_WIDTH || charOffset > DISPLAY_WIDTH) {
// off the 'screen' nothing to do
return;
}
unsigned long graphic = characterMap[theChar - MAP_START];
for (byte y = 0; y < DISPLAY_HEIGHT; y++) {
for (byte x = 0; x < DISPLAY_WIDTH; x++) {
// 3 - x to reverse order
setPixel(3 - x - charOffset, y, graphic & 0x1);
graphic = graphic >> 1;
}
}
}
// light a pixel at the given coordinates
void setPixel(byte x, byte y, boolean ledStatus) {
if (x >= 0 && x < DISPLAY_WIDTH) {
if (y <= x) {
x++;
}
setLed(y, x, ledStatus);
}
}
// turn on the pins to light a LED
void setLed(byte vin, byte gnd, boolean ledStatus) {
delay(1);
pinMode(0, INPUT);
pinMode(1, INPUT);
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(4, INPUT);
if(!ledStatus) return;
pinMode(vin, OUTPUT);
pinMode(gnd, OUTPUT);
digitalWrite(vin, HIGH);
digitalWrite(gnd, LOW);
}
// runs at start
void setup() {
// set up render map
// Rows: 1---2---3---4---5---
Chr('A', 0b01101001111110011001);
Chr('B', 0b11101001111010011110);
Chr('C', 0b01111000100010000111);
Chr('D', 0b11101001100110011110);
Chr('E', 0b11111000111010001111);
Chr('F', 0b11111000111010001000);
Chr('G', 0b01111000101110010110);
Chr('H', 0b10011001111110011001);
Chr('I', 0b01110010001000100111);
Chr('J', 0b01110010001010100100);
Chr('K', 0b10011010110010101001);
Chr('L', 0b10001000100010001111);
Chr('M', 0b10011111111110011001);
Chr('N', 0b10011101101110011001);
Chr('O', 0b01101001100110010110);
Chr('P', 0b11101001111010001000);
Chr('Q', 0b01101001101101100001);
Chr('R', 0b11101001111010101001);
Chr('S', 0b11111000111100011111);
Chr('T', 0b01110010001000100010);
Chr('U', 0b10011001100110010110);
Chr('V', 0b10011001100110100100);
Chr('W', 0b10011001111111110110);
Chr('X', 0b10011001011010011001);
Chr('Y', 0b10011001011000101100);
Chr('Z', 0b11110001001001001111);
Chr(' ', 0b00000000000000000000);
Chr('!', 0b01000100010000000100);
// how long to wait between shifting the display
timeout = 1000 / SPEED;
}
// loops continuously
void loop() {
currentMillis = millis();
renderString(myString, offset);
if (currentMillis - lastMillis > timeout) {
lastMillis = currentMillis;
// shift string over one "pixel"
offset++;
// if it's past the length of the string, start over from the beginning
if (offset > length * (DISPLAY_WIDTH + 1)) {
offset = -DISPLAY_WIDTH;
}
}
}