5x7 ドットマトリクスLEDを光らせてみる

 なんかのときに秋月で買った5x7 ドットマトリクスLEDが家にあったんで光らせてみます。

akizukidenshi.com

 マイコンArduino (ProMicro)を使います。

 データシートを確認すると、中身の回路はこんな感じです。

f:id:moutakusan:20201103210417p:plain
5x7ドットマトリックス回路図

 光らせ方は前回作ったキーマトリックスと同じような考え方ですね。つまり、COL①~⑤を順番にHighにしていって、タイミングを合わせて光らせたい場所のROW①~⑦をLowに、それ以外はHi-Z(ハイインピーダンス)にすればいいって感じです。
 例えば左上端のLEDだけを光らせたければ、COL①がHighのタイミングでROW①をLow、ROW②~⑦をHi-Zにすればいいですね。
 これを人の目にもとまらぬ速さで全ドットLEDに対して行うと、残像効果でまるで全ドットが同時に光っているように見えるという算段です。

回路を描いてみる

 ということで、全体の回路はこんな感じにしました。

f:id:moutakusan:20201103220236p:plain
5x7ドットマトリクスLED点灯回路
 COLを走査する予定なので、制限抵抗はROW側につけてあります。抵抗値は、順方向電流の設計目標値を10mAとして、データシートより順方向電圧が3.2Vくらいになるようなので、
  (5-3.2)V/0.01A = 180ohm
にしました。

コードを書いてみる

 COL①~⑤をHighに走査して、タイミングを合わせてROW①~⑦をLOWにします。
 とりあえず、"A"と出力してみましょうか。

const int columnPinNumber[] = {9,10,14,15,16};
const int rowPinNumber[] = {2,3,4,5,6,7,8};

// "A"
bool LEDMatrix[7][5] ={
  {0,1,1,1,0},
  {1,0,0,0,1},
  {1,0,0,0,1},
  {1,0,0,0,1},
  {1,1,1,1,1},
  {1,0,0,0,1},
  {1,0,0,0,1}
};

void init5x7DotMatrixLED(int columnPinNumber[5], int rowPinNumber[7]);
void bright5x7DotMatrixLED(int columnPinNumber[5], int rowPinNumber[7], bool LEDMatrix[7][5]);
void openDrain(int pin, bool state);

void setup() {
  init5x7DotMatrixLED(columnPinNumber,rowPinNumber);
}

void loop() {
  bright5x7DotMatrixLED(columnPinNumber,rowPinNumber,LEDMatrix);
}

//5x7 Dot Matrix LED初期化関数
void init5x7DotMatrixLED(int columnPinNumber[5], int rowPinNumber[7]){
  for(int i=0; i<=4; i++){
    pinMode(columnPinNumber[i],OUTPUT);
    digitalWrite(columnPinNumber[i],LOW);
  }

  for(int i=0; i<=6; i++){
    openDrain(columnPinNumber[i],HIGH);
  }
}

//5x7 Dot Matrix LED 点灯関数
void bright5x7DotMatrixLED(int columnPinNumber[5], int rowPinNumber[7], bool LEDMatrix[7][5]){
  for(int i=0; i<=4; i++){
    digitalWrite(columnPinNumber[i],HIGH);
    for(int j=0; j<=6; j++){
      openDrain(rowPinNumber[j],1-LEDMatrix[j][i]);
      delayMicroseconds(476);     //=60Hz
      openDrain(rowPinNumber[j],HIGH);
    }
    digitalWrite(columnPinNumber[i],LOW);
  }
}

//オープンドレイン動作関数
void openDrain(int pin, bool state){
  if(state == HIGH){
    pinMode(pin,INPUT);
  }
  else if (state == LOW){
    pinMode(pin,OUTPUT);
    digitalWrite(pin,LOW);    
  }
}

 オープンドレイン動作関数について少し補足。Arduinoの出力ピンはハイインピーダンス出力ができないため、ピンを入力に切り替えて無理やりハイインピーダンスにしています。そんなことをやっているのがオープンドレイン動作関数さんです。

動かしてみる

 では、実際に回路を組んで動かしてみましょう。かなり簡単な回路なんですが、一点だけ、ドットマトリクスLEDのピン配置がなぜかデータシートに書かかれていませんでした。いや、書かれてはいるんですがデータシートに書かれてるような識別マークは手元のものには書いてないし、どちらにしろ1ピンの位置しかわからない内容だし…
 ともかく、裏面から見ると透明な樹脂のしたにうっすらと”1”と”12”の表記があり、下図のように時計回りに割り当てられていることがわかります。

f:id:moutakusan:20201107153429p:plain
5x7ドットマトリックスLED ピン配置

 で、実際に回路を組んでコードを書き込むと…

f:id:moutakusan:20201107154735p:plain
”A”が表示された!!

”A”が表示されました!やったー!

何が起こってるか見てみる

 5x7=35個のLEDを12本のピンで制御してるなんて不思議ですね。まあ、原理は初めに説明した通りなんですが、本当に?って思いはありますよね。
 ということで、コード中の一つ当たりの点灯時間を476usから100msくらいに伸ばしてみましょう。すると、こうなります。

f:id:moutakusan:20201107161520g:plain
スロー点灯
おお、本当に一つずつ順番に光らせてますね… これを目にもとまらぬ速さで繰り返すことで”A”が表示されてたんですね。


 今回はこれでおしまいです。お疲れ様でした。




 おしまい。