4bit 同期カウンタIC 74HC161A をつかって、デジタル時計をつくっています。
デジタル時計はできましたが、BCD信号を出力するだけなのでわかりにくいです。とりあえず、仮に 7セグメントLED をつけて、時分を表示できるようにしました。今回は、そのメモ、ってことで。
回路図
7セグメントLED ドライバは TM1630 をつかいますので、制御は Arduino NANO で行ないます。
図1 が Arduino まわりの接続図です。
入力は、デジタル時計からの時、分の BCD データ。分は 1の位が 4桁、10の位が 3桁。時は 1の位が 4桁、10の位が 1桁です。午前/午後表示は行なっていません。
TM1630 にわたす出力は DIO、CK、STB の 3線です。
図2 は、TM1630 を使った 7セグメントLED 表示回路です。これは毎回使っている回路。ドライバ IC 1個でできるので、とっても便利です。TM1630 の取り扱いについては、過去記事を参照ください。
ということで、回路としては単純につなげただけです。
えーと、回路図はバス配線 (青色のライン) で書いてます。たとえば、図1 では、MIN00 の信号はラベル「2」でバスに入って、Arduino の D2 ピンにつながる。図2 ならば、TM1630 の SEG2/KS2 ピンからラベル「SEG2」でバスに入って、抵抗 R9 をとおって Seg-A から 7セグメントLED につながる。
そんな感じ。
スケッチ
デジタル時計からの時、分の BCD データを、7セグメントLED 4桁に表示させるだけのスケッチです。
- // Digital Clock Display v.0.1 2023.04.16 meyon
- class TM1630 {
- private:
- const byte DISPLAY_MODE = 0x00;
- const byte WRITE_REG_AUTO_ADDR = 0x40;
- const byte WRITE_REG_FIXED_ADDR = 0x44;
- const byte READ_KEY_SCAN = 0x42;
- const byte SET_DISPLAY_ADDR = 0xC0;
- const byte DISPLAY_OFF = 0x80;
- const byte DISPLAY_ON = 0x88 | 0x84;
- const byte STB_ENABLE = LOW;
- const byte STB_DISABLE = HIGH;
- const int DOT_POSITION = -1;
- const byte digit[12] = {
- 0b01111110, // 0
- 0b00001100, // 1
- 0b10110110, // 2
- 0b10011110, // 3
- 0b11001100, // 4
- 0b11011010, // 5
- 0b11111010, // 6
- 0b01001110, // 7
- 0b11111110, // 8
- 0b11011110, // 9
- 0b00000000, // 10:blank
- 0b00100000 // 11:dot
- };
- const byte dioPin = 10;
- const byte clkPin = 11;
- const byte stbPin = 12;
- const byte numberOfDigits = DISPLAY_MODE & 1 ? 5 : 4;
- const byte blank = 10;
- const byte dot = 11;
- byte gridData[];
- public:
- TM1630() {
- pinMode(dioPin, OUTPUT);
- pinMode(clkPin, OUTPUT);
- pinMode(stbPin, OUTPUT);
- gridData[numberOfDigits] = {0};
- digitalWrite(stbPin, STB_ENABLE);
- shiftOut(dioPin, clkPin, LSBFIRST, DISPLAY_MODE);
- digitalWrite(stbPin, STB_DISABLE);
- digitalWrite(stbPin, STB_ENABLE);
- shiftOut(dioPin, clkPin, LSBFIRST, WRITE_REG_AUTO_ADDR);
- digitalWrite(stbPin, STB_DISABLE);
- }
- void displayNumbers(int num) {
- int n = constrain(num, 0000, 9999);
- for (byte i = 0; i < numberOfDigits; i++) {
- int exponentialInDecimal = pow(10, i) + 0.5;
- bool zeroSuppression = (0 != i) && (DOT_POSITION < i) && (exponentialInDecimal > n);
- gridData[i] = zeroSuppression ? blank : n / exponentialInDecimal % 10;
- }
- digitalWrite(stbPin,STB_ENABLE);
- shiftOut(dioPin, clkPin, LSBFIRST, SET_DISPLAY_ADDR | 0x00);
- for (byte i = 0; i < numberOfDigits; i++) {
- shiftOut(dioPin, clkPin, LSBFIRST, digit[gridData[i]]);
- shiftOut(dioPin, clkPin, LSBFIRST, DOT_POSITION == i ? digit[dot] : 0);
- }
- digitalWrite(stbPin, STB_DISABLE);
- digitalWrite(stbPin, STB_ENABLE);
- shiftOut(dioPin, clkPin, LSBFIRST, DISPLAY_ON);
- digitalWrite(stbPin, STB_DISABLE);
- }
- };
- const byte min00 = 2;
- const byte min01 = 3;
- const byte min02 = 4;
- const byte min03 = 5;
- const byte min10 = 6;
- const byte min11 = 7;
- const byte min12 = 8;
- const byte hour00 = 9;
- const byte hour01 = 14;
- const byte hour02 = 15;
- const byte hour03 = 16;
- const byte hour10 = 17;
- TM1630 ssd;
- void setup() {
- }
- void loop() {
- static byte bcd_min0 = 0;
- static byte bcd_min1 = 0;
- static byte bcd_hour0 = 0;
- static byte bcd_hour1 = 0;
- static int bcd = 0;
- bcd_min0 = digitalRead(min00);
- bcd_min0 += digitalRead(min01) << 1;
- bcd_min0 += digitalRead(min02) << 2;
- bcd_min0 += digitalRead(min03) << 3;
- bcd_min1 = digitalRead(min10);
- bcd_min1 += digitalRead(min11) << 1;
- bcd_min1 += digitalRead(min12) << 2;
- bcd_hour0 = digitalRead(hour00);
- bcd_hour0 += digitalRead(hour01) << 1;
- bcd_hour0 += digitalRead(hour02) << 2;
- bcd_hour0 += digitalRead(hour03) << 3;
- bcd_hour1 = digitalRead(hour10);
- bcd = bcd_hour1*1000;
- bcd += bcd_hour0*100;
- bcd += bcd_min1*10;
- bcd += bcd_min0;
- ssd.displayNumbers(bcd);
- delay(0);
- }
3~78行目は、TM1630 の制御部分。displayNumbers(n) に、表示したい 4桁の数値 n を渡すだけです。
80~92行目が入力ピン番号の定義。94行目は TM1630 クラスのインスタンス化。
setup() は何もすることがありません。各ピンの入力モードを明示的に宣言しておいても良いかも。出力ピンに関してはコンストラクタがやりますので、何もしなくていいです。出力ピンの定義は 31~33行目にあります。
loop() では、各入力データをべた〜っとつなげて 4桁の数値にしているだけ。129行目の delay(0) は、TM1630 の処理待ち時間です。
後記
TM1630 は、7セグメントLED の表示とともにキー入力もできるので、いろいろガジェットに利用できそうです。ライブラリもあるようなので、お好みで。
今回は、時分表示用の 7セグメントLED を、仮に、つけてみました。7セグメントLED については、以前にも試してみたのですが、ダイナミック点灯の回路 (過去記事) をつくりたいと思っています。まぁ、近いうちに。