●TM1638 モジュール

TM1638 モジュールを購入しました。

RASBEE 2個セット TM1638 8ビット LED デジタル チューブ 8キー

Arduinoに取り付けると3つのピンで複数のLEDやスイッチを扱えるようです。
しかし私が購入した基盤は、上部LEDの品質が良くなく一つの基板につき3個以上が故障していました。

Arduinoとの接続

VCC ------ 5V
GND ------ GND
STB ------ D2
CLK ------ D3
DIO ------ D4

私の場合はこのように接続しました。


▼ LEDのアドレス

各LEDにはアドレスが振り分けられています。
LEDのアドレスに対して点灯・消灯を送り操作します。




▼ LEDを個別で点灯するプログラム

#define STB 2
#define CLK 3
#define DIO 4

void setup() {
  pinMode(STB, OUTPUT);//使用するピンは出力に指定する必要がある
  pinMode(CLK, OUTPUT);
  pinMode(DIO, OUTPUT);

  digitalWrite(STB, LOW);
  shiftOut(DIO, CLK, LSBFIRST, 0x88);//LEDの明るさを指定、0x80 〜 0x8F
  digitalWrite(STB, HIGH);

  digitalWrite(STB, LOW);
  shiftOut(DIO, CLK, LSBFIRST, 0x44);//アドレス指定モード
  digitalWrite(STB, HIGH);
}

void loop() {
  digitalWrite(STB, LOW);
  shiftOut(DIO, CLK, LSBFIRST, 0xC0);//アドレス
  shiftOut(DIO, CLK, LSBFIRST, 0xFF);//表示する値
  digitalWrite(STB, HIGH);
  delay(500);

  digitalWrite(STB, LOW);
  shiftOut(DIO, CLK, LSBFIRST, 0xC0);//アドレス
  shiftOut(DIO, CLK, LSBFIRST, 0x00);//表示する値
  digitalWrite(STB, HIGH);
  delay(500);
}
赤文字部分にてアドレス 0xC0 を指定して一番左のデジタル表示を全点灯0.5秒毎にON/OFFします。
他のLEDは初期化していないためON/OFFの状態は不定(点いているか点いていないかわからない)状態になっています。


▼ LEDを連続書き込みで全点灯するプログラム

連続書き込みモードを使用して全てのLEDを全点灯します。
#define STB 2
#define CLK 3
#define DIO 4

void setup() {
  pinMode(STB, OUTPUT);//使用するピンは出力に指定する必要がある
  pinMode(CLK, OUTPUT);
  pinMode(DIO, OUTPUT);

  digitalWrite(STB, LOW);
  shiftOut(DIO, CLK, LSBFIRST, 0x88);//LEDの明るさを指定、0x80 〜 0x8F
  digitalWrite(STB, HIGH);

  digitalWrite(STB, LOW);
  shiftOut(DIO, CLK, LSBFIRST, 0x40);//連続書き込みモード
  digitalWrite(STB, HIGH);
}

void loop() {
  digitalWrite(STB, LOW);
  shiftOut(DIO, CLK, LSBFIRST, 0xC0);//アドレス
  for (int i = 0; i < 16; i++) {
    shiftOut(DIO, CLK, LSBFIRST, 0xFF);//表示する値
  }
  digitalWrite(STB, HIGH);
  delay(500);

  digitalWrite(STB, LOW);
  shiftOut(DIO, CLK, LSBFIRST, 0xC0);//アドレス
  for (int i = 0; i < 16; i++) {
    shiftOut(DIO, CLK, LSBFIRST, 0x00);//表示する値
  }
  digitalWrite(STB, HIGH);
  delay(500);
}
大きな違いとしては赤文字部分、書き込みモードを 0x40 連続書き込みモードに変更して、 先頭アドレスからまとめて値を書き込んでいます。
これにより全てのLEDが0.5秒毎にON/OFFするはずです。


▼ デジタル表示部分の操作

デジタル表示部分では点灯したい箇所のビットを立てて書き込む事により表示されます。



数字の "0" を表示するプログラム
#define STB 2
#define CLK 3
#define DIO 4

