【Raspberry Pi Pico入門 – 応用編】シフトレジスタの使い道

2024年4月18日Raspberry Pi Pico入門,応用編Arduino,Raspberry Pi Pico

概要

基本編でシフトレジスタを使ってバー表示LEDを動かしてみましたが、シフトレジスタには他にも色々な使い方が出来ます。
ここでは色々な作例を紹介していきます。随時更新中。

7セグメントLED

7個のLEDが数字の8の形に並べられている表示器で、デジタル数字と聞いて思い浮かぶであろうアレです。電子工作においては表示器として一番簡単で扱いやすいかもしれません。
回路としてもLEDが7個並んでいるだけなので理解しやすいと思います。

回路

以下のように配線します。抵抗は220Ωを使用します。
チュートリアルの順番とは異なっているので注意してください。順番は好みなのでチュートリアルと同じ回路でも問題ないですし、自分で独自の配線のパターンを考えてもOKです。

回路図は以下のようになります。

コーディング

新しくスケッチを作成し、以下の内容をコピペしてください。チュートリアルと回路が異なるので、それに合わせて点灯パターンも異なっています。

/* GPIO設定 */
const int DATA_PIN = 16;
const int LATCH_PIN = 17;
const int CLOCK_PIN = 18;

/* LEDの点灯パターン */
/* 左からdot,a,b,c,d,e,f,gの順で、0にすると点灯 */
const byte led_pattern[] = {
  /* 1セグメントずつ点灯 */
  0b01111111, /* ドット */
  0b10111111, /* a */
  0b11011111, /* b */
  0b11101111, /* c */
  0b11110111, /* d */
  0b11111011, /* e */
  0b11111101, /* f */
  0b11111110, /* g */

  /* 数字 */
  0b10000001, /* 0 */
  0b11001111, /* 1 */
  0b10010010, /* 2 */
  0b10000110, /* 3 */
  0b11001100, /* 4 */
  0b10100100, /* 5 */
  0b10100000, /* 6 */
  0b10001111, /* 7 */
  0b10000000, /* 8 */
  0b10000100, /* 9 */
};
int pattern_num = 0;

void setup() {
  /* GPIO初期設定 */
  pinMode(DATA_PIN, OUTPUT);
  pinMode(LATCH_PIN, OUTPUT);
  pinMode(CLOCK_PIN, OUTPUT);

  /* LEDパターンの数を確認 */
  pattern_num = sizeof(led_pattern) / sizeof(led_pattern[0]);
}

void loop() {
  /* 全てのパターンを順に表示 */
  for (int i = 0; i < pattern_num; i++) {
    Write7seg(led_pattern[i]);
    delay(1000);
  }
}

void Write7seg(int num) {
  digitalWrite(LATCH_PIN, LOW);
  shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, num);
  digitalWrite(LATCH_PIN, HIGH);
}

動作確認

各セグメントが1つずつ点灯し、その後に0~9の数字が表示されれば成功です。

カスケード接続(シフトレジスタの連結)

シフトレジスタの特徴としてカスケード接続ができるという点があります。シフトレジスタを複数連結して使うことで出力を16個、24個、32個と増やすことができます。

回路

2つのシフトレジスタをカスケード接続する時の回路は以下のようになります。(配線がぐちゃぐちゃになりそうなのでブレッドボードの配線図は省略します)

LATCH、CLOCKは共通の配線にして、1個のときは使わなかったQ7’を2個目のDATAに繋ぎます。こうすることによってQ7のHigh/Low情報を2個目のシフトレジスタに送れるようになり、マイコンで制御するのは1個目のDATAだけでよくなります。同じように3個目や4個目も繋いでいくことで、マイコンのピンの仕様数は3本のまま出力をどこまででも増やすことが出来ます。

コーディング

基本編20のコードとほぼ同じでOKです。変わったのではloop()のshiftOut()が1つ増えただけです。

/* GPIO設定 */
const int DATA_PIN = 16;
const int LATCH_PIN = 17;
const int CLOCK_PIN = 18;
const byte led_pattern[] = {
  0b11000000,
  0b01100000,
  0b00110000,
  0b00011000,
  0b00001100,
  0b00000110,
  0b00000011,
  0b10000001
};
int pattern_num = 0;
void setup() {
  pinMode(DATA_PIN, OUTPUT);
  pinMode(LATCH_PIN, OUTPUT);
  pinMode(CLOCK_PIN, OUTPUT);
  pattern_num = sizeof(led_pattern) / sizeof(led_pattern[0]);
}
void loop() {
  for (int i = 0; i < pattern_num; i++) {
    digitalWrite(LATCH_PIN, LOW);
    shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, led_pattern[i]);
    shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, led_pattern[pattern_num - i]);
    digitalWrite(LATCH_PIN, HIGH);
    delay(500);
  }
}