スポンサーリンク

Arduino スケッチ例「8×8 LED Matrix」で Lチカしてみた

L チカさせる LED をどんどん増やして (^_^;) 、ついに 64 個になりました。Arduino スケッチ例「Row-columm Scanning to control an 8×8 LED Matrix」を実験してみましょう。
が、この解説通りに製作してもいまいちうまくいきませんでした。うまくいかない点を改善しながら、実験していきましょう。

まず完成したブレッドボードです

写真は完成したブレッドボードです。
右にある 2つのボリュームを回すと、その値に応じた位置の LED が点灯します。

スケッチ例では LDM-24488NI (データシート)というマトリクスパネルを使用していますが、俺は持っていません。
でも LED が手元にたくさんありましたので、自分でマトリクス回路を作ってしまいました。ブレッドボード上でこんなマトリクスを組むのはけっこうトリッキーで、あまりきれいになってませんけど (^_^;)

回路の改善点

この回路は、ひとつの Row (行) を HIGH に、ひとつの Column (列) を LOW にすることで、その Row と Column の交差する点にある LED が点灯するというものです。これは「ソース回路」と「シンク回路」の組み合わせですね。ソース側を HIGH 、シンク側を LOW にすることで、ソースから電流が流れ出て LED を通り、シンクへ流れ込みます。
ひとつの LED に着目したとき、アノード側を HIGH (5V) 、カソード側を LOW (0V) にするわけですから、とうぜん電流を制限するための抵抗器が必要です。解説の回路図にはその「とうぜん必要となる抵抗器」がありません。下手をすればマイコンを壊してしまいます。必ず抵抗器を挿入しましょう。

図は、抵抗器を追加して作った回路図です。

点灯する LED は 1 個だけですので、いつものように電流値を計算すれば OK です。抵抗器は、Column 側でも Row 側でもかまいません。この回路では 470Ω として、6mA 程度の電流を流しています。
なお、IO ポートから取り出せる、あるいは流し込める電流の合計を 100mA とすると、同時に点灯できるのは 16 個までです。実験中に間違ってたくさんの LED を点灯させないように注意しましょう。

スケッチの改善点

スケッチ例を Arduino に書き込んで起動すると、とりあえず動きます。ボリュームを回すと、それに応じて点灯する位置も変化していきます。でも、LED はなぜか薄暗く点灯しているだけです。6mA の電流を流したときの明るさではありません。

スケッチをみてみましょう。

まず、setup() ですべての Column を HIGH にして LED を消灯し、位置変数 Pixels[x][y] をすべて HIGH にします。

loop() では、まず関数 readSensors() で ボリュームの位置を検出し、その位置の変数 Pixels を LOW にしています。そして、関数 refreshScreen() では、ひとつの Row を HIGH にしてから Column を順にチェックしていきます。もしその位置の Pixels が LOW であれば、その Column を LOW にすることで交点の LED を点灯させます。
そしてすぐに Column を HIGH に戻し、Row を LOW にすることですべて消灯して、loop() の最初に戻ります。

点灯時間を長くする

なぜ LED が暗くしか点灯しないのか。それは、LED が点灯してもすぐに消灯されてしまい、一回りチェックし終わるまで消灯のまま待たされるからですね。であれば、もう少し点灯している時間を長くすれば良さそうです。

そこで、下のスケッチのように 105 行目に delay(10); を挿入しました。点灯したときのみ時間待ちさせますので、チェックする時間には影響しません。時間は長いほどデューティ比が大きくなるのでしっかり点灯しますが、ボリュームの変化に対するレスポンスが悪くなってしまいます。

レンジの変更

スケッチを変更したついでに、83 、84 行目の map() のパラメータも変更しました。
スケッチ例の map(analogRead(A0), 0, 1023, 0, 7) では、入力値の 0~5V の範囲を 7 等分することになります。これでは電源電圧が下がったときなど入力値が 5V に届かなかった場合に 8 番目の LED が点灯しません。そこでここは 8 等分することで 8 番目の LED の点灯レンジを下げてやることにします。

変更したスケッチ

ということで、以下のようなスケッチになりました。上記の変更点以外はまったく変えていません。クレジットも変更していませんので、再利用にはご留意下さい。

なお、こうしたマトリクスを制御するライブラリもあるようです。ライブラリを利用することで、もっと簡単でエクセレントなスケッチにできるかもしれませんね (^_^;)

  1. /*
  2.   Row-Column Scanning an 8x8 LED matrix with X-Y input
  3.   This example controls an 8x8 LED matrix using two analog inputs.
  4.   This example works for the Lumex LDM-24488NI Matrix. See
  5.   http://sigma.octopart.com/140413/datasheet/Lumex-LDM-24488NI.pdf
  6.   for the pin connections.
  7.   For other LED cathode column matrixes, you should only need to change the pin
  8.   numbers in the row[] and column[] arrays.
  9.   rows are the anodes
  10.   cols are the cathodes
  11.   ---------
  12.   Pin numbers:
  13.   Matrix:
  14.   - digital pins 2 through 13,
  15.   - analog pins 2 through 5 used as digital 16 through 19
  16.   Potentiometers:
  17.   - center pins are attached to analog pins 0 and 1, respectively
  18.   - side pins attached to +5V and ground, respectively
  19.   created 27 May 2009
  20.   modified 30 Aug 2011
  21.   by Tom Igoe
  22.   This example code is in the public domain.
  23.   http://www.arduino.cc/en/Tutorial/RowColumnScanning
  24.   see also http://www.tigoe.net/pcomp/code/category/arduinowiring for more
  25. */
  26. // 2-dimensional array of row pin numbers:
  27. const int row[8] = {
  28.   2, 7, 19, 5, 13, 18, 12, 16
  29. };
  30. // 2-dimensional array of column pin numbers:
  31. const int col[8] = {
  32.   6, 11, 10, 3, 17, 4, 8, 9
  33. };
  34. // 2-dimensional array of pixels:
  35. int pixels[8][8];
  36. // cursor position:
  37. int x = 5;
  38. int y = 5;
  39. void setup() {
  40.   // initialize the I/O pins as outputs iterate over the pins:
  41.   for (int thisPin = 0; thisPin < 8; thisPin++) {
  42.     // initialize the output pins:
  43.     pinMode(col[thisPin], OUTPUT);
  44.     pinMode(row[thisPin], OUTPUT);
  45.     // take the col pins (i.e. the cathodes) high to ensure that the LEDS are off:
  46.     digitalWrite(col[thisPin], HIGH);
  47.   }
  48.   // initialize the pixel matrix:
  49.   for (int x = 0; x < 8; x++) {
  50.     for (int y = 0; y < 8; y++) {
  51.       pixels[x][y] = HIGH;
  52.     }
  53.   }
  54. }
  55. void loop() {
  56.   // read input:
  57.   readSensors();
  58.   // draw the screen:
  59.   refreshScreen();
  60. }
  61. void readSensors() {
  62.   // turn off the last position:
  63.   pixels[x][y] = HIGH;
  64.   // read the sensors for X and Y values:
  65.   x = 7 - map(analogRead(A0), 0, 896, 0, 7);
  66.   y = map(analogRead(A1), 0, 896, 0, 7);
  67.   // set the new pixel position low so that the LED will turn on in the next
  68.   // screen refresh:
  69.   pixels[x][y] = LOW;
  70. }
  71. void refreshScreen() {
  72.   // iterate over the rows (anodes):
  73.   for (int thisRow = 0; thisRow < 8; thisRow++) {
  74.     // take the row pin (anode) high:
  75.     digitalWrite(row[thisRow], HIGH);
  76.     // iterate over the cols (cathodes):
  77.     for (int thisCol = 0; thisCol < 8; thisCol++) {
  78.       // get the state of the current pixel;
  79.       int thisPixel = pixels[thisRow][thisCol];
  80.       // when the row is HIGH and the col is LOW,
  81.       // the LED where they meet turns on:
  82.       digitalWrite(col[thisCol], thisPixel);
  83.       // turn the pixel off:
  84.       if (thisPixel == LOW) {
  85.         delay(10);
  86.         digitalWrite(col[thisCol], HIGH);
  87.       }
  88.     }
  89.     // take the row pin low to turn off the whole row:
  90.     digitalWrite(row[thisRow], LOW);
  91.   }
  92. }
タイトルとURLをコピーしました