トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS

DIY/mbed/MatrixLED

Last-modified: 2015-05-02 (土) 17:48:42 (958d)
Top / DIY / mbed / MatrixLED

DIY/mbed


Seeed Studio の Matrix LED

Seeed Studio で 60mm Square な 8x8 Matrix LED を購入しました。

matrix_led1.jpg


製品ページにある Spec によると、製品型番は SZ012388K/9 というものだそうで。

matrix_led2.png


回路はこんなかんじになっています。
点灯させたい場所に電位差を発生させることで点灯します。

例えば右上最上段の GREEN を点灯させたい場合は、
COL PIN の10番を ON、ROW PIN の22番を OFF にすれば 22 から 10 に電流が流れますので結果点灯します。

陽極(anode)を共有して各 LED を点灯させることから
こういうマトリックス LED を「アノードコモン」というそうです。
逆の場合は陰極(cathode)共有なので「カソードコモン」。

テスト点灯

mbed と Matrix LED を接続してみます。
mbed、ピンが多いので助かる(^^)
anode の方に抵抗を入れました。
抵抗値は 120 Ω(茶赤茶金)

matrix_led3.jpg


コードを書いてみました。

  1. #include "mbed.h"
  2.  
  3. // SZ012388K9 はアノードコモン (陽極を共有)
  4.  
  5. // USER_BUTTON = PC_13
  6. // LED1 = PA_5
  7.  
  8. InterruptIn myButton(USER_BUTTON);
  9. DigitalOut myLed(LED1);
  10.  
  11. static const int ANODE_PIN_NUMBER = 8;
  12. static const int CATHODE_PIN_NUMBER = 8;
  13.  
  14. DigitalOut anodePins[ANODE_PIN_NUMBER] = { PC_9, PC_8, PB_8, PC_6, PB_9, PC_5, PA_12, PA_6 };
  15. DigitalOut cathodePinsGreen[CATHODE_PIN_NUMBER] = { PC_10, PC_11, PC_12, PD_2, PA_13, PA_14, PA_15, PB_7 };
  16. DigitalOut cathodePinsRed[CATHODE_PIN_NUMBER] = { PA_11, PA_7, PB_12, PB_6, PC_7, PA_9, PB_2, PA_8 };
  17.  
  18. enum Mode
  19. {
  20.     Mode_Green,
  21.     Mode_Red,
  22.     Mode_Off
  23. };
  24.  
  25. int mode = Mode_Green;
  26.  
  27. double delay = 0.1; // 100ms
  28. bool isPressed = false;
  29.  
  30. void setup()
  31. {
  32.     myLed = 0;
  33.     for (int i = 0; i < ANODE_PIN_NUMBER; i++)
  34.     {
  35.         anodePins[i] = 0;
  36.     }
  37.     for (int i = 0; i < CATHODE_PIN_NUMBER; i++)
  38.     {   
  39.         cathodePinsGreen[i] = 1;
  40.         cathodePinsRed[i] = 1;
  41.     }
  42. }
  43.  
  44. void pressed()
  45. {
  46.     mode++;
  47.     if (mode > Mode_Off)
  48.     {
  49.         mode = Mode_Green;
  50.     }
  51.     myLed = (mode == Mode_Off) ? 1 : 0;
  52. }
  53.  
  54. int main()
  55. {
  56.     setup();
  57.  
  58.     myButton.fall(&pressed);
  59.  
  60.     while (1) {
  61.         if (mode != Mode_Off)
  62.         {
  63.             DigitalOut* pCathodePins = (mode == Mode_Green) ? cathodePinsGreen : cathodePinsRed;   
  64.             for (int cat = 0; cat < CATHODE_PIN_NUMBER; cat++)
  65.             {
  66.                 pCathodePins[cat] = 0;
  67.                 for (int ano = 0; ano < ANODE_PIN_NUMBER; ano++)
  68.                 {
  69.                     anodePins[ano] = 1;
  70.                     wait(delay);
  71.                     anodePins[ano] = 0;
  72.                 }           
  73.                 pCathodePins[cat] = 1;
  74.             }
  75.         }           
  76.     }
  77. }


