Skip to content

Instantly share code, notes, and snippets.

@CLCL

CLCL/picari-01.js

Last active Aug 29, 2015
Embed
What would you like to do?
akibaLEDピカリ館で販売している単色LEDパネル(32cm×16cm)を専用基盤を使わずRaspberry Piとnode.jsを使いパターン点灯させるサンプル。Raspberry Pi(256MB以上)、Node.js 0.12で動作確認済み。
'use strict';
// akibaLEDピカリ館の単色LEDマトリクスパネルP10を
// Raspberry Piのnode.js(v0.12)で光らせる
//
// 配線については http://cl.hatenablog.com/entry/picari-ledmatrix-raspberrypi 参照
// Usage:
// (Raspberry PiにRaspbian Wheezyをインストールして、piユーザでログイン後)
// git clone https://gist.github.com/aad7b6ad8f97ca9a8a2a.git picari
// cd $_
// npm install onoff pi-spi
// sudo node picalri-01.js
// #Use libs
var SPI = require('pi-spi');
var Gpio = require('onoff').Gpio;
// #define
var HIGH = 1;
var LOW = 0;
var OE = 22; // GPIO22(15pin)
var DYNA = 24; // GPIO24(18pin)
var DYNB = 23; // GPIO23(16pin)
var LATCH = 25; // GPIO25(22pin)
// MOSI(19pin):SPI DATA OUTPUT
// SCLK(23pin):SPI CLOCK
var WAIT = 1; // 0: 410Hz, 1: 250Hz
var pattern = [
0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
1,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,
0,0,1,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,
0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
1,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
1,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
];
// SPI/GPIO初期化
var spi = SPI.initialize('/dev/spidev0.0');
spi.clockSpeed(7812500); // 7.8MHz(15.6MHzだと取りこぼしがみられた)
//spi.bitOrder(SPI.order.LSB_FIRST); // パネル仕様ではLSBだがpi-spiでエラーになるので
var oe = new Gpio(OE , 'out');
var dyna = new Gpio(DYNA , 'out');
var dynb = new Gpio(DYNB , 'out');
var latch = new Gpio(LATCH, 'out');
oe.writeSync(LOW); // 消灯
dyna.writeSync(LOW); // ライン0より走査
dynb.writeSync(LOW); // ライン0より走査
latch.writeSync(LOW); // ラッチ
// VRAM初期化
var vram = [
new Buffer(16),
new Buffer(16),
new Buffer(16),
new Buffer(16)
];
var workVram = [
new Buffer(16),
new Buffer(16),
new Buffer(16),
new Buffer(16)
];
for (var i = 0; i < 4; i++) {
var buf = new Buffer(16); // LEDパネル1面分(画素512bitのうち1回の駆動での画素128bit=16byte)
vram[i].copy(buf);
buf.fill(255); // bufferクリア
// 配列からbufferに転記するループ
for (var j = 0; j < 16; j++) {
var s = 255;
for (var k = 0; k < 8; k++) {
s = s - (pattern[i * 32 + ((15 - j) % 4) * 128 + (j >> 2) * 8 + k] << (7 -k));
}
buf.writeUInt8(s, j);
//console.log("i:"+i+" j:"+j+ " s:"+s);
}
vram[i] = buf;
}
var loop = function(i) { // i: 表示ライン(0~3)
i %= 4;
// ティアリング防止のため第0ライン表示時に画素を固定する
if (i == 0) {
vram[0].copy(workVram[0]);
vram[1].copy(workVram[1]);
vram[2].copy(workVram[2]);
vram[3].copy(workVram[3]);
}
// SPI転送
spi.write(workVram[i], function(e) {
if (e) console.error(e);
// LEDパネル制御線の操作
oe.writeSync(LOW); // パネル消灯
dyna.write(i & 1); // ダイナミック点灯桁指定(LOW)
dynb.write(i >> 1 & 1); // ダイナミック点灯桁指定(HIGH)
latch.write(HIGH); // ラッチ解除
oe.write(HIGH); // パネル点灯
latch.write(LOW); // ラッチ
var timerId1 = setTimeout(function() {loop(++i);}, WAIT); // 0: 410Hz, 1: 250Hz
//var timerId2 = setImmediate( function() { f(++i); }); // 410Hz
});
};
var main = function() {
process.on('SIGINT', function() {
oe.writeSync(LOW); // 消灯
console.log('');
process.exit(0);
});
loop(0);
};
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment