Skip to content

Instantly share code, notes, and snippets.

@possan
Created September 10, 2014 22:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save possan/cd3211a3deb1244c13ed to your computer and use it in GitHub Desktop.
Save possan/cd3211a3deb1244c13ed to your computer and use it in GitHub Desktop.
64x32 ledpanel driver for node.js
var SerialPort = require("serialport");
// https://github.com/tompreston/4x5-Font/blob/master/4x5-font.js
var font4x5 = {
'': [0x0, 0x0, 0x0, 0x0, 0x0],
'!': [0x4, 0x4, 0x4, 0x0, 0x4],
'#': [0x6, 0xf, 0x6, 0xf, 0x6],
'\'': [0x0, 0xa, 0x0, 0x0, 0x0],
'%': [0x7, 0xe, 0x4, 0x7, 0xe],
'$': [0x7, 0xa, 0x6, 0x5, 0xe],
'"': [0x1, 0x2, 0x0, 0x0, 0x0],
'&': [0x2, 0x5, 0x6, 0xa, 0x5],
')': [0x4, 0x2, 0x2, 0x2, 0x4],
'(': [0x4, 0x8, 0x8, 0x8, 0x4],
'+': [0x0, 0x2, 0x7, 0x2, 0x0],
'*': [0x0, 0x6, 0xf, 0x6, 0x0],
'-': [0x0, 0x0, 0x0, 0xf, 0x0],
',': [0x0, 0x0, 0x0, 0x2, 0x4],
'/': [0x1, 0x1, 0x2, 0x4, 0x8],
'.': [0x0, 0x0, 0x0, 0x0, 0x4],
'1': [0x2, 0x6, 0x2, 0x2, 0x2],
'0': [0x6, 0xb, 0xf, 0xd, 0x6],
'3': [0xe, 0x1, 0x6, 0x1, 0xe],
'2': [0xe, 0x1, 0x6, 0x8, 0xf],
'5': [0xf, 0x8, 0xe, 0x1, 0xe],
'4': [0x2, 0x6, 0xa, 0xf, 0x2],
'7': [0xf, 0x1, 0x2, 0x4, 0x8],
'6': [0x6, 0x8, 0xe, 0x9, 0x6],
'8': [0x6, 0x9, 0x6, 0x9, 0x6],
'9': [0x6, 0x9, 0xf, 0x1, 0x6],
':': [0x0, 0x4, 0x0, 0x4, 0x0],
';': [0x0, 0x4, 0x0, 0x4, 0x8],
'<': [0x2, 0x4, 0x8, 0x4, 0x2],
'=': [0x0, 0xf, 0x0, 0xf, 0x0],
'>': [0x4, 0x2, 0x1, 0x2, 0x4],
'?': [0x6, 0x9, 0x2, 0x0, 0x2],
'@': [0x6, 0xd, 0xb, 0x8, 0x6],
'A': [0x4, 0xa, 0xe, 0xa, 0xa],
'B': [0xe, 0x9, 0xe, 0x9, 0xe],
'C': [0x6, 0x9, 0x8, 0x9, 0x6],
'D': [0xe, 0x9, 0x9, 0x9, 0xe],
'E': [0xf, 0x8, 0xe, 0x8, 0xf],
'F': [0xf, 0x8, 0xe, 0x8, 0x8],
'G': [0x6, 0x8, 0xb, 0x9, 0x6],
'H': [0x9, 0x9, 0xf, 0x9, 0x9],
'I': [0xe, 0x4, 0x4, 0x4, 0xe],
'J': [0x1, 0x1, 0x1, 0x9, 0x6],
'K': [0x9, 0xa, 0xc, 0xa, 0x9],
'L': [0x8, 0x8, 0x8, 0x8, 0xf],
'M': [0x9, 0xf, 0xf, 0x9, 0x9],
'N': [0x9, 0xd, 0xf, 0xb, 0x9],
'O': [0x6, 0x9, 0x9, 0x9, 0x6],
'P': [0xe, 0x9, 0xe, 0x8, 0x8],
'Q': [0x6, 0x9, 0x9, 0xb, 0x7],
'R': [0xe, 0x9, 0xe, 0xa, 0x9],
'S': [0x7, 0x8, 0x6, 0x1, 0xe],
'T': [0xe, 0x4, 0x4, 0x4, 0x4],
'U': [0x9, 0x9, 0x9, 0x9, 0x6],
'V': [0x9, 0x9, 0x9, 0x6, 0x6],
'W': [0x9, 0x9, 0xf, 0xf, 0x9],
'X': [0x9, 0x9, 0x6, 0x9, 0x9],
'Y': [0x9, 0x5, 0x2, 0x2, 0x2],
'Z': [0xf, 0x2, 0x4, 0x8, 0xf],
'[': [0xe, 0x8, 0x8, 0x8, 0xe],
'\\': [0x8, 0x8, 0x4, 0x2, 0x1],
']': [0x7, 0x1, 0x1, 0x1, 0x7],
'^': [0x4, 0xa, 0x0, 0x0, 0x0],
'_': [0x0, 0x0, 0x0, 0x0, 0xf],
'`': [0x4, 0x2, 0x0, 0x0, 0x0],
'a': [0x0, 0x5, 0xb, 0xb, 0x5],
'b': [0x8, 0x8, 0xe, 0x9, 0xe],
'c': [0x0, 0x7, 0x8, 0x8, 0x7],
'd': [0x1, 0x1, 0x7, 0x9, 0x7],
'e': [0x0, 0x6, 0xf, 0x8, 0x7],
'f': [0x3, 0x4, 0xe, 0x4, 0x4],
'g': [0x7, 0x9, 0x7, 0x1, 0x7],
'h': [0x8, 0x8, 0xe, 0x9, 0x9],
'i': [0x0, 0x2, 0x0, 0x2, 0x2],
'j': [0x1, 0x0, 0x1, 0x1, 0x6],
'k': [0x8, 0xa, 0xc, 0xa, 0x9],
'l': [0xc, 0x4, 0x4, 0x4, 0xe],
'm': [0x0, 0x9, 0xf, 0xf, 0x9],
'n': [0x0, 0xe, 0x9, 0x9, 0x9],
'o': [0x0, 0x6, 0x9, 0x9, 0x6],
'p': [0x0, 0xe, 0x9, 0xe, 0x8],
'q': [0x0, 0x6, 0x9, 0x7, 0x1],
'r': [0x0, 0xb, 0xc, 0x8, 0x8],
's': [0x0, 0x7, 0x4, 0x2, 0xe],
't': [0x4, 0xe, 0x4, 0x4, 0x3],
'u': [0x0, 0x9, 0x9, 0x9, 0x6],
'v': [0x0, 0x9, 0x9, 0x6, 0x6],
'w': [0x0, 0x9, 0xf, 0xf, 0x6],
'x': [0x0, 0x9, 0x6, 0x6, 0x9],
'y': [0x0, 0x9, 0x7, 0x1, 0x6],
'z': [0x0, 0xf, 0x2, 0x4, 0xf],
'{': [0x6, 0x4, 0xc, 0x4, 0x6],
'|': [0x4, 0x4, 0x0, 0x4, 0x4],
'}': [0xc, 0x4, 0x6, 0x4, 0xc],
'~': [0x0, 0x0, 0x5, 0xa, 0x0],
};
var serialPort = new SerialPort.SerialPort('/dev/tty.usbmodem1421', {
baudrate: 57600
});
var open = false;
var pixels = new Array(64*16);
serialPort.on("open", function () {
console.log('opened');
serialPort.write(new Buffer('C'));
open = true;
});
var scanrow = 0;
function queueSend() {
// update one row
var o = scanrow * 8;
var bytes = 8;
var packet = new Buffer(5 + bytes);
packet[0] = 'W'.charCodeAt(0);
packet[1] = o & 255;
packet[2] = o >> 8;
packet[3] = bytes & 255;
packet[4] = bytes >> 8;
var o2 = scanrow * 64;
for(var j=0; j<bytes; j++) {
var b = 0;
for(var k=0; k<8; k++) {
if (pixels[o2 ++]) b |= 1 << k;
}
packet[5 + j] = b;
}
// console.log('sending: ' + packet);
serialPort.write(packet);
scanrow ++;
scanrow %= 16;
}
function gotAck() {
setTimeout(queueSend.bind(this), 0);
}
serialPort.on("data", function (data) {
// console.log('got data', data.toString());
if (data.toString().substring(0, 1) == 'K') { gotAck(); }
});
serialPort.on("close", function (data) {
open = false;
console.log('closed');
});
var fr = 0;
function setPixel(x, y, on) {
if (x < 0 || y < 0 || x >= 64 || y >= 16)
return;
pixels[Math.floor(y) * 64 + Math.floor(x)] = on;
}
function drawChar(ch, x, y) {
var chardata = font4x5[ch];
// console.log('drawChar', ch, chardata);
if (chardata) {
for(var r=0; r<5; r++) {
for(var c=0; c<4; c++) {
var b = chardata[r];
var mask = 1 << (3-c);
if ((b & mask) == mask)
setPixel(x+c, y+r, true);
}
}
}
}
function drawString(str, x, y, spacing) {
for(var c=0; c<str.length; c++) {
drawChar(str.substring(c, c+1), x + c*(5 + spacing || 0), y);
}
}
setInterval(function() {
var o = 0;
for(var y=0; y<16; y++) {
for(var x=0; x<64; x++) {
// pixels[o] = (((x ^ y) % 16) == (fr % 16));
pixels[o] = false;
o ++;
}
}
var str = 'Hello world!';
for(var c=0; c<str.length; c++) {
drawChar(str.substring(c, c+1), 3 + 5 * c + 5 * Math.sin(fr / 13.0 + c / 5.0 ), 3 + 3.0 * Math.sin(fr / 10.0 + c / 2.1));
}
drawString((new Date()).toString().substring(16, 24), 12 + 12 * Math.sin(fr/40.0), 11, 0);
o = 0;
var all = '';
for(var y=0; y<16; y++) {
for(var x=0; x<64; x++) {
all += pixels[o] ? '()' : ' '
o ++;
}
all += '\n';
}
console.log('\033[2J' + all);
fr ++;
}, 40);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment