tl;dr
- 秋月電子通商の長期保存品のお買い得商品で、7セグLEDを買ったよ
- 7セグLEDを使いたくて、Grove I2Cで、簡単に制御できるデバイスを作ったよ
- 整数値をI2Cで送るとそのまま表示する機能を付けたよ
- 制御サンプルコードはM5stack Atom Liteで作ったよ、ブラウザで書き込みできて便利!
- OSHWとして公開中! Boothでキットも販売中!
秋月のお買い得品の7セグLEDを買ってしまう
秋月電子通商の秋葉原店の2階店舗には、お買い得品がいつも置かれるようになっています。 私自身も秋葉の秋月電子通商に行くと、真っ先に見に行ってしまいます。
ここで、7セグLED、白、赤、オレンジのものがお買い得品としておかれていました。 非常にお安く赤、オレンジは200円で50個程度と手に取りやすい量で得でしたが、自分は白が良いなと思い、悩んだ末176個528円の品を購入してしまいました。
秋葉秋月2階にて、一生で使い切れないくらいの7セグLEDを買ってしまった pic.twitter.com/T66uVJv52w
— 74th (@74th) December 7, 2024
これは7セグLEDを使った工作をしなければならないと思い、Groveデバイス化することを考えました。
作った7セグLEDデバイス
I2Cコントローラとしては、CH32V003を使いました。 既に、自作キーボードの左手ICや、StickPointVでI2Cコントローラとして使っているため、慣れたものです。
7セグLEDの制御
LEDの制御にはマトリックス回路を作ることにしました。
まず、7セグLED(OSL10561-LW)の内部回路は以下のようになっています。
アノード側のピンがセグメント別LEDに分かれて用意されており、カソード側がカソードコモンとして共通のピンで共通になっています。
これを、複数の7セグLEDを制御するために以下のように、マトリックスで回路を組みました。
回路図を見るとマトリックス感はないですが、アノード側が全ての7セグLEDで共通(SA〜AG、SDP)になっています。 カソードコモン側は、7セグLED毎に用意します(SEL1〜4)。
これで、以下のように制御して点灯させます。
- SA〜AG、SDPを、すべてLowにする
- SEL1をLow、SEL2〜4をHighにする
- SA〜AG、SDPを、点灯するLEDをHigh、しないものをLowにする
- 一定時間待つ(点灯時間、100us)
- SA〜AG、SDPを、すべてLowにする
- LED2〜4で2〜5を繰り返す
交互に点灯しているので実際は点滅しているわけですが、人間の目にはずっと点灯しているように見えます。いわゆるダイナミック点灯
I2Cスレーブデバイスとしての仕様
I2Cには、メッセージボックスという仕様があり、マスタからスレーブデバイスのレジスタを読み書きするように使うことがあります。このデバイスもそのように使うようにしました。
レジスターは以下の通りです。
address | R/W | reset | |
---|---|---|---|
0x00 | Direct IO for LED 1 | R/W | 0x00 |
0x01 | Direct IO for LED 2 | R/W | 0x00 |
0x02 | Direct IO for LED 3 | R/W | 0x00 |
0x03 | Direct IO for LED 4 | R/W | 0x00 |
0x10 | Number uint16 input(Upper bit) | W | 0x00 |
0x11 | Number uint16 input(lower bit) | W | 0x00 |
0x12 | Point location(0xFF is OFF) | W | 0x00 |
Direct IOの場合、各bitは以下に対応します。
基本は、DirectIOとして1byteで1LEDの状態を登録することで点灯できます。
せっかくならば、整数値を入力すると、それをそのまま表示する機能を付けました。0x10、0x11に16bit整数値を入れることで、その値がそのまま表示されるようにしました。これで、このデバイスを利用する側は7セグLEDを数字を表示するためにどうやって入力すべきか知っている必要はなくなりました。
実際のArduinoのコードでも、以下のように使えます。
// 表示する16bit整数 uint16_t num = step % 10000; // 送るメッセージ uint8_t msg[4] = {0}; msg[0] = 0x10; // 整数入力用のレジスタアドレス msg[1] = num >> 8; // 上位8bit msg[2] = num % 0x100; // 下位8bit msg[3] = 1; // 小数点の位置 printf("Num: %x,%x\n", msg[1], msg[2]); // I2Cで送信 Wire.beginTransmission(SEG7_ADDR); Wire.write(msg, 4); Wire.endTransmission();
検討したこと
今回7セグLEDへのカソード側もアノード側もMCUのピンに繋いでいます。本来はMCUのピンではなく、もっと電流が流せるようにMOSFETをつけるなどすべきでしょう。ブレッドボード上で実験していたところ、ひとまずLEDを十分に制御できそうだったので、直接MCUのピンに繋ぐことにしました。部品点数も減らせるので。
7セグLEDの制御にはTM1637などのICがあります。100円程度で購入できるため、本来であればこのようなモジュールを使うべきです。しかし、自分は全て慣れているCH32V003で制御できるようにしたいと思いました。さらに、整数値を直接入れて数字を表示できるようにしたいです。そのため、CH32V003で強行しています。
現状の問題点
前述の通り、7セグLEDの両ピンをMCUのピンに繋いでいます。そのせいか、少しリークしているのか、DPピンが点灯していないにもかかわらずほんの少し点滅しています。暗いところで見ないと分からないくらいなので、まぁ良いかとしています。
制御サンプルをM5Stack Atom Liteで作る
デバイスを作ったからには、すぐに試せるサンプルコードがあるべきです。サンプルコードを用意しようと思いました。Groveポートを持ったデバイスとして、M5Stack Atom Lite(以下Atom)を利用することにしました。
Atomは、Switch Sienceや秋月電子通商などで1,700円程度で購入することができます。更にボタン、LEDもあるため、簡単な入力やインジケータとしても機能します。一般的なマイコン開発ボードでは、ボタンやLEDを外付けする必要がありますが、Atomであれば含まれています。
このサンプルの動画のツイートがこちらです。
Grove I2C仕様の7セグLEDモジュール、残像取り除けた!!
— 74th (@74th) December 20, 2024
小数点のところが点灯させなくても若干ちらつくが、暗いところでないとわからんレベル。しかし、点灯シグナルなしでこれだけちらつくの謎。 https://t.co/bhzjJi20Ux pic.twitter.com/oOQGotgODz
ESP32であれば、PC内にツールを入れなくても、ブラウザ経由で書き込みできるツールESP Web Toolsがあります。
PCにAtomを接続し、このWebページにアクセスして「CONNECT」を押して、インストールを進めることができます。
設計ファイルはオープンソースとして公開中
今回作成した全ては、オープンソースハードウェアとしてMITライセンスでGitHubにて公開しています。回路図や、KiCad設計ファイルもあるので、見てみてください。
キットとして販売中
この制作したデバイスを、キットとしてBoothで販売中です。良かったら入手してみてください。
使おうと思っている用途
ESP32C3-IoT-Serverに接続して、温度などを表示させたいと思います!
あと、ハンドルネームの74thが、7セグLEDで表現できると気づいて、嬉しくなりました。