GainerとProcessingで8×8マトリクスLEDを制御する
前回のエントリでちょっと情けないミスをやらかしてしまったが、ProcessingからGainerのMODE7を使ってマトリクスLEDを制御することができたので記事にしてみる。
まずは動画。まだ撮影環境は携帯のままなので、画質などについてはご容赦いただきたい。
●Gainerライブラリの修正
前回の方法でProcessingのGainerライブラリを再ビルドする。コードは前回から引き続きお世話になっているbird.dip.jpのMODE7用実装をそのままいただいている。diffを取ったので参考にされたい。入出力の初期化を変更し、MODE7用のメソッドを実装している。
386c386
< digitalInput = new boolean[0];
---
> digitalInput = new boolean[8];
388c388
< analogOutput = new int[8];
---
> analogOutput = new int[0];
815,857d814
< // for MODE7
< public boolean scanLine(int ch, int[] values){
< if ((analogOutput.length != 8) || (digitalOutput.length != 8)){
< return false;
< }
< if (ch >= 8){
< return false;
< }
< String code = "a" + Integer.toString(ch);
< for (int i = 0; i < 8; i++){
< int value = values[i];
< value = value < 0? 0: value;
< value = value > 0x0f? 0x0f: value;
< code += Integer.toHexString(value).toUpperCase();
< }
< code += "*";
< execCode(code, false);
<
< return true;
< }
<
< public boolean scanMatrix(int[] values){
< if (currentVerbose)
< System.out.println("scanMatrix");
<
< if (values.length != 64) {
< // System.out.println("scanMatrix != 64");
< return false;
< }
< if ((analogOutput.length != 8) || (digitalOutput.length != 8)) {
< // System.out.println("scanMatrix != 8");
< return false;
< }
< int[] v = new int[8];
< for (int i = 0; i < 8; i++) {
< for (int j = 0; j < 8; j++) {
< v[j] = values[i * 8 + j];
< }
< scanLine(i, v);
< }
<
< return true;
< }
●配線
こちらの記事同様、秋月で買ってきたTOM-1588BH-Bを使っている。そのため+Gainer P.134~の図とはROW / COLが逆になっている。aout0~3/dout0~3をROWの1~8へ1kΩの抵抗をはさんで接続、ain0~3/din0~3をCOLの1~8へ接続する。ピン配置が飛んでいるので注意しよう。
●コード
ペイントソフトで文字を書き縦8pixelにした画像をデータソースにして、画面とLEDに表示している。グレースケール画像なので赤成分(何色でもいいのだが)を取り出し15段階に丸めてLEDに送る。
/**
* Matrix LED
* @author kwappa (http://www.kwappa.net/)
*/
import processing.gainer.* ;
Gainer gainer ;
int count ;
int idx ;
PImage img ;
int zoom = 32 ; // 画像の倍率
void setup()
{
// 画像読み込み
img = loadImage("src_img0.png") ;
// キャンバスサイズ
size(img.height * zoom, img.height * zoom) ;
// Gainerの準備
gainer = new Gainer(this, Gainer.MODE7) ;
idx = -img.height ;
}
void draw()
{
//**************************************************************************
// 描画
//**************************************************************************
colorMode(RGB, 255) ;
if (++ count > 8) // 8フレームで1ピクセル移動
{
count = ;
idx ++ ;
if (idx >= img.width) idx -= img.width + img.height ;
// 描画用データ配列を用意
int[] p = new int[64] ;
for (int y = ; y < 8 ; y ++)
{
for (int x = ; x < 8 ; x ++)
{
// 元画像のpixel位置を生成
int u = idx + x + y * img.width ;
// 画像外なら消灯
if (idx + x >= img.width || idx + x < )
{
p[y * 8 + x] = ;
}
// 画像内なら赤を15段階に丸めて出力
else
{
p[y * 8 + x] = (int)red(img.pixels[u]) / 15 ;
}
}
}
// 描画データをMatrix LEDに送る
gainer.scanMatrix(p) ;
}
// キャンバスを塗りつぶして画像を描画
background(, , ) ;
image(img, idx * -zoom, , img.width * zoom, img.height * zoom) ;
}
ソースコードと画像データ、Gainerライブラリ(Gainer.java/gainer.jar)はこちら。
やはりLEDが光るのは単純に楽しいが、8×8ではなかなか表現が難しい。ゲーム屋あがりなのだがドット絵の技術がないので、表示して楽しいデータを用意できるかどうかが今後の勝負だろうか。入出力ピンをすべて使い切っているので、他のセンサでコントロールできないのがちょっともどかしい。
●bird.dip.jp: GAINER 用 Processing ライブラリ
http://bird.dip.jp/mt/archives/2008/04/04/2154.html
●bird.dip.jp: Matrix LED on Processing
http://bird.dip.jp/mt/archives/2008/04/08/2109.html