07.T-Watchのメニュー作成


07.T-Watchのメニュー作成

説明

注意:この機種は技適が通っていません。中国で動作確認したスケッチとメモを日本で整理してブログ発信しています。

時計表示以外の動作をさせるためメニューを作成しました。

時計画面
* 時計動作はしていますが、表示はあっていません。
↓(タッチ)
メニュー画面
* 9つの中から選びます。
↓(タッチ)
各メニュー
* 戻る以外は未作成です。
↓(タッチ)
時計画面

タッチで振動モーターを動作させます。振動モーターの動作にオプションは無さそうです。

スケッチ


// 07menu.ino
// 時計画面→(タッチ)→メニュー画面→(タッチ)→各メニュー→(タッチ)→時計画面 の動作
#include "icon9.h"  // 3x3アイコンpng1枚
// 1:目覚まし時計,2:時計+手,3:袋,4:時計+wifi
// 5:太陽,6:歯車,7:トレイ,8:風車,9:戻る
#define LGFX_AUTODETECT            // 機種の自動認識
#include <LovyanGFX.hpp>           // ヘッダをinclude
#include <LGFX_AUTODETECT.hpp>     // クラス"LGFX"を用意
static LGFX lcd;                   // LGFXのインスタンスを作成
#define LILYGO_WATCH_2020_V3       // T-Watch2020v3を使用
#define LILYGO_WATCH_HAS_MOTOR     // 振動モータを使用
#include <LilyGoWatch.h>           // LilyGoWatchを使用
TTGOClass *ttgo;                   //
AXP20X_Class *power;               // 電源管理 AXP202
extern const unsigned char img[];  // 表示png画像1枚
int8_t Mcase = 0;                  // メニュー番号
int16_t x, y;                      // タッチ位置変数

void SetFont() {                            // Font等初期化関数
  ttgo = TTGOClass::getWatch();             // ttgoに略します
  ttgo->begin();                            // 本体の初期化
  lcd.init();                               // LCDの初期化
  lcd.setRotation(2);                       // 画面回転 0-3 (4-7で上下反転)
  lcd.setBrightness(128);                   // バックライト輝度 0-255(実際は256通りの輝度ではない)
  lcd.fillScreen(TFT_BLACK);                // 全画面黒
  lcd.setFont(&fonts::lgfxJapanGothic_28);  // 固定幅ゴシック体 8,12,16,20,24,28,32,36,40
  lcd.setTextColor(TFT_GREEN, TFT_BLACK);   // (緑字,黒地)
  lcd.setTextSize(1);                       // 文字サイズの倍数
  lcd.setTextWrap(true);                    // 自動折返し
}

void printBT() {                                // バッテリー残量表示関数
  lcd.setCursor(185, 0);                        // カーソル位置
  lcd.setTextSize(0.7);                         // 文字サイズ(倍)
  uint8_t per = power->getBattPercentage();     // 電池%測定
  if (power->isChargeing()) {                   // 充電中の時
    lcd.setTextColor(TFT_CYAN, TFT_BLACK);      // (水字,黒地)
    lcd.print("充");                            // 画面表示
  } else {                                      // 充電中でない時
    lcd.print(" ");                            // 画面表示
    if (per <= 20) {                            // 0-20%時
      lcd.setTextColor(TFT_RED, TFT_BLACK);     // (赤字,黒地)
    } else if (per <= 40) {                     // 21-40%
      lcd.setTextColor(TFT_YELLOW, TFT_BLACK);  // (黄字,黒地)
    } else if (per <= 80) {                     // 41-80%時
      lcd.setTextColor(TFT_GREEN, TFT_BLACK);   // (緑字,黒地)
    } else {                                    // 81-100%時
      lcd.setTextColor(TFT_WHITE, TFT_BLACK);   // (白字,黒地)
    }
  }
  lcd.printf("%3d%%", per);  // 電池%表示
  lcd.setTextSize(1);        // 文字サイズを戻す
}

