いきなりですが、今回作ってみたのはこれです↓。
下の青いボリュームの出力をESP8266のアナログ入力に繋いで、ボリュームを回して2桁の7セグメントLEDで00~99まで表示できるようにしてみました。
使った7セグメントLEDは秋月電子で税込み90円で売っているものです。とても安いのですが、1個1個のセグメントがLEDとなっているため、1桁あたり7個で2桁だと14個のLEDを制御する必要があります。
ESP8266にはGPIOが11個しかないため、単純には制御することができません。何かいいものがないかと秋月電子のサイトを調べていたら、7セグメントドライバなるものを見つけました。1桁をBCD(2進化10進数・4ビット)で入力できるようになっているので、これを使うと4個のGPIOで済みます。これを2つ使えば2桁の7セグメントLEDを制御できるようになりますが、それではあまり面白くないので1個で済むように少し工夫してみました。
買ったもの
- 7セグメントLED表示器 高輝度赤2文字 カソードコモン C-552SRD 秋月電子
- 7セグメントドライバ(7セグメントデコーダ) CD74HC4511E 秋月電子
- DIP型厚膜ネットワーク抵抗 82Ω BDN-3-820GLF 千石電商
回路図
セグメント1個1個のLEDを制御しなくてはいけないため、ワイヤリングは結構多いです。LEDの抵抗には普通の抵抗を使っても良かったのですが、ネットワーク抵抗というものを使った方が抵抗値のバラツキがなく、桁のセグメントの輝度が揃うという記事を読んだこともあって興味本位に使ってみました。
WeMos D1 miniのD6(GPIO12)の接続先が十の位の桁のカソード(コモン)に繋がっていて、D7(GPIO13)の接続先が1の位の桁のカソード(コモン)に繋がっています。D6とD7を高速で切り替えることで、肉眼の残像現象により2桁の表示が見えるようにしています。
動作ビデオ
肉眼ではちらつきは全くみえません。
7秒ぐらいにスーパースロー表示していて、一度に片方の桁しか表示していないのがわかるようにしています。
スケッチ ※2018/5/20修正 不必要なライブラリのインクルードを削除しました。
/*
* VoltmeterLED
* May 20, 2018
* By Hiroyuki ITO
* http://intellectualcuriosity.hatenablog.com/
* MIT Licensed.
*/
// CD74HC4511
#define BCD_D1_PIN 5 // D1
#define BCD_D2_PIN 4 // D2
#define BCD_D3_PIN 0 // D3
#define BCD_D0_PIN 14 // D5
// LED
#define DIG1_C_PIN 12 // D6
#define DIG2_C_PIN 13 // D7
int digit = 0;
void dispayLED(int number) {
bool led[][4] = {
{LOW, LOW, LOW, LOW}, // 0
{LOW, LOW, LOW, HIGH}, // 1
{LOW, LOW, HIGH, LOW}, // 2
{LOW, LOW, HIGH, HIGH}, // 3
{LOW, HIGH, LOW, LOW}, // 4
{LOW, HIGH, LOW, HIGH}, // 5
{LOW, HIGH, HIGH, LOW}, // 6
{LOW, HIGH, HIGH, HIGH}, // 7
{HIGH, LOW, LOW, LOW}, // 8
{HIGH, LOW, LOW, HIGH}, // 9
};
digitalWrite(BCD_D0_PIN, led[number][3]);
digitalWrite(BCD_D1_PIN, led[number][2]);
digitalWrite(BCD_D2_PIN, led[number][1]);
digitalWrite(BCD_D3_PIN, led[number][0]);
}
void setup() {
// CD74HC4511
pinMode(BCD_D0_PIN, OUTPUT);
pinMode(BCD_D1_PIN, OUTPUT);
pinMode(BCD_D2_PIN, OUTPUT);
pinMode(BCD_D3_PIN, OUTPUT);
// LED
pinMode(DIG1_C_PIN, OUTPUT);
pinMode(DIG2_C_PIN, OUTPUT);
}
void loop() {
int number = 0;
int volume = analogRead(A0);
volume = volume * 100 / 1024;
if (volume > 99) {
volume = 99;
}
switch (digit) {
case 0: // DIG.2
number = volume % 10;
digitalWrite(DIG2_C_PIN, LOW);
digitalWrite(DIG1_C_PIN, HIGH);
digit = 1;
break;
case 1: // DIG.1
number = volume / 10;
digitalWrite(DIG1_C_PIN, LOW);
digitalWrite(DIG2_C_PIN, HIGH);
digit = 0;
break;
}
dispayLED(number);
delay(10);
}
スケッチはいたってシンプルで、工夫したところは桁を交互に表示するようにしたことと、CD74HC4511のデータシートの「FUNCTION TABLE」をledという2次元配列で定義したことぐらいです。
おわり