秋月電子の 7セグメントLEDシリアルドライバモジュール を使うと、簡単に 7セグLED を扱えるようになります。
この記事では Arduino Nano を使用しています。配線は異なりますが、回路とプログラムは Arduino Uno にも対応しています。
Arduino 自体の使い方については他の記事をご参照ください。
モジュールの特徴
7セグLED の点灯は各LEDごとの配線が煩雑になりがちです。さらに、複数桁を点灯させるために配線がさらに多くなり、場合によりダイナミック点灯の制御が必要になります。
これらの問題を一挙に解決するのがこのモジュールです。
- 信号線は3本のみ : SDI, SCK, LATCH のみ
- 桁数に制限なし : 電源が確保できればいくらでも増設可、しかも信号線は増えません
- スタティック点灯 : 消費電流は大きいですが、原理的にちらつきがありません
- 表示中の制御の必要なし : 表示以外にCPUリソースを割けます
- 5V, 3.3V駆動可 : ただし表示色の制限があります(後述)
用意するもの
部品名 | 画像 | はんだ付け | 入手先 (参考) |
---|---|---|---|
Arduino Nano (Arduino UNO でも可) |
必要なし |
秋月電子 千石電商 など |
|
7セグLEDシリアルドライバモジュール 完成品 |
必要なし | 秋月電子: 赤色, 緑色, 青色 | |
7セグLEDシリアルドライバモジュール DIP化キット |
必要 | 秋月電子 | |
7セグLEDシリアルドライバモジュール 基板のみ |
必要 | 秋月電子 |
7セグLEDモジュールは必要な桁数のみご用意ください。完成品、DIP化キット、基板のみの3種が存在します。
完成品 はやや割高ですが、はんだ付け不要ですぐに使え、赤、緑、青の3色がラインナップされています。
DIP化キット は部品のみのセットで、はんだ付けされていません。またキットは赤色のみです。
基板のみ は最安ですが、7セグLEDが同梱されていません。好みの7セグLEDを使えます。
どのセットでも表面実装部品はすでに実装済みです。
電源電圧
7セグLEDの電源を Arduino Nano の 5V から供給すると、VF (LED の順方向電圧)が高い青色や緑色の7セグであっても問題なく点灯できます。
しかし、電源が 3.3V の場合は VF が足りず、青色や緑色は点灯しないことがあります。
7セグLEDモジュールの電源ピンと各ピンに入力する信号の H レベルは同一としてください。
モジュールに適合する7セグLED
自前の 7セグLED を使用する際は カソードコモン 品を使用してください。7セグLEDモジュールに実装されている各セグメントの電流制限抵抗は 470Ω です。ピン配置、寸法は図を確認してください。また、モジュールの電源電圧が LEDの VF を十分上回っているか確認してください。
回路
回路図 | # | ピン名 | 説明 |
1, 9 | VDD | 5V または 3.3V | |
2, 10 | GND | グランド | |
3 | SCK | クロック入力 | |
4 | SDI | シリアル入力 | |
5 | SDO | シリアル出力 | |
6 | MR# | リセット | |
7 | LATCH | ラッチ入力 | |
8 | OE | 出力有効化 |
モジュールには 10 本のピンがあります。2本ずつある VDD と GND はどちらか1本ずつ接続すれば十分です。
1桁だけ点灯する場合は、太字で示した SCK, SDI, LATCH の3本のみを通信用のピンとして使います。
2桁以上の場合はさらに、SDO ピンを使い、次の桁の SDI ピンと接続します。
MR#, OE ピンは未接続で構いません。
SPI接続の場合
回路図 | Arduino側ピン | モジュール側ピン | 説明 |
5V または 3V3 | VDD | ||
GND | GND | ||
SCK (D13) | SCK | クロック入力 | |
MOSI (D12) | SDI | シリアル入力 | |
D9 | LATCH | ラッチ入力 (どのピンでも可) |
SPI の割り当てがあるピンへ SCK, SDI を接続します。LATCH は /SS (D10)以外のピンに接続してください。
GPIO接続の場合
回路図 | Arduino側ピン | モジュール側ピン | 説明 |
5V または 3V3 | VDD | ||
GND | GND | ||
D4 | SCK | クロック入力 (どのピンでも可) | |
D5 | SDI | シリアル入力 (どのピンでも可) | |
D9 | LATCH | ラッチ入力 (どのピンでも可) |
SCK, SDI, LATCH はお好きなGPIOピンに接続してください。
スケッチ
秋月電子のサイトで用意されているサンプルプログラムを参考に、専用のライブラリ ae7seg を作りました。ライブラリをインストール後、ヘッダファイル ae7seg.h
をインクルードしてください。
#include "ae7seg.h"
SPI と GPIO とでは宣言の仕方が異なるだけで、以降の関数の呼び出しは全く同じです。
SPI接続の場合
AE7SEGSPI
を使用してください。コンストラクタにはどのピンを LATCH として使うかを指定します。
SDI, SCK はそれぞれ、SPI の MOSI, SCK に対応します。MISO, /SS は使用しません。
#include "ae7seg.h"
#define PIN_LATCH 9
AE7SEGSPI ae7seg(PIN_LATCH);
GPIO接続の場合
AE7SEGGPIO
を使用してください。コンストラクタにはどのピンを LATCH, SDI, SCK として使うかを指定します。
#include "ae7seg.h"
#define PIN_SDI 5
#define PIN_SCK 4
#define PIN_LATCH 9
AE7SEGGPIO ae7seg(PIN_LATCH, PIN_SDI, PIN_SCK);
以下、簡略化のために AE7SEGSPI
を使い、LATCH ピンとして 9 を指定したプログラム例を示しますが、GPIO として使う場合は適宜読み替えてください。
例: カウンタのスケッチ
0 から 9 までの数字を表示します。
数字を表示するには、beginWrite()
と endWrite()
の間に writeNumber(number)
を呼びます。
#include "ae7seg.h"
#define PIN_LATCH 9
#define INTERVAL 1000
AE7SEGSPI ae7seg(PIN_LATCH);
void setup() {}
void loop() {
static uint16_t count = 0;
ae7seg.beginWrite();
ae7seg.writeNumber(count % 10);
ae7seg.endWrite();
delay(INTERVAL);
count++;
}
書き込みに成功すると、1秒ごとに数字がカウントアップしていきます。
発展
16進表示
ライブラリは16進表示にも対応しています。
実は上述のカウンタスケッチの loop()
関数内を以下のように変更すると、
void loop() {
static uint16_t count = 0;
ae7seg.beginWrite();
ae7seg.writeNumber(count % 16); // <- 0 から 15 が入るように修正
ae7seg.endWrite();
delay(INTERVAL);
count++;
}
0 から F までカウントアップするようになります。
複数桁表示
複数桁の表示にも対応しています。物理的スペースや電源の確保ができれば桁数の制限はありません。
beginWrite()
と endWrite()
の間に、必要な桁数分だけ writeNumber(number)
を呼び出すだけです。
ただし、必ず上位桁から呼び出す点に注意してください。
void loop() {
ae7seg.beginWrite();
ae7seg.writeNumber(4); // 上位桁
ae7seg.writeNumber(2); // 下位桁
ae7seg.endWrite();
}
42 と表示されます。
ドットセグメント表示
もちろんドットの表示にも対応しています。
writeNumber(number, true)
を使ってください。第二引数を指定しない場合は暗黙的にドットが非表示となります。
void loop() {
ae7seg.beginWrite();
ae7seg.writeNumber(4, true); // 上位桁, ドット表示あり
ae7seg.writeNumber(2); // 下位桁, ドット表示なし
ae7seg.endWrite();
}
4.2 と表示されます。
1/100秒タイマー
複数桁とドット表示を応用したタイマーを作ります。
モジュールを4つ使用した 1/100 秒(疑似)タイマーです。2桁目にドットを表示しています。
#define INTERVAL 10
void loop() {
static uint16_t count = 0;
ae7seg.beginWrite();
{
if (count >= 1000)
ae7seg.writeNumber((count / 1000) % 10);
else
ae7seg.clear();
ae7seg.writeNumber((count / 100) % 10, true);
ae7seg.writeNumber((count / 10) % 10);
ae7seg.writeNumber(count % 10);
}
ae7seg.endWrite();
delay(INTERVAL);
count++;
if (count >= 10000)
count = 0;
}
clear()
は全セグメントを消灯する関数です。0〜10秒までの最上位桁の消灯に使っています。
任意のセグメントの表示
writeDigit(digit)
を使うと、数字以外のセグメントの表示が行なえます。引数の digit
には8ビット整数を指定し、上位7ビットが7つのセグメントA〜G、残りの下位1ビットがドットセグメントDPに対応しています。各ビットにおいて、0
のとき消灯、1
のとき点灯します。
#define INTERVAL 100
const uint8_t FRAME[] PROGMEM = {
0b10000000,
0b01000000,
0b00000010,
0b00001000,
0b00010000,
0b00100000,
0b00000010,
0b00000100,
};
void loop() {
for (uint8_t i = 0; i < sizeof(FRAME); i++) {
ae7seg.beginWrite();
ae7seg.writeDigit(pgm_read_byte_near(FRAME + i));
ae7seg.endWrite();
delay(INTERVAL);
}
}