以前、ESP32とGPSモジュールを使い表示にLED-MatrixPanelを使用した時計を作成しました。
(当ホームページのESP32の項目を参照)
今回は、Arduino NANOとGPSモジュールを使い、表示に18"128x160 RGB TFT-LCD(ST7735)を使いました。
このTFT-LCDは、廉価なので購入しましたが、テキストの消去に手間取りました。テキストを表示して、次のテキストを表示すると
重ねて表示されます。
ヘッダーファイルのTFT.hは、テキストのみを消去する関数がありません。
調べたところ、次の2つの方法しかないようです。
①前のテキストを消すために、同じテキスト・同じ位置で背景と同じ色のテキストを書いて前のテキストを消し、それから新たなテキストを表示する
②前のテキストが入るような背景色の四角形で塗りつぶしてから、新たなテキストを表示する。
ほかに良い方法があればよいのですが、今のところこの方法しか見つかりませんでした。今回は②の方法を使いました。
以下にその概要を記します。
GPSモジュールからデータを受信して、時間・日付・曜日を表示しています。
時・分・秒をLCDの上部に表示し、下に年・月・日・曜日を表示しています。
時・分・秒、年、日付の表示が変わるごとに、fillRect()を使って前の表示を削除しています。
1.Arduino NANO
2.GPSモジュール(GY-GPS 8M V3)
3.TFT-LCD(18"128x160 RGB TFT-LCD(ST7735)
4.降圧電源モジュール(ASM1117-3.3
このモジュールは、5Vを3.3Vにステップダウンします。
これを使用した理由は、Arduino NANOの3.3VをGPSモジュールとTFT-LCDの両方で使用すると、電流容量が大きく
LCDのチラツキが生じるため、LCDの電源は、5VからASM1117で3.3Vにステップダウンして使うようにしました。
5.ケースは、3Dプリンターで作成しました。
配線図です。(画像をコピーしてペイント等で拡大表示してください。)
「ツール」、「ライブラリを管理…」から次のライブラリをインストールします。
*TinyGPS++.hは、TinyGPSPlus by Mikal Hert
*Adafruit_GFX.hは、Adafruit GFX Library
*Adafruit_ST7735.hは、Adafruit ST7735 and ST7789 LLibrary
*TimeLib.hは、次のgithubからインストールします。
https://github.com/PaulStoffregen/Time
参考として以下に、スケッチプログラムを掲載しておきます。
秒、分、時刻の消去は、GPSから受信したgps.time.second()、gps.time.minute()、gps.time.hour()の値が変更されたときに、
fillRectで前のテキストを消去するようにしました.
電源を入れた初期段階では、LCDに表示される日付のテキストが重なって表示される
場合があるので、日付の消去は、day()とyear()が変更されたときにfillRectで前のテキストを消去するようにしました。
//Arduino GPS Clock LCD_Adafruit #include <TinyGPS++.h> #include <TimeLib.h> #include <SoftwareSerial.h> #include <Adafruit_GFX.h> #include <Adafruit_ST7735.h> TinyGPSPlus gps; #define GPS_BAUDRATE 9600 #define time_offset 32400 SoftwareSerial mySerial(3, 2); //RX,TX #define CS 10 #define DC 9 #define RST 8 Adafruit_ST7735 tft = Adafruit_ST7735(CS, DC, RST); char Timeh[] = "00"; char Timem[] = "00"; char Times[] = "00"; char DateY[] = "2000"; char Date[] = "00/00"; byte Second, Minute, Hour, Day, Month; byte last_second, last_minute, last_hour, last_day, last_month; int Year, last_year; int xoff=6; int yoff=20; void setup() { //Serial.begin(115200); mySerial.begin(GPS_BAUDRATE); tft.initR(INITR_BLACKTAB); tft.fillScreen(ST77XX_BLACK); tft.setRotation(1); tft.setTextWrap(false); } void loop() { while (mySerial.available() > 0) { if (gps.encode(mySerial.read())) { if (gps.time.isValid()) { Second = gps.time.second(); Minute = gps.time.minute(); Hour = gps.time.hour(); } if (gps.date.isValid()) { Day = gps.date.day(); Month = gps.date.month(); Year = gps.date.year(); } if(last_second != Second) { tft.fillRect(118+xoff, 12+yoff, 146+xoff, 40+yoff, ST7735_BLACK); //Clear Times last_second = Second; if(last_minute != Minute) { tft.fillRect(67+xoff, -2+yoff, 117+xoff, 32+yoff, ST7735_BLACK); //Clear Timem last_minute = Minute; } if(last_hour != Hour) { tft.fillRect(-2+xoff, -2+yoff, 56+xoff, 32+yoff, ST7735_BLACK); //Clear Timeh last_hour = Hour; } setTime(Hour, Minute, Second, Day, Month, Year); adjustTime(time_offset); // update time Times[0] = second() / 10 + '0'; Times[1] = second() % 10 + '0'; Timem[0] = minute() / 10 + '0'; Timem[1] = minute() % 10 + '0'; Timeh[0] = hour() / 10 + '0'; Timeh[1] = hour() % 10 + '0'; // update date array DateY[2] = (year() / 10) % 10 + '0'; DateY[3] = year() % 10 + '0'; Date[0] = month() / 10 + '0'; Date[1] = month() % 10 + '0'; Date[3] = day() / 10 + '0'; Date[4] = day() % 10 + '0'; if(last_day == 0 || last_day != day()) { tft.fillRect(22+xoff, 78+yoff, 150+xoff, 100+yoff, ST7735_BLACK);//Clear Date(week) last_day = day(); } if(last_year == 0 || last_year != year()) { tft.fillRect(-2+xoff, 40+yoff, 50+xoff, 62+yoff, ST7735_BLACK);//Clear Year last_year = year(); } tft.setTextColor(ST7735_YELLOW); tft.setTextSize(4); tft.setCursor(xoff, yoff); tft.println(Timeh); tft.setCursor(47+xoff, yoff); tft.println(":"); tft.setCursor(69+xoff, yoff); tft.println(Timem); tft.setTextSize(2); tft.setCursor(120+xoff, 14+yoff); tft.println(Times); tft.setCursor(24+xoff, 80+yoff); tft.println(Date); tft.setTextColor(ST7735_GREEN); tft.setCursor(xoff, 50+yoff); tft.println(DateY); print_wday(weekday()); } } } if (millis() > 5000 && gps.charsProcessed() < 10) { tft.setTextSize(2); tft.setTextColor(ST7735_RED); tft.setCursor(6, 72); tft.println("No GPSdata"); } } void print_wday(byte wday) { tft.setCursor(87+xoff, 80+yoff); switch(wday) { case 1: tft.println("(SUN)"); break; case 2: tft.println("(MON)"); break; case 3: tft.println("(TUE)"); break; case 4: tft.println("(WED)"); break; case 5: tft.println("(THU)"); break; case 6: tft.println("(FRI)"); break; default: tft.println("(SAT)"); } }