Arduinoと戯れてみる!

Arduino 入門 Lesson 20 【8bitシフトレジスタによる複数LED制御編】

Arduino-lesson20-00Arduino入門編
スポンサーリンク
子供と一緒に始める マイコンプログラム
Arduino 入門
Lesson 20
【8bitシフトレジスタによる複数LED制御編】

「Arduino」を使ったマイコンプログラミングを子供と一緒に学習するブログ。

少しずつ、子供と一緒に楽しみながら気長にアップしてく予定です。

 

本日は「Lesson 20 シフトレジスタによる複数LED制御編」です。

複数のLEDを直接Arduinoに抵抗と合わせて接続して制御するということではありません。

これをしてしまうと、Arduino UNOのピンが足りなくなり、センサーやボタンなど他電子部品を接続できないためピン不足になってしまいます。

 

そこで、「74HC595」のICを使うことでArduino UNOのピンを節約します。

「74HC595」は8bitのシフトレジスタです。

シリアル・パラレル・コンパレータとも、呼ばれます。

 

06.30
コードが一部見づらかったので修正しました。

 

本Lesson解説で使用しているのはArduino互換品です。

互換品とは言え、Arduinoはオープンソースであり複製して販売するのもライセンス的に問題なし。

そのため互換品の品質も悪くなく、それでいて値段は安いです。

正規品本体の値段程度で豊富な部品が多数ついています。

 

スポンサーリンク

はじめに

今回は8bitシフトレジスタについて理解したいと考えています。

ネットで検索する場合は「74HC595」で検索してみてください。

 

Amazonでも購入できますので確認してみてください。

メーカは多種多様です。

 

学術的に「シフトレジスタ」とは何か?

言葉の定義については、Wikipediaにおまかせします。

Wikipedia シフトレジスタ

シフトレジスタ(英: Shift register)とは、複数のフリップフロップをカスケード接続し、データがその回路内を移動(シフト)していくよう構成したデジタル回路のこと。

 

 

Lesson 20 目標

8bitシフトレジスタの「Arduinoでの使い方を理解」します。

また、「8bitシフトレジスタを使い複数のLEDを制御することを理解」します

最後に、本Lessonも、「遊ぶというところが一番大事」なところです。

 

準備

ではLessonの準備に取り掛かりましょう。

今回も部品は多くないので、すぐに実践に移ることができます。

 

必要なもの

 

Jumper wire抵抗は今後も頻繁に利用しますのセットで購入することをお勧めします。

 

Jumper wireできれば、「オス-メス オス-オス メス –メス」の3種類を揃えておくことをお勧めします。

 

今回のLessonではLEDを多数使用します。

手持ちがないかたは以下などおすすめです。

種類が豊富で色々と楽しめます。

色付き

 

透明

 

 

使用部品説明

8bitシフトレジスタについて説明していきます。

本Lessonで使用するICは「SN74HC595N」となります。

 

本Lessonでのシフトレジスタの使用目的は以下となります。

少ないピンで多くの出力制御をする。
※直列入力並列出力(SIPO:Serial In Parallel Out)と呼ばれます。

 

SN74HC595N 8bitシフトレジスタ 仕様

下の写真が、8bitシフトレジスタ「SN74HC595N」です。

Arduino-lesson20-01

 

データシートは以下から入手可能です。

秋月電子通商 - 電子部品・半導体 【通販・販売】

下記通販コードで検索してください。
通販コード:I-09952

 

端子は全部で16ピンあります。

メーカのデータシートによって端子名は異なります。

Arduino-lesson20-02

 

以下に端子の説明を示します。

メーカーによってピン名などは異なりますが、基本的な使い方は同じです。

ピン番号IC
ピン名前
fritzing
ピン名
入出力内容
1~7
15
QB~QH
QA
Q1~Q7
Q0
出力パラレル出力。
9QH’Q7′出力シフトレジスタの最上位ビットの状態を出力。
シフトレジスタを何個も繋げて使う時に使用。
10SRCLRMR入力シフトレジスタのクリア(リセット)。
Lでシフトレジスタの全bitがLに初期化。
11SRCLKSH_CP入力シフトレジスタのクロック信号。
立上りエッジに同期してシフトレジスタが動作。
12RCLKST_CP入力ラッチクロック。
ストレージレジスタのクロック信号。
RCLK信号の立ち上がりに同期して、シフトレジスタの出力がストレージレジスタに転送されます。
8bitのデータを送信順に出力
13OEOE入力出力の有効化。
全パラレル出力が切断状態になる。
※ハイインピーダンス状態
14SERDS入力シリアル入力。
SRCLK信号の立ち上がりに同期して、シフトレジスタの初段Dフリップフロップに取り込まれる。
8GNDGNDグランド(UNOのGNDに接続)
16VCCVCC電源(UNOの5Vに接続)

 

