はじめに
前回はトランジスタアレイで複数のLEDを制御しました。
しかしArduino Unoにはデジタル出力ピンが14個しかないので、その方法では14個までしか制御できません。そんなときはシフトレジスタが役に立つとのことです。ここではシフトレジスタの使い方を備忘録として残しておきます。
材料
Arduino Uno
シフトレジスタはよく使われる型番(U74HC595)を用意しました。
あとは適当な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という構成になりそうです。