4/14(日) 足・靴・木型研究会「第2回研究集会」を開催します☆彡

7-30. ArduinoでたくさんのLEDを制御する2(シフトレジスタの使い方)

はじめに

前回はトランジスタアレイで複数のLEDを制御しました。

しかしArduino Unoにはデジタル出力ピンが14個しかないので、その方法では14個までしか制御できません。そんなときはシフトレジスタが役に立つとのことです。ここではシフトレジスタの使い方を備忘録として残しておきます。

材料

Arduino Uno

403- 現在メンテナンス中です。

シフトレジスタはよく使われる型番(U74HC595)を用意しました。

8ビットシフトレジスタ U74HC595AG-D16-T: 半導体 秋月電子通商-電子部品・ネット通販
電子部品,通販,販売,半導体,IC,LED,マイコン,電子工作8ビットシフトレジスタ U74HC595AG-D16-T秋月電子通商 電子部品通信販売

あとは適当なLED×8個、適当な抵抗(1kΩ)×8個、配線用のジャンパワイヤです。

回路

U74HC595のデータシートを見ると足は次のようになっています。

ブレッドボード上で次のように配線。シリアル、ラッチ、クロックはそれぞれデジタル2, 3, 4ピンに挿しました。

プログラム

Arduinoに書き込みます。

// ピンID
const int SER = 2;
const int RCLK = 3;
const int SRCLK = 4;

void setup(){
  // シリアルポートを9600 bpsで初期化
  Serial.begin(9600);
  // 3つのピンをoutputに
  pinMode(SER, OUTPUT);
  pinMode(RCLK, OUTPUT);
  pinMode(SRCLK, OUTPUT);
  // 全消灯で初期化
  shiftOut(SER, SRCLK, LSBFIRST, 0b00000000);
  digitalWrite(RCLK,  LOW);
  digitalWrite(RCLK,  HIGH);
}

void loop(){
  // 8ビット分のデータをシフトレジスタへ送る
  shiftOut(SER, SRCLK, LSBFIRST, 0b00000001); 
  // シフトレジスタの状態をストレージレジスタへ反映させる
  digitalWrite(RCLK,  LOW);
  digitalWrite(RCLK,  HIGH);
  // 点灯時間
  delay(500);

  // 8ビット分のデータをシフトレジスタへ送る
  shiftOut(SER, SRCLK, LSBFIRST, 0b00101010); 
  // シフトレジスタの状態をストレージレジスタへ反映させる
  digitalWrite(RCLK,  LOW);
  digitalWrite(RCLK,  HIGH);
  // 点灯時間
  delay(500);
}

ここで、信号は8ビットで送り込んでいて、

shiftOut(SER, SRCLK, LSBFIRST, 0b00000001);

「0b00000001」で出力8が光ります。「LSBFIRST」がビットの左(上の桁)から送るみたいな意味で、出力[1,2,3,4,5,6,7,8] に ビット[0,0,0,0,0,0,0,1] が対応しています。「0b00101010」も同様です。

ところで、ビットではなく整数を送っても同じことができます。正確にはuint8_t(8ビット符号なし整数、0~255までの256階調)を受け取ることができます。

// ピンID
const int SER = 2;
const int RCLK = 3;
const int SRCLK = 4;

void setup(){
  // シリアルポートを9600 bpsで初期化
  Serial.begin(9600);
  // 3つのピンをoutputに
  pinMode(SER, OUTPUT);
  pinMode(RCLK, OUTPUT);
  pinMode(SRCLK, OUTPUT);
  // 全消灯で初期化
  shiftOut(SER, SRCLK, LSBFIRST, 0);
  digitalWrite(RCLK,  LOW);
  digitalWrite(RCLK,  HIGH);
}

void loop(){
  // 8ビット分のデータをシフトレジスタへ送る
  shiftOut(SER, SRCLK, LSBFIRST, 1); 
  // シフトレジスタの状態をストレージレジスタへ反映させる
  digitalWrite(RCLK,  LOW);
  digitalWrite(RCLK,  HIGH);
  // 点灯時間
  delay(500);

  // 8ビット分のデータをシフトレジスタへ送る
  shiftOut(SER, SRCLK, LSBFIRST, 42); 
  // シフトレジスタの状態をストレージレジスタへ反映させる
  digitalWrite(RCLK,  LOW);
  digitalWrite(RCLK,  HIGH);
  // 点灯時間
  delay(500);
}

ここが変わっています。

shiftOut(SER, SRCLK, LSBFIRST, 0);  //0b00000000
shiftOut(SER, SRCLK, LSBFIRST, 1);  //0b00000001
shiftOut(SER, SRCLK, LSBFIRST, 42);  //0b00101010

2進数「0b00101010」に対応する10進数「42」を送ると、「0b00101010」と解釈されて出力3, 5, 7が光ります。試していませんが、例えば10進数「260」を送ると桁溢れで10進数「4」つまり2進数「0b00000100」と解釈されて3番目が光るのでしょうか?

Pythonで制御

けっこう複雑なのでコードは載せませんが、Pythonから制御できるようになりました。キビキビ動きます。

さいごに

シフトレジスタをカスケードすると無限の(?)LEDを制御できるらしいので、壮大なイルミネーションが作れそうです。ただし大電流を要するLEDを同時に点灯させるとシフトレジスタの定格電流を超えてしまうかもしれません。その場合は、Python→Arduino→シフトレジスタ→トランジスタアレイ→LEDという構成になりそうです。

SNS等でお気軽にご連絡ください

※当ブログに関することは何でもご相談・ご依頼可能です(Servicesになくても)
※TwitterはFF外の場合はDMではなく返信orメンションでお願いしますm(_ _)m

情報発信しています

質問・コメントはSlackやDiscordでお気軽に

勉強会の告知はこちらで

Raspberry Pi / Arduino
この記事を書いた人

博士(理学)。専門は免疫細胞、数理モデル、シミュレーション。米国、中国で研究に携わった。遺伝的アルゴリズム信者。物価上昇のため半額弁当とともに絶滅寸前。

この記事をシェアする
Vignette & Clarity(ビネット&クラリティ)
タイトルとURLをコピーしました