ESP32でntpサーバから時刻を取得して、秋月の7セグLEDに時刻を表示するサンプル


背景

ESP32を使って時刻を取得するサンプルを作ってみようと思ったのと、ついでなので埃かぶってる7セグメントLEDで表示してみようという試み。基本的にはサンプルコード組み合わせたものなのですが、秋月のセグメント、「.」の表示bitを書いてなかったりしたので、そのへんを追記したり。
※ ソフトウェアリセット、確かESP32だと別の方法じゃなきゃNGだった気がするので、リセットはかからないかもです、すみません。

This is a sample code for ESP32 to get time from NTP server and output by 7 Segment LEDs.

用意するもの

回路図

ポイントは、SDIとSDOを互い違いに配線する点、SCKとLATCHは数珠つなぎにする点、くらいでしょうか。

ソースコード

ESP32_ClockLCD.ino
/**
 * ESP32でntpサーバから時刻を取得して、秋月の7セグLED(AE-7SEG-BOARD)に時刻を表示するサンプル
 */
#include <SPI.h>
#include <WiFi.h>
#include "time.h"

//////////////////////////////
// for Wifi
const char* ssid     = "xxxxxxx";
const char* password = "xxxxxxx";

//////////////////////////////
// for NTP
const char* ntpServer          = "ntp.jst.mfeed.ad.jp";
const long  gmtOffset_sec      = 3600 * 9;
const int   daylightOffset_sec = 0;

byte nHour = 0;
byte nMin = 0;
int  nSec = 0;

//////////////////////////////
// for LEDs

#define INTERVAL  1000
#define LATCH_PIN 22

// VSPI pins
#define SCK_PIN   18 // SCLK
#define SDO_PIN   19 // MISO
#define SDI_PIN   23 // MOSI
#define CS_PIN     5 // SS

const byte digits[] = {
  0b11111100, // 0
  0b01100000, // 1
  0b11011010, // 2
  0b11110010, // 3
  0b01100110, // 4
  0b10110110, // 5
  0b10111110, // 6
  0b11100000, // 7
  0b11111110, // 8
  0b11110110, // 9
  0b00000001, // .
};

boolean dotFlag = false;
uint32_t nTimer = 0;

/**
 *
 */
void getLocalTime() {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("Failed to obtain time");
    return;
  }
  else {
    nHour = timeinfo.tm_hour;
    nMin  = timeinfo.tm_min;
    nSec  = timeinfo.tm_sec;
    if (nHour == 0 && nMin == 0 && nSec < 3) {
      ESP.restart();
    }
  }
  //Serial.println(&timeinfo, "%Y %m %d %a %H:%M:%S");
}

/**
 *
 */
void setup() {
  Serial.begin(115200);

  // setup WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" CONNECTED");

  // setup VSPI
  pinMode(LATCH_PIN, OUTPUT);
  SPI.begin(SCK_PIN, SDO_PIN, SDI_PIN, CS_PIN);
  SPI.setBitOrder(LSBFIRST);
  SPI.setDataMode(0);
  SPI.setHwCs(true);

  // setup NTP
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  getLocalTime();

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

/**
 *
 */
void loop() {
  if (millis() - nTimer > INTERVAL) {
    getLocalTime();

    digitalWrite(LATCH_PIN, LOW);
    SPI.transfer (digits[nHour / 10]); // x000
    SPI.transfer (dotFlag == true ? (digits[nHour % 10] | digits[10]) : digits[nHour % 10]); // 0x00
    SPI.transfer (digits[nMin / 10]); // 00x0
    SPI.transfer (digits[nMin % 10]); // 000x
    digitalWrite(LATCH_PIN, HIGH);

    dotFlag = !dotFlag;
    nTimer = millis();
  }
}

うごいてる動画へのリンク

youtube

参考にしたサイト

■ NTPサーバからの時刻取得
https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/Time/SimpleTime/SimpleTime.ino

■ SPIについて(今回はVSPIを使用)
https://deviceplus.jp/hobby/entry_f01/

■ 秋月の7セグメントLEDモジュール
http://akizukidenshi.com/catalog/g/gK-10194/