//board-esp32-devkit-c-v4
//ESP32-DevKitC V4
//https://docs.espressif.com/projects/esp-idf/en/stable/esp32/hw-reference/esp32/get-started-devkitc.html
/*
Connect:
NodeMCU -> Matrix
MOSI-D7-GPIO13 -> DIN
CLK-D5-GPIO14 -> CK
GPIO0-D3 -> CS
D6 --> DHTPIN nhietdo
*/
//#include "vn_lunar.h"
#include "Date.h"
#include "LunarConverter.h"
// #include <ESP8266WiFi.h>
#include <WiFi.h>
// #include <ESP8266WebServer.h>
#include <WebServer.h>
#include <SPI.h>
#include <DHT.h>
// #include <DHT_U.h>
#include <Adafruit_GFX.h>
#include <Adafruit_Sensor.h>
#include "Max72xxPanel.h"
#include <ArduinoJson.h>
#define DHTPIN 12 //12/IO12/D6
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE)
#include <WiFiUdp.h>
#include "NTPClient.h"
#include "TimeLib.h"
String DHT_NhietDoC = "";
String DHT_Doam = "";
const int buzzer = 17;//D1
// #include <Fonts/FreeSerif9pt7b.h>
// #include <Fonts/FreeSerif9pt7b.h>
// #include "fonts.h"
//vn_lunar solar;
// =======================================================================
// Connection data:
// =======================================================================
//const char* ssid = "HatDeFAM"; // SSID
//const char* password = "honganh123"; // PASSWORD
const char* ssid = "Wokwi-GUEST"; // SSID
const char* password = ""; // PASSWORD
String weatherKey = "openweathermap API"; // openweathermap API http://openweathermap.org/api
String weatherLang = "&lang=en";
String cityID = "1597591"; //Chaweng (Ban Thung)
// =======================================================================
#include "virtuabotixRTC.h" // DS1302 RTC module library
virtuabotixRTC myRTC(7, 8, 9); // Wiring of the RTC (CLK,DAT,RST) //D0, D1, D2
#define LED 7 //Led nodeMCU main D4
WiFiClient client;
String weatherMain = "";
String weatherDescription = "";
String weatherLocation = "";
String country;
int humidity;
int pressure;
//float temp;
//float tempMin, tempMax;
//int clouds;
float windSpeed;
String date;
String currencyRates;
String weatherString;
long period;
int offset = 1, refresh = 0;
int pinCS = 0; // การเชื่อมต่อขา CS
int numberOfHorizontalDisplays = 4; // จำนวนอาร์เรย์ LED แนวนอน
int numberOfVerticalDisplays = 1; // จำนวนของ LED อาร์เรย์แนวตั้ง
String decodedMsg;
Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);
//matrix.cp437(true);
int wait = 60; // ความเร็วของการวิ่ง
int spacer = 1;
int width = 5 + spacer; // width and space chacater
bool ledState = false;
bool is_Error_RTC = false;
char buffer[80];
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "asia.pool.ntp.org");
void setup(void) {
Serial.begin(115200);
dht.begin();
pinMode(LED, OUTPUT);
delay(100);
digitalWrite(LED, LOW); // Turn oon the LED initially
matrix.setIntensity(8); // ความสว่าง 0-15
pinMode(buzzer, OUTPUT);
// change position defalt 8 * 8
matrix.setRotation(0, 1); // 1
matrix.setRotation(1, 1); // 2
matrix.setRotation(2, 1); // 3
matrix.setRotation(3, 1); // 4
myRTC.updateTime();
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
digitalWrite(LED, HIGH); // Turn off when connect wifi
timeClient.begin(); // Start NTP client
// Set offset time in seconds to adjust for your timezone, for example:
// GMT +1 = 3600
// GMT +8 = 28800
// GMT -1 = -3600
// GMT 0 = 0
timeClient.setTimeOffset(0);
timeClient.update(); // Retrieve current epoch time from NTP server
// unsigned long unix_epoch = timeClient.getEpochTime(); // Get epoch time
updateTimeNTF();
}
void updateTimeNTF() {
timeClient.update(); // Update time from NTP server
unsigned long unix_epoch = timeClient.getEpochTime(); // Get current epoch time
sprintf(buffer, "updateTimeNTF Time: %02d:%02d:%02d %02d/%02d/%02d", hour(unix_epoch), minute(unix_epoch), second(unix_epoch), day(unix_epoch), month(unix_epoch), year(unix_epoch));
Serial.println(buffer);
Serial.println("Dayof week : ");
unsigned long dayofweek = ((unix_epoch / 86400L) + 4) % 7;
Serial.println(dayofweek);
//myRTC.setDS1302Time(50, 59, 19, 5, 26, 1, 2020); // uncomment line, upload to reset RTC and then comment, upload.
myRTC.setDS1302Time(second(unix_epoch), minute(unix_epoch), hour(unix_epoch), dayofweek, day(unix_epoch), month(unix_epoch), year(unix_epoch)); // uncomment line, upload to reset RTC and then comment, upload.
myRTC.updateTime(); // update of variables for time or accessing the individual elements.
}
// =======================================================================
#define MAX_DIGITS 16
byte dig[MAX_DIGITS] = { 0 };
byte digold[MAX_DIGITS] = { 0 };
byte digtrans[MAX_DIGITS] = { 0 };
int updCnt = 0;
int dots = 0;
long dotTime = 0;
long clkTime = 0;
int dx = 0;
int dy = 0;
byte del = 0;
int h, m, s;
int mo, da, ye;
int am_mo, am_da, am_ye;
String view = "";
String namThanhCanChi(int year) {
String can[] = { "Canh", "Tan", "Nham", "Quy", "Giap", "At", "Binh", "Dinh", "Mau", "Ky" };
String chi[] = { "Than", "Dau", "Tuat", "Hoi", "Ty", "Suu", "Dan", "Mao", "Thin", "Ti", "Ngo", "Mui" };
int canIndex = year % 10;
int chiIndex = year % 12;
String rs = can[canIndex] + "-" + chi[chiIndex];
return rs;
}
String formartZero(int number) {
if (number < 10) {
return "0" + String(number);
}
return String(number);
}
void checkInput() {
if (Serial.available()) {
String command = Serial.readString(); // Read command from serial monitor
if (command == "a") {
} else {
if (command == "u") {
updateTimeNTF();
} else {
}
}
}
}
// =======================================================================
void DisplayTime() {
updateTime();
matrix.fillScreen(LOW);
int y = (matrix.height() - 8) / 2;
if (s & 1) {
matrix.drawChar(14, y, (String(":"))[0], HIGH, LOW, 1);
} else {
matrix.drawChar(14, y, (String(" "))[0], HIGH, LOW, 1);
}
String hour1 = String(h / 10);
String hour2 = String(h % 10);
String min1 = String(m / 10);
String min2 = String(m % 10);
String sec1 = String(s / 10);
String sec2 = String(s % 10);
int xh = 2;
int xm = 19;
// int xs = 28;
matrix.drawChar(xh, y, hour1[0], HIGH, LOW, 1);
matrix.drawChar(xh + 6, y, hour2[0], HIGH, LOW, 1);
matrix.drawChar(xm, y, min1[0], HIGH, LOW, 1);
matrix.drawChar(xm + 6, y, min2[0], HIGH, LOW, 1);
// matrix.drawChar(xs, y, sec1[0], HIGH, LOW, 1);
// matrix.drawChar(xs+6, y, sec2[0], HIGH, LOW, 1);
matrix.write();
}
// =======================================================================
void DisplayText(String text, int delaytime, int spaceDis) {
int widthSpace = 5 + spaceDis;
matrix.fillScreen(LOW);
for (int i = 0; i < text.length(); i++) {
int letter = (matrix.width()) - i * (widthSpace - 1);
int x = (matrix.width() + 1) - letter;
int y = (matrix.height() - 8) / 2;
matrix.drawChar(x, y, text[i], HIGH, LOW, 1);
matrix.write();
delay(wait);
}
delay(delaytime);
}
// =======================================================================
void ScrollText(String text) {
for (int i = 0; i < width * text.length() + matrix.width() - 1 - spacer; i++) {
if (refresh == 1) i = 0;
refresh = 0;
matrix.fillScreen(LOW);
int letter = i / width;
int x = (matrix.width() - 1) - i % width;
int y = (matrix.height() - 8) / 2;
while (x + width - spacer >= 0 && letter >= 0) {
if (letter < text.length()) {
matrix.drawChar(x, y, text[letter], HIGH, LOW, 1);
}
letter--;
x -= width;
}
matrix.write();
delay(wait);
}
}
float utcOffset = +7; //การแก้ไขเขตเวลา
long localEpoc = 0;
long localMillisAtUpdate = 0;
void getTime() {
myRTC.updateTime();
Serial.print("RTC Time: ");
sprintf(buffer, "RTC Time: %02d:%02d:%02d %02d/%02d/%02d", myRTC.hours, myRTC.minutes, myRTC.seconds, myRTC.dayofmonth, myRTC.month, myRTC.year);
Serial.println(buffer);
if (myRTC.dayofmonth == 0 || myRTC.dayofmonth > 31) {
ledState = true;
is_Error_RTC = true;
} else {
ledState = false;
is_Error_RTC = false;
}
date = String(myRTC.dayofmonth) + "/" + String(myRTC.month) + "/" + String(myRTC.year);
mo = myRTC.month;
da = myRTC.dayofmonth;
ye = myRTC.year;
h = myRTC.hours;
m = myRTC.minutes;
s = myRTC.seconds;
localMillisAtUpdate = millis();
localEpoc = (h * 60 * 60 + m * 60 + s);
checkNextDayVsUTCOffset();
Espace::Date date = Espace::Date(da, mo, ye);
Espace::LunarConverter converter = Espace::LunarConverter();
Espace::Date lunarDate = converter.Convert(date);
Serial.print(lunarDate.DayInMonth);
Serial.print("/");
Serial.print(lunarDate.Month);
Serial.print("/");
Serial.print(lunarDate.Year);
am_da = lunarDate.DayInMonth;
am_mo = lunarDate.Month;
am_ye = lunarDate.Year;
Serial.println("getTime");
return;
}
// =======================================================================r
void updateTime() {
long curEpoch = localEpoc + ((millis() - localMillisAtUpdate) / 1000);
long temp = round(curEpoch + 3600 * utcOffset + 86400L);
long epoch = temp % 86400L;
h = ((epoch % 86400L) / 3600) % 24;
m = (epoch % 3600) / 60;
s = epoch % 60;
}
void checkLighToLed() {
if (ledState == false) {
digitalWrite(LED, HIGH); // Turn off the LED
} else {
digitalWrite(LED, LOW); // Turn on the LED
}
}
void checkTimeSetLight() {
if (h > 5 && h < 18) {
setLight(3);
} else {
setLight(0);
}
}
int isUpdateEveryDay = false;
void checkTimeUpdateNTF() {
if (h == 0 && isUpdateEveryDay == true) {
updateTimeNTF();
isUpdateEveryDay = false;
} else {
isUpdateEveryDay = true;
}
}
void setLight(int number) {
matrix.setIntensity(number); // 0-15
}
void checkNextDayVsUTCOffset() {
if ((h + utcOffset) > 23) {
setTime(h, m, s, da, mo, ye); // set time to 12:00:00am Jan 1 2022
adjustTime(86400); //+1day
mo = month();
da = day();
ye = year();
}
}
String monthToAbbreviation(int month) {
switch (month) {
case 1: return "Jan";
case 2: return "Feb";
case 3: return "Mar";
case 4: return "Apr";
case 5: return "May";
case 6: return "Jun";
case 7: return "Jul";
case 8: return "Aug";
case 9: return "Sep";
case 10: return "Oct";
case 11: return "Nov";
case 12: return "Dec";
default: return "ERR";
}
}
void setDHT() {
// tone(buzzer, 1000);
// delay(1000);
// noTone(buzzer);
float h = dht.readHumidity();
float t = dht.readTemperature();
// float f = dht.readTemperature(true);//Fahrenheit,isFahrenheit = true
if (isnan(h) || isnan(t)) {
} else {
DHT_NhietDoC = String(dht.readTemperature(), 0);
DHT_Doam = String(dht.readHumidity(), 0);
}
Serial.println("NhietDo: " + DHT_NhietDoC);
Serial.println("Do Am: " + DHT_Doam);
}
// =======================================================================
void loop(void) {
checkLighToLed();
checkTimeSetLight();
checkTimeUpdateNTF();
setDHT();
if (updCnt >= 7) {
updCnt = 1;
Serial.println("Getting data ...");
getTime();
Serial.println("Data loaded 123");
clkTime = millis();
}
if (millis() - clkTime > 5000) {
updCnt++;
clkTime = millis();
}
if (mo == 0) {
getTime();
updCnt = 0;
}
matrix.setFont();
switch (updCnt) {
case 0:
ScrollText("Loading........oading.........ing");
break;
case 1:
DisplayTime();
break;
case 2:
view = formartZero(da) + '/' + formartZero(mo);
//ScrollText(view);
DisplayText(view, 5000, 2);
break;
case 3:
view = formartZero(da) + '/' + monthToAbbreviation(mo);
ScrollText(view);
break;
case 4:
DisplayText(String(ye), 5000, 4);
break;
case 5:
view = "AL:" + formartZero(am_da) + "/" + formartZero(am_mo) + "/" + am_ye;
ScrollText(view);
break;
case 6:
if(DHT_NhietDoC != ""){
view = "ND:" + DHT_NhietDoC + " DA:" + DHT_Doam;
ScrollText(view);
}else{
updCnt++;
}
break;
default:
// //ScrollText("Xin-Chao");
// matrix.setFont(&FreeSerif9pt7b);
ScrollText(namThanhCanChi(ye));
break;
}
if (millis() - dotTime > 500) {
dotTime = millis();
dots = !dots;
}
checkInput();
}