2種類のカスタムフォントで Wi-Fi NTP 時計を M5Stack に表示させてみる
では、今度はバイナリ形式カスタムフォントを使って、ESP32 の Wi-Fi 機能を使って、インターネットの NTPサーバーから時刻を定期的に補正する NTP 時計を M5Stack に表示させてみます。
バイナリ形式カスタムフォントの場合、先ほど述べたように、micro SD カードのフォントアドレス計算が簡単なので、スケッチプログラムも書きやすいです。
では、2種類作成したカスタム(自作)フォントを表示させてみたいと思います。
追加ライブラリのインストール
このブログを何度も見ている方は既に済んでいるかと思いますが、事前準備として、私の以下のライブラリを予め Arduino IDE にインストールを済ませておいてください。
ZIPファイルの Arduino IDE へのインストール方法はこちらを参照してください。
(※古いバージョンのライブラリは必ずフォルダごと削除してから再インストールしてください)
ESP32_WebGet ライブラリ
私の自作ライブラリで、NTP サーバー取得プログラムをライブラリ化しています。
https://github.com/mgo-tec/ESP32_WebGet
Time ライブラリ
Arduino 標準の時刻関連ライブラリです。
https://github.com/PaulStoffregen/Time
使用するカスタム(自作)フォント
自分で作ったバイナリ形式カスタムフォントを2種類作って置きます。
ここでは、先ほどダウンロードしたファイルの中に同梱されている以下の私の自作フォントを例に使ってみます。
MyFont_ver3.0.fnt MyFont.fnt
これを micro SD カードの /font/ フォルダにコピーしておいてください。
スケッチの入力
M5Stack とパソコンを接続し、Arduino IDE を起動し、以下のスケッチを入力してみてください。
【ソースコード】 (※無保証 ※PCの場合、ダブルクリックすればコード全体を選択できます)
#include "ESP32_LCD_ILI9341_SPI.h" //beta ver 1.25- #include "ESP32_WebGet.h" //beta ver 1.12- #include "TimeLib.h" //Use Arduino time library ver1.5- #include <SD.h> const int8_t sck = 18; // SPI clock pin const int8_t miso = -1; // MISO(master input slave output) don't using const int8_t mosi = 23; // MOSI(master output slave input) pin const int8_t cs = 14; // Chip Select pin const int8_t dc = 27; // Data/Command pin const int8_t rst = 33; // Reset pin const int8_t LCD_LEDpin = 32; const uint8_t CS_SD = 4; //SD card CS ( Chip Select ) const char* ssid = "xxxxxxxx"; //ご自分のルーターのSSIDに書き換えてください const char* password = "xxxxxxxx"; //ご自分のルーターのパスワードに書き換えてください ESP32_LCD_ILI9341_SPI LCD(sck, miso, mosi, cs, dc, rst, LCD_LEDpin); ESP32_WebGet _EWG; const char* my_fontfile1 = "/font/MyFont_ver3.0.fnt"; const char* my_fontfile2 = "/font/MyFont.fnt"; File _MyF1, _MyF2; const uint8_t MAX_TXT_NUM = 3; //文字列表示最大列数 uint8_t test_buf[ MAX_TXT_NUM ][ 20 ][ 16 ] = {}; uint16_t test_sj_len[ MAX_TXT_NUM ] = {}; uint8_t num = 0; //文字列番号 uint8_t X0 = 0, Y0 = 0; uint8_t H_size = 2, V_size = 4; //H_size(水平方向サイズ)、V_size(垂直方向文字サイズ) uint8_t Fnt_Cnt = 0; //半角相当フォントカウント uint8_t red = 31, green = 63, blue = 31; uint8_t bg_red = 0, bg_green = 0, bg_blue = 0; uint32_t LastTime = 0; uint32_t NTPget_LastTime = 0; void setup() { Serial.begin(115200); delay(1000); LCD.ILI9341_Init(false, 40000000); //※M5StackでSDカードと併用する場合は必ずfalseにすること LCD.Display_Clear(); LCD.Brightness(255); //LCD LED Full brightness SD.begin(CS_SD, SPI, 40000000, "/sd"); _MyF1 = SD.open(my_fontfile1, FILE_READ); if (!_MyF1) { Serial.print(my_fontfile1); Serial.println(" File not found"); return; }else{ Serial.print(my_fontfile1); Serial.println(" File read OK!"); } _MyF2 = SD.open(my_fontfile2, FILE_READ); if (!_MyF2) { Serial.print(my_fontfile2); Serial.println(" File not found"); return; }else{ Serial.print(my_fontfile2); Serial.println(" File read OK!"); } //--------Wi-Fiアクセスポイント接続--------- Serial.println(); Serial.print(F("Connecting to ")); Serial.println(ssid); _EWG.EWG_AP_Connect(ssid, password); //Wi-Fi ルーターと接続 delay(1000); _EWG.EWG_NTP_TimeLib_init(9, "time.windows.com"); //NTPサーバー取得初期化 _EWG.NTP_OtherServerSelect(9); //NTPサーバーと接続できなかった場合、他のNTPサーバーと接続できるか試す関数 delay(1000); LastTime = millis(); NTPget_LastTime = millis(); } void loop() { if( LastTime != now() ){ num = 0; red = 0, green = 63, blue = 0; bg_red = 0, bg_green = 0, bg_blue = 0; X0 = 0, Y0 = 0; MyFont_Watch_DisplayOut(_MyF1, num, X0, Y0, red, green, blue, bg_red, bg_green, bg_blue); num = 1; red = 31, green = 63, blue = 31; bg_red = 0, bg_green = 0, bg_blue = 31; X0 = 0, Y0 = 80; MyFont_Watch_DisplayOut(_MyF1, num, X0, Y0, red, green, blue, bg_red, bg_green, bg_blue); num = 2; red = 31, green = 0, blue = 31; bg_red = 31, bg_green = 63, bg_blue = 31; X0 = 0, Y0 = 160; MyFont_Watch_DisplayOut(_MyF2, num, X0, Y0, red, green, blue, bg_red, bg_green, bg_blue); LastTime = now(); } if( millis() - NTPget_LastTime > 300000){ //5分毎にNTPサーバー時刻補正 time_t get_time = EWG_Get_Ntp_Time(); if( get_time > 0 ) setTime( get_time ); NTPget_LastTime = millis(); } } //**************************************************** void MyFont_Watch_DisplayOut(File F, uint8_t Line_Num, uint8_t x0, uint8_t y0, uint8_t Red, uint8_t Green, uint8_t Blue, uint8_t Bg_Red, uint8_t Bg_Green, uint8_t Bg_Blue ){ uint8_t hour1 = 0, hour2 = 0, min1 = 0, min2 = 0, sec1 = 0, sec2 = 0; if( hour() < 10 ){ hour1 = 0; hour2 = hour(); }else{ hour1 = hour() / 10; hour2 = hour() % 10; } if( minute() < 10 ){ min1 = 0; min2 = minute(); }else{ min1 = minute() / 10; min2 = minute() % 10; } if( second() < 10 ){ sec1 = 0; sec2 = second(); }else{ sec1 = second() / 10; sec2 = second() % 10; } Serial.printf("%2d:%02d:%02d\r\n",hour(), minute(), second()); if( hour1 == 0 ){ MyFont_SD_Read(F, 2, 32, &test_buf[ Line_Num ][ 0 ]); //スペース }else{ MyFont_SD_Read(F, 2, hour1, &test_buf[ Line_Num ][ 0 ]); } MyFont_SD_Read(F, 2, hour2, &test_buf[ Line_Num ][ 2 ]); MyFont_SD_Read(F, 2, 29, &test_buf[ Line_Num ][ 4 ]); //コロン MyFont_SD_Read(F, 2, min1, &test_buf[ Line_Num ][ 6 ]); MyFont_SD_Read(F, 2, min2, &test_buf[ Line_Num ][ 8 ]); MyFont_SD_Read(F, 2, 29, &test_buf[ Line_Num ][ 10 ]); //コロン MyFont_SD_Read(F, 2, sec1, &test_buf[ Line_Num ][ 12 ]); MyFont_SD_Read(F, 2, sec2, &test_buf[ Line_Num ][ 14 ]); LCD.HVsizeUp_8x16_Font_DisplayOut(H_size, V_size, 16, x0, y0, Red, Green, Blue, test_buf[ Line_Num ], Bg_Red, Bg_Green, Bg_Blue); } //***************************************************** void MyFont_SD_Read(File F, uint8_t ZorH, uint8_t font_num, uint8_t buf[][16]){ //ZorH : 全角=2, 半角=1 F.seek(font_num * (16 * ZorH)); F.read(buf[0], 16); F.read(buf[1], 16); }
16-17行目を、ご自分のWi-Fi ルーターの環境に合わせて、SSID とパスワードを書き替えてください。
22-23行目は2つのフォントファイル名を指定しています。
107-110行目で5分毎に NTP サーバーから時刻を取得して補正しています。
このスケッチからも分かる通り、バイナリ形式のフォント番号の引数が、時刻数値に直接割り当てられるというところがミソです。
カスタムフォント番号がゼロから数値のゼロ文字を作っていけば、プログラムが簡単で済みますね。
コンパイル書き込み実行
では、コンパイル書き込み実行させてみてください。
最初に紹介した動画と同じものですが、以下の様に表示されていればOKです。
本当は以下の記事にあるように、縦スクロールする NTP 時計にしたかったのですが、これは次回に持ち越しとします。
https://www.mgo-tec.com/blog-entry-esp32-oled-ssd1331-my-font-ntp-watch.html
編集後記
いかがでしょうか?
今回は、ある方からカスタムフォントを M5Stack で作成する方法を質問されたのと相まって、自分自身も表示させたかったこともあり、この記事作成に取り掛かりましたが、作っている段階でいろいろと付け足したいことが出てきてしまって、収拾がつかなくなってしまいました。
それでもって、疲労困ぱい・・・。
いつものことですが、最近特に感じているのが、うまくまとめるということにストレスを感じて来ています。
「文章が汚くても、日本語になっていなくてもイイから、思った事を自由に書けばいい!」
と思うようになりました。
年齢を重ねると、ストレスに弱くなってきますね・・・。
スイマセン、ただ単にコンパクトにまとめることが下手なだけの愚痴でした。
ということで、今回はここまでです。
ではまた・・・。
コメント