ピンがたくさんあり、混乱しそうですがシフトレジスタの動作で必要なのは以下だけです。

  • シリアル入力 ・・・ データを入れる
  • パラレル出力 ・・・ データ出力
  • シフトレジスタクロック ・・・ データの入力先を次のアドレスに移動
  • ラッチクロック ・・・8bitのデータを送信順に出力

この4種類を制御することで、シリアルデータをパラレルデータに変換することができます。

 

今回のLessonではShiftOut関数を使います。

これによって、意識するピンはラッチクロックだけとなります。

 

8bitシフトレジスタの使い方

ここでは簡単に使い方のみ説明します。

shiftOut関数を利用することで簡単に制御することが可能です。

この関数は8bit分のデータを一括でシフトレジスタに送ることができます。

RCLK以外のシフトレジスタの制御をshiftOut関数が担ってくれるのです。

 

そのため、サンプルコードとして意識する動作は以下のみとなります。

1.RCLK(ST_CP)をLowにする。
  データ送信中はLow。
2.shiftOut関数を使って8bit分のデータをシフトレジスタに送る。
  動作としては点灯するLEDを選択するということ。
3.RCLK(ST_CP)をHighにする。
  送信終了。

たったこれだけです。

補足
実際はRCLKでフリップフロップの状態を更新する制御をしています。

 

タイミングチャートなどであらわすと、もっと複雑なのですがその辺がわかっていなくても動かせてしまうのがArduinoです。

 

参考にタイミングチャートを載せておきます。

Arduino-lesson20-03

 

ただし、何かをさせるために応用しようとする場合、動作理解が必要です。

学習する時間のあるかたは下記サイトを参照ください。

ここで説明も考えましたが、

まじめに、説明しようと思うとシフトレジスタだけで記事ができてしまうので・・・。

またの機会に。

 

シフトレジスタについて下記サイトにて詳しく記載されています。

「シフトレジスタ」の解説
用語「シフトレジスタ」の意味を解説しています。…

 

実践 回路作成とコード作成

最初に回路図を確認してください。

次に、回路図に合わせて部品を接続します。

最後にコードを書いて、LEDの点灯、消灯で動作を確認していきましょう。

 

Arduinoのピン配置を確認したい方は番外編02を参照してください。

 

回路図

回路図がこちら。

LEDと抵抗が多いので接続が大変ですが、ある意味繰り返しの接続なので単純と言えます。

LEDが焼き切れるのを防ぐために電流制限抵抗は忘れずに入れてください。

Arduino-lesson20-04

 

こちらがブレッドボード図。
※M-M jumper wireのみで結線できます。

Arduino-lesson20-05

 

回路図は「fritzing」を利用しています。

「fritzing」の使い方は下記を参照してください。

 

接続

下図に示すように、用意した部品を使用して接続しましょう。

部品は8bitシフトレジスタ、LED、抵抗です。

LEDと抵抗の数が多いですが、頑張って接続しましょう!

Arduino-lesson20-06

 

使用するポートは、デジタル入出力ピンの「9、11、12」。

電源の「5V」、「GND」です。

穴に挿入しづらいときは、ラジオペンチなどを使用してください。

 

デジタルピン3つのみで8個のLEDを制御できるというのが今回のミソです。

 

コードの書き込み

接続が終わったら、USBケーブルを使用してUNOにプログラムを書き込んで行きましょう。

今回は、Arduino公式サイトのShiftOutコードなどを参考に2つのサンプルコードを書いてみました。

 

参考にして、実践してみてください。

もちろん、サンプルコードをそのまま使っていただいてかまいません。

 

サンプルコードは一例です。

書き方は色々ありますので、ネットなど検索して見るのもよいかと思います。

 

コマンド説明

今回新たにでてくるコマンドを説明しておきます。

コマンド説明
byte0から255までの8bitの数値を格納。
負の数値は扱えません。
例 変数に18(10進数)を代入。
byte value = B10010;
※Bは2進数を表しています。
bitSet(x,n)指定したビットをセットします。
セットする値は1です。
x:対象となる数
n:セットするビットの位置
右端(LSB)から数えて何ビット目か。
戻り値:なし

変数xの2ビット目を1にする。
bitSet(x,1);
bitClear指定したビットをクリアします。
セットする値は0です。
x:対象となる数
n:クリアするビットの位置
右端(LSB)から数えて何ビット目か。
戻り値:なし

