2022/5/6 HPトップとサービス一覧を一新しました!トップの新着情報にご注目ください!

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

はじめに

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

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

材料

Arduino Uno

Arduino Uno Rev3: マイコン関連 秋月電子通商-電子部品・ネット通販
電子部品,通販,販売,半導体,IC,マイコン,電子工作Arduino Uno Rev3秋月電子通商 電子部品通信販売

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

8ビットシフトレジスタ U74HC595AG−D16−T: 半導体(モジュール) 秋月電子通商-電子部品・ネット通販
電子部品,通販,販売,半導体,IC,マイコン,電子工作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という構成になりそうです。

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