2022年12月6日火曜日

秋月電子通商 超大型4桁LED表示キット K-04380

超大型と書かれているが、先日作成した4インチ7セグLEDよりは小さい。
2.2インチの16セグLEDを7セグLEDとして利用する為の基板で、別売のマイコンデジタル時計キットと合わせて利用する前提の基板として販売されている。
2.2インチのアノードコモン16セグLEDは随分前にデジットで投げ売りされていた物を購入していて、長らく放置状態だった。
元々時計として使うつもり購入していたので、この秋月の基板もほぼ同時期に購入していたのだが、買って満足してしまって同様に放置状態。
放置される原因は概ね基板むき出しで使うのが嫌で、ケースを用意するのが面倒くさいからなのだけれど、ここ数年で3Dプリンターの利用環境が随分と良くなった事で積んだままの電子工作が捗るようになった。

今回はこの4桁LED表示キットを利用して、日付表示ユニットを作成する。まぁ、折角なのでボタンを押せば時計が表示できるようにはしておきたい。
基板の回路図は秋月の公式ページに書かれているので、そちらを参照すれば良い。
マイコンに関してはWeMOS D1 Miniの互換ボードを使用。

Arduino IDE上でのボード選択は「LOLIN(WEMOS)D1 R2 & mini」で問題無く動作した。USBのコネクターがType-Cになっているので、microUSBよりは抜挿への耐久性は期待できるかもしれない。
このボードはESP8266(ESP-12F)が使われているのでWiFiが利用できる。技適は通過しているのかどうかは分からないが、技適マークは無い。
既に無許可の海外製品だらけで汚れまくっている2.4GHz帯ではあるが、日本の法律では特定の条件を除いてFCCやCEやWi-Fi CERTIFIEDに通っていたところで、周囲に電波を出してはいけない事になっているから、電波を出す際にはその辺りを留意する事。
まぁ理屈だけで考えればアクセスポイントと繋いで使うのであれば、その周波数の波しか出ない訳で、技適に通っているAPを使って繋ぐ分には、何ら迷惑がかかる事は無いと思う。実際に計測したわけじゃないから想像でしかないけど。 たぶんUSB3.0の放射ノイズの方が酷い。

話が逸れた。今回の時計兼日付表示器の仕様としては、ESP8266を使ってNTPサーバーにアクセスして時刻を補正。 基本的に無線LANが繋がらない場所に持って行く予定は無いのでRTCは無し。 電源投入時とその後適当な間隔でNTPで時刻補正をかける事で対応する。
7セグLEDの制御はEPS8266で直接ドライブするにはピン数や電流量が足りないので、何故か10個程ストックしていたDIP仕様のTM1637というドライバーICを利用する。データシートはこちら

TM1637のDIP仕様はもう秋月では売っていなくて、amazonやaliexpressあたりで怪しげなのを買うしかない。国内流通在庫は探せばあるのかもしれないが面倒くさいので、素直にSOP仕様を購入するか、4桁までしか使わないなら、TM1630のDIP仕様を買った方が良いかもしれない。
ドライバーICを使うと抵抗とか考えなくても良くなるのが地味に有難い。

例によってラッピングワイヤーで繋ぐので、ピン配列だけ回路図で追いかけて、一覧表にまとめる。

LED_信号 TM1637 基板(K-04380) D1 mini
A 2 17  
B 3 18  
C 4 12  
D,月日LED-K 5 14  
E 6 13  
F 7 16  
G 8 15  
LED1,LED2-K 9 19  
DP   3  
DIG5(月日LED-A) 11 8  
DIG4,LED1-A 12 5,20  
DIG3 13 1  
DIG2 14 2  
DIG1 15 4  
GND 1   GND
VDD 16   5V
DIO 17   D1
CLK 18   D2
切替ボタン     D5

ドライバーICとマイコン間の接続は4芯だけなので楽だけど、ドライバーICと表示基板の間は結構接続ピン数が多い。

この秋月の基板で一か所に纏めてくれてるだけでも随分と有難いのだけれど…5台以上作るなら基板を作った方が良いかもしれない。

マイコンへのコーディングはいつも通りネット上に公開されているコードや既成ライブラリのサンプルコードのコピペ&改変。
esp8266のNTPを利用しての時間設定については、こちらのコードを拝借した。
先のページの解説によると、1時間に1回NTPサーバーに時刻を問い合わせているらしい。
今回利用したライブラリは「Seeed-Studio/Grove_4Digital_Display」と、前回に引き続き「ButtonEvents」。
Grove_4Digital_Displayについては、リンク先の説明を読めばわかるとおり、TM1637を利用した4桁7セグの時計ユニットを対象としたライブラリで、当然の事ながらそれが使いやすいような形になっているのだが、ライブラリ内の設定ファイル「TM1637.h」の最後の方に「const int DIGITS = 」という項目があって、利用桁数を変更できるようになっている。
今回はClockPoint(時計モードの際に0.5秒毎に点滅するアレ)とは別に月日表示の際にLEDを点灯させたいので、5桁目の適当なセグメントを利用する事にした。
このライブラリに付属しているClockDisplay.inoというサンプルプログラムの一部を利用してTM1637を制御する。
ClockPointの制御に関しては、DPセグメントをON/OFFしているので、秋月基板上のDPには接続せず、基板上のClockPoint(LED1,2)に接続する。
秋月基板のDPはLED4/LED6(時・分のそれぞれ一桁目)にしか接続されていないので月日表示の目印として使うには丁度良かったのだけれど、日付や時間を表示している際には、いずれのLEDも常時電圧が印加されているので、TM1637以外でGNDに落とす必要があって面倒くさかったので、別に2つLEDを用意して5桁目のアノードとDセグメントに接続した。
Dセグメントは7セグの下の横棒の事なので、5桁目を「1」や「8」に切り替えて点灯、消灯を制御している。
詳しい制御はコードを読んだ方が早いかもしれない。

