7セグメントLEDをArduinoで動かす②スケッチを読み解く

2021/05/08

7セグメントLED Arduino

t f B! P L

  目次:

今回の目標

前回は手持ちの7セグメントLEDを確認しました。

前回の記事→7セグメントLEDをArduinoで動かす①品物を確認した

今回はELEGOOのチュートリアルでどう動かしているのか把握します。

※チュートリアルの文章(PDF日本語版含む)もスケッチもELEGOOのサイトから無料でダウンロードできました。

Download ⇒「Arduino Kits & ~」⇒「UNO R3 Starter Kits」⇒ 「ELEGOO UNO R3 The Most Complete Starter Kit」 からダウンロードリンクに辿り着けます。


「74HC595と7セグメント表示」

(「ELEGOO THE MOST COMPLETE STARTER KIT TUTORIAL FOR UNO」より)

組み合わせて点灯(左上はモバイルバッテリー)


74HC595

組み合わせは モバイルバッテリー ⇒ Arduino ⇒ 74HC595 ⇒ 抵抗220Ω ⇒ 7セグメントLED です。

8ビットシフトレジスタ 74HC595

具体的にはTI製8ビットシフトレジスタ SN74HC595Nを使っております(スターターキットの内容物)。
メーカサイト(データシートあります):SN74HC595N

7セグメントLEDの場合、同時に8つのLED(セグメント×7個 + D.P.×1個)に意図する電圧を与えなければなりません。これをすべてマイコン(今回の場合Arduino)の出力と1対1の関係にすると、マイコンの出力ポート(出力に端子)を8つも占有してしまうことになってしまいます。

7セグメントLEDを1つ点灯させるだけの回路であればどうにでもなるのでしょうが、マイコンにLED表示の他の制御をさせたい場合もありますし、LED表示だけとしても16セグメントLEDであったり、さらに桁数が増えた場合にはとても出力ポートが足りなくなってしまいます。

そこで、シフトレジスタの登場ですが、「シリアル-パラレル変換」と言うそうです。マイコンの1つの出力ポートから7セグメントLEDへの8つのHigh/Lowを順繰りに出力して、シフトレジスタが順繰りに受け取る(シリアル)。受け取り終えたシフトレジスタは8つのLEDそれぞれに同時にHigh/Lowの出力を与える(パラレル)仕組みです。

※なお、8セグメント分を順繰りに受信している途中でもシフトレジスタは途中状態のHigh/Lowを7セグメントLEDに与えてしまっているのですが(少なくともこのチュートリアルのスケッチでは)、そのマイコン-シフトレジスタ間のシリアル伝送はとても速い変化のため、そのLED出力は肉眼では認識されないようです。


電流制限抵抗 220Ω

無いとLEDに無限大の電流が流れて壊れます(理論的には。実際は内部抵抗がありますし、無くても平気だったりしますが。寿命を気にしなければ特に)。

この電流制限抵抗の選択が、LED、シフトレジスタ(ドライバ)、そして電流制限抵抗自体の定格を満たす構成ができるか否かにかかってきます。以下、ざっと見ていきます。

1.LEDについて計算

74HC595NのVIH=4.2Vが点灯させるLEDのアノードに印加されるとします。

LEDの順方向電圧VFを1.8Vと仮定して、電流制限抵抗220Ωより、このLEDに流れる電流値は11mA(≒(4.2V - 1.8V)÷ 220Ω)に制限されます(ここで抵抗を0Ωとすれば無限大の電流です)。

そして、このLEDにかかる電力は20mW(≒ 1.8V × 11mA)となります。

このLEDの最大定格情報は見つけられませんでしたが、きっと定格を満たしていることでしょう。

2.電流制限抵抗について計算

さらに、電流制限抵抗220Ωにかかる電力は、27mW(≒ 11mA^2 × 220Ω)です。

この抵抗もスターターキットの内容物であり定格不明ですが、これくらいなら定格に余裕があることでしょう。

3.74HC595について計算

これは定格と比較できます。

LED×1個に対して11mA < 35mA(SN74HC595NのIO(MAX))・・・OK

LED×7個同時点灯として77mA(= 11mA×7個) > 70mA(SN74HC595Nの対GNDのIO(MAX))・・・NG

長時間は点灯(特に「8」)させない方が良いかもしれません。


Arduinoのスケッチ

ELEGOOのスケッチを基に色々変えた上、かみ砕きます。


byte d[10] = { B11111100,  // = 0

↑ byte配列"d"の第1要素としてLED表示"0"に対応する入力信号のHigh/Lowを設定します。

                       B01100000,  // = 1

 <中略>

                     }; 

↑ byte配列"d"の第2~10要素としてLED"1"~"9"に対応する入力信号のHigh/Lowを設定します。

 <中略>

void 7seg(byte digit) {

↑ voidで関数"7seg"を以降定義します

  digitalWrite(RCLK, LOW);

↑ 74HC595のRCLK(pin12)にLowを与える(RCLKがHighになるタイミングで74HC595は出力を変化させる)。

  shiftOut(SER, SRCLK, LSBFIRST, d[digit]);

↑ shiftOut関数です。"SER"(=pin2)に配列"d"の"digit"番目について、"LSB"(Least Significant Bit First:最小位ビット側)から送信します。送信のたびにSRCLKのHigh/Lowを反転させます(74HC595はデータをシフトする)。

  digitalWrite(RCLK, HIGH);

}

↑ 74HC595のRCLK(pin12)にHighを与える(RCLKがHighになるタイミングで74HC595は出力を変化させる)。つまり1表示分のデータをシフトレジスタが取り込んだ状態で、シフトレジスタの出力を取り込んだ内容に変化させる。

void loop() {       

  for (byte digit = 10; digit > 0; --digit) {

    delay(1000);

    sevenSegWrite(digit - 1);

}

↑ 先に定義した関数"7seg"に1000m秒(1秒)毎に引数9~0を与えます。つまり7セグメントLEDに"9"~"0"を繰り返して表示させます。

このブログを検索

ブログ アーカイブ

自己紹介

にほんブログ村

QooQ