/*
作品名稱:物聯網時鐘
功能:
1. 連網至NTP伺服器抓取時間,並顯示於七段顯示器(共六位)
2. 計算星期,印在第七位
*/
#include <WiFi.h>
#include <iostream>
#include "pin.h"
using namespace std;
int lowArr[7] = {pin_DIG1,pin_DIG2,pin_DIG3,pin_DIG4,pin_DIG5,pin_DIG6,pin_DIG7};
int highArr[8] = {pin_A,pin_B,pin_C,pin_D,pin_E,pin_F,pin_G,pin_DP};
// 字形
int numArr[10][8] ={
{light,light,light,light,light,light,dark,dark},
{dark,light,light,dark,dark,dark,dark,dark},
{light,light,dark,light,light,dark,light,dark},
{light,light,light,light,dark,dark,light,dark},
{dark,light,light,dark,dark,light,light,dark},
{light,dark,light,light,dark,light,light,dark},
{light,dark,light,light,light,light,light,dark},
{light,light,light,dark,dark,light,dark,dark},
{light,light,light,light,light,light,light,dark},
{light,light,light,light,dark,light,light,dark},
};
// 網路設定
const char* ssid = "Your wifi ssid";
const char* password = "your password";
// 取得網路時間相關參數設定
const char* ntpServer = "time.google.com"; // Google - NTP Server
const long gmtOffset_sec = 28800; //台灣時區+8hr,28800=8*60*60
const int daylightOffset_sec = 0; //台灣無日光節約時間
void connet_wifi() {
// Connect to Wi-Fi
Serial.print("Connecting to ");
Serial.println(ssid);
//WiFi.begin(ssid, password); // 以STA(網路終端)模式連接到WiFi基地台
WiFi.begin("Wokwi-GUEST", "", 6); //wokwi提供的虛擬 WiFi 接入點
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected.");
Serial.print("IP位址: ");
Serial.println(WiFi.localIP()); // 回傳分配到的IP位址
Serial.print("WiFi RSSI: ");
Serial.println(WiFi.RSSI()); // 回傳接收訊號強度(以 dBm 為單位)
}
void set_pin_mod() {
// set pin mode
for (int p: lowArr){
pinMode(p, OUTPUT);
digitalWrite(p, 0);
}
for (int p: highArr){
pinMode(p, OUTPUT);
digitalWrite(p, 0);
}
}
void display(int pos, int number){
for (int i = 0 ; i < 7 ; i++){
digitalWrite(lowArr[i], 1);
}
for (int i = 0 ; i < 8 ; i++){
digitalWrite(highArr[i], numArr[number][i]);
}
digitalWrite(lowArr[pos], 0);
}
int scantime = 1;
int numbers = 7;
void draw(int* arr, int ms){
int start_time = millis();
while (millis() - start_time < ms){
for (int i = 0; i < numbers; i++) {
display(i, arr[i]);
delay(scantime);
}
}
}
void setup() {
Serial.begin(115200);
connet_wifi();
set_pin_mod();
// Init and get the time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
for (;;) {
printLocalTime();
}
}
void loop() {
// null
delay(1000);
}
int find_week(int year,int month,int date) {
bool is_lunar = is_lunar = (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0));
int arr[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
int day_sum;
if (is_lunar && month >= 3){
day_sum = arr[month - 1] + date + 1;
} else {
day_sum = arr[month - 1] + date ;
}
return (year + (year-5)/4 + (year-1)/400 - (year-1)/100 + day_sum) % 7;
}
void printLocalTime(){
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
return;
}
int year = timeinfo.tm_year + 1900;
int month = timeinfo.tm_mon + 1;
int date = timeinfo.tm_mday;
int week = find_week(year, month, date);
int n1 = timeinfo.tm_hour / 10;
int n2 = timeinfo.tm_hour % 10;
int n3 = timeinfo.tm_min / 10;
int n4 = timeinfo.tm_min % 10;
int n5 = timeinfo.tm_sec / 10;
int n6 = timeinfo.tm_sec % 10;
int n7 = week;
cout << n1 << n2 << ":"
<< n3 << n4 << ":"
<< n5 << n6 << "; week: " << n7 << "\n";
draw(new int [7] {n1,n2,n3,n4,n5,n6,n7}, 1000);
}