はじめに
こんにちは、ほうき星です。
みなさんは セグメントLED を制御したいと思ったことはありませんか?
私はあります。
今回 セグメントLED を自作しましたので、セグメントLED についてとその制御方法について紹介したいと思います。
セグメントLED とは
セグメントLED とは複数のLED等を組み合わせて、数字や記号等を表示できるデバイスです。
一般的なものだと 7 もしくは 8セグメントLED があり、7つの直線的に光る部分(セグメント)があり、0~9の数字と8セグメントの場合はドット( . )も表示できます。
各セグメントの名称
7 / 8セグメントLED の各セグメントは名前がついており、一番上を a とし時計回りに b、c、d...となっており、中央が g となっています。ドット( . )が表示できる部分は dt と呼ばれています。
アノードコモン / カソードコモン
セグメントLED は各セグメントに配置される LED の端子のどちらかが共通になっており、共通となる端子によって名称が異なります。
市販の セグメントLED を購入する際や後述する制御 IC 等利用する場合は、アノードコモン / カソードコモンどちらに対応しているか?を確認しておく必要があります。
アノードコモン
すべての LED のアノード( + )側が共通になっているタイプで、各セグメントのカソード( - )側を個別に制御することで点灯させる方式です。
カソードコモン
すべての LED のカソード( - )側が共通になっているタイプで、各セブメントのアノード( + )側を個別に制御することで点灯させる方式です。
自作した セグメントLED を制御する
今回はアノードコモンタイプの セグメントLED を作成しました。
(へたくそハンダが恥ずかしいですが...)
この セグメントLED をまずは ESP32S3 を使用して制御します。
回路図
今回制御する セグメントLED と ESP32S3 は次のように接続しました。
- ESP32S3 GPIO1 - セグメントLED アノード
- ESP32S3 GPIO2 - セグメントLED a
- ESP32S3 GPIO3 - セグメントLED b
- ESP32S3 GPIO4 - セグメントLED c
- ESP32S3 GPIO5 - セグメントLED d
- ESP32S3 GPIO6 - セグメントLED e
- ESP32S3 GPIO7 - セグメントLED f
- ESP32S3 GPIO8 - セグメントLED g
MicroPython で制御する
各セグメントを光らせるにはアノードと接続した GPIO ピンを HIGH に、該当のセグメントのカソードと接続した GPIO ピンを LOW にすることで、電位差が生まれ光らせられます。
逆に該当のセグメントのカソードと接続した GPIO ピンを HIGH にすることで、電位差がなくなり消灯します。
以下は MicroPython で0~9を1秒ごとに変化させるサンプルコードです。
import time
from machine import Pin
# アノード
anode: Pin = Pin(1, Pin.OUT)
anode.value(1)
# 各セグメント
segments: dict[str, Pin] = {
"a": Pin(2, Pin.OUT),
"b": Pin(3, Pin.OUT),
"c": Pin(4, Pin.OUT),
"d": Pin(5, Pin.OUT),
"e": Pin(6, Pin.OUT),
"f": Pin(7, Pin.OUT),
"g": Pin(8, Pin.OUT),
}
# 数字ごとの点灯セグメント定義
digits: dict[int, list[str]] = {
0: ["a","b","c","d","e","f"],
1: ["b","c"],
2: ["a","b","g","e","d"],
3: ["a","b","c","d","g"],
4: ["f","g","b","c"],
5: ["a","f","g","c","d"],
6: ["a","f","g","c","d","e"],
7: ["a","b","c"],
8: ["a","b","c","d","e","f","g"],
9: ["a","b","c","d","f","g"],
}
def show_digit(n: int) -> None:
# 一旦全セグメント OFF(GPIOピンをHIGHに)
for pin in segments.values():
pin.value(1)
# 点灯させるセグメントだけ ON(GPIOピンをLOWに)
for seg in digits[n]:
segments[seg].value(0)
# 0〜9を順番に1秒ごとに表示
while True:
for i in range(10):
show_digit(i)
time.sleep(1)
動作の様子はこちら
複数の セグメントLED を制御する
セグメントLEDを1つだけ制御したい場合は、前述のように GPIO ピンで制御しても困らないかもしれません。
しかし複数の セグメントLED を制御したい場合、例えば2つのセグメントLEDの場合は単純に考えると必要な GPIO ピンは16個(7セグメントLEDの場合)となります。
今回使用している ESP32S3 は GPIO ピンが11個しかなく、同様の方法では制御できません。
そこで TM1637 という IC を利用します。
TM1637 とは
TM1637 は セグメントLED を簡単に制御するためのドライバ IC です。
マイコン(例では ESP32S3)とは クロック(CLK)とデータ(DIO)の2線のみで、最大6個(桁)までの セグメントLED の制御に対応しています。
また、セグメントLED の輝度も8段階で調節可能です。
秋月電子等で購入可能でデータシートはこちらです。
TM1637 はアノードコモンタイプの セグメントLED に対応しています
回路図
今回制御する2個の セグメントLED と ESP32S3、TM1637 は次のように接続しました。
- ESP32S3 GPIO2 - TM1637 DIO
- ESP32S3 GPIO3 - TM1637 CLK
- ESP32S3 5V - TM1637 VDD
- ESP32S3 GND - TM1637 GND
- TM1637 GRID1 - セグメントLED1 アノード
- TM1637 GRID2 - セグメントLED2 アノード
- TM1637 SEG1 - セグメントLED1及び2 a
- TM1637 SEG2 - セグメントLED1及び2 b
- TM1637 SEG3 - セグメントLED1及び2 c
- TM1637 SEG4 - セグメントLED1及び2 d
- TM1637 SEG5 - セグメントLED1及び2 e
- TM1637 SEG6 - セグメントLED1及び2 f
- TM1637 SEG7 - セグメントLED1及び2 g
TM1637 を MictoPython で制御する
TM1637 を使用して セグメントLED を制御するには CLK 及び DIO へ適切な信号を送る必要がありますが、以下の MicroPython 用のライブラリが以下の git リポジトリで公開されていますので、こちらを利用します。
以下は MicroPython で0~99を1秒ごとに変化させるサンプルコードです。
import time
from machine import Pin
from tm1637 import TM1637
tmClkPin: Pin = Pin(3,Pin.OUT)
tmDioPin: Pin = Pin(2,Pin.OUT)
tm: TM1637 = TM1637(clk=tmClkPin,dio=tmDioPin)
tm.brightness(7)
count: int = 0
while True:
tm.show("{:02d}".format(count))
count += 1
if count > 99:
count = 0
time.sleep(1)
動作の様子はこちら
TM1637 の仕組み
TM1637 は前述のように複数個の セグメントLED を制御できますが、各 セグメントLED は同時に光っていません。
同時に光っているように見せるために、マルチプレクス処理を行っています。
- GRID1 をオンにし、SEG1 ~ SEG7 に セグメントLED1 で表示したいパターンを出力
- 「1」をごく短い時間だけ点灯させる
- GRID1 をオフにする
- GRID2 をオンにして、SEG1 ~ SEG7 に セグメントLED2 で表示したいパターンを出力
- 「4」をごく短い時間だけ点灯させる
- GRID2 をオフにする
- 「1」に戻る
上記サイクルを人の目では認識できないほど高速に実施するため、実際には「1桁ずつ高速に点滅しているだけ」でもすべての行が常時点灯しているように見えるという仕組みです。
さいごに
本記事では、自作した セグメントLED を ESP32S3 と TM1637 を使って制御する方法を紹介しました。
TM1637 が行っているマルチプレクス処理は、ESP32 単体でもタイマー処理などを用いて実装できますが、複数桁になると GPIO を多く消費したり、制御ロジックが複雑になりがちです。
センサや他のデバイスも接続したい場合は、今回のように専用 IC に任せてしまうのが安定性・保守性の面でも良いでしょう。
この記事が誰かの参考になれば幸いです。




