8×8ドットマトリックス4連(4)・・歩け小緑人
はじめに
台湾の歩行者用信号機のアニメーション「小緑人」。
16ドット×16ドットのマトリクスLED(8×8ドットの4連)を買ったのは、実はこれを作ってみたかったからなんですよ(笑)
取材(1)・・信号機
さて、データを揃えるために、取材です。歩行者用信号機を録画してきました。
こいつをコマ送りで再生し、全7枚のドット配列を描き出しました。
使用したドット絵
取材(2)・・聖地巡礼
台北、信義区の松壽路と松智路の交差点近くに小緑人誕生の地の記念碑があるんです(笑)これに8枚のドット絵(歩き7枚、停止1枚)がありましたがどうも自分で撮ったビデオとは違う感じでした。
実装
#include <LedControl.h>
const int DIN_PIN = 7;
const int CS_PIN = 6;
const int CLK_PIN = 5;
const int DEVICES = 4;
const byte walkingimages[7][4][8]={
{{//0
B00000000,
B00000110,
B00001111,
B00000110,
B00000011,
B00000011,
B00000011,
B00000101
},{
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B11100000,
B10010000,
B10001000
},{
B00001001,
B00000000,
B00000000,
B00000001,
B00000010,
B00001110,
B00001000,
B00000000
},{
B11000000,
B11000000,
B10100000,
B00010000,
B00000000,
B00000100,
B00000100,
B00000000
}},
{{//1
B00000000,
B00000110,
B00001111,
B00000110,
B00000011,
B00000011,
B00000011,
B00000101
},{
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B11100000,
B10010000,
B10001000
},{
B00001001,
B00000000,
B00000000,
B00000000,
B00000001,
B00000010,
B00001100,
B00000000
},{
B11000000,
B11000000,
B10100000,
B10011100,
B00000100,
B00000100,
B00000100,
B00001000
}},
{{//2
B00000000,
B00000011,
B00000111,
B00000011,
B00000001,
B00000001,
B00000001,
B00000010
},{
B00000000,
B00000000,
B10000000,
B00000000,
B00000000,
B11000000,
B00100000,
B10010000
},{
B00000100,
B00000000,
B00000001,
B00000010,
B00000010,
B00000001,
B00000111,
B00000000
},{
B11010000,
B01000000,
B00100000,
B00111100,
B00000100,
B00001000,
B00000000,
B00000000
}},
{{//3
B00000000,
B00000011,
B00000111,
B00000011,
B00000001,
B00000001,
B00000001,
B00000000
},{
B00000000,
B00000000,
B10000000,
B00000000,
B10000000,
B11000000,
B10100000,
B11010000
},{
B00000000,
B00000001,
B00000000,
B00000001,
B00000010,
B00000001,
B00000000,
B00000011
},{
B11010000,
B01100000,
B11100000,
B00100000,
B00010000,
B10000100,
B10000100,
B10000000
}},
{{//4
B00000000,
B00000011,
B00000111,
B00000011,
B00000001,
B00000001,
B00000001,
B00000000
},{
B00000000,
B00000000,
B10000000,
B00000000,
B10000000,
B11000000,
B10100000,
B11010000
},{
B00000000,
B00000001,
B00000000,
B00000001,
B00000001,
B00000000,
B00000000,
B00000001
},{
B11010000,
B01100000,
B11100000,
B00100000,
B00010000,
B11001000,
B01011000,
B11010000
}},
{{//5
B00000000,
B00000011,
B00000111,
B00000011,
B00000001,
B00000001,
B00000001,
B00000000
},{
B00000000,
B00000000,
B10000000,
B00000000,
B10000000,
B11000000,
B11000000,
B11100000
},{
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000
},{
B11100000,
B01100000,
B01100000,
B10110000,
B01010000,
B01110000,
B00010000,
B01010000
}},
{{//6
B00000000,
B00000110,
B00001111,
B00000110,
B00000011,
B00000011,
B00000011,
B00000001
},{
B00000000,
B00000000,
B00000000,
B00000000,
B10000000,
B11000000,
B10100000,
B11010000
},{
B00000001,
B00000000,
B00000000,
B00000000,
B00000001,
B00000000,
B00000001,
B00000000
},{
B11010000,
B11100000,
B01100000,
B11000000,
B00100000,
B10011000,
B10000100,
B00011100
}}
};
LedControl display = LedControl(DIN_PIN, CLK_PIN, CS_PIN, DEVICES);
void setup() {
int devices = display.getDeviceCount();
for(int address=0;address<devices;address++) {
display.shutdown(address,false);
display.setIntensity(address,0);
display.clearDisplay(address);
};
}
void displayImage(int device,const byte *image) {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
display.setLed(device , i, j, bitRead(image[i], 7 - j));
}
}
}
void displayImageL(const byte image[4][8]){
displayImage(3, image[0]);
displayImage(2, image[1]);
displayImage(1, image[2]);
displayImage(0, image[3]);
}
void loop() {
for (byte num = 0; num<7; num++){
displayImageL(walkingimages[num]);
//delay(50);
}
}
ノロいけど動きました
次の課題
コード見ていただければわかるように、速く動かそうとしてついには画面表示後のdelayを消してしてしまいましたが、それでも「のろのろ歩いている」感じですね。
16×16の計256点についてLEDのONOFFを設定する関数display.setLed() という関数を実行していますがこれが結構時間を食っているみたいですね。
さて、考えてみれば消えたきりのLEDも多数あるわけです。
LEDがOFFからONになる場合、ONからOFFになる場合、のようにdisplay.setLed() に「変化があるときだけ」実行すればよいのですから、そういう方向で高速化を試みたいと思います。