shiftOut関数について
shiftOut 関数は、Arduinoでシフトレジスタなどの外部デバイスにデータを送信するために使用される標準的な関数です。この関数は、シリアル通信を模倣し、1ビットずつ順次データを送る役割を果たします。
shiftOut 関数の構文
shiftOut(dataPin, clockPin, bitOrder, value);
パラメータ
dataPin:- データを送信するために使用されるArduinoのデジタルピンを指定します。このピンは、シフトレジスタの「データ入力ピン」(例えば、74HC595では
DSピン) に接続されます。
- データを送信するために使用されるArduinoのデジタルピンを指定します。このピンは、シフトレジスタの「データ入力ピン」(例えば、74HC595では
clockPin:- クロック信号を送るために使用されるArduinoのデジタルピンを指定します。このピンは、シフトレジスタの「クロック入力ピン」(例えば、74HC595では
SHCPピン) に接続されます。 - クロック信号は、各ビットをデバイスに転送するタイミングを指示します。クロックピンがHIGHになるたびに、シフトレジスタはデータピンから1ビットのデータを読み込みます。
- クロック信号を送るために使用されるArduinoのデジタルピンを指定します。このピンは、シフトレジスタの「クロック入力ピン」(例えば、74HC595では
bitOrder:- データをシフトする順序を指定します。このパラメータには次の2つのオプションがあります:
MSBFIRST(Most Significant Bit First):最上位ビット(MSB)から順にデータをシフトします。LSBFIRST(Least Significant Bit First):最下位ビット(LSB)から順にデータをシフトします。
- 例えば、データが
10110011の場合、MSBFIRSTでは最初に1(左側のビット)が送られ、LSBFIRSTでは最初に1(右側のビット)が送られます。
- データをシフトする順序を指定します。このパラメータには次の2つのオプションがあります:
value:- 送信する8ビットのデータ(バイト値)です。このデータがシフトレジスタに転送されます。
shiftOut の動作の詳細
shiftOut 関数は次の手順で動作します:
- ビットごとのデータ送信:
- 指定されたデータ (
value) の各ビットを1つずつ読み取り、dataPinを通じてシフトレジスタに送信します。
- 指定されたデータ (
- クロック信号の生成:
- データビットが
dataPinにセットされた後、clockPinにHIGH信号が送信されます。このクロック信号がシフトレジスタにデータを取り込ませるタイミングを決定します。
- データビットが
- 次のビットへの移行:
- クロック信号がHIGHになり、その後LOWに戻ると、
shiftOut関数は次のビットに移行し、再び同じプロセスを繰り返します。このプロセスがすべてのビット(通常8ビット)が送信されるまで続きます。
- クロック信号がHIGHになり、その後LOWに戻ると、
実際の使用例
次に、シフトレジスタ74HC595を使用して8個のLEDを制御する場合の例を見てみましょう。
int dataPin = 2; // データピン
int clockPin = 3; // クロックピン
int latchPin = 4; // ラッチピン
void setup() {
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(latchPin, OUTPUT);
}
void loop() {
digitalWrite(latchPin, LOW); // ラッチを低にしてデータ送信開始
shiftOut(dataPin, clockPin, MSBFIRST, 0b10101010); // データを送信
digitalWrite(latchPin, HIGH); // ラッチを高にして出力更新
delay(1000); // 1秒待機
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, 0b01010101);
digitalWrite(latchPin, HIGH);
delay(1000);
}
説明:
digitalWrite(latchPin, LOW);:latchPinをLOWに設定して、シフトレジスタの出力を一時的に保持します。この間にデータをシフトレジスタに送り込みます。
shiftOut(dataPin, clockPin, MSBFIRST, 0b10101010);:- データ
0b10101010をdataPin経由でclockPinのクロック信号に同期して送信します。MSB(最上位ビット)から順に送信します。
- データ
digitalWrite(latchPin, HIGH);:latchPinをHIGHに設定し、シフトレジスタの出力を更新します。これにより、送信されたデータがLEDなどに表示されます。
delay(1000);:- 1秒間待機します。
このループによって、LEDは順番にパターン 10101010 と 01010101 を表示し、1秒ごとに点滅を繰り返します。
まとめ
shiftOut 関数は、データをシフトレジスタなどのシリアルデバイスに送信する便利な方法です。シフトレジスタは、少ないピン数で多くの出力を制御するための強力なツールであり、shiftOut 関数を使うことで、簡単にその操作が可能になります。この仕組みを理解することで、より複雑な制御やパターン生成が行えるようになります。
ビットシフト演算子について
updateShiftRegister(1 << i); は、Arduinoプログラムでシフトレジスタを制御するためのコードの一部です。この部分は、特定のビットを順次ONにしてシフトレジスタにデータを送信する際に使用されます。
背景知識
シフトレジスタ(例えば74HC595など)を用いると、Arduinoの限られたピン数で多くの出力(LEDなど)を制御できます。updateShiftRegister 関数は、シフトレジスタにデータを送り込み、そのデータに応じてシフトレジスタの出力ピンに信号を出力させる役割を担っています。
1 << i の意味
1 << i は、ビットシフト演算子 << を使用した式です。この式は、ビット列の中で特定のビットをONにするために使われます。
1: 二進数の00000001に相当します(8ビットで考えた場合)。<< i: ビットを左にi回シフトします。
例えば:
1 << 0は、00000001です(1番目のビットがON)。1 << 1は、00000010です(2番目のビットがON)。1 << 2は、00000100です(3番目のビットがON)。1 << 3は、00001000です(4番目のビットがON)。
このように、1 << i は、i 番目のビットだけがONになり、他のビットはOFF(0)になるような8ビットのデータを生成します。
updateShiftRegister(1 << i); の動作
updateShiftRegister(1 << i); は、ビットシフトによって生成されたデータを updateShiftRegister 関数に渡します。この関数は、そのデータをシフトレジスタに送信し、シフトレジスタの出力を更新します。
動作の流れ
1 << iの計算:- 例えば、
iが0の場合、1 << 0で00000001が生成されます。 iが1の場合、1 << 1で00000010が生成されます。- これを
iが0から7まで変化するループで実行することで、1つのビットが順にONになり、他のビットはすべてOFFになります。
- 例えば、
- データの送信:
updateShiftRegister関数は、生成されたビットパターン(例:00000001)をシフトレジスタに送信します。- その結果、シフトレジスタに接続された8つの出力(例えばLED)が順次1つずつ点灯します。
- シフトレジスタの出力更新:
updateShiftRegister関数内でシフトレジスタのラッチピンを制御することで、新しいデータに基づいて出力が更新され、対応するLEDが点灯します。
具体例
void loop() {
for (int i = 0; i < 8; i++) {
updateShiftRegister(1 << i); // 各ビットを順にONにする
delay(100); // 0.1秒待機
}
}
このループでは、i が0から7まで変化し、そのたびに 1 << i が計算されます。結果として、シフトレジスタの出力ピンに接続されたLEDは次のように点灯します:
i = 0: LED 1 が点灯(00000001)i = 1: LED 2 が点灯(00000010)i = 2: LED 3 が点灯(00000100)- …
i = 7: LED 8 が点灯(10000000)
この動作により、LEDが1つずつ順に点灯し、アニメーション効果が得られます。
まとめ
updateShiftRegister(1 << i); は、ビットシフト演算を用いて特定のビットだけをONにするデータを生成し、それをシフトレジスタに送り込むことで、出力デバイス(例えばLED)を順次制御するための手法です。このような操作により、少ないピン数で複数の出力を効果的に制御することが可能になります。