みなさん,こんにちは
おかしょです.
マイコンを使った電子工作をしていると出力ピンが足りなくなることがあります.そのようなときはもっとピンが多い違うマイコンを買うことがまず頭に浮かぶと思いますが,もう一つ方法があります.
その方法がシフトレジスタです.この記事ではシフトレジスタについて解説していきます.
この記事を読むと以下のようなことがわかる・できるようになります.
- シフトレジスタとは何か
- シフトレジスタの使い方
- Arduinoでシフトレジスタを使う方法
この記事を読む前に
この記事ではシフトレジスタを使ってLEDを制御します.LEDの光らせ方を知らない方は以下の記事を先に読んでおくことをおすすめします.
シフトレジスタとは
LEDキューブと言うものをご存知でしょうか.これは大量のLEDを立方体上に配置して,それぞれのLEDの光らせるパターンを工夫してイルミネーションのようにするものです.これはLEDが多ければ多いほどきれいなイルミネーションを作ることができますが,難易度も上がってきます.
マイコンでLEDを制御する場合は出力ピンが必要になります.Arduino Unoを使用する場合は最大でも20ピン程度です.そのため,LEDの制御も20個程度しかできません.これでは3×3×3の立方体を作ることもできません.
このように出力ピンが足りないときに便利な電子部品がシフトレジスタです.これを使うことで1つのピンで複数のLEDを制御することが可能になります.
通常,ArduinoなどのマイコンでLEDを光らせる場合は以下のような電子回路を組みます.
上記のようにLED1つを制御するためにArduinoとつなぐのはGNDと出力ピンの2つが必要になります.この後詳細に解説しますが,シフトレジスタを使用することで制御できるLEDの数が数倍に増やすことができるようになります.
シフトレジスタの使い方
それではシフトレジスタの使い方や有効性を解説していきます.
使用するもの
シフトレジスタの使い方を確認するために使用するものは以下になります.
- マイコン(Arduino Uno)
- シフトレジスタ(74HC595)
- LED
- 抵抗器
[itemlink post_id=”3942″]
シフトレジスタなどは秋月電子で購入した方が安いです.以下にリンクを貼っておきます.
シフトレジスタ・LED・抵抗器
抵抗値はLEDのデータシートを見て決定してください.抵抗値の計算方法についてはこちらを参考にして下さい.
シフトレジスタのデータシートを読み解く
シフトレジスタの使い方を確認するためにはデータシートを読む必要があります.今回使用するシフトレジスタは74HC595と言うもので,データシートはこちらで確認できます.
データシートを確認するとピン配置は以下のようになっています.
一つ一つピンの機能を説明していきます.
Qn(n=A, …, H)
右上の2番目と左上からQA, QB, …, QHとなっています.この8つのピンは出力ピンです.つまり,それぞれのピンにLEDをつなげることでそれぞれのLEDを制御することができます.
Vcc
一番右上にあるVccと言うのは供給電圧です.このピンに電圧を供給することでシフトレジスタを機能させることができます.2Vから6Vの電圧が推奨されています.Arduinoを使用する場合は5Vのピンと接続すれば問題ありません.
SER
右上から3番目のSERと言うのはシリアルデータを入力するピンです.このピンに1byteつまり8bitの数値を与えることで,QAからQHの8つのピンにHIGHとLOWの出力ができるようになります.
例えば,SERピンに2進数でB10010011と与えた場合,各ピンの出力は以下のようになります.
\begin{array}{c|cccccccc}
Qn & QA &QB &QC &QD &QE &QF &QG &QH\\
\hline
SER & 1&0&0&1&0&0&1&1\\
\hline
H/L & H&L&L&H&L&L&H&H
\end{array}
したがって,SERピンにどのような数値を与えるのかによってLEDを制御することができます.
\(\bar{OE}\)
次に\(\bar{OE}\)は’Output Enable’の略で,このピンをLowにしておくことで出力を有効化することができます.
RCLK
その下のRCLKはラッチと呼ばれるピンでこのピンをLowからHighにするとSERに入力された8bitのデータをラッチする(保存する)ことができます.そのため,SERピンに値を入力する前はRCLKをLowにしておき,SERピンに値を入力したらRCLKピンをHighにして保存します.
SRCLK
次にSRCLKピンはクロックと呼ばれるもので,このピンを操作することでデータをシフトすることができます.シフトレジスタではSERピンに入力された8bitのデータを1bitずつシフトしてQAからQHピンに振り分けていきます.このシフトするタイミングをSRCLKピンで操作します.Arduinoの場合は’shiftOut’コマンドを使用することで簡単にシフトすることができます.このコマンドの使い方についてはプログラムの解説で詳細に扱います.
\(\bar{SRCLR}\)
右下の2番目のピン\(\bar{SRCLR}\)はシリアルデータをクリアするピンです.このピンをLOWにするとクリアしてしまうので,常にHIGHにしておく必要があります.
QH’
一番右下のピンはシリアルデータを出力します.このピンはシフトレジスタを複数使うときに用いるものなので,シフトレジスタを一つしか使わない場合は必要ありません.シフトレジスタを複数使う場合の解説は別の記事で行います.
GND
最後に一番左下のGNDはそのままGND(グラウンド)に接続します.
ピンの解説は以上になります.
電子回路
データシートからそれぞれのピンの役割がわかったので,電子回路を組みます.電子回路を組むと以下のようになります.
上記の回路ではLEDを同時に8個制御することができます.
回路図を見るとわかるように,Arduino の出力ピン3つだけで8個も制御できるようになっています.これはシフトレジスタが1つ増えるたびに出力ピンが3つ必要になるわけではありません.3つの内の2つはデータを処理するタイミングを制御するために使用するものなので,2つのピンを犠牲にすればそのあとシフトレジスタを1つ増やすにはピンも1つだけあれば十分です.このシフトレジスタを増やす方法については別の記事で解説します.
Arduinoプログラム
次にシフトレジスタを使うためのArduinoのプログラムの解説をします.まずはプログラムは以下のようになります.
#define SER 2
#define RCLK 1
#define SRCLK 0
byte data;
void setup() {
pinMode(SER, OUTPUT);
pinMode(RCLK, OUTPUT);
pinMode(SRCLK, OUTPUT);
}
void loop() {
data = B00000001;
digitalWrite(RCLK, LOW);
shiftOut(SER, SRCLK, LSBFIRST, data);
digitalWrite(RCLK, HIGH);
delay(50);
data = B00000010;
digitalWrite(RCLK, LOW);
shiftOut(SER, SRCLK, LSBFIRST, data);
digitalWrite(RCLK, HIGH);
delay(50);
data = B00000100;
digitalWrite(RCLK, LOW);
shiftOut(SER, SRCLK, LSBFIRST, data);
digitalWrite(RCLK, HIGH);
delay(50);
data = B00001000;
digitalWrite(RCLK, LOW);
shiftOut(SER, SRCLK, LSBFIRST, data);
digitalWrite(RCLK, HIGH);
delay(50);
data = B00010000;
digitalWrite(RCLK, LOW);
shiftOut(SER, SRCLK, LSBFIRST, data);
digitalWrite(RCLK, HIGH);
delay(50);
data = B00100000;
digitalWrite(RCLK, LOW);
shiftOut(SER, SRCLK, LSBFIRST, data);
digitalWrite(RCLK, HIGH);
delay(50);
data = B01000000;
digitalWrite(RCLK, LOW);
shiftOut(SER, SRCLK, LSBFIRST, data);
digitalWrite(RCLK, HIGH);
delay(50);
data = B10000000;
digitalWrite(RCLK, LOW);
shiftOut(SER, SRCLK, LSBFIRST, data);
digitalWrite(RCLK, HIGH);
delay(50);
}
上記の回路を組んで,このプログラムを実行すると順番にLEDが点灯します.
シフトレジスタの使い方を確認しました. pic.twitter.com/lBrbvrby8T
— おかしょ (@okasho_engineer) July 18, 2021
宣言
まずは宣言のところから解説していきます.最初の1から6行目の部分です.
最初の3行はピン番号と文字を対応させています.これによって,あとのプログラムではピンの番号ではなく文字で定義することができるのでプログラムの意味が分かりやすくなります.
5行目では’data’と言う変数をbyte型で宣言しています.この変数には後でSERピンに入力する値が格納されます.つまり,この変数によってLEDの制御をします.
setup
7行目から11行目のsetup関数ではピンのモードを設定します.1行目から3行目で宣言した文字を使用してピンのモードが入力(INPUT)か出力(OUTPUT)かを設定します.ここでは出力の設定をすれば良いので上記のプログラムのようになります.
loop
loop関数に書かれるプログラムは電源が供給される間繰り返されます.上記のプログラムではLEDをQHにつなげられているものから順番にQAまで点灯させていきます.
まずは14から18行目のプログラムを見てみましょう.まず最初に宣言したbyte型の変数’data’に入力したい値を格納します.QHにつなげられているLEDのみを点灯させるので,2進数表記で1byte分のデータを与えます.Arduinoの場合は2進数表記をする場合は,数値の先頭に’B’を付けることでできます.
次の15行目ではシフトレジスタのRCLKピンを’LOW’にします.これは先ほど説明したように,このピンをLOWからHIGHにすることでラッチをすることができるので,SERピンに数値を入力する前にLOWにしておきます.
16行目では’shiftOut’コマンドを使用してデータをSERピンに入力していきます.
‘shiftOut’コマンドの引数は左から順番にデータを入力するピン,データを出力するタイミングを制御するピン,データの読み取り方,データとなっています.
データを入力するピンは’SER’ピンになります.データを出力するタイミングを制御するのは’SRCLK’ピンです.
データの読み取り方と言うのは,dataに格納された数値を左から順番に読んでいくのか右から順番に読んでいくのかを指定します.この引数には’MSBFIRST’か’LSBFIRST’を入力します. ‘MSBFIRST’ とした場合はdataを左から読み取り, ‘LSBFIRST’ とした場合はdataを右から読み取ります.
データの処理を16行目で行ったら,17行目でRCLKピンをHIGHにしてラッチを行います.
以上で一通りの処理が終わりました.あとはこの処理を繰り返すことでLEDの制御をすることができます.今回のプログラムではLEDを順番に点灯させるのですが,すべての処理を連続で行ってしまうと光の流れが目に見えずらいので’delay’コマンドで描く処理の間隔を空けるようにしています.この感覚を調整することで,LEDの点灯するタイミングが早くなったり遅くなったりします.
まとめ
この記事ではシフトレジスタの使い方をピンの説明からプログラムまで詳細に解説しました.結論として,シフトレジスタを利用することで3つのピンを8つのピンに拡張することができました.元のピン3つに対して8つにすることができます.
これによって,出力ピンの不足をシフトレジスタで補うことが十分可能になります.
続けて読む
このピンの拡張できる数はシフトレジスタを複数用いた場合は,元のピン3つに対して8つに拡張するわけではないことに注意してください.3:8の関係ではなく,もっと効率よくピンを拡張することができます.
複数のシフトレジスタを使う方法については以下の記事で解説しているので続けて読んでみてください.
「現在,準備中です...」
Twitterでは記事の更新情報や活動の進捗などをつぶやいているので気が向いたらフォローしてください.
YouTubeでも制御工学や電子工作などの解説をしているので,ぜひのぞいてみてください.
それでは最後まで読んでいただきありがとうございました.
コメント