Skip to content

Instantly share code, notes, and snippets.

@hikari-no-yume
Created January 12, 2012 23:09
Show Gist options
  • Save hikari-no-yume/1603727 to your computer and use it in GitHub Desktop.
Save hikari-no-yume/1603727 to your computer and use it in GitHub Desktop.
LED Matrix - letters with Arduino and Python :)
# 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(" };")
# 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)
// 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();
}
# 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