やっていることは

  • 初期化時(setup)に全消灯すべく、アノードをすべて 0、カソードをすべて 1 にする。
  • 二重ループにて、外側のループでカソードピンを順々に 0 -> 1、内側のループでアノードピンを順々に 1 -> 0、とすることで左上の LED を始点、右下の LED を終点として順々に点灯させる
  • USER ボタン(青いやつ)を押すごとに表示する LED の色切り替え。最初は緑、押すと赤。次は消灯で、その次はまた緑から、という感じ。

と単純です。


ちゃんと表示されてますねー。

ちなみに左上最上段の GREEN LED の点灯がショボイのですが、
これは最初抵抗付けずに試しに長時間点灯してたらショートして焼けてしまったからです(^^;)
抵抗は入れないといけませんね。。

matrix_led4.jpg

全点灯させる

次はすべての LED を一度に点灯させることに挑戦します。

とは言っても一度にに点灯させるほどの電流は mbed から出せないと思われますので、
ここは「高速に点滅」させることによって人間の目からは「常時点灯」しているように見せる方法、いわゆる「ダイナミック点灯」をやってみます。

すでに一つ一つ表示する回路・コードはできているので、その間隔を短くすればいける?

double delay = 0.1; // 100ms


上記の27行目に遅延(ここでは 100ms)の値があります。
この値を69~71行目のアノードピンの点灯->消灯に使用しています。

anodePins[ano] = 1;
wait(delay);
anodePins[ano] = 0;


この値を小さい値に変えれば LED ごとの点灯の間隔が短くなりますので、
人間の目からすると「全点灯」しているように見えてきます。

この値を変えていって変化を見ます。

  • 10ms だとまだ順々に点灯しているとわかります。
  • 1ms だと「ちらつき」があるように見えます。
  • 0.5ms (=500us)でも「ちらつき」を感じる。(1ms よりはマシ)
  • 0.1ms (=100us)だと完全に全点灯に見える。

ということで 100us ぐらいがちょうど良いようです。
データシート見ると、I_PF という項があり、
これは "Peak Forward Current Per Segment(Duty-0.1,1KHz)" と説明がありました。

ですがワタクシにはさっぱりなので(苦笑)、
ハードに強い当サークルの nukiwo に聞いてみたところ、
瞬間的に流せる電流の量とのことでした。
Duty-0.1,1KHz は

1KHz の中に duty-0.1 = 10% だけ ON にして OK ということだと思います。
つまりこの場合 100us ON → 900us OFF ということですね。


という意味だそうです。
まぁ実験の 100us という値がそう間違いでも無いってことですね。

しかし、100us だと非常に暗いです(^^;)

matrix_led5.jpg


抵抗値120Ωというのが高過ぎるのかもしれません。
再びデータシートに目をやると、

  • I_PF (100us 流せる電流値) : RED=90mA, GREEN=90mA
  • V_F (順方向電圧)
    • TYP : RED=1.8V, GREEN=2.1V
    • MAX : RED=2.2V, GREEN=2.5V

とあり、mbed が 3.3V なのを考慮すると、

I_RED = (V - V_F_RED_TYP) / R = (3.3 - 1.8) / 120 = 0.0125 = 12.5mA
I_GREEN = (V - V_F_GREEN_TYP) / R = (3.3 - 2.1) / 120 = 0.01 = 10mA


赤には12.5mA、緑には10mA しか流れていません。
これが原因かな?ということで 20Ω (赤黒黒金) に変えてみます。
これなら赤には75mA、緑には60mA流れるはず!

matrix_led6.jpg


うーん。。
写真ではいい感じにもなっているんですが、目視だとまだ暗いのです。

そこでふと気付く。
そもそもこいつ(NUCLEO-F410RE)にはそこまでの電流を出す能力が無いのではないか、と・・・。

ST のページからデータシートをダウンロードします。

6.2 "Absolute maximum ratings" にそのものズバリの表がありました。

matrix_led7.png


I_IO というのが一つのピンあたりの吐き出し、吸い込み電流能力です。
値は 25mA なので、そりゃあ 75mA、60mA を要求してもダメな話ですよね(^^;)

もうちょい色々ためしてみたいところですが、
一応全点灯はしましたので今回はこんなところで~。


2015/05/02 : 1st