先日Amazonで8桁7セグLEDを買ったので遊んでみました
商品リンクはこちら、僕はここから買いました
MAX7219とは?
秋月で探してみるとデータシートがあったので見てみましょう
Serially Interfaced, 8-Digit LED Display Driversとある通りLEDディスプレイドライバICです。8-DIGIT
となっているのは数字表記用の7つのセグメントのほかに.
があるからです
しかもシリアル入力で制御ができるので非常に便利です。実際このLEDディスプレイのピン足の印字を見ると
シリアル通信してそう(キタナイのははんだ付け間違えたからです・・・)
制御方法
細かいところは省きますが、Arduinoで制御する場合CS
と繋がっているデジタルピンをLOW
にしてshiftOut(DIN, CLK, MSBFIRST, addr);
でアドレスを送信しshiftOut(DIN, CLK, MSBFIRST, dat);
でデータを送信、CS
をHIGH
で終了、といった感じです
関数化するとこんな感じでしょうか
void LED_OUT(uint8_t addr, uint8_t dat){
digitalWrite(LED_CS, LOW);
shiftOut(LED_DIN, LED_CLK, MSBFIRST, addr);
shiftOut(LED_DIN, LED_CLK, MSBFIRST, dat);
digitalWrite(LED_CS, HIGH);
}
あらかじめ#define
でLED_DIN
とLED_CLK
とLED_CS
につながっているピンの番号をそれぞれ指定してあります。
では、以下にデータアドレス(16進で表記)と送られるデータの関係を示します。よく分からないのは-
で。詳しいことはコードに記述するときに
データアドレス | 内容 | データアドレス | 内容 |
---|---|---|---|
0x0 | - | 0x8 | Digit 7 |
0x1 | Digit 0 | 0x9 | デコードモード |
0x2 | Digit 1 | 0xA | 輝度 |
0x3 | Digit 2 | 0xB | 桁数 |
0x4 | Digit 3 | 0xC | シャットダウン |
0x5 | Digit 4 | 0xD | - |
0x6 | Digit 5 | 0xE | - |
0x7 | Digit 6 | 0xF | ディスプレイテスト |
細かいことはデータシートを
とりあえず光らせる①
では早速光らせてみましょう。目標は12345678
を表示することとします
始めに初期設定みたいなのが必要になります。
先ほどのアドレスと内容の表でいうところの「デコードモード」「輝度」「桁数」がそれにあたります
それぞれについて説明していきますね
デコードモード
7セグメントLEDなので主用途は数値の表示です。そのためには数字やアルファベットを表示するためにデコードする必要がある訳ですが、このICにはその機能が内蔵されています。それを各桁毎に有効にするか無効にするかを指定するのがデコードモードです。有効にしたい桁のビットを立ててあげれば使えます
仮にすべてのセグメントで有効にする場合、以下の通りにします
LED_OUT(0x9, 0b1111111);
これは前述の関数をそのまま用いた場合です。また0b11111111
は0xFF
や0d255
でも大丈夫です。全桁で有効・無効を揃えたい場合は16進表記にするのが楽でいいと思います
ちなみにですが僕はいつも無効にしてます。有効無効切り替えてアレコレするより関数化してしまった方が個人的には楽だからです。その方法については次の記事で
輝度
データシートではIntensity
とあります。直訳すると「強度・強さ」となりますがここでは「(光の)強さ」ということでしょう
このアドレスに送信するデータは0-15、16進だと0x0-0xFになります。ここに入れるべき数値は環境によって変わると思うので各々で調整してください。屋内なら3くらいで十分な気がします
桁数
使用する桁数-1を指定します。8桁すべて使う場合は7を、1桁しか使わない場合は0を、といった具合です
基本的に7で良いと思います
とりあえず光らせる②
以上を踏まえ実際にデータを送信するコードを書いていきます。
ちなみに一番右のセグメントがDigit 0
、一番左のセグメントがDigit 7
になります
とりあえず光らせるだけなので各Digitに対応する数字を投げれば光りそうですね
ということで簡単に書いてみました
#define LED_CS 10
#define LED_CLK 11
#define LED_DIN 12
void setup() {
pinMode(LED_CS, OUTPUT);
pinMode(LED_CLK, OUTPUT);
pinMode(LED_DIN, OUTPUT);
digitalWrite(LED_CS, HIGH);
digitalWrite(LED_CLK, LOW);
digitalWrite(LED_DIN, LOW);
LED_OUT(0x9, 0xFF); //7セグでデコードするビットに1を立てる:
LED_OUT(0xA, 5); //輝度を設定, 0-15:
LED_OUT(0xB, 7); //使用する桁数を指定, 桁数-1:
LED_OUT(0xC, 1); //特にいじる必要なし:
LED_OUT(0xF, 0); //同上:
LED_OUT(0x1, 8); //1ケタ目のセグメントに表示するものを指定:
LED_OUT(0x2, 7); //2ケタ目:
LED_OUT(0x3, 6); //3ケタ目:
LED_OUT(0x4, 5); //4ケタ目:
LED_OUT(0x5, 4); //5ケタ目:
LED_OUT(0x6, 3); //6ケタ目:
LED_OUT(0x7, 2); //7ケタ目:
LED_OUT(0x8, 1); //8ケタ目:
}
void loop() {
}
void LED_OUT(uint8_t addr, uint8_t dat){
digitalWrite(LED_CS, LOW);
shiftOut(LED_DIN, LED_CLK, MSBFIRST, addr);
shiftOut(LED_DIN, LED_CLK, MSBFIRST, dat);
digitalWrite(LED_CS, HIGH);
}
早速書き込んで実行しましょう
ちゃんとつきました。これで光らせれると分かれば勝ったも同然ですね、それは言い過ぎ
今回はこんな感じで終わります。次の記事ではより複雑な関数を使ったプログラムを紹介しています。どうぞよしなに