🚥

シフトレジスタのカスケード接続

2023/05/20に公開

主な部品

名前 個数
8ビットシフトレジスタ 74HC595 2個
LED 16個
抵抗 220Ω 16個

配線

こちらがとてもわかりやすい。

https://iot.keicode.com/arduino/arduino-shift-register-sn74hc595-cascading.php

ただコンデンサを使う意図がわからず使用しなかったが特に問題は起こらなかった。

コード

class Storage {
 public:
  const int SER   = 2;
  const int RCLK  = 3;
  const int SRCLK = 4;

  Storage() {
    initialize();
  }

  void write(uint16_t value) {
    for (int i = 0; i < 8 * sizeof(value); i++) {
      input(bitRead(value, i));
      shift();
    }
    commit();
  }

 private:
  void initialize() {
    pinMode(RCLK, OUTPUT);
    pinMode(SRCLK, OUTPUT);
    pinMode(SER, OUTPUT);
  }

  void input(boolean value) {
    digitalWrite(SER, value);
  }

  void shift() {
    digitalWrite(SRCLK, LOW);
    digitalWrite(SRCLK, HIGH);
  }

  void commit() {
    digitalWrite(RCLK, LOW);
    digitalWrite(RCLK, HIGH);
  }
};

Storage s = Storage();

void setup() {
}

uint64_t count = 0;

void loop() {
  int value = 16 / 2 + sin(2 * PI / 60 * count) * 16 / 2;
  int pos = constrain(value, 0, 16 - 1);
  s.write(bit(pos));
  count++;
  delay(1000 / 60);
}

要点

void write(uint16_t value) {
  for (int i = 0; i < 8 * sizeof(value); i++) {
    input(bitRead(value, i));
    shift();
  }
  commit();
}

これで引数の型のビット数分をまとめて送る。シフトレジスタを4つ繋いだ場合は uint32_t に変更するだけでよい。今回は2つ繋いだので uint16_t としている。shiftOut(SER, SRCLK, LSBFIRST, ...) を2回実行するのでもよいが抽象化が台無しになるので避けた。

Discussion