void appWatch() {             // Mcase=0 時計
  lcd.fillScreen(TFT_BLACK);  // 全画面黒
  do {
    lcd.setCursor(5, 40);                     // カーソル位置
    lcd.setTextColor(TFT_GREEN, TFT_BLACK);   // (字,地)
    lcd.setFont(&fonts::Font7);               // Font 7セグ
    lcd.print(ttgo->rtc->formatDateTime());   // 時:分:秒の文字列表示
    lcd.setFont(&fonts::lgfxJapanGothic_28);  // 固定幅ゴシック体 8,12,16,20,24,28,32,36,40
    printBT();                                // バッテリー残量表示関数へ
    if (ttgo->getTouch(x, y)) {               // タッチしたら
      ttgo->motor->onec();                    // モータを振動(0.2秒程度)
      delay(250);                             // 250mS待つ 連続:-200 不連続:250-
      Mcase = 10;                             // メニューへ
    }
  } while (Mcase == 0);  // Mcaseが変わるまでループ
}

void appMenu() {                                  // Mcase=10 アイコンメニュー
  //lcd.fillScreen(TFT_BLACK);                      // 全画面黒
  lcd.drawPng((std::uint8_t *)img, 34644, 7, 7);  // png表示 (配列名,サイズ,x,y)
  delay(1);                                       // 1mS待つ
  do {
    delay(100);                  // 0.1秒待つ
    if (ttgo->getTouch(x, y)) {  // タッチしたらx,yを読取る
      ttgo->motor->onec();       // モータを振動(0.2秒程度)
      delay(250);                // 250mS待つ 連続:-200 不連続:250-
      if (y < 80) {              // 1行目なら
        if (x < 80) {            // 1行1列目なら
          Mcase = 1;             // 1へ
        } else if (x < 160) {    // 1行2列目なら
          Mcase = 2;             // 2へ
        } else {                 // 1行3列目なら
          Mcase = 3;             // 3へ
        }
      } else if (y < 160) {    // 2行目なら
        if (x < 80) {          // 2行1列目なら
          Mcase = 4;           // 4へ
        } else if (x < 160) {  // 2行2列目なら
          Mcase = 5;           // 5へ
        } else {               // 2行3列目なら
          Mcase = 6;           // 6へ
        }
      } else {                 // 3行目なら
        if (x < 80) {          // 3行1列目なら
          Mcase = 7;           // 7へ
        } else if (x < 160) {  // 3行2列目なら
          Mcase = 8;           // 8へ
        } else {               // 3行3列目なら
          Mcase = 9;           // 9へ
        }
      }
    }
  } while (Mcase == 10);  // Mcaseが変わるまでループ
}

void app1() {                              // 1.未作成
  lcd.setTextColor(TFT_WHITE, TFT_BLACK);  // (字,地)
  lcd.print("メニュー1");                  // 表示
  delay(1000);                             // 1秒待つ
  do {
    delay(100);                  // 0.1秒待つ
    if (ttgo->getTouch(x, y)) {  // タッチしたら
      ttgo->motor->onec();       // モータを振動(0.2秒程度)
      delay(250);                // 250mS待つ 連続:-200 不連続:250-
      Mcase = 0;                 // 時計画面へ
    }
  } while (Mcase == 1);  // Mcaseが変わるまでループ
}

void app2() {                              // 2.未作成
  lcd.setTextColor(TFT_WHITE, TFT_BLACK);  // (字,地)
  lcd.print("メニュー2");                  // 表示
  delay(1000);                             // 1秒待つ
  do {
    delay(100);                  // 0.1秒待つ
    if (ttgo->getTouch(x, y)) {  // タッチしたら
      ttgo->motor->onec();       // モータを振動(0.2秒程度)
      delay(250);                // 250mS待つ 連続:-200 不連続:250-
      Mcase = 0;                 // 時計画面へ
    }
  } while (Mcase == 2);  // Mcaseが変わるまでループ
}

void app3() {                              // 3.未作成
  lcd.setTextColor(TFT_WHITE, TFT_BLACK);  // (字,地)
  lcd.print("メニュー3");                  // 表示
  delay(1000);                             // 1秒待つ
  do {
    delay(100);                  // 0.1秒待つ
    if (ttgo->getTouch(x, y)) {  // タッチしたら
      ttgo->motor->onec();       // モータを振動(0.2秒程度)
      delay(250);                // 250mS待つ 連続:-200 不連続:250-
      Mcase = 0;                 // 時計画面へ
    }
  } while (Mcase == 3);  // Mcaseが変わるまでループ
}

void app4() {                              // 4.未作成
  lcd.setTextColor(TFT_WHITE, TFT_BLACK);  // (字,地)
  lcd.print("メニュー4");                  // 表示
  delay(1000);                             // 1秒待つ
  do {
    delay(100);                  // 0.1秒待つ
    if (ttgo->getTouch(x, y)) {  // タッチしたら
      ttgo->motor->onec();       // モータを振動(0.2秒程度)
      delay(250);                // 250mS待つ 連続:-200 不連続:250-
      Mcase = 0;                 // 時計画面へ
    }
  } while (Mcase == 4);  // Mcaseが変わるまでループ
}

