以前、加速度センサや曲げセンサからの情報を Arduino から UART 経由で PC へ送り、PC 上でセンサ情報を表示させるソフトを作成しました。
これを使ってサーキット走行した際に、ロガーとしての効果を期待するなら...
- PC をクルマに搭載し、車載カメラにセンサ表示を映り込ませる
- 後から、車載映像を加工してセンサ情報をオーバレイ表示させる
お手軽かつ、安価なのはやっぱり、LED による表示機を作成する事でしょうか。
・・・という前置きを経て本題。
センサ情報を LED 表示したい場合...スロットルポジション10段階(LED10個)、ブレーキ10段階、加速度が、前方向10段階、後ろ方向10段階、右方向も10、左も10...最低でも合計60個のLEDを制御しなければなりません。Arduino から 60個の LED を個別制御するために、MAX7219 を試してみました。
◆MAX7219 について
MAX7219 は、計64個の LED をシリアル制御で個別駆動可能なディスプレイドライバICです。Arduino との接続は、5V、GND、DIN、CLK、LOAD の5本。DIN、CLK、LOAD の3本は DIGITAL ピンに接続。DIN に 16bit のデータを shiftOut() 関数を使って送ることで、64個のLED を個別に制御できます。
2個の IC をカスケード接続することもでき、使用ピン数はそのままで、128個のLED制御も可能です。
◆送信するシリアルデータについて
Arduino のデジタルピンと、MAX7219 の DIN 端子を接続します。送信するデータのフォーマットですが、基本、7セグLEDでの利用を前提に考えられているので...16bitのウチ上位8bit に桁の指定(8桁まで対応)、下位8bitに7セグLED(DP含む)のそれぞれのセグメントが対応しています。(BCDモードもありますが今回は使いません)
D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
× | × | × | × | ADDRESS(各桁) | DATA(各セグメント) |
1回のデータ送信(16bit)で、点灯の指定が可能なのは、8個のLED(D0-D7)ですが、このICは、V+が 2V を上回っている限り、各桁の値を保持しますので、続けて個々の桁を更新可能です。
別に、7セグLED を接続しなきゃイケナイ訳では無く、マトリックスLED でも、単体の LED 64個でも良くて、LED を8個のづつのグループに分けて管理すれば OK です。
ADDRESS に指定する値ですが、表示したい桁の指定などのほかに、MAX7219 内のレジスタを指定できます。使用する桁数や、動作モードなどを初期設定します。
◆MAX7219 と LED の接続
カソードコモンの7セグLED が前提です。アノードの A~G、DP の8本と、カソード側が1本...8桁まで対応なので8本。計16本を接続します。1桁(単体LEDが8個以下)しか使わない場合は、カソードの接続は1本のみ。
接続が3桁以下の場合、電流が流れすぎて輝度に影響が出るそうなので、I_SET 端子に接続する抵抗値で調整します。
※ MAX7219 で検索してデータシートを見てください。
◆実験
配線が面倒なので、今回は7セグLED を1つだけ使いました。初期設定周りのソースコードを固めるのが目的なので。
輝度ですが、I_SET 端子には、100kΩ を接続しました。INTENSITY レジスタのデューティーは 15/32 です。
続きに今回のスケッチ。
//----------------------------------------------------- // MAX7219 のテスト // //----------------------------------------------------- // MAX7219 REGISTER ADDRESS MAP #define REG_NO-OP 0x00 #define REG_DIG_0 0x01 #define REG_DIG_1 0x02 #define REG_DIG_2 0x03 #define REG_DIG_3 0x04 #define REG_DIG_4 0x05 #define REG_DIG_5 0x06 #define REG_DIG_6 0x07 #define REG_DIG_7 0x08 #define REG_DECODEMODE 0x09 #define REG_INTENSITY 0x0A #define REG_SCANLIMIT 0x0B #define REG_SHUTDOWN 0x0C #define REG_DISPLAYTEST 0x0F // MAX7219 PIN at Arduino int DIN = 2; // DATA IN int LOAD = 3; // LATCH int CLK = 4; // CLOCK //----------------------------------------------------- // 初期化 // //----------------------------------------------------- void setup() { pinMode(DIN, OUTPUT); pinMode(LOAD, OUTPUT); pinMode(CLK, OUTPUT); // Scan Limit MAX7219_SendData(REG_SCANLIMIT, 0); // 0: Display digit-0 only. // Decode Mode MAX7219_SendData(REG_DECODEMODE, 0); // 0: No decode for digits 7–0 // Intensity MAX7219_SendData(REG_INTENSITY, 0x07); // 7: Duty Cycle 15/32 // Shutdown Mode MAX7219_SendData(REG_SHUTDOWN, 1); // 1: Normal Operation. // Display Test MAX7219_SendData(REG_DISPLAYTEST, 0); // 0: Normal Operation. } //----------------------------------------------------- // メイン // //----------------------------------------------------- void loop() { MAX7219_SendData(REG_DIG_0, 0x0); // LED off delay(1000); MAX7219_SendData(REG_DIG_0, 0x01); // G delay(1000); MAX7219_SendData(REG_DIG_0, 0x02); // F delay(1000); MAX7219_SendData(REG_DIG_0, 0x04); // E delay(1000); MAX7219_SendData(REG_DIG_0, 0x08); // D delay(1000); MAX7219_SendData(REG_DIG_0, 0x10); // C delay(1000); MAX7219_SendData(REG_DIG_0, 0x20); // B delay(1000); MAX7219_SendData(REG_DIG_0, 0x40); // A delay(1000); MAX7219_SendData(REG_DIG_0, 0x80); // DP delay(1000); MAX7219_SendData(REG_DIG_0, 0x30); // 1 (B+C) delay(500); MAX7219_SendData(REG_DIG_0, 0x6D); // 2 (A+B+D+E+G) delay(500); MAX7219_SendData(REG_DIG_0, 0x79); // 3 (A+B+C+D+G) delay(500); MAX7219_SendData(REG_DIG_0, 0x33); // 4 (B+C+F+G) delay(500); MAX7219_SendData(REG_DIG_0, 0x5B); // 5 (A+C+D+F+G) delay(1000); } //----------------------------------------------------- // MAX7219 の DIN へデータ (16bit) を送る // void MAX7219_SendData(unsigned char regAddress, unsigned char data) { digitalWrite(LOAD, LOW); regAddress &= 0x0F; shiftOut(DIN, CLK, MSBFIRST, regAddress); shiftOut(DIN, CLK, MSBFIRST, data); digitalWrite(LOAD, HIGH); }