Arduino UNO R4 ボード上のLEDマトリクス
ハードウェア仕様
ボード上のLED配置
Arduino UNO R4では、ボード上に 12×8 のチップLEDマトリクスが配置されています。LEDには、図のように左上から1~96の番号が振られています(次の回路図と対応)。
LED回路図
LEDマトリクスはこのような回路になっています。
たとえば pin7 を HIGH 、 pin2 を LOW にすると LED1 が点灯する…ということはすぐに判るのですが、回路をよく見ると任意のパターンで点灯させようとするとかなり難しそうであることが判ります。たとえば次のような問題があります。
・ LED1 を点灯するには pin7 を HIGH/pin3 をLOW、LED2 を点灯するには pin3 を HIGH/pin7 を LOWにする必要があります。つまり LED1 と LED2 は同時に点灯することが出来ません。
・LED3 と LED9 を同時に点灯するには pin3 と pin7 を HIGH/pin4 と pin8 を LOW にすればよさそうですが、そうすると LED5 と LED7 も一緒に点灯してしまいます。
このように、同時に複数のLEDを点灯しようとするといろいろ問題が生じるため、マトリクス全体に図形などを表示するには、短い時間のうちに1つずつ順次LEDを点灯させていき、残像によって人間の目には同時に複数のLEDが点灯して図形が表示されているようにみせるダイナミック制御を行う必要がありそうです。
というわけで。
うん、これは無理。
独自の表示プログラムを作るのはとりあえず無理!ということで、最初はおとなしく公式から提供されているライブラリを利用することにします。
LEDマトリクス用ライブラリ
Arduino UNO R4 ボード上のLEDマトリクスの制御ライブラリとして、 Arduino_LED_Matrix が提供されています。自分でインストール作業を行った憶えはないので、たぶんR4を最初に接続したときに自動的にインストールされたのだと思います。
基本的な使い方
#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix matrix;
void setup() {
matrix.begin();
}
ライブラリを利用するには、Arduino_LED_Matrix.h をインクルードします。
基本的にLEDマトリクスに対する処理は ArduinoLEDMatrix クラスのメンバ関数として実装されているので、ArduinoLEDMatrix 型のインスタンスを用意します。
LEDマトリクスに関する処理の初期化を行うため、setup()関数内などで ArduinoLEDMatrixクラスの begin() 関数を実行します。
具体的な描画方法は後のプログラム例で解説します。
プログラム例
例1:2次元配列で点灯パターンを指定する
まず、直感的にもっとも理解しやすい、12×8の2次元配列による点灯パターン指定方法です。
スケッチ
#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix matrix;
byte frame[8][12] = {
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,1,0,0,0,0,1,0,0,0},
{0,0,1,0,1,0,0,1,0,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,0,1,0,0,0,0,1,0,0,0},
{0,0,0,0,1,1,1,1,0,0,0,0}
};
void setup() {
matrix.begin();
matrix.renderBitmap(frame, 8, 12);
}
void loop() {
}
プログラムの解説
ライブラリのインクルードおよびArduinoLEDMatrixクラス変数の宣言
#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix matrix;
『基本的な使い方』で解説したとおり、LEDマトリクスを使用するには Arduino_LED_Matrix.h をインクルードし、ArduinoLEDMatrix クラスのインスタンスを生成します。ここではインスタンス名(変数名)を matrix としています。
フレーム(点灯パターン)配列の用意
byte frame[8][12] = {
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,1,0,0,0,0,1,0,0,0},
{0,0,1,0,1,0,0,1,0,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,0,1,0,0,0,0,1,0,0,0},
{0,0,0,0,1,1,1,1,0,0,0,0}
};
要素がbyte型でLEDの個数と同じ12×8の配列を用意します。各要素がLED1つ1つと対応しており、要素の値が0のとき対応する位置のLEDは消灯、要素の値が1のときは点灯します。上の例のように記述するとLEDマトリクスと配列の要素の並びが同じになり、点灯パターンが判りやすいと思います。
このように定義された1コマ分のデータ(点灯パターン)のことを『フレーム』といいます。
※ある程度C言語に慣れている人には解説不要と思いますが、プログラミング経験の少ない人は配列のサイズが[12][8]ではなく[8][12]となることに注意してください。
ArduinoLEDMatrixの使用開始
void setup() {
matrix.begin();
matrix.renderBitmap(frame, 8, 12);
}
setup()関数の中で、ArduinoLEDMatrixクラスの begin()関数によってArduinoLEDMatrixクラスを初期化・使用開始しています。
書式:
void ArduinoLEDMatrix.begin()
begin()関数の内部では、ダイナミック点灯のためのタイマーがセットされています。
フレームの表示
void setup() {
matrix.begin();
matrix.renderBitmap(frame, 8, 12);
}
配列に従ってLEDマトリクスを点灯させるには、ArduinoLEDMatrixクラスの renderBitmap() を使用します。書式は以下の通りです。
書式:
ArduinoLEDMatrix.renderBitmap(byte[][] bitmap, int rows, int cols)
引数:
名前 | 型 | 意味 |
---|---|---|
bitmap | byte[][] | フレーム(点灯パターン)を格納した2次元配列変数名 |
rows | int | フレームの行数(縦方向のピクセル数) |
cols | int | フレームの列数(横方向のピクセル数) |
余談ですが、実は renderBitmap() は関数ではなく引数付きマクロとして定義されています。そのため、
matrix.renderBitmap(frame, 8, 12);
の代わりに
matrix.renderBitmap(frame, 7+1, 1+11);
などと記述するとバグります。
どうしても引数に数値ではなく式を書く必要がある場合は、
matrix.renderBitmap(frame, (7+1), (1+11));
このように括弧でくくっておいた方が無難です。
また、第一引数について
matrix.renderBitmap(&frame[0][0], 8, 12);
などと書くと動きません(関数だったらこれでも動くはずですが)。第一引数には『フレームのデータを格納した二次元配列の名前』を書くようにしてください。
loop()ではなにもしない
void loop() {
}
この例では、setup()関数の中ですべての用事が済んでしまっているため、loop()関数の中には何も記述していません。LEDマトリクスに何らかのパターンを表示したまま、まったく違う処理を行うことが出来ます。
実行結果
実行するとこのようになります。
絵心皆無でスミマセン…。
例2:1次元配列で点灯パターンを指定する
byte型2次元配列による点灯パターンの指定は、直感的にはわかりやすいですが、実はメモリの利用効率がよくありません。そこで次は、32bit長整数3つで点灯パターンを指定する方法を試してみます。
スケッチ
#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix matrix;
uint32_t frame[3] = {
0B00000000000000010000100000101001,
0B01000000000000000000000000000000,
0B00000000000100001000000011110000
};
void setup() {
matrix.begin();
matrix.loadFrame(frame);
}
void loop() {
}
プログラム解説
ライブラリのインクルードおよびArduinoLEDMatrixクラス変数の宣言
#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix matrix;
ライブラリのインクルードおよびインスタンスの生成については例1と同じです。
フレーム(点灯パターン)配列の用意
uint32_t frame[3] = {
0B00000000000000010000100000101001,
0B01000000000000000000000000000000,
0B00000000000100001000000011110000
};
この例では、フレームを uint32_t(符号なし32bit整数)の値3つで定義しています。各値の先頭にある”0B”は、値が2進数で記述されていることを示しています。
この3つの整数の各ビットが、それぞれ LED の1つ1つに対応しています。
数値は 32bit×3 = 96bit、LED の数は 12×8 = 96個で、ちょうどすべてのLEDの点灯パターンが表せるのです。
byte型2次元配列の場合、96個のLEDのために96バイトのメモリが必要でしたが、32bit(=4バイト)整数3つなら同じ点灯パターンを4バイト×3=12バイトで表すことができ、必要メモリが1/8ですみます。多数のフレームを使用するアニメーションではこちらの方が断然有利です。
これらの32bitの数値は簡単に求めることが出来ます。
1.
まず、点灯パターンを0と1の文字列、12桁×8行で描きます。0が消灯、1が点灯です。これはbyte型2次元配列で記述した場合の、0と1の部分だけをつなげたものと同じです。
000000000000
000100001000
001010010100
000000000000
000000000000
000000000000
000100001000
000011110000
2.
改行を削除して横一列につなぎます。
000000000000000100001000001010010100000000000000000000000000000000000000000100001000000011110000
3.
32桁ごとに区切ります。ぴったり3行になるはずです。
00000000000000010000100000101001
01000000000000000000000000000000
00000000000100001000000011110000
4.
“0B”やカンマなどを補えばできあがりです。
uint32_t frame[3] = {
0B00000000000000010000100000101001,
0B01000000000000000000000000000000,
0B00000000000100001000000011110000
};
もちろん、以下のように各数値を16進数に直しても同じように動作します。
uint32_t frame[3] = {
0x10829,
0x40000000,
0x1080F0
};
また、初期値を記述している場合は配列のサイズを省略することもできます。
uint32_t frame[] = {
0x10829,
0x40000000,
0x1080F0
};
ArduinoLEDMatrixの初期化
void setup() {
matrix.begin();
matrix.loadFrame(frame);
}
例1と同様、ArduinoLEDMatrixクラスの begin()関数によってインスタンスを初期化します。
フレームの表示
void setup() {
matrix.begin();
matrix.loadFrame(frame);
}
フレームを32bit数の配列で記述した場合、フレームの表示には loadFrame()関数を使用します。
書式:
void ArduinoLEDMatrix.loadFrame(uint32_t[] frame)
引数:
名前 | 型 | 意味 |
---|---|---|
frame | uint32_t[3] | LEDマトリクスの点灯パターンを表す |
やはりloop()ではなにもしない
void loop() {
}
この例でも、setup()関数の中ですべての用事が済んでしまっているため、loop()関数の中には何も記述していません。
実行結果
実行結果は例1の場合とまったく同じになります。
まとめ
・Arduino UNO R4のボード上のLEDマトリクスに何かを表示するには、 ArduinoLEDMatrix.h ライブラリを利用するのが簡単
コメント