Arduinoで作る48×8 スクロールLEDマトリックス 完全ガイド
必要なコンポーネントと用品
| パーツ | 数量 | 備考 |
|---|---|---|
| Arduino UNO | 1 | |
| 74HC595 8ビット シリアル-パラレル シフトレジスタ | 7 | |
| 抵抗 475Ω | 56 | |
| ピンヘッダー 40ピン 1列 (0.1インチ) | 2 | |
| ソケットヘッダー 8ピン 1列 (0.1インチ) | 21 | |
| 汎用PCB基板 6×4インチ | 4 | |
| 8×8 LEDマトリックス | 6 | |
| BC548 トランジスタ | 1 |
必要な工具
- はんだごて(汎用)
- グルーガン(汎用)
- デジタルマルチメーター(Mastech MS8217等)
アプリとオンラインサービス
- Arduino IDE
プロジェクト概要
こんにちは!
このプロジェクトは、Arduino UNOと74HC595シフトレジスタを使用して、48×8のプログラマブル・スクロールLEDマトリックスを作るものです。これが私のArduino初作品で、先生からの挑戦でした。当時はLEDの点滅さえ知りませんでしたが、根気と理解があれば初心者でも作れます。回路図はネットで見つけたものを参考にし、シフトレジスタとマルチプレクシングについて調べながら進めました。
回路
部品調達
5mm 8×8 共通カソードLEDマトリックスをオンラインで購入。
プロトタイプ製作
回路図の通り、1個のシフトレジスタで8行を制御し、列側は8列ごとに1個のシフトレジスタを使用します。つまり、8×8マトリックスが作れれば、列制御部分を複製するだけで任意の列数に拡張可能です。8列追加ごとに74HC595を1個追加すればよく、列数に制限はありません。まずは8×8プロトタイプを作りました。
ハンダ付けと拡張
行制御と列制御を別々のドット基板で作り、ワイヤーとヘッダーで接続。8×8が動作したら、列側のシフトレジスタをデイジーチェーン接続(共通クロック)で増やしていきます。行側は常に1個の74HC595で制御します。
後半部分の構築も同様に行い、最終的に48列(6モジュール)になりました。
当時3Dプリンターがなかったため、地元の大工さんにケースを作ってもらいましたが、想像より大きくなりました。Fusion 360などで設計し3Dプリントするのがベストです。電源とUSBケーブル用の穴を開けています。
コード
コードは添付ファイルにあります。行をスキャンしながら列データを出力する仕組みで、スクロール速度と表示メッセージを制御します。デフォルトは右→左スクロールですが、少し修正すれば他方向も可能です。
/*////////////////////////////////////////////////////////////////////////////////
* Arduino code to display scrolling characters on 6 or more 8x8 LED matrix.
* The no: of matrices can be increased with a small change in code.
* Comments are given in each statement for editing.
* Coded by Prasanth K S
* Contact : kksjunior@hotmail.com
*////////////////////////////////////////////////////////////////////////////////
char msg[] = "WELCOME WIZ"; // 表示テキストをここで変更
int scrollspeed = 5; // スクロール速度(小さいほど高速)
int x, y;
// 列側シフトレジスタピン
int clockPin1 = 2; // 74HC595 Pin 11 (Clock)
int latchPin1 = 3; // 74HC595 Pin 12 (Latch)
int dataPin1 = 4; // 74HC595 Pin 14 (Data)
// 行側シフトレジスタピン
int clockPin2 = 5;
int latchPin2 = 6;
int dataPin2 = 7;
// ビットマップ配列: 8行 × 7ゾーン(6モジュール+1)
byte bitmap[8][7];
int numZones = sizeof(bitmap) / 8; // ゾーン数 = 8×8マトリックス数
int maxZoneIndex = numZones - 1;
int numCols = numZones * 8; // 総列数
// フォント定義(5×7ドット、文字間2ドット空き)
byte alphabets[][8] = {
{0,0,0,0,0}, // @ as SPACE
{31, 36, 68, 36, 31}, // A
{127, 73, 73, 73, 54}, // B
{62, 65, 65, 65, 34}, // C
{127, 65, 65, 34, 28}, // D
{127, 73, 73, 65, 65}, // E
{127, 72, 72, 72, 64}, // F
{62, 65, 65, 69, 38}, // G
{127, 8, 8, 8, 127}, // H
{0, 65, 127, 65, 0}, // I
{2, 1, 1, 1, 126}, // J
{127, 8, 20, 34, 65}, // K
{127, 1, 1, 1, 1}, // L
{127, 32, 16, 32, 127}, // M
{127, 32, 16, 8, 127}, // N
{62, 65, 65, 65, 62}, // O
{127, 72, 72, 72, 48}, // P
{62, 65, 69, 66, 61}, // Q
{127, 72, 76, 74, 49}, // R
{50, 73, 73, 73, 38}, // S
{64, 64, 127, 64, 64}, // T
{126, 1, 1, 1, 126}, // U
{124, 2, 1, 2, 124}, // V
{126, 1, 6, 1, 126}, // W
{99, 20, 8, 20, 99}, // X
{96, 16, 15, 16, 96}, // Y
{67, 69, 73, 81, 97}, // Z
};
void setup() {
pinMode(latchPin1, OUTPUT);
pinMode(clockPin1, OUTPUT);
pinMode(dataPin1, OUTPUT);
pinMode(latchPin2, OUTPUT);
pinMode(clockPin2, OUTPUT);
pinMode(dataPin2, OUTPUT);
// ビットマップクリア
for (int row = 0; row < 8; row++) {
for (int zone = 0; zone <= maxZoneIndex; zone++) {
bitmap[row][zone] = 0;
}
}
}
// ビットマップをマトリックスに表示
void RefreshDisplay() {
for (int row = 0; row < 8; row++) {
int rowbit = 1 << row;
digitalWrite(latchPin2, LOW);
shiftOut(dataPin2, clockPin2, MSBFIRST, rowbit);
digitalWrite(latchPin1, LOW);
for (int zone = maxZoneIndex; zone >= 0; zone--) {
shiftOut(dataPin1, clockPin1, MSBFIRST, bitmap[row][zone]);
}
digitalWrite(latchPin1, HIGH);
digitalWrite(latchPin2, HIGH);
delayMicroseconds(300);
}
}
// 指定座標のドットをON/OFF
void Plot(int col, int row, bool isOn) {
int zone = col / 8;
int colBitIndex = x % 8; // 注意: ここではxを使用しているが、元コードではcolを使うべき
byte colBit = 1 << colBitIndex;
if (isOn) bitmap[row][zone] |= colBit;
else bitmap[row][zone] &= ~colBit;
}
// メッセージを1文字ずつ右端に描画し、左へシフトスクロール
void XProcess() {
for (int charIndex = 0; charIndex < (sizeof(msg) - 1); charIndex++) {
int alphabetIndex = msg[charIndex] - '@';
if (alphabetIndex < 0) alphabetIndex = 0;
// 1文字5列+スペース2列 = 7列分ループ
for (int col = 0; col < 7; col++) {
for (int row = 0; row < 8; row++) {
bool isOn = 0;
if (col < 5) isOn = bitRead(alphabets[alphabetIndex][col], 7 - row) == 1;
Plot(numCols - 1, row, isOn); // 右端に描画
}
for (int refreshCount = 0; refreshCount < scrollspeed; refreshCount++) RefreshDisplay();
// ビットマップを1列左シフト(右スクロール表示)
for (int row = 0; row < 8; row++) {
for (int zone = 0; zone < numZones; zone++) {
bitmap[row][zone] >>= 1;
if (zone < maxZoneIndex) bitWrite(bitmap[row][zone], 7, bitRead(bitmap[row][zone + 1], 0));
}
}
}
}
}
void loop() {
XProcess();
}
回路図(参考)
ピン接続はコード内のコメントを参照してください。
製造プロセス
- Arduinoで作るモニター用Ambilightシステム:没入感アップの自作ガイド
- ArduinoでBluetooth経由でLEDを制御 – シンプルDIYガイド
- PIRセンサー連動 インタラクティブLEDマトリクスドアディスプレイ - ホリデーグリーティング
- スマートArduino四足歩行ロボットの製作:ステップバイステップガイド
- Bolt IoTとArduino UNOでLED輝度をシームレス制御
- Arduino Nanoで作る8×8 LEDマトリックスのフリップクロック - 自作リアルタイムクロック
- Arduino RGB LEDカラーミキサー:初心者向けDIYプロジェクト
- Arduino Unoで8×8 LEDマトリックスを制御:ステップバイステップガイド
- Arduino NanoとRDA5807Mで作るコンパクトFMラジオ
- 屋外対応DMX制御RGB LED投光器 – 低コスト・高性能・自作PCB
- DIY LEDルーレットゲーム – Arduino Nanoで作る1人用アーケードゲーム