木曜日, 4月 21, 2016

Arduino: ドットマトリクス・ディスプレイで遊ぶ


 ドットマトリクス・ディスプレイというものがあります。

ドット(点、それぞれLED)で構成されたディスプレイなわけですが、一行ずつ行のLEDを点灯すると、行ごとパターンが光ります。

これを繰り返していくとディスプレイ全体で図形が表示されるというのが一般的なドットマトリクス・ディスプレイの使い方です。

Arduino 単体でも 8x8 であれば動くわけですが、そのままだと行+列ぶんだけ信号線が要ります。この処理を引き受けてくれるICを使うとドットマトリクス・ディスプレイを楽しく使うことができます。



写真は MAX7219 を使ったキットです。よくできてます。作るときのワクワク感、できたときの満足感が保証できるのがキットのいいところといえるでしょう。出来上がりも見事です。明るく輝くLEDディスプレイで遊んでみました。

まずはキットから。MAX7219, セラミック、電解コンデンサ、抵抗とピンソケットをはんだ付けします。

そして、配線。

VCC    5V
GND    GND
DIN    8 ピン
CS    9 ピン
CLK    10ピン

こちら Arduino 用のスケッチです。ドットのパターンは Java アプリを書いて作成しました。

できた動画がこれです。今の気分を表してます (^^




このディスプレイを赤外線センサーPIRを使って手を振ると動作を開始するよう改良してみました。

リモートでも動くよう割り込みを調整してみました。

ブレッドボード Arduino で組めばそこかしこ置いて遊べます。

百均ケースでうまく収まってます。



#3Dプリンタで作るケースならしっかり収まります。STL ファイルはこちら(2017-12-23)





コードはこちらです。

#include <IRremote.h>
int pinCLK = 10;
int pinCS = 9;
int pinDIN = 8;
boolean displayOn = false;
int pir = 2;
int remote = 3;
IRrecv irrecv(remote);
decode_results results;
unsigned char dat[8] = {0b010000001,
0b001011010,
0b000100100,
0b001011010,
0b001011010,
0b000100100,
0b001011010,
0b010000001
};
unsigned char heart[8] = {0b00000000,
0b01100110,
0b11111111,
0b11111111,
0b11111111,
0b01111110,
0b00111100,
0b00011000
};
unsigned char smily[8] = {0b00000000,
0b01000010,
0b11100111,
0b01000010,
0b00000000,
0b01000010,
0b00100100,
0b00011000
};
unsigned char handsup[8] = {0b10000001,
0b01011010,
0b00100100,
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00100100
};
unsigned char handshoriz[8] = {0b00000000,
0b00011000,
0b11100111,
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00100100
};
unsigned char handsdown[8] = {0b00000000,
0b00011000,
0b00100100,
0b01011010,
0b10011001,
0b00011000,
0b00011000,
0b00100100
};
void WriteByte(unsigned char DATA)
{
unsigned char i;
digitalWrite(pinCS, LOW);
for (i = 8; i >= 1; i--)
{
digitalWrite(pinCLK, LOW);
digitalWrite(pinDIN, DATA & 0x80);
DATA = DATA << 1;
digitalWrite(pinCLK, HIGH);
}
}
void writeChar(unsigned char address, unsigned char dat)
{
digitalWrite(pinCS, LOW);
WriteByte(address);
WriteByte(dat);
digitalWrite(pinCS, HIGH);
}
void clearScreen()
{
for (int i = 1; i < 9; i++)
writeChar(i, 0);
}
void initDisplay(void)
{
writeChar(0x09, 0x00);
writeChar(0x0a, 0x03);
writeChar(0x0b, 0x07);
writeChar(0x0c, 0x01);
writeChar(0x0f, 0x00);
}
void setup()
{
pinMode(pir, INPUT_PULLUP);
pinMode(remote, INPUT_PULLUP);
pinMode(pinCLK, OUTPUT);
pinMode(pinCS, OUTPUT);
pinMode(pinDIN, OUTPUT);
delay(50);
initDisplay();
displayOn = true;
irrecv.enableIRIn();
attachInterrupt(digitalPinToInterrupt(pir), displayToggle, CHANGE);
attachInterrupt(digitalPinToInterrupt(remote), checkRemote, CHANGE);
}
void checkRemote()
{
if (irrecv.decode(&results)) {
displayOn = !displayOn;
irrecv.resume();
}
}
void displayToggle()
{
displayOn = !displayOn;
}
void loop()
{
if (displayOn)
{
for (int j = 0; j < 5; j++)
{
for (int i = 1; i < 9; i++)
writeChar(i, handsup[i - 1]);
delay(100);
for (int i = 1; i < 9; i++)
writeChar(i, handshoriz[i - 1]);
delay(100);
for (int i = 1; i < 9; i++)
writeChar(i, handsdown[i - 1]);
delay(100);
for (int i = 1; i < 9; i++)
writeChar(i, handshoriz[i - 1]);
delay(100);
}
for (int i = 1; i < 9; i++)
writeChar(i, smily[i - 1]);
delay(1000);
for (int i = 1; i < 9; i++)
writeChar(i, heart[i - 1]);
delay(1000);
displayOn = false;
clearScreen();
}
}

Qt: 外部プログラムを起動する

  Qt/C++ のアプリは、外部へ直接アクセスできます。これはネットアプリでは不可能な Qt のメリットです。 外部プログラムを起動することもできます。QProcess::startDetached() を使うと独立したプロセスを立ち上げることができます。 この QProces...