変数xの2ビット目を0にする。
bitClear(x,1);
shiftOut(dataPin, clockPin, bitOrder, value)1バイト分のデータを1ビットずつ「シフトアウト」する。
最上位ビット(MSB)と最下位ビット(LSB)のどちらからもスタート可能。
各ビットはまずdataPinに出力され、その後clockPinが反転して、そのビットが有効になったことが示されます。
dataPin:各ビットを出力するピン
clockPin:
クロックを出力するピン。
dataPinに正しい値がセットされたら、このピンが1回反転します
bitOrder:
MSBFIRSTまたはLSBFIRSTを指定。
Most Significant Bit Firstは最上位ビットから送ること、Least Significant Bit Firstは最下位ビットから送ることを示す。
value:送信したいデータ (byte)
戻り値:なし

 

サンプルコード1

サンプルコード1を下記に示します。

こちらは、LEDを順番に点灯させるサンプルコードです。

点灯するLEDは1つのみです。

//Lesson 20-1 8bitシフトレジスタを使ってLEDを順番に点灯1
//https://omoroya.com/

int tDelay = 200;   //200ms遅延設定
int rclkPin = 11;   // (11) ST_CP [RCLK] on 74HC595
int srclkPin = 9;   // (9)  SH_CP [SRCLK] on 74HC595
int dsPin = 12;     // (12) DS [SER] on 74HC595

byte leds = 0; //ledsをbyte型としてb00000000で定義

void setup() 
{
  pinMode(rclkPin, OUTPUT);   //11番ピンをOUTPUTとして定義
  pinMode(dsPin, OUTPUT);     //12番ピンをOUTPUTとして定義
  pinMode(srclkPin, OUTPUT);  //9番ピンをOUTPUTとして定義
}

void loop() 
{
  // LED1からLED8までを順に光らせる。
  for (int i = 0; i < 8; i++)
  {
    bitSet(leds, i); //bitbyte操作関数で指定したビットを1にする
    
    digitalWrite(rclkPin, LOW);                //送信中のRCLKをLowにする
    shiftOut(dsPin, srclkPin, LSBFIRST, leds); //シフト演算を使って点灯するLEDを選択
    digitalWrite(rclkPin, HIGH);               //送信終了後RCLKをHighにする
    
    delay(tDelay);
    
    bitClear(leds, i);                         //点灯させたLEDのbitを0にして消灯させるための設定
  }
}

 

サンプルコード2

サンプルコード2を下記に示します。

こちらも、LEDを順番に点灯させるサンプルコードですが、

LEDが順番に全て点灯します。

その後、全てが消えて繰り返す動作となっています。

全て点灯したら消灯するようになっています。

//Lesson 20-1 8bitシフトレジスタを使ってLEDを順番に点灯2
//https://omoroya.com/

int tDelay = 200;   //200ms遅延設定
int rclkPin = 11;   // (11) ST_CP [RCLK] on 74HC595
int srclkPin = 9;   // (9)  SH_CP [SRCLK] on 74HC595
int dsPin = 12;     // (12) DS [SER] on 74HC595

byte leds = B00000000; //ledsをbyte型としてb00000000で定義

void setup() 
{
  pinMode(rclkPin, OUTPUT);   //11番ピンをOUTPUTとして定義
  pinMode(dsPin, OUTPUT);     //12番ピンをOUTPUTとして定義
  pinMode(srclkPin, OUTPUT);  //9番ピンをOUTPUTとして定義
}

void loop() 
{
  // LED1からLED8までのレジスタを初期化。
  leds = 0;                                  //初期化設定、b00000000(8bitを0にする)
  digitalWrite(rclkPin, LOW);                //送信中のRCLKをLowにする
  shiftOut(dsPin, srclkPin, LSBFIRST, leds); //全てのLEDを消灯
  digitalWrite(rclkPin, HIGH);               //送信終了後RCLKをHighにする
  
  delay(tDelay);
  
  // LED1からLED8までを順に光らせる。
  for (int i = 0; i < 8; i++)
  {
    bitSet(leds, i);                           //bitbyte操作関数で指定したビットを1にする
    
    digitalWrite(rclkPin, LOW);                //送信中のRCLKをLowにする
    shiftOut(dsPin, srclkPin, LSBFIRST, leds); //シフト演算を使って点灯するLEDを選択
    digitalWrite(rclkPin, HIGH);               //送信終了後RCLKをHighにする
    
    delay(tDelay);
  }
}

 

サンプルコード1とサンプルコード2の違いを考えてコードを読んでみると理解がし易いと考えます。

 

動作確認

では、さっそく動作を確認していきます。

といっても、動画ではないので順番に点灯しているのを表現するのは難しい・・・。

