自作16×8 LEDマトリックスでテトリスゲーム:Arduino Nano実装
必要な部品と用品
| Arduino Nano R3 | ×1 |
| タクトスイッチ(12mm) | ×4 |
| 74HC595 シフトレジスタ(シリアル-パラレル) | ×2 |
| スライドスイッチ(電源用) | ×1 |
| 5mm 黄色LED | ×128 |
必要な工具
- はんだごて(汎用) - LEDマトリックス組み立てに必須
アプリとオンラインサービス
- Arduino IDE
プロジェクトについて
自作の16列×8行(128個)LEDマトリックス、Arduino Nano、2個の74HC595シフトレジスタを使ってテトリスゲームを実装しました。ボタン操作時にビープ音も鳴ります。
ハードウェア構成
- LEDマトリックス: 16列(アノード)× 8行(カソード)の動的点灯。列制御用に74HC595を2個直列接続(16ビット)、行制御はArduinoのD5〜D12(8ピン)で直接駆動。
- 操作ボタン: アナログピンA4〜A7に接続(左、下、右、上/回転)。内部プルダウンまたは外部抵抗でプルダウン。
- 電源: スライドスイッチでON/OFF。LED同時点灯数を考慮し、外部5V電源推奨(USB給電でも動作可能だが電流制限あり)。
ソフトウェアのポイント
- タイマー割り込み: Timer1を2kHz(CTCモード、1024分周)で設定し、ISR内で
LEDRefresh()を呼び出し、8行を高速スキャン(各行1ms)してフリッカーフリー表示を実現。 - ゲームロジック: 標準的なテトリスルール(7種類テトロミノ、回転、ライン消去、スコア、ゲームオーバー)を実装。ブロック形状は
lib[10][5][7]配列で定義。 - 乱数生成: アナログピン未接続ノイズをシードに
random()で次のブロック決定。 - ピン配線ミス対応: 行ドライバピンのはんだ付け順序間違い(0-7ではなく1-7,0)をソフトウェア側
LEDRefresh()内で補正。
ソースコード(全文)
コードは長いため全文を掲載します。主要関数:
setup(): ピン設定、タイマー割り込み設定、ブロックライブラリ初期化、乱数シード生成loop(): 落下タイマー管理、ボタン読み取り(アナログ閾値判定)、移動/回転処理moveLeft/Right/Down(),rotate(): ブロック移動・回転・衝突判定updateLED(),LEDRefresh(): 表示バッファ合成・行スキャン駆動checkGameOver(),gameOver(): ライン消去アニメーション、スコア表示、無限ループnewBlock(): 次ブロック生成、初期位置設定
/* Author: Jae Yeong Bae, UBC ECE
Tetris v2 on 16x8 LED Matrix with 2x 74HC595 */
unsigned char latchPin = 3;
unsigned char clockPin = 2;
unsigned char dataPin = 4;
unsigned char rowPin = 5; // D5-D12 で8行駆動
long delays = 0;
short delay_ = 500; // 落下間隔(ms)
long bdelay = 0;
short buttondelay = 150;
short btdowndelay = 30;
short btsidedelay = 80;
unsigned char blocktype, blockrotation;
int lines = 0;
boolean block[8][18]; // 現在ブロック(回転用に+2列)
boolean pile[8][16]; // 固定済みブロック
boolean disp[8][16]; // 表示用マージバッファ
boolean lib[10][5][7]; // ブロック形状ライブラリ
void setup() {
// lib[] に7種類テトロミノ+αの形状をビットパターンで定義
// 乱数シード生成(アナログノイズ利用)
// Timer1 CTC割り込み 2kHz 設定
// ピンモード設定、シリアル開始
newBlock(); updateLED();
}
void loop() {
if (delays < millis()) { delays = millis() + delay_; movedown(); }
int btn = readBut();
if (btn == 1) rotate();
else if (btn == 2) moveright();
else if (btn == 3) moveleft();
else if (btn == 4) movedown();
}
// 以下、移動・回転・衝突判定・ライン消去・ゲームオーバー・表示リフレッシュ等の全関数実装
// ISR(TIMER1_COMPA_vect) { LEDRefresh(); }
回路図
添付の回路図を参照。74HC595×2のシリアル接続(Data→D4, Clock→D2, Latch→D3)、Q0-Q7が列0-7、Q8-Q15が列8-15を駆動。行アノードD5-D12。ボタンA4-A7。LEDマトリックスはユニバーサル基板に128個手配線とはんだ付けが必要。
製作のヒント
- LED128個のはんだ付けは根気が必要。列ごと/行ごとにテストしながら進めるとデバッグしやすい。
- 74HC595の出力電流は1ピン約6-8mA程度。全列同時点灯時の総電流に注意(行スキャンで1/8デューティーなら平均電流は抑えられる)。
- ブザーを追加する場合は空いているPWMピン(D9, D10等)に接続し、ボタン押下/ライン消去/ゲームオーバーで音を出す。
製造プロセス
- Arduino NanoとMPU-6050で作るリアルタイムジャイロスコープゲーム
- Arduinoデジタルダイス: LCD表示の乱数ジェネレーター自作
- 自作Arduino TV-B-Gone:全テレビ対応の万能リモコン
- DIY Arduino USBゲームコントローラー - 高性能ゲームパッドを自作
- Arduino NanoとMAX7219で作る24×16 LEDポングゲーム機
- Pixel Chaser: Arduino Nanoで作るワンタップLEDゲーム
- Arduino Nanoで作る8×8 LEDマトリックスのフリップクロック - 自作リアルタイムクロック
- Arduino Nanoで作るNeoPixelマトリックス版Pongゲーム
- Arduino Nanoで作る携帯型ガイガーカウンター
- Arduino NanoとWS2812 LEDストリップで作る1次元ポンゲーム - 完全DIYガイド
- Never Ride Alone:サイクリストのためのスマート安全システム