#include Arduino.h
#include ESP8266WiFi.h
#include time.h
#include TM1637.h
#include ButtonEvents.h

#define WIFI_SSID   "hoge_ID"
#define WIFI_PASSWORD   "hoge_Pass"
#define JST     3600*9

#define ON 1
#define OFF 0

#define WAT 500 //ウェイト時間(ms)

// Define Digital Pins
#define CLK 4
#define DIO 5
TM1637 tm1637(CLK, DIO);

int8_t TimeDisp[] = {0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char ClockPoint = 1;
const int mdled_pin = 12; //月日LED
const int button_pin    = 14; //表示切替ボタン
unsigned char DispMode = 0;
unsigned long wattime;

ButtonEvents change_button;

void setup() {
  Serial.begin(115200);
  delay(100);
  Serial.print("\n\nReset:\n");

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while(WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(500);
  }
  Serial.println();
  Serial.printf("Connected, IP address: ");
  Serial.println(WiFi.localIP());
  configTzTime("JST-9", "ntp.nict.jp", "ntp.jst.mfeed.ad.jp");   // 2.7.0以降, esp32コンパチ
  tm1637.init();
  tm1637.set(BRIGHTEST);//BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7;
  tm1637.clearDisplay();
  pinMode(mdled_pin, OUTPUT);
  pinMode(button_pin, INPUT_PULLUP);
  change_button.attach(button_pin);
  change_button.doubleTapTime(200);
  change_button.holdTime(5000);
  wattime = millis();
}

void loop() {
  while((millis() - wattime)
    change_button.update();
    if(change_button.tapped() == true) {
      DMode();
    }
  }
  if(DispMode) {
    TimeUpdate();
  } else {
    DateUpdate();
  }
  tm1637.display(TimeDisp);
  wattime = millis();

  //time_t t;
  //struct tm *tm;
  //static const char *wd[7] = {"Sun","Mon","Tue","Wed","Thr","Fri","Sat"};
  //t = time(NULL);
  //tm = localtime(&t);
  /*Serial.printf("ESP8266/Arduino ver%s :  %04d/%02d/%02d(%s) %02d:%02d:%02d\n",
        __STR(ARDUINO_ESP8266_GIT_DESC),
        tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
        wd[tm->tm_wday],
        tm->tm_hour, tm->tm_min, tm->tm_sec);
        delay(1000); */
}

void TimeUpdate() {
  digitalWrite(mdled_pin, LOW);
  time_t t;
  struct tm *tm;
  t = time(NULL);
  tm = localtime(&t);
  ClockPoint = (~ClockPoint) & 0x01;
  if (ClockPoint) {
    tm1637.point(POINT_ON);
  } else {
    tm1637.point(POINT_OFF);
  }
    TimeDisp[0] = ((tm->tm_hour) / 10);
    TimeDisp[1] = ((tm->tm_hour) % 10);
    TimeDisp[2] = ((tm->tm_min) / 10);
    TimeDisp[3] = ((tm->tm_min) % 10);
    TimeDisp[4] = 1;
}

void DateUpdate() {
  digitalWrite(mdled_pin, HIGH);
  time_t t;
  struct tm *tm;
  t = time(NULL);
  tm = localtime(&t);
  tm1637.point(POINT_OFF);
    TimeDisp[0] = ((tm->tm_mon+1) / 10);
    TimeDisp[1] = ((tm->tm_mon+1) % 10);
    TimeDisp[2] = ((tm->tm_mday) / 10);
    TimeDisp[3] = ((tm->tm_mday) % 10);
    TimeDisp[4] = 8;
}

void DMode() {
    DispMode = (~DispMode) & 0x01;
}


各基板を収めるケースは手持ちの3Dプリンターでは一体形成品が印刷できなかったので、前回同様分割して印刷した。

今回は手抜きせずにマイコンボードを収める場所を作ったり、Type-Cのコネクターを繋いでメンテナンスができるように穴をあけたりしている。

なるべく高さを抑えたかったので、コンタクトピンを付けるにしても、高さを考えてカットする必要がある。

基板を作って直接実装してしまえば、あと3mmは追い込めるし、スッキリするから良いとは思うけれど、そこまでの完成度は求めていないからこの辺りが妥当なところだろう。
で、配線した基板とドライバーIC、ボタンスイッチをケースに入れて、グルーガンで固定。LEDが載ってる基板は更に4隅をネジ止めしておく。

あとはコレに適当な暗さのアクリル板を貼ってやれば、そこそこ見やすい時計&日付表示器になる。
因みに電源はType-CのコネクターからD1 mini互換ボードを経由し、D1 miniの5V出力をTM1637のVDDに接続している。 電流が足りるか分からなかったのだけれど、1週間以上動作させて問題無く動いているので、たぶん大丈夫なのだろう。
また、RTCを実装していないので、電源投入時に無線LANをつかみ損ねると暫く時計が初期化された状態で表示されるから、時刻補正されるまでは少し不安になるが、極力シンプルかつ安価に作りたかったので、我慢する事にしよう。

 

 

 

 

 

0 件のコメント:

コメントを投稿