ギガぞうDetector


2021/10/9公開

概要
現在地でギガぞうWi-Fiを使えるかどうかを判定する"ギガぞうDetector"を作りましたので公開します。
スマホを出さずともその場で手軽に利用可否がチェックできるのでギガぞうユーザの方には有用なのではないでしょうか。

主な機能

注意事項

動作説明
電源投入時はNTPで時刻を取得するようになっています。
過去に他のスケッチでWiFiの設定が行われている場合はその接続情報を利用して接続されます。
※接続情報が存在しない場合はスマホ用のESP-TOUCHアプリから設定します。(設定方法は後述)

WiFi接続が完了するとNTPサーバに接続され、時刻合わせが行われます。
続いてSSIDのスキャンが行われ、ギガぞうWiFiが利用可能な場合は"Available"、そうでない場合は"Not Available"が表示されます。
そのまま1分が経過するとスリープ状態となり、以後はボタンA押下でスリープが解除されSSIDのスキャンが実行されます。
※時刻合わせが行われるのは電源投入時のみ。

インストール
以下はM5StickC PlusのArduino開発環境が構築済みの前提です。

初期設定

M5StickC Plusの操作

・電源を投入します。
本体内部に接続設定が存在しない場合は下記のような動作をします。
SmartConfigモードが表示されている間にESP-TOUCHアプリの設定中画面を表示してください。

1.WiFi接続モード
"WiFi begin"の表示に加え1秒経過毎に.が表示され、10秒以内に接続に失敗した場合はSmartConfigモードに移行します。
2.SmartConfigモード
"Waiting for SmartConfig"表示の表示に加え1秒経過毎に#が表示され、30秒以内に設定が完了しなかった場合は再起動され1に戻ります。

ESP-TOUCHアプリの操作

下記はAndroid版アプリの例です。
・アプリを起動し、メニューからEspTouchを選択します。


・希望の接続先が表示されていることを確認してパスワードを入力し、CONFIRMボタンをタップします。


・設定中画面が表示されます。(M5StickCに"Waiting for SmartConfig"が表示されている間にこの画面を表示してください。)


・設定が完了した場合はNTPで時刻合わせが行われ、ギガぞうSSIDのスキャンに移行します。
完了画面が表示されない場合もありますが、M5StickC側が画面遷移していれば設定は完了しています。

ダウンロード
gigazo_detector_100.zip

コード(gigazo_detector.ino)
#include "FS.h"
#include "SPIFFS.h"

#define LGFX_USE_V1
#define LGFX_AUTODETECT
#include <LovyanGFX.hpp>

#define _M5DISPLAY_H_
class M5Display {};
#include <M5StickCPlus.h>

static LGFX lcd;
static LGFX_Sprite sprBat(&lcd);
static LGFX_Sprite sprTime(&lcd);

#include <WiFi.h>
#include <time.h>

const char* ntpServer = "ntp.jst.mfeed.ad.jp";
const long  gmtOffset_sec = 9 * 3600; // GMT+9(JPN)
const int   daylightOffset_sec = 0; // No DST

RTC_TimeTypeDef RTC_TimeStruct;
unsigned long setuptime;
int8_t bat_p = 0;

const char SsidName[53][40] PROGMEM = {
  "Wi2eap",
  "Beach WiFi",
  "au_Wi-Fi2",
  "0000Wi2",
  "Wi2_club",
  "Wi2premium_club",
  "Wi2",
  "Wi2premium",
  "wifi_square",
  "Wi2_free",
  "00_HAKODATE_FREE_Wi-Fi",
  "HIROSAKI_Free_Wi-Fi",
  "SENDAI_free_Wi-Fi",
  "Akita-City_WiFi",
  "Omoriyama_WiFi",
  "000free_wi-fi_yamagata",
  "SHINJO-wifi",
  "Aizu_Free_Wi-Fi",
  "Sayama_Free_Wi-Fi",
  "YokohamaTransportation_FreeWi-Fi",
  "HAKUBAVALLEY-Free-Wi-Fi",
  "otari-kankou",
  "bousai-otari",
  "tsugaike-free",
  "wireless",
  "OGAKI_FREE_Wi-Fi",
  "Hida Free Wi-Fi",
  "GUJO_Free_Wi-Fi",
  "Aichi_Free_WiFi",
  "00_NAGOYA_Free_WiFi",
  "Toyohashi_Wi-Cert",
  "KARIYA_FREE_Wi-Fi",
  "ToyotaCity_Free_Wi-Fi_app",
  "ToyotaCity_Free_Wi-Fi",
  "Anjo-City_app",
  "Tokoname City_app",
  "MiyoshiCity_Free_Wi-Fi_app",
  "Toyoyama_Free_WiFi_app",
  "KYOTO Wi-Fi",
  "KOBE Free Wi-Fi",
  "Itami_Free_Wi-Fi",
  "TOYOOKA_CITY_Free_Wi-Fi",
  "RIKUnoMINATO_FREE_Wi-Fi",
  "ASUKA_Free_Wi-Fi",
  "Tokushima_City_Wi-Fi",
  "Ehime_Free_Wi-Fi",
  "00-NAGASAKI_Free_Wi-Fi",
  "01-NAGASAKI_Free_Wi-Fi",
  "Be.Okinawa_Free_Wi-Fi",
  "OKINAWA_01",
  "Uruma_FreeWi-Fi",
  "mobilepoint",
  "mobilepoint2"
};

const char * const SsidTable[] PROGMEM = {
  SsidName[0],
  SsidName[1],
  SsidName[2],
  SsidName[3],
  SsidName[4],
  SsidName[5],
  SsidName[6],
  SsidName[7],
  SsidName[8],
  SsidName[9],
  SsidName[10],
  SsidName[11],
  SsidName[12],
  SsidName[13],
  SsidName[14],
  SsidName[15],
  SsidName[16],
  SsidName[17],
  SsidName[18],
  SsidName[19],
  SsidName[20],
  SsidName[21],
  SsidName[22],
  SsidName[23],
  SsidName[24],
  SsidName[25],
  SsidName[26],
  SsidName[27],
  SsidName[28],
  SsidName[29],
  SsidName[30],
  SsidName[31],
  SsidName[32],
  SsidName[33],
  SsidName[34],
  SsidName[35],
  SsidName[36],
  SsidName[37],
  SsidName[38],
  SsidName[39],
  SsidName[40],
  SsidName[41],
  SsidName[42],
  SsidName[43],
  SsidName[44],
  SsidName[45],
  SsidName[46],
  SsidName[47],
  SsidName[48],
  SsidName[49],
  SsidName[50],
  SsidName[51],
  SsidName[52]
};

bool isExistGigazoSsid() {
  String strBuff;
  bool findFlg = false;
  
  int n = WiFi.scanNetworks();
  if (n > 0) {
    // Any SSID found
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < sizeof(SsidTable); j++) {
        strBuff = String((char*)&(SsidTable[j]));
        
        if( strBuff.equals(WiFi.SSID(i)) ) {
          // Detect!!
          findFlg = true;
          break;
        }
      }
      if(findFlg) break;
    }
  }
  return findFlg;
}

int8_t getBatteryPercentage() {
  // Get battery voltage
  float vbat = M5.Axp.GetBatVoltage();
  float percent = (vbat - 3.2f) / (4.2f - 3.2f);
  return roundf(percent * 100.0f);
}

void setup() {
  M5.begin();
  SPIFFS.begin();
  lcd.init();
  
  M5.Axp.ScreenBreath(9);
  
  lcd.setRotation(1);
  lcd.setColorDepth(24);
  lcd.fillScreen(TFT_BLACK);

  setCpuFrequencyMhz(80);

  esp_sleep_wakeup_cause_t wakeup_reason;
  wakeup_reason = esp_sleep_get_wakeup_cause();
  switch(wakeup_reason) {
    case ESP_SLEEP_WAKEUP_EXT0:  // wake up by RTC IO
      break;
    default:  // power-on
      // connect to WiFi
      lcd.setTextFont(1);
      lcd.setCursor(0, 0);
      lcd.setTextColor(TFT_WHITE);
      lcd.setTextSize(1);

      lcd.println("WiFi begin");
      WiFi.begin();

      while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
        lcd.print(".");
        if ( 10000 < millis() ) {
          break;
        }
      }

      if ( WiFi.status() != WL_CONNECTED ) {
        WiFi.mode(WIFI_STA);
        WiFi.beginSmartConfig();
        lcd.println("");
        lcd.println("Waiting for SmartConfig");
        while (!WiFi.smartConfigDone()) {
          delay(500);
          lcd.print("#");
          
          if ( 40000 < millis() ) {
            lcd.println("");
            lcd.println("Reset");
            ESP.restart();
          }
        }
        
        lcd.println("");
        lcd.println("Waiting for WiFi");
        while (WiFi.status() != WL_CONNECTED) {
          delay(500);
          lcd.print(".");

          if ( 60000 < millis() ) {
            lcd.println("");
            lcd.println("Reset");
            ESP.restart();
          }
        }
      }

      lcd.println("");
      lcd.println("WiFi Connected.");

      // Set ntp time to local
      configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  
      // Get local time
      struct tm timeInfo;
      if (getLocalTime(&timeInfo)) {
        lcd.print("NTP : ");
        lcd.println(ntpServer);
  
        // Set RTC time
        RTC_TimeTypeDef TimeStruct;
        TimeStruct.Hours   = timeInfo.tm_hour;
        TimeStruct.Minutes = timeInfo.tm_min;
        TimeStruct.Seconds = timeInfo.tm_sec;
        M5.Rtc.SetTime(&TimeStruct);
  
        RTC_DateTypeDef DateStruct;
        DateStruct.WeekDay = timeInfo.tm_wday;
        DateStruct.Month = timeInfo.tm_mon + 1;
        DateStruct.Date = timeInfo.tm_mday;
        DateStruct.Year = timeInfo.tm_year + 1900;
        M5.Rtc.SetData(&DateStruct);
      }
      break;
  }

  lcd.drawPngFile(SPIFFS,"/scan.png", 0, 0);

  // Show battery
  bat_p = getBatteryPercentage();
  sprBat.createSprite(120, 26); // width, height
  sprBat.fillScreen(0xFFFFCCu);
  sprBat.setTextFont(4);
  sprBat.setTextSize(1);
  sprBat.setTextColor(TFT_BLACK);
  sprBat.printf("Bat: %3d%%", bat_p);
  sprBat.pushSprite(3, 100);

  // Show time
  M5.Rtc.GetTime(&RTC_TimeStruct);
  sprTime.createSprite(70, 26); // width, height
  sprTime.fillScreen(0xFFFFCCu);
  sprTime.setTextFont(4);
  sprTime.setTextSize(1);
  sprTime.setTextColor(TFT_BLACK);
  sprTime.printf("%02d:%02d", RTC_TimeStruct.Hours, RTC_TimeStruct.Minutes);
  sprTime.pushSprite(170, 100);
  
  if(isExistGigazoSsid()) {
    // Available
    lcd.drawPngFile(SPIFFS,"/ok.png", 0, 0);
  } else {
    // Not available
    lcd.drawPngFile(SPIFFS,"/ng.png", 0, 0);
  }

  // disconnect WiFi as it's no longer needed
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);

  setuptime = millis();
}

void loop() {
  M5.update();

  bat_p = getBatteryPercentage();
  sprBat.setCursor(0,0);
  sprBat.fillScreen(0xFFFFCCu);
  sprBat.printf("Bat: %3d%%", bat_p);
  sprBat.pushSprite(3, 100);
  
  M5.Rtc.GetTime(&RTC_TimeStruct);
  sprTime.setCursor(0,0);
  sprTime.fillScreen(0xFFFFCCu);
  sprTime.printf("%02d:%02d", RTC_TimeStruct.Hours, RTC_TimeStruct.Minutes);
  sprTime.pushSprite(170, 100);
  
  pinMode(GPIO_NUM_37, INPUT_PULLUP);
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_37, LOW);

  if(millis() > setuptime + 1000 * 60){ // Sleep after 1 minute.
    lcd.fillScreen(TFT_BLACK);
    //M5.Axp.SetSleep(); //Display OFF(for M5StickC)
    M5.Axp.ScreenBreath(0);    //Display OFF(for M5StickC Plus)
    esp_deep_sleep_start();
  }

  delay(1000);
}  
  


戻る