「夜中に目が覚めた時、もう一寝入りするか、そろそろ起きるか、知りたくなりますね。身動きせずにねぼけた目を開けるだけで時刻がわかる大きなデジタル時計が欲しいと思いました。日中は明るくカラフルで楽しい表示でも、暗くなったらまぶしくない明るさで落ち着いた色で表示してくれる時計があったらいいですね。」
2年前に作った「手作りの大型7セグメントフルカラー表示器を使った置き時計」はその後もブレッドボードのまま動作を続けています。壁に掛けられるようにリメークしようかと思いましたが、大きなサイズのフルカラーLEDマトリックスが3699円で売っていたので、これを使った方が楽にできると思って新しく作ることにしました。
構成
(1) ESP32でWiFi LANに接続し、NTPで時刻を定期的に取得する。
(2) ESP32でTimeライブラリを使い、NTP時刻で定期的に校正しながら1秒ごとに時刻を得る。
(3) ESP32でFastLEDライブラリを使い、32×8 LEDマトリックスを制御する。
(4) 時刻表示用数字フォントはComic San MS Bold Italic 96pointをベースにして8×7のグレースケールフォントを自作する。
部品リスト
(1) ESP32(MH-ET LIVE ESP32 MiniKit):AliExpressで$6ぐらいで購入できます。
(2) フルカラーLEDマトリックス(32×8 10mmピッチ):Quimat Arduino用RGB LED パネル…..
配線
ESP32 MiniKit-J2-6pin(5V) —– LED Matrix 5V
ESP32 MiniKit-J2-8pin(GND) —– LED Matrix GND
ESP32 MiniKit-J2-10pin(IO16) —– LED Matrix Din
Arduino IDEへの追加
ESP32ボードの追加 「Arduinoで遊ぶページ」などを調べてください。
FastLEDライブラリの追加 「ArduinoでNeopixel操作」などを調べてください。
Arduinoプログラム
青色で1秒ごとに時刻を表示するプログラムです。
– NTPサーバーに300秒ごとにアクセスしますが、loop()関数の if(SecCount>=xxxx)で自由に変更してください。
– FastLEDライブラリは高度な色指定ができますので自由に改造してください。
– フォントデータは、3次元配列 NumFont[10][FontHeight][FontWidth]です。好きなフォントに改造してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
#include <WiFi.h> #include "time.h" const char* ssid = "YourSSID"; const char* password = "YourPWD"; const char* ntpServer = "ntp.nict.jp"; const long gmtOffset_sec = 9*3600; const int daylightOffset_sec = 0; int SecCount=300; //------------------------------ #include <FastLED.h> #define DATA_PIN 16 #define WIDTH 32 #define HEIGHT 8 #define NUM_LEDS (WIDTH * HEIGHT) CRGBArray<NUM_LEDS> leds; int Pos[HEIGHT][WIDTH]; const int FontWidth=7; const int FontHeight=8; const int ColWidth=2; byte ColonFont[FontHeight][ColWidth]={{0,0},{0,80},{80,80},{0,0},{0,0},{0,80},{80,80},{0,0}}; byte NumFont[10][FontHeight][FontWidth]={ //-0- {{0,0,50,90,90,50,0},{0,40,90,40,50,100,30},{10,90,30,0,0,95,40},{30,100,10,0,0,100,40}, {50,90,0,0,20,100,30},{50,90,0,0,50,80,0},{30,100,50,40,90,40,0},{0,60,100,90,40,0,0}}, //-1- {{0,0,0,40,80,0,0},{0,0,50,100,80,0,0},{0,0,30,70,70,0,0},{0,0,0,80,50,0,0}, {0,0,0,90,40,0,0},{0,0,20,100,20,0,0},{0,20,50,100,30,0,0},{0,70,90,90,70,0,0}}, //-2- {{0,0,20,60,70,50,0},{0,30,90,70,70,100,30},{0,20,20,0,20,100,20},{0,0,0,30,80,60,0}, {0,10,70,90,50,10,0},{0,70,70,0,0,0,0},{30,100,50,50,60,20,0},{30,90,90,90,90,40,0}}, //-3- {{0,0,30,70,90,50,0},{0,10,90,50,60,100,30},{0,0,0,10,30,100,20},{0,0,40,100,100,50,0}, {0,0,10,30,70,80,0},{0,20,0,0,50,90,0},{10,100,50,40,80,60,0},{0,50,90,90,50,0,0}}, //-4- {{0,0,0,0,40,80,20},{0,0,0,40,100,100,10},{0,0,30,90,70,90,0},{0,20,80,50,60,70,0}, {20,70,90,50,80,70,30},{30,70,80,80,100,90,40},{0,0,0,10,100,30,0},{0,0,0,20,90,20,0}}, //-5- {{0,30,100,100,100,100,60},{0,50,90,20,20,20,0},{0,70,90,90,100,60,0},{0,90,70,30,30,100,30}, {0,40,20,0,10,100,30},{0,10,0,0,40,100,10},{40,80,50,50,90,40,0},{20,70,90,80,40,0,0}}, //-6- {{0,0,0,3,70,40,0},{0,0,40,90,60,0,0},{0,20,90,60,10,0,0},{0,70,100,100,100,60,0}, {0,100,60,20,40,100,20},{10,100,20,0,20,100,20},{10,100,50,10,60,60,0},{0,60,100,100,70,20,0}}, //-7- {{40,90,90,90,90,90,40},{20,30,40,40,90,70,20},{0,0,0,60,80,20,0},{0,0,40,100,40,0,0}, {0,10,80,60,0,0,0},{0,60,80,10,0,0,0},{20,100,30,0,0,0,0},{40,70,0,0,0,0,0}}, //-8- {{0,0,30,70,90,60,10},{0,20,90,60,50,100,30},{0,40,90,10,30,100,20},{0,30,100,100,100,60,0}, {0,60,80,50,70,90,10},{20,100,20,0,30,100,20},{30,100,40,20,70,80,0},{0,60,90,90,70,20,0}}, //-9- {{0,20,60,100,100,60,0},{0,70,60,10,30,100,40},{20,100,20,0,0,100,40},{20,100,60,20,50,100,20}, {0,50,100,100,100,70,0},{0,0,0,50,100,30,0},{10,30,50,100,40,0,0},{40,90,70,20,0,0,0}} }; void setup() { Serial.begin(115200); //connect to WiFi Serial.printf("Connecting to %s ", ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(" CONNECTED"); configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); printLocalTime(); //--------------- FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS); LEDS.setBrightness(150); setPosArray(); clearDisplay(); delay(3000); } void loop(){ if(SecCount>=300){ configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); Serial.print("Updated to "); printLocalTime(); SecCount=0; } printLocalTime(); SecCount=SecCount+1; delay(1000); } void printLocalTime(){ struct tm timeInfo; getLocalTime(&timeInfo); int time_h=timeInfo.tm_hour;; int time_m=timeInfo.tm_min; int time_s=timeInfo.tm_sec; Serial.print(time_h); Serial.print(":"); Serial.print(time_m); Serial.print(":"); Serial.println(time_s); int h1=time_h/10; int h0=time_h%10; int m1=time_m/10; int m0=time_m%10; clearDisplay(); delay(10); //showTime(2,3,4,8); showTime(h1,h0,m1,m0); } void showTime(int h1,int h0,int m1, int m0){ static uint8_t hue=180; int PosH1=1; int PosH0=8; int PosCol=15; int PosM1=17; int PosM0=24; //Hour1 for(int j=0;j<FontWidth;j++){ for(int i=0; i < FontHeight; i++){ byte FontBrightness=NumFont[h1][i][j]; int led_num=Pos[i][j+PosH1]; leds[led_num] = CHSV(hue,255,FontBrightness); } FastLED.show(); delay(10); } //Hour0 for(int j=0;j<FontWidth;j++){ for(int i=0; i < FontHeight; i++){ byte FontBrightness=NumFont[h0][i][j]; int led_num=Pos[i][j+PosH0]; leds[led_num] = CHSV(hue,255,FontBrightness); } FastLED.show(); delay(10); } //: for(int j=0;j<ColWidth;j++){ for(int i=0; i < FontHeight; i++){ byte FontBrightness=ColonFont[i][j]; int led_num=Pos[i][j+PosCol]; leds[led_num] = CHSV(hue,255,FontBrightness); } FastLED.show(); delay(10); } //Min1 for(int j=0;j<FontWidth;j++){ for(int i=0; i < FontHeight; i++){ byte FontBrightness=NumFont[m1][i][j]; int led_num=Pos[i][j+PosM1]; leds[led_num] = CHSV(hue,255,FontBrightness); } FastLED.show(); delay(10); } //Min0 for(int j=0;j<FontWidth;j++){ for(int i=0; i < FontHeight; i++){ byte FontBrightness=NumFont[m0][i][j]; int led_num=Pos[i][j+PosM0]; leds[led_num] = CHSV(hue,255,FontBrightness); } FastLED.show(); delay(10); } } void setPosArray(){ for(int i=0; i < HEIGHT; i++){ for(int j=0; j < WIDTH; j++){ if(i%2==0){ Pos[i][j]=i*WIDTH+j; } else{ Pos[i][j]=(i+1)*WIDTH-j-1; } } } } void clearDisplay(){ for(int i=0;i<NUM_LEDS;i++){ leds[i] = CRGB::Black; } FastLED.show(); } |