(8×8ledマトリクス使ってみた。)
今回は、秋月電子で購入した砂時計用の8×8 LEDマトリクスを使ってみました。
一旦LEDマトリクスの簡単な動作原理を理解しておきます。
LEDマトリクスには行(ROW)と列(COL)がありそれを組み合わせることで、点灯させています。例として、1つだけ光らせる場合は対象の行をhigh、対象の列をLOWにすることで、その交点だけ光る仕組みです。ただし人間の目は残像が残るため、同時に光っているように見えます。このような仕組みをダイナミック点灯というようです。
■配線作業。
写真(1)と下の表を参考に、アノード側に抵抗を入れて配線していきます。
今回は、マトリクスの定格電圧が2.1〜2.5Vだったため、手元に多くあった10kΩの抵抗を使用しました。
| マトリクスLED(ピン番号) | Arduino側(ピン番号) |
|---|---|
| 1 | Digital 6 |
| 2 | Digital 8 |
| 3 | Digital 11 |
| 4 | Digital 12 |
| 5 | Digital 9 |
| 6 | Analog 1 |
| 7 | Digital 7 |
| 8 | Digital 4 |
| 9 | Digital 2 |
| 10 | Analog 0 |
| 11 | Analog 2 |
| 12 | Digital 5 |
| 13 | Digital 10 |
| 14 | Digital 3 |
| 15 | Analog 3 |
| 16 | Analog 4 |
写真(1)
配線後の様子。
内部回路
■「×」をマトリクスに表示してみる。
ソースコードを書く
①arduinoとマトリクスの配線を配列で定義する。
・ROW(行)
const int rowPins[8] = { 2, // R1 3, // R2 4, // R3 5, // R4 6, // R5 7, // R6 8, // R7 9 // R8 };
・COL(列)
Arduino Unoではデジタルピンだけでは出力ピンが足りないため、アナログピンも使用しています。
const int colPins[8] = { 10, // C1 11, // C2 12, // C3 A0, // C4 A1, // C5 A2, // C6 A3, // C7 A4 // C8 };
②点灯データーを作る。
LEDの点灯状態を2次元配列で表現します。
以下のデータで「×」の模様を表示できます。
byte matrix[8][8] = { {1,0,0,0,0,0,0,1}, {0,1,0,0,0,0,1,0}, {0,0,1,0,0,1,0,0}, {0,0,0,1,1,0,0,0}, {0,0,0,1,1,0,0,0}, {0,0,1,0,0,1,0,0}, {0,1,0,0,0,0,1,0}, {1,0,0,0,0,0,0,1} };
③マトリクス表示コード
これまで設定した内容を使って、実際にLEDマトリクスを点灯させます。
const int rowPins[8] = {2, 3, 4, 5, 6, 7, 8, 9}; const int colPins[8] = {10, 11, 12, A0, A1, A2, A3, A4}; byte matrix[8][8] = { {1,0,0,0,0,0,0,1}, {0,1,0,0,0,0,1,0}, {0,0,1,0,0,1,0,0}, {0,0,0,1,1,0,0,0}, {0,0,0,1,1,0,0,0}, {0,0,1,0,0,1,0,0}, {0,1,0,0,0,0,1,0}, {1,0,0,0,0,0,0,1} }; void setup() { for (int i = 0; i < 8; i++) { pinMode(rowPins[i], OUTPUT); pinMode(colPins[i], OUTPUT); } } void loop() { for (int row = 0; row < 8; row++) { // 全行OFF for (int i = 0; i < 8; i++) { digitalWrite(rowPins[i], LOW); } // 全列OFF for (int i = 0; i < 8; i++) { digitalWrite(colPins[i], HIGH); } // 点灯データ反映 for (int col = 0; col < 8; col++) { if (matrix[row][col] == 1) { digitalWrite(colPins[col], LOW); } } // 行ON digitalWrite(rowPins[row], HIGH); delay(2); } }
■動作の様子
カメラで見ると点滅しているのがわかります。
応用として最終的な目標である、砂時計制作に向けて砂が流れ落ちていくアニメーションを作りました(chatgptが)。
改善点が何個かありますが、次からはこれも参考にするため、貼っておきます。
// ひし形砂アニメーション // 1秒に1個ずつ砂が落ちる const int rowPins[8] = {2,3,4,5,6,7,8,9}; const int colPins[8] = {10,11,12,A0,A1,A2,A3,A4}; byte matrix[8][8]; int sandCount = 0; const int MAX_SAND = 64; int sandRow[MAX_SAND]; int sandCol[MAX_SAND]; // ======================= // 初期化 // ======================= void setup() { for(int i=0; i<8; i++){ pinMode(rowPins[i], OUTPUT); pinMode(colPins[i], OUTPUT); } buildSandOrder(); } // ======================= // メイン // ======================= void loop() { if(sandCount >= MAX_SAND){ delay(2000); sandCount = 0; clearMatrix(); } int targetRow = sandRow[sandCount]; int targetCol = sandCol[sandCount]; // 砂を落とす animateSand(targetRow, targetCol); // 着地 matrix[targetRow][targetCol] = 1; sandCount++; // 1秒待つ showMatrix(1000); } // ======================= // 積もる順番生成 // ======================= void buildSandOrder(){ int index = 0; // 右下から対角線ごと for(int sum=14; sum>=0; sum--){ for(int r=7; r>=0; r--){ int c = sum - r; if(c >=0 && c <8){ sandRow[index] = r; sandCol[index] = c; index++; } } } } // ======================= // 左上→右下へ流す // ======================= void animateSand(int targetRow, int targetCol){ int x = 0; int y = 0; while(x <= targetCol && y <= targetRow){ drawStoredSand(); matrix[y][x] = 1; // 落下スピード showMatrix(80); x++; y++; } } // ======================= // 積もった砂描画 // ======================= void drawStoredSand(){ clearMatrix(); for(int i=0; i<sandCount; i++){ int r = sandRow[i]; int c = sandCol[i]; matrix[r][c] = 1; } } // ======================= // 全消去 // ======================= void clearMatrix(){ for(int r=0; r<8; r++){ for(int c=0; c<8; c++){ matrix[r][c] = 0; } } } // ======================= // 表示 // ======================= void showMatrix(int duration){ unsigned long start = millis(); while(millis() - start < duration){ for(int row=0; row<8; row++){ // 全行OFF for(int i=0; i<8; i++){ digitalWrite(rowPins[i], LOW); } // 全列OFF for(int i=0; i<8; i++){ digitalWrite(colPins[i], HIGH); } // LED反映 for(int col=0; col<8; col++){ if(matrix[row][col]){ digitalWrite(colPins[col], LOW); } } // 行ON digitalWrite(rowPins[row], HIGH); delay(2); } } }
■まとめ
今回は8×8 LEDマトリクスを使って「×」マークと砂のシュミレーション的なものをを表示してみました。
配線自体はピン数が多くて大変ですが、行と列を組み合わせて制御する仕組みが分かりちょっと使えるようになりました。











































