齢寿天任せ

写真付きで日記や趣味を書くならgooブログ

1.28インチ丸形LCDディスプレイ(GC9A01)とESP32でデジタル時計を試作した

2023-11-24 13:47:06 | 電子工作

1.28インチの丸形LCDディスプレイ(カラー、ドライバはGC9A01)が500円位で購入できるようになったので表示装置として利用できないか調べてみることにした。インターネットで調べてみると、レポートはあまり多くない。その中で、このディスプレイの特徴を生かしたデジタル時計の製作例があったので、それを参考に試作してみた。

製作例では、RTC(リアルタイムクロック)モジュールが必須になっているが、RTCモジュールの持ち合わせは無い。以前、Seeed StudioのXIAO ESP32C3を利用して時計を作ったので、RTCの替わりにNTPから時刻を得るのはどうかということで取り組んでみた。

ディスプレイのドライバGC9A01対応のライブラリは幾つかあるが、ここでは「TFT_eSPI」を利用した。ライブラリにはサンプル例が色々あるので動作確認のために幾つか試してみると良い。このサイトが参考になる。確認には「Boing Ball」がお勧めである。

TFT_eSPIは事前に、使用するドライバとMCUに対応するための変更が必要である。ライブラリをインストールした後、「..\Arduino\libraries\TFT_eSPI」の「User_Setup.h」を編集する。

  1. 「Section 1. Call up the right driver file and any options for it」の個所に、ディスプレイ対応のドライバの定義があるので、「#define ILI9341_DRIVER」の行をコメント化し、「#define GC9A01_DRIVER」の行を「非」コメント化する。
  2. 「Section 2. Define the pins that are used to interface with the display here」の個所に、各MCUごとSPIに対するピンの定義があるのでそれを変更する。まず、ESP8266のピン定義をコメント化する。

// ###### EDIT THE PIN NUMBERS IN THE LINES FOLLOWING TO SUIT YOUR ESP8266 SETUP ######

// For NodeMCU - use pin numbers in the form PIN_Dx where Dx is the NodeMCU pin designation  ##### comment out to line 176
//#define TFT_MISO  PIN_D6  // Automatically assigned with ESP8266 if not defined
//#define TFT_MOSI  PIN_D7  // Automatically assigned with ESP8266 if not defined
//#define TFT_SCLK  PIN_D5  // Automatically assigned with ESP8266 if not defined

//#define TFT_CS    PIN_D8  // Chip select control pin D8
//#define TFT_DC    PIN_D3  // Data Command control pin
//#define TFT_RST   PIN_D4  // Reset pin (could connect to NodeMCU RST, see next line)
//#define TFT_RST  -1     // Set TFT_RST to -1 if the display RESET is connected to NodeMCU RST or 3.3V

次に、XIAO_ESP32C3に対するピン定義を追加する。


// For the XIAO_ESP32C3 module use these #define lines   with GC9A01 display ####
#define TFT_MOSI 10  // SDA
#define TFT_SCLK 8   // SCL
#define TFT_CS   3   // Chip select control pin
#define TFT_DC   5   // Data Command control pin
#define TFT_RST  4   // Reset pin (could connect to Arduino RESET pin)

なお、使用しないピン(BLK)は定義していない。接続の様子を以下に示す。

大元のスケッチは、こちら(Github)にあるが、説明は何もない。2ファイルあり、「fonts.h」はそのまま利用し、「watchESP.ino」を改修した。なお、オープンソースのライセンスが明確ではないため、Githubに載せたり、全体を紹介するのは控えることにする。

改修内容を紹介すると、「setup」においては、RTCに関係するコードと意味不明のコードをコメント化し、Wifiに接続後、NTPを参照して、XIAO_ESP32C3の時刻に設定するコードを追加している。

ここで紹介していない部分(特にwifisyncjst())は、XIAO_ESP32C3による時計の記事(上方にリンクあり)を参照するとよい。WifiのSSIDとPASSWORDは、実際にアクセスする無線LANを設定する。


void setup() {
    Serial.begin(115200);
    Serial.println("");
    delay(10);

    //if (! rtc.begin()) {
    //  Serial.println("Couldn't find RTC");
    //}
    //pinMode(2,OUTPUT);
    //pinMode(0,INPUT_PULLUP);
    //pinMode(35,INPUT_PULLUP);
    //pinMode(13,INPUT_PULLUP);

    //digitalWrite(2,0);

    //ledcSetup(pwmLedChannelTFT, pwmFreq, pwmResolution);
    //ledcAttachPin(5, pwmLedChannelTFT);
    //ledcWrite(pwmLedChannelTFT, 200);
    WiFi.mode(WIFI_STA);
    wifiMulti.addAP(ssid.c_str(), password.c_str());  
    wifiMulti.run();   // It may be connected to strong one

    while (true) {
      if(WiFi.status() == WL_CONNECTED){ break; }  // WiFi connect OK then next step
      Serial.println("WiFi Err");
      WiFi.disconnect(true);
      delay(5000);
      wifiMulti.run();
      delay(1000*60);  // Wait for Wifi ready
    }
    wifisyncjst(); // refer time and day
    WiFi.disconnect(true);  // Connection is no longer needed

    //tft.init();  ####
    tft.begin();  // initialize
    //tft.setRotation(0);
     
    //tft.setSwapBytes(true);  ####
    tft.fillScreen(TFT_WHITE); //#### BLACK
    delay(100);
        
    //img.setSwapBytes(true);
    img.setColorDepth(8);      // Create an 8bpp Sprite of 240x240 pixels
    img.createSprite(240, 240);
    img.fillSprite(TFT_BLACK); // Fill the Sprite with black
    img.setTextColor(TFT_GREEN);        // Green text
    img.setTextDatum(4);
   :
   :
}

「loop」では、XIAO_ESP32C3から時刻を得たのち、もとの「DateTime now」変数に設定するコードを追加している。

又、そのままだと何故か、曜日が1日ずれるためXIAO_ESP32C3の時刻から得た曜日を使っている。


void loop() {  
  rAngle=rAngle-2;
  //DateTime now = rtc.now();   ####
  time_t t = time(NULL);
  tm = localtime(&t);
  d_year = tm->tm_year;
  d_mon  = tm->tm_mon+1;
  d_mday = tm->tm_mday;
  d_hour = tm->tm_hour;
  d_min  = tm->tm_min;
  d_sec  = tm->tm_sec;
  d_wday = tm->tm_wday;

  //DateTime now = DateTime(1110000 + sec1);
  DateTime now = DateTime(d_year, d_mon, d_mday, d_hour, d_min,  d_sec);
  angle=now.second()*6; 
:
:
 //img.drawString(days[now.dayOfTheWeek()],circle,120,2);
 img.drawString(days[d_wday],circle,120,2);
:
:
}

 

とりあえず、手元にあったお菓子の容器に入れてみた。外側の秒表示が回転する。外側の赤い丸印は反時計回りに回転する(ただの飾りだと思われる)。ついでに、紹介しておくと、「volos projects」で検索すると、この種の色々なガジェットがyoutubeで見られる。