void setup() {
  pinMode(STB, OUTPUT);//使用するピンは出力に指定する必要がある
  pinMode(CLK, OUTPUT);
  pinMode(DIO, OUTPUT);

  digitalWrite(STB, LOW);
  shiftOut(DIO, CLK, LSBFIRST, 0x88);//LEDの明るさを指定、0x80 〜 0x8F
  digitalWrite(STB, HIGH);

  digitalWrite(STB, LOW);
  shiftOut(DIO, CLK, LSBFIRST, 0x44);//アドレス指定モード
  digitalWrite(STB, HIGH);
}

void loop() {
  unsigned int i = B00100000 | B00010000 | B00001000 | B00000100 | B00000010 | B00000001;
  digitalWrite(STB, LOW);
  shiftOut(DIO, CLK, LSBFIRST, 0xC0);//アドレス
  shiftOut(DIO, CLK, LSBFIRST, i);//表示する値
  digitalWrite(STB, HIGH);
  delay(500);

  digitalWrite(STB, LOW);
  shiftOut(DIO, CLK, LSBFIRST, 0xC0);//アドレス
  shiftOut(DIO, CLK, LSBFIRST, 0x00);//表示する値
  digitalWrite(STB, HIGH);
  delay(500);
}
赤色部分にてビット演算を行い、数字の "0" を作成し値を書き込んでいます。
このプログラムでは左端のデジタル表示部分が "0" と表示され点滅します。


▼ スイッチの入力

スイッチの値を全て取得するには、shiftIn にて1バイトのデータを4回受け取る必要があります。
1バイトのデータにはスイッチの状態(OFFなら0、ONなら1)がこのように入ってきます。



スイッチの状態を取得するプログラム
#define STB 2
#define CLK 3
#define DIO 4

void setup() {
  Serial.begin(9600);
  pinMode(STB, OUTPUT);//使用するピンは出力に指定する必要がある
  pinMode(CLK, OUTPUT);
  pinMode(DIO, OUTPUT);
}

void loop() {
  int b;
  digitalWrite(STB, LOW);
  shiftOut(DIO, CLK, LSBFIRST, 0x42);//データ取得モードに変更
  pinMode(DIO, INPUT);//DIOをshiftInのため入力に変更
  for (int i = 0; i < 4; i++) {
    b = shiftIn(DIO, CLK, LSBFIRST);
    Serial.println(b, BIN);
  }
  Serial.print("------------\n");
  pinMode(DIO, OUTPUT);//DIOを出力に戻す
  digitalWrite(STB, HIGH);

  delay(500);
}
赤い行で、データ取得モードに変更し shiftIn を4回行いスイッチの値を取得しています。
シリアルモニタを開くと現在のスイッチの状態により値が変化します。


スイッチの状態を取得するプログラムの改良版

#define STB 2
#define CLK 3
#define DIO 4

void serial_write_bin(unsigned int data) {
  for (int i = 0; i < 8; i++) {
    if ((data << i) & B10000000) {
      Serial.write('1');
    } else {
      Serial.write('0');
    }
  }
  Serial.write('\n');
}

void setup() {
  Serial.begin(9600);
  pinMode(STB, OUTPUT);//使用するピンは出力に指定する必要がある
  pinMode(CLK, OUTPUT);
  pinMode(DIO, OUTPUT);
}

void loop() {
  int b;
  digitalWrite(STB, LOW);
  shiftOut(DIO, CLK, LSBFIRST, 0x42);//データ取得モードに変更
  pinMode(DIO, INPUT);//DIOをshiftInのため入力に変更
  b = shiftIn(DIO, CLK, LSBFIRST);
  b |= (shiftIn(DIO, CLK, LSBFIRST) << 1);
  b |= (shiftIn(DIO, CLK, LSBFIRST) << 2);
  b |= (shiftIn(DIO, CLK, LSBFIRST) << 3);
  pinMode(DIO, OUTPUT);//DIOを出力に戻す
  digitalWrite(STB, HIGH);
  serial_write_bin(b);
  delay(500);
}
赤色部分にて、4回で取得したスイッチの状態を一つの変数に代入しています。
緑色部分は、2進数の値を 0詰めで出力する関数です。
シリアルモニタを開いて、スイッチを押すとビットが変化するのが確認できるはずです。


▲トップページ > マイコンなど