ぜひ、実践して確かめてみてください。

 

サンプルコード1の結果

点灯するLEDは1つのみです。

順番に左から右へ点灯が移っていきます。

一番右までいったら、始めに戻り繰り返します。

Arduino-lesson20-07

 

サンプルコード2の結果

こちらは、左から順番にLEDが点灯します。

全て点灯したら消灯して、始めに戻り繰り返します。

Arduino-lesson20-08

 

いかがでしょうか?

色んな色のLEDを使うととっても綺麗です!

 

まとめ

今回は以下の内容について理解しました。

今回も項目3の遊ぶことが一番の目標でした。

1.8bitシフトレジスタの「Arduinoでの使い方を理解」する。
2.「8bitシフトレジスタを使い複数のLEDを制御することを理解」する。
3.楽しんで遊ぶ。

1.に関しては、時間をかけてゆっくりと理解してみてください。

参考になるサイトはたくさんあります。

 

最後に、本Lessonも、「遊ぶというところが一番大事」なところです。

 

いかがだったでしょうか。

Lesson 20 シフトレジスタによる複数LED制編はここまで。

ぜひ、みなさんも子供と一緒にやられてみることをお勧めします。

 

8bitシフトレジスタについては、別記事にて詳細を説明できればなと考えています。

しかし、ボリュームがありすぎて躊躇しています・・・。

 

次回Lesson 21は【シリアルモニタによるLED制御編】です。

Arduino 入門 Lesson 21 【シリアルモニタによるLED制御編】
本日は「Lesson 21 シリアルモニタによるLED制御編」です。Arduino シリアルモニタを利用してPCからLEDを制御することに挑戦です。PCから直接UNOを制御することで、LEDのON、OFF制御をさせるといったことか可能です。…

 

最後に

疑問点、質問などありましたら気軽にコメントください。

この電子部品の解説をしてほしい!などなどなんでもOKです。

リンク切れなどあればコメントいただけると助かります。

 

Arduino入門編、番外編、お役立ち情報などなどサイトマップで記事一覧をぜひご確認ください。

 

Arduino入門編で使用しているUNOはAmazonにて購入可能です。

互換品とは言え、Arduinoはオープンソース。

複製して販売するのもライセンス的に問題なし。

 

そのため互換品の品質も悪くなく、それでいて値段は安いです。

正規品本体の値段程度で豊富な部品が多数ついています。

 

学習用、遊び用、お試し用には安価な互換品がおすすめです。

 

Amazon ベストセラーNo.1
ELEGOO UNO キット レベルアップ  チュートリアル付 uno mega2560 r3 nanoと互換 Arduino用

 

上記のものでも十分に多数の部品が入っていますが、最初からもっと多数の部品が入っているこちらもお勧めです。

 

Amazonでお得に買う方法

Amazonでお得に購入するなら、Amazonギフト券がおすすめです。

現金でチャージするたびに、チャージ額に応じたポイントが付与されます。

最大2.5%!!!(Amazonプライム会員ならさらにお得)

チャージ額(一回分)一般プライム会員
5,000円~19,999円0.5%1.0%
2,0000円~39,999円1.0%1.5%
40,000円~89,999円1.5%2.0%
90,000円~2.0%2.5%

さらに、初回チャージで1000ポイントもらえるキャンペーンも実施中!

\Amazonギフト券 1000ポイントキャンペーン/
Amazonチャージ 初回購入で1000ポイントキャンペーン

 

補足情報
コンビニ・ATM・ネットバンクが対象
購入は1円単位で可能

コメント

  1. アオキノコ より:

    omoroya様
    初めてコメントします。素人の工作者なのですが、このサイトにたどり着いて参考にさせていただいています!わかりやすくてとても助かっています。

    ご迷惑でなければ一つ質問があるのですが・・・
    シフトレジスタを使用して増やしたLEDをぼんやり点灯→消灯しながら光が流れるようにするのは可能なのでしょうか?LEDを個別のアナログピンでPWM制御する方法までは分かったのですが、ピンの数以上のLEDを制御したくて・・・
    素人なので質問内容自体が間違っていたり意味不明かもしれません。お時間がありましたらお答えいただけると幸いです。
    これからも応援しています!
    アオキノコ

    • omoroyaomoroya より:

      コメントありがとうございます。
      記事更新のはげみになります!
      色々な方法があると思いますが、Lesson 20のスケッチを利用する場合は
      for文を2重ループにすればできるのではと考えます。
      内側のfor文でPWM制御、外側のfor文で点灯させるLEDを制御する見たいな感じです。
      時間ができたら、スケッチを作成してみます。

タイトルとURLをコピーしました