Created
January 12, 2012 23:09
-
-
Save hikari-no-yume/1603727 to your computer and use it in GitHub Desktop.
LED Matrix - letters with Arduino and Python :)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Generate C header from CGA font data | |
import struct | |
with open("rawcga.bin", "r") as fi: | |
data = fi.read() | |
with open("rawcga.h", "w") as fo: | |
fo.write("char RAW_CGA[2048] = { ") | |
bytevalues = [] | |
for byte in data: | |
byte = struct.unpack("B", byte)[0] | |
# unmangle bit order (12345670 > 01234567) | |
byte = ((byte & 1) << 7) + byte >> 1 | |
bytevalues.append("{:#x}".format(byte)) | |
fo.write(", ".join(bytevalues)) | |
fo.write(" };") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Continuously output time (24H) to serial to display on matrix | |
import time | |
import serial | |
ser = serial.Serial(port='COM10') | |
print "Connected to COM port, waiting 5 seconds for arduino to reset" | |
time.sleep(5) | |
print "Starting:" | |
while 1: | |
data = b"\x7f"+time.strftime("%H:%M:%S ").encode("ascii") | |
ser.write(data) | |
print(repr(data)) | |
time.sleep(1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// from http://overcode.yak.net/12 converted using pngascii.py | |
char FONT_DATA[1024] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xff, 0xf7, 0xff, 0xeb, 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0xeb, 0xff, 0xf7, 0xe1, 0xd7, 0xe3, 0xf5, 0xc3, 0xf7, 0xff, 0xff, 0xcd, 0xcb, 0xf7, 0xe9, 0xd9, 0xff, 0xff, 0xe7, 0xd7, 0xef, 0xd7, 0xb9, 0xbb, 0xc5, 0xff, 0xf7, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xf7, 0xef, 0xef, 0xef, 0xf7, 0xfb, 0xff, 0xef, 0xf7, 0xfb, 0xfb, 0xfb, 0xf7, 0xef, 0xff, 0xf7, 0xb6, 0xd5, 0xe3, 0xd5, 0xb6, 0xf7, 0xff, 0xf7, 0xf7, 0xf7, 0x80, 0xf7, 0xf7, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xf3, 0xfb, 0xf7, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xf3, 0xff, 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0xff, 0xe3, 0xdd, 0xdd, 0xd5, 0xdd, 0xdd, 0xe3, 0xff, 0xf7, 0xe7, 0xf7, 0xf7, 0xf7, 0xf7, 0xe3, 0xff, 0xe3, 0xdd, 0xfd, 0xfb, 0xf7, 0xef, 0xc1, 0xff, 0xe3, 0xdd, 0xfd, 0xf3, 0xfd, 0xdd, 0xe3, 0xff, 0xf3, 0xeb, 0xdb, 0xc1, 0xfb, 0xfb, 0xf1, 0xff, 0xc1, 0xdf, 0xdf, 0xc3, 0xfd, 0xdd, 0xe3, 0xff, 0xe3, 0xdd, 0xdf, 0xc3, 0xdd, 0xdd, 0xe3, 0xff, 0xc1, 0xfd, 0xfb, 0xf7, 0xef, 0xef, 0xef, 0xff, 0xe3, 0xdd, 0xdd, 0xe3, 0xdd, 0xdd, 0xe3, 0xff, 0xe3, 0xdd, 0xdd, 0xe1, 0xfd, 0xdd, 0xe3, 0xff, 0xff, 0xf3, 0xf3, 0xff, 0xf3, 0xf3, 0xff, 0xff, 0xff, 0xf3, 0xf3, 0xff, 0xf3, 0xf3, 0xfb, 0xf7, 0xfb, 0xf7, 0xef, 0xdf, 0xef, 0xf7, 0xfb, 0xff, 0xff, 0xff, 0x80, 0xff, 0x80, 0xff, 0xff, 0xff, 0xdf, 0xef, 0xf7, 0xfb, 0xf7, 0xef, 0xdf, 0xff, 0xe3, 0xdd, 0xfd, 0xfb, 0xf7, 0xff, 0xf7, 0xff, 0xe3, 0xdd, 0xd1, 0xd5, 0xd1, 0xdf, 0xe3, 0xff, 0xe3, 0xdd, 0xdd, 0xc1, 0xdd, 0xdd, 0xdd, 0xff, 0xc3, 0xdd, 0xdd, 0xc3, 0xdd, 0xdd, 0xc3, 0xff, 0xe3, 0xdd, 0xdf, 0xdf, 0xdf, 0xdd, 0xe3, 0xff, 0xc3, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xc3, 0xff, 0xc1, 0xdf, 0xdf, 0xc3, 0xdf, 0xdf, 0xc1, 0xff, 0xc1, 0xdf, 0xdf, 0xc1, 0xdf, 0xdf, 0xdf, 0xff, 0xe3, 0xdd, 0xdf, 0xd1, 0xdd, 0xdd, 0xe3, 0xff, 0xdd, 0xdd, 0xdd, 0xc1, 0xdd, 0xdd, 0xdd, 0xff, 0xe3, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xe3, 0xff, 0xf1, 0xfb, 0xfb, 0xfb, 0xdb, 0xdb, 0xe7, 0xff, 0xdd, 0xdd, 0xdb, 0xc7, 0xdb, 0xdd, 0xdd, 0xff, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xe1, 0xff, 0xbe, 0x9c, 0xaa, 0xb6, 0xbe, 0xbe, 0xbe, 0xff, 0xdd, 0xcd, 0xd5, 0xd5, 0xd9, 0xdd, 0xdd, 0xff, 0xe3, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xe3, 0xff, 0xe3, 0xed, 0xed, 0xe3, 0xef, 0xef, 0xef, 0xff, 0xe3, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xe3, 0xf9, 0xc3, 0xdd, 0xdd, 0xc3, 0xd7, 0xdb, 0xdd, 0xff, 0xe3, 0xdd, 0xdf, 0xe3, 0xfd, 0xdd, 0xe3, 0xff, 0xc1, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xff, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xe3, 0xff, 0xdd, 0xdd, 0xdd, 0xeb, 0xeb, 0xf7, 0xf7, 0xff, 0xbe, 0xbe, 0xbe, 0xd5, 0xd5, 0xeb, 0xeb, 0xff, 0xdd, 0xdd, 0xeb, 0xf7, 0xeb, 0xdd, 0xdd, 0xff, 0xdd, 0xdd, 0xeb, 0xf7, 0xf7, 0xf7, 0xf7, 0xff, 0xc1, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xc1, 0xff, 0xe3, 0xef, 0xef, 0xef, 0xef, 0xef, 0xe3, 0xff, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe, 0xff, 0xe3, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xe3, 0xff, 0xf7, 0xeb, 0xdd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xef, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xfd, 0xe1, 0xdd, 0xdd, 0xe2, 0xff, 0xef, 0xef, 0xe3, 0xed, 0xed, 0xed, 0xd3, 0xff, 0xff, 0xff, 0xe3, 0xdf, 0xdf, 0xdf, 0xe3, 0xff, 0xfd, 0xfd, 0xf1, 0xed, 0xed, 0xed, 0xf2, 0xff, 0xff, 0xff, 0xe3, 0xdd, 0xc1, 0xdf, 0xe3, 0xff, 0xf3, 0xed, 0xef, 0xc7, 0xef, 0xef, 0xef, 0xff, 0xff, 0xff, 0xe2, 0xdd, 0xdd, 0xe1, 0xfd, 0xe3, 0xdf, 0xdf, 0xd3, 0xcd, 0xdd, 0xdd, 0xdd, 0xff, 0xff, 0xf7, 0xff, 0xf7, 0xf7, 0xf7, 0xf7, 0xff, 0xff, 0xf7, 0xff, 0xf7, 0xf7, 0xf7, 0xf7, 0xcf, 0xdf, 0xdf, 0xdb, 0xd7, 0xcf, 0xd7, 0xdb, 0xff, 0xe7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xff, 0xff, 0xff, 0x49, 0xb6, 0xb6, 0xbe, 0xbe, 0xff, 0xff, 0xff, 0xd3, 0xed, 0xed, 0xed, 0xed, 0xff, 0xff, 0xff, 0xe3, 0xdd, 0xdd, 0xdd, 0xe3, 0xff, 0xff, 0xff, 0xd3, 0xed, 0xed, 0xe3, 0xef, 0xef, 0xff, 0xff, 0xe5, 0xdb, 0xdb, 0xe3, 0xfb, 0xfb, 0xff, 0xff, 0xd3, 0xcf, 0xdf, 0xdf, 0xdf, 0xff, 0xff, 0xff, 0xe3, 0xdf, 0xe7, 0xfb, 0xc7, 0xff, 0xff, 0xf7, 0xe3, 0xf7, 0xf7, 0xf7, 0xf7, 0xff, 0xff, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xe5, 0xff, 0xff, 0xff, 0xdd, 0xdd, 0xdd, 0xeb, 0xf7, 0xff, 0xff, 0xff, 0xbe, 0xbe, 0xb6, 0xaa, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xeb, 0xf7, 0xeb, 0xdd, 0xff, 0xff, 0xff, 0xed, 0xed, 0xed, 0xf1, 0xfd, 0xe3, 0xff, 0xff, 0xc3, 0xfb, 0xf7, 0xef, 0xc3, 0xff, 0xf3, 0xef, 0xef, 0xdf, 0xef, 0xef, 0xf3, 0xff, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xff, 0xcf, 0xf7, 0xf7, 0xfb, 0xf7, 0xf7, 0xcf, 0xff, 0xff, 0xff, 0xcf, 0xb6, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | |
// Font line macro | |
#define FONT_ROW(c, r) (~FONT_DATA[c*8+r]) | |
// Message buffer | |
char message[200]; | |
// Message length | |
int message_len = 0; | |
//Pin connected to ST_CP of 74HC595 | |
int latchPin = 8; | |
//Pin connected to SH_CP of 74HC595 | |
int clockPin = 12; | |
////Pin connected to DS of 74HC595 | |
int dataPin = 11; | |
// Power pins for each row | |
int ROWPIN[] = { | |
2, | |
3, | |
4, | |
5, | |
6, | |
7, | |
9, | |
10 | |
}; | |
// Outputted row values | |
int ROW[8]; | |
void setup() { | |
//set pins to output so you can control the shift register | |
pinMode(latchPin, OUTPUT); | |
pinMode(clockPin, OUTPUT); | |
pinMode(dataPin, OUTPUT); | |
for (int r = 0; r < 8; r++) { | |
pinMode(ROWPIN[r], OUTPUT); | |
} | |
Serial.begin(9600); | |
} | |
void lightMatrix() { | |
for (int r = 0; r < 8; r++) { | |
// take the latchPin low so | |
// the LEDs don't change while you're sending in bits: | |
digitalWrite(latchPin, LOW); | |
// shift out the bits: (inverted since sinking current) | |
shiftOut(dataPin, clockPin, LSBFIRST, ~ROW[r]); | |
//take the latch pin high so the columns will be sunk: | |
digitalWrite(latchPin, HIGH); | |
//take the row pin high so the rows will be powered: | |
digitalWrite(ROWPIN[r], HIGH); | |
delay(1); | |
// take the row pin low so the row will be unpowered: | |
digitalWrite(ROWPIN[r], LOW); | |
} | |
} | |
// PC sends rows to display (each row is byte) | |
void getSerialRows() { | |
static int curSerialRow = 0; | |
while (Serial.available() > 0) { | |
if (curSerialRow > 7) | |
curSerialRow = 0; | |
ROW[curSerialRow] = Serial.read(); | |
curSerialRow++; | |
} | |
} | |
// PC sends ASCII text to display | |
void getSerialMessage() { | |
while (Serial.available() > 0) { | |
char c; | |
c = Serial.read(); | |
if (c == 0x7f) { // 0x7f resets message buffer | |
message_len = 0; | |
}else{ | |
if (message_len >= 100) | |
message_len = 0; | |
message[message_len] = c; | |
message_len++; | |
} | |
} | |
} | |
#define tickinc 8 | |
#define tickmax 8 | |
// Scrolling text | |
void scrollMessage() { | |
static char c1 = 0x7f; | |
static char c2 = 0x7f; | |
static int tick = tickmax*tickinc; | |
static int stringpos = -1; | |
if (tick >= tickinc*tickmax) { | |
tick = 0; | |
stringpos++; | |
if (stringpos >= message_len) | |
stringpos = 0; | |
c1 = c2; | |
c2 = message[stringpos]; | |
} | |
for (int r = 0; r < 8; r++) { | |
if (r-tick/tickinc >= 0 and r-tick/tickinc < 8) | |
ROW[r-tick/tickinc] = FONT_ROW(c1, r); | |
if (r-tick/tickinc+8 >= 0 and r-tick/tickinc+8 < 8) | |
ROW[r-tick/tickinc+8] = FONT_ROW(c2, r); | |
} | |
tick++; | |
} | |
void loop() { | |
// Display rows | |
lightMatrix(); | |
// Check for serial input | |
getSerialMessage(); | |
// Change rows | |
scrollMessage(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Generate C header from PNG font | |
import struct | |
import Image | |
fn = Image.open("8x8font.png") | |
def getCharFromImage(char, img): | |
code = ord(char) | |
lines = [] | |
for y in range(8): | |
line = "" | |
for x in range(8): | |
px = img.getpixel( (code*8 + x, y) ) | |
line += "1" if px else "0" | |
lines.append(line) | |
return lines | |
def binaryChar(char): | |
chardata = getCharFromImage(char, fn) | |
binarydata = b"" | |
for row in chardata: | |
num = int(row, 2) | |
binarydata += struct.pack("B", num) | |
return binarydata | |
with open("font.h", "w") as f: | |
data = [] | |
for char in range(128): | |
for byte in binaryChar(chr(char)): | |
data.append(byte) | |
f.write("char FONT_DATA[1024] = { ") | |
f.write(", ".join(["{:#x}".format(struct.unpack("B", byte)[0]) for byte in data])) | |
f.write(" };") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment