とある実験のーと

趣味ブログ

Arduino MKR WiFi 1010(WiFININAライブラリ)で時間取得

時間取得はNTPCliant.hライブラリを用いてNTPサーバーにアクセスし取得するのが一般的だが、MKR WiFi 1010に積んでるモジュールからシンプルに時間を取得できる。コードがとても簡素化できる。WiFiに接続するときはCurrent Time情報が必要とのことで、WiFiモジュールはその情報を保持していてそれを引っ張ってこれるらしい。

reference.arduino.cc

下にコード全文を載せているが、至ってシンプルで

  • WiFiNINAライブラリのWiFi.getTime()関数を呼び、それに日本の時差(9時間分)を加算するだけ

である。余計なライブラリは必要無し。

//Time
 unsigned long epochTimeWiFi =WiFi.getTime()+3600*9; //時差9時間分をエポック秒にプラス

あとの、エポック秒から日時フォーマットへの変更は以下のブログのコードを拝借しました。

NTPサーバーに繋いで時間も取得してみましたが、全く同じ値だったのでまず問題無いかと思います。

終わり。

101010.fun

#include <SPI.h>
#include <WiFiNINA.h>

#include "arduino_secrets.h" 
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;        // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;                                // your network key index number
int status = WL_IDLE_STATUS;                     // the WiFi radio's status


void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WEP network, SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, keyIndex, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
  // once you are connected :
  Serial.print("You're connected to the network");
  printCurrentNet();
  printWifiData();

}

void loop() {
  // check the network connection once every 10 seconds:
  delay(5000);

//Time
 unsigned long epochTimeWiFi =WiFi.getTime()+3600*9; //時差9時間分をエポックタイムにプラス
 String formattedDateWiFi=getFormattedDate(epochTimeWiFi);

   Serial.print(epochTimeWiFi);
    Serial.print("  ");
    Serial.println(formattedDateWiFi);

}

void printWifiData() {
  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
  Serial.println(ip);

  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  printMacAddress(mac);
}

void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  printMacAddress(bssid);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);

  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption, HEX);
  Serial.println();
}

void printMacAddress(byte mac[]) {
  for (int i = 5; i >= 0; i--) {
    if (mac[i] < 16) {
      Serial.print("0");
    }
    Serial.print(mac[i], HEX);
    if (i > 0) {
      Serial.print(":");
    }
  }
  Serial.println();
}

/**
 *エポックタイムを元に現在時刻を整形して返す(ex: 2022-10-31T19:00:48Z)
 *
 */
String getFormattedTime(unsigned long secs) {
    unsigned long rawTime = secs;
    unsigned long hours = (rawTime % 86400L) / 3600;
    String hoursStr = hours < 10 ? "0" + String(hours) : String(hours);

    unsigned long minutes = (rawTime % 3600) / 60;
    String minuteStr = minutes < 10 ? "0" + String(minutes) : String(minutes);

    unsigned long seconds = rawTime % 60;
    String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds);

    return hoursStr + ":" + minuteStr + ":" + secondStr;
}

String getFormattedDate(unsigned long secs) {
  #define LEAP_YEAR(Y) ((Y > 0) && !(Y % 4) && ((Y % 100) || !(Y % 400)))
    unsigned long rawTime = secs / 86400L;  // in days
    unsigned long days = 0, year = 1970;
    uint8_t month;
    static const uint8_t monthDays[] = {31, 28, 31, 30, 31, 30,
                                        31, 31, 30, 31, 30, 31};

    while ((days += (LEAP_YEAR(year) ? 366 : 365)) <= rawTime) year++;
    rawTime -=
        days - (LEAP_YEAR(year)
                    ? 366
                    : 365);  // now it is days in this year, starting at 0
    days = 0;
    for (month = 0; month < 12; month++) {
        uint8_t monthLength;
        if (month == 1) {  // february
            monthLength = LEAP_YEAR(year) ? 29 : 28;
        } else {
            monthLength = monthDays[month];
        }
        if (rawTime < monthLength) break;
        rawTime -= monthLength;
    }
    String monthStr =
        ++month < 10 ? "0" + String(month) : String(month);  // jan is month 1
    String dayStr = ++rawTime < 10 ? "0" + String(rawTime)
                                   : String(rawTime);  // day of month
    return String(year) + "-" + monthStr + "-" + dayStr + "T" +
           getFormattedTime(secs) + "Z";
}