void app5() {                              // 5.未作成
  lcd.setTextColor(TFT_WHITE, TFT_BLACK);  // (字,地)
  lcd.print("メニュー5");                  // 表示
  delay(1000);                             // 1秒待つ
  do {
    delay(100);                  // 0.1秒待つ
    if (ttgo->getTouch(x, y)) {  // タッチしたら
      ttgo->motor->onec();       // モータを振動(0.2秒程度)
      delay(250);                // 250mS待つ 連続:-200 不連続:250-
      Mcase = 0;                 // 時計画面へ
    }
  } while (Mcase == 5);  // Mcaseが変わるまでループ
}

void app6() {                              // 6.未作成
  lcd.setTextColor(TFT_WHITE, TFT_BLACK);  // (字,地)
  lcd.print("メニュー6");                  // 表示
  delay(1000);                             // 1秒待つ
  do {
    delay(100);                  // 0.1秒待つ
    if (ttgo->getTouch(x, y)) {  // タッチしたら
      ttgo->motor->onec();       // モータを振動(0.2秒程度)
      delay(250);                // 250mS待つ 連続:-200 不連続:250-
      Mcase = 0;                 // 時計画面へ
    }
  } while (Mcase == 6);  // Mcaseが変わるまでループ
}

void app7() {                              // 7.未作成
  lcd.setTextColor(TFT_WHITE, TFT_BLACK);  // (字,地)
  lcd.print("メニュー7");                  // 表示
  delay(1000);                             // 1秒待つ
  do {
    delay(100);                  // 0.1秒待つ
    if (ttgo->getTouch(x, y)) {  // タッチしたら
      ttgo->motor->onec();       // モータを振動(0.2秒程度)
      delay(250);                // 250mS待つ 連続:-200 不連続:250-
      Mcase = 0;                 // 時計画面へ
    }
  } while (Mcase == 7);  // Mcaseが変わるまでループ
}

void app8() {                              // 8.未作成
  lcd.setTextColor(TFT_WHITE, TFT_BLACK);  // (字,地)
  lcd.print("メニュー8");                  // 表示
  delay(1000);                             // 1秒待つ
  do {
    delay(100);                  // 0.1秒待つ
    if (ttgo->getTouch(x, y)) {  // タッチしたら
      ttgo->motor->onec();       // モータを振動(0.2秒程度)
      delay(250);                // 250mS待つ 連続:-200 不連続:250-
      Mcase = 0;                 // 時計画面へ
    }
  } while (Mcase == 8);  // Mcaseが変わるまでループ
}

void appReturn() {  // 9.時計画面へ戻る
  Mcase = 0;        // 時計画面へ
}

void setup() {
  SetFont();                                       // Font等初期化関数へ
  power = ttgo->power;                             // 簡単に書けるようにオブジェクトを受取る
  ttgo->motor_begin();                             // 振動モータの初期設定
  ttgo->rtc->setDateTime(2024, 8, 12, 15, 0, 53);  // RTC時刻を(年,月,日,時,分,秒)とする
}

void loop() {
  switch (Mcase) {  // 表示状態
    case 0:
      appWatch();  // 0.時計へ
      break;
    case 1:
      app1();  // 1.未作成
      break;
    case 2:
      app2();  // 2.未作成
      break;
    case 3:
      app3();  // 3.未作成
      break;
    case 4:
      app4();  // 4.未作成
      break;
    case 5:
      app5();  // 5.未作成
      break;
    case 6:
      app6();  // 6.未作成
      break;
    case 7:
      app7();  // 7.未作成
      break;
    case 8:
      app8();  // 8.未作成
      break;
    case 9:
      appReturn();  // 9.時計画面へ戻る
      break;
    case 10:
      appMenu();  // 10.メニュー画面へ
      break;
    default:  // それ以外
      break;
  }
  delay(100);                 // 100mS待つ
  lcd.fillScreen(TFT_BLACK);  // 全画面黒
}
* flash memory(6.5Mbyte)のうち、スケッチが13%使用。RAM(4.5Mbyte)のうち、global変数が0%使用、local変数で4.5Mbyte使用可能。(1000byte=1kbyteで計算)