TM1637でLED時計を作る ~ ATOM Lite版

2022年4月15日

TM1637 Atom Lite

これまで、7セグメントLEDを使って時計表示をしてみましたが、配線が多くて4桁以上になると使いづらくて困りました。

7セグメントLED
7セグメントLEDの裏側配線

そこで、TM1637を使った7セグメントLED表示機を使って時計表示をしてみました。TM1637は、端子が4つだけで4桁表示ができます。これであれば、コンパクトなLED時計を作成できるでしょう。

まずは、ATOM Liteを使って、時計を作成してみました。

1.ライブラリの取得

Arduino IDE LIB

TM1637を簡単に操作できるライブラリを取得します。Arduino IDEライブラリ管理で「TM1637」で検索します。

関連するライブラリがいくつか出ますが、作者「Avishay Orpaz」さんのものを利用します。インストールしてください。

2.プログラム

インターネットから時刻を取得して表示します。

#include <M5Atom.h>
#include <Arduino.h>
#include <time.h>
#include <WiFi.h>
#include <TM1637Display.h>

// wifiの設定
const char* ssid     = "XXXXXXXXXXXX"; // Wi-FiのSSID
const char* password = "XXXXXXXXXXXX";  // Wi-Fiのパスワード

// 時計の設定
const char* ntpServer = "ntp.jst.mfeed.ad.jp"; // NTPサーバー
const long  gmtOffset_sec = 9 * 3600;          // 時差9時間
const int   daylightOffset_sec = 0;            // サマータイム設定なし

// #define CLK 32 // grove
// #define DIO 26 // grove
#define CLK 23
#define DIO 33

TM1637Display display(CLK, DIO);

// 表示モード
int dispmode = 0 ; // 0 : 時分 1 : 月日 2 : ---

void print_wifi_state(){
  delay(100);

  Serial.println("Wi-Fi接続完了");
  Serial.println(WiFi.localIP());

  delay(100);
 
}

void setup_wifi(){
 
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
 
  Serial.println("\nWi-Fi 接続開始");

  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
  }
 
  print_wifi_state();

}


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  
  M5.begin();

  delay(100);
  
  setup_wifi();

  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

  time_t t;
  do {
      t = time(NULL);
      delay(100);
  } while (t == 0);
  
  delay(1000);
}

void loop() {
  // put your main code here, to run repeatedly:
  M5.update();
  
  if (M5.Btn.wasPressed()) {    
    switch (dispmode) {
      case 0 :
        dispmode = 1 ;
        break ;
      case 1 :
        dispmode = 0 ;
        break ;
      default :
        dispmode = 0 ;
        break ;
    }
  } 

  display.setBrightness(0x0f);

  time_t t;
  struct tm *tm;
  t = time(NULL);

  if (t != 0) {
    tm = localtime(&t);

    switch (dispmode) {
      case 0 :
        {
        int hourmin = 0;
        hourmin = tm->tm_hour * 100 + tm->tm_min ;
        display.showNumberDecEx(hourmin, 0x40, true);
        Serial.println(hourmin);
        }
        break ;

      case 1 :
        {
        int monday = 0;
        monday = (tm->tm_mon + 1)* 100 + tm->tm_mday ;
        display.showNumberDecEx(monday, 0x00, true);
        Serial.println(monday);
        }
        break ;

      default :  
        break ;      
    
    }
  }

  delay(100); 

}

当初、時刻取得にRTCを使うつもりだったのですが、ATOM LiteにはRTCが搭載されていませんでした。プログラムがエラーになった時は何が悪いのか惑いましたが、まさかのRTC非搭載でした。しかし、よく考えればRTCを使うまでもないと思いました。

TM1637CLK端子にGPIO23を接続し、DIO端子にGPIO33を接続しています。また、TM1637の電源は3.3Vでも5Vでも良いようですが、今回は5Vを供給するようにしました。(製品によるかも)

showNumberDecEx関数で、LEDの表示をしています。最初の引数に時分を4桁の数字で入れます。

第二引数はコロンの表示で、0x40を入れます。これは位置を指定するみたいですが、購入したTM1637のコロンを表示できる場所は一つだけです。もしコロンなしで表示する時は、showNumberDec関数を使えば良いでしょう(第二引数なし)。

第三引数は上位桁の0表示をするかしないかですが、時刻の場合は分の表示がありますから、分が一桁の場合、必ず0が表示されます。よって、0表示する方が良いでしょう。

ボタンを押すことにより時分と月日が入れ替わるように変更

日付表示はコロンなし

ボタンを押すごとに時分表示と月日表示を入れ替える仕様に変更しました。それ以外の表示も考慮したコードにしました。

3.動作結果

LED watch complete

結構、明るく時刻が表示されました。明るすぎですが、setBrightness関数で明るさを調整できます。

このように、簡単にLED時計ができました。自分好みの筐体に組み込んで使いたいですね。

今回は、あくまでもテスト表示なので、実用に耐えるような機能追加が必要です。それも、それほど難しくないでしょう。また、終了処理を入れていないので、実用の際には考慮してください。

4.Groveを使った方がスッキリします

今回は、GPIO23GPIO33を使いましたが、接続をすっきりさせるためにGrove端子を使う方が良いでしょう。

Grove端子を使う場合は、CLK/DIOを以下のGPIO番号に変更します。

define CLK 32 // grove
define DIO 26 // grove

また、M5Stampを使えば、ほんとすっきりとしたLED時計を作成できると思います。ぜひ、チャレンジしてみてください。