From 208f5f753451618827e89b16e3e2c0734d628a49 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Thu, 10 Jul 2025 21:48:30 +0200 Subject: [PATCH] Fixed RTC and Ethernet drivers, with NTP --- lib/ETH/ETH_Driver.cpp | 72 +++++++++++++++++++++++++++++++++++++ lib/ETH/ETH_Driver.h | 46 ++++++++++++++++++++++++ lib/RTC/PCF85063_Driver.cpp | 19 ++++++++-- lib/RTC/PCF85063_Driver.h | 4 ++- src/main.cpp | 45 ++++++++++++----------- 5 files changed, 160 insertions(+), 26 deletions(-) create mode 100644 lib/ETH/ETH_Driver.cpp create mode 100644 lib/ETH/ETH_Driver.h diff --git a/lib/ETH/ETH_Driver.cpp b/lib/ETH/ETH_Driver.cpp new file mode 100644 index 0000000..3d8ba96 --- /dev/null +++ b/lib/ETH/ETH_Driver.cpp @@ -0,0 +1,72 @@ +#include "ETH_Driver.h" + +namespace drivers +{ + + Ethernet::Ethernet(const std::string hostname) : m_hostname(hostname), m_connected(false), m_localIP(IPAddress()), m_udp(NetworkUDP()), m_timeClient(m_udp) + { + SPI.begin(ETH_SPI_SCK, ETH_SPI_MISO, ETH_SPI_MOSI); + ETH.begin(ETH_PHY_TYPE, ETH_PHY_ADDR, ETH_PHY_CS, ETH_PHY_IRQ, ETH_PHY_RST, SPI); + + m_timeClient = std::move(NTPClient(m_udp, "pool.ntp.org", 0, 3600)); // NTP server, time offset in seconds, update interval + m_timeClient.begin(); + } + + Ethernet::~Ethernet() + { + m_timeClient.end(); + ETH.end(); + SPI.end(); + } + + const bool Ethernet::getNtpTime(time_t &time) + { + if (m_connected && m_timeClient.update()) + { + time = m_timeClient.getEpochTime(); + LOG_DEBUG("Epoch Time:", (long)time); + return true; + } + return false; + } + + const bool Ethernet::isConnected() + { + return m_connected; + } + + void Ethernet::onEvent(arduino_event_id_t event, arduino_event_info_t info) + { + switch (event) + { + case ARDUINO_EVENT_ETH_START: + ETH.setHostname("waveshare-esp32s3"); + break; + case ARDUINO_EVENT_ETH_CONNECTED: + LOG_INFO("ETH Connected"); + break; + case ARDUINO_EVENT_ETH_GOT_IP: + m_localIP = ETH.localIP(); + LOG_INFO("ETH ", esp_netif_get_desc(info.got_ip.esp_netif), " Got IP:", m_localIP.toString().c_str()); + LOG_INFO("ETH ", esp_netif_get_desc(info.got_ip.esp_netif), " Gateway:", ETH.gatewayIP().toString().c_str()); + LOG_INFO("ETH ", esp_netif_get_desc(info.got_ip.esp_netif), " Netmask:", ETH.subnetMask().toString().c_str()); + m_connected = true; + break; + case ARDUINO_EVENT_ETH_LOST_IP: + LOG_INFO("ETH Lost IP"); + m_connected = false; + break; + case ARDUINO_EVENT_ETH_DISCONNECTED: + LOG_INFO("ETH Disconnected"); + m_connected = false; + break; + case ARDUINO_EVENT_ETH_STOP: + LOG_INFO("ETH Stopped"); + m_connected = false; + break; + default: + break; + } + } + +} \ No newline at end of file diff --git a/lib/ETH/ETH_Driver.h b/lib/ETH/ETH_Driver.h new file mode 100644 index 0000000..17466f9 --- /dev/null +++ b/lib/ETH/ETH_Driver.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +// PHY defines hardware related +#ifndef ETH_PHY_TYPE +#define ETH_PHY_TYPE ETH_PHY_W5500 +#define ETH_PHY_ADDR 1 +#define ETH_PHY_CS 16 +#define ETH_PHY_IRQ 12 +#define ETH_PHY_RST 39 +#endif + +// SPI pins +#define ETH_SPI_SCK 15 +#define ETH_SPI_MISO 14 +#define ETH_SPI_MOSI 13 + +namespace drivers +{ + + class Ethernet + { + + public: + Ethernet(const std::string hostname); + ~Ethernet(); + + void onEvent(arduino_event_id_t event, arduino_event_info_t info); + const bool isConnected(); + const bool getNtpTime(time_t &time); + + private: + const std::string m_hostname; + bool m_connected; + NetworkUDP m_udp; + IPAddress m_localIP; + NTPClient m_timeClient; + }; + +} diff --git a/lib/RTC/PCF85063_Driver.cpp b/lib/RTC/PCF85063_Driver.cpp index b4972fc..0bf7e2d 100644 --- a/lib/RTC/PCF85063_Driver.cpp +++ b/lib/RTC/PCF85063_Driver.cpp @@ -157,12 +157,27 @@ namespace drivers return false; } - const std::string PCF85063::getTimeStr() { + const std::string PCF85063::getTimeStr() + { datetime_t dt; readDatetime(dt); return datetime2str(dt); } + PCF85063::datetime_t PCF85063::fromEpoch(time_t currentTime) + { + PCF85063::datetime_t tm; + struct tm *localTime = std::localtime(¤tTime); + tm.year = localTime->tm_year + 1900; + tm.month = localTime->tm_mon + 1; + tm.day = localTime->tm_mday; + tm.dotw = localTime->tm_wday; + tm.hour = localTime->tm_hour; + tm.minute = localTime->tm_min; + tm.second = localTime->tm_sec; + return tm; + } + const std::string PCF85063::datetime2str(datetime_t &datetime) { tm dtime; @@ -171,7 +186,7 @@ namespace drivers dtime.tm_hour = datetime.hour; dtime.tm_wday = datetime.dotw; dtime.tm_mday = datetime.day; - dtime.tm_mon = datetime.month; + dtime.tm_mon = datetime.month - 1; dtime.tm_year = datetime.year - 1900; // time offset in structure according cpp reference return std::string(std::asctime(&dtime)); } diff --git a/lib/RTC/PCF85063_Driver.h b/lib/RTC/PCF85063_Driver.h index 6169fd0..45d3ef1 100644 --- a/lib/RTC/PCF85063_Driver.h +++ b/lib/RTC/PCF85063_Driver.h @@ -130,10 +130,12 @@ namespace drivers const bool readAlarm(datetime_t &time); const bool getAlarmFlag(uint8_t &flags); + const std::string datetime2str(datetime_t &datetime); const std::string getTimeStr(); + static PCF85063::datetime_t fromEpoch(time_t currentTime); + private: - const std::string datetime2str(datetime_t &datetime); const uint8_t decToBcd(const int val); const int bcdToDec(const uint8_t val); }; diff --git a/src/main.cpp b/src/main.cpp index 24ec2a0..5550c72 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,15 +6,11 @@ #include #include #include - -#include +#include #include "utils.h" /////////////// GLOBALS /////////////// -uint16_t k(0); -bool v(true); - void setup() { Serial.begin(9600); @@ -33,22 +29,37 @@ void loop() auto relays = drivers::TCA9554PWR(i2c, TCA9554_ADDRESS); auto bus = drivers::MODBUS(9600, SERIAL_8N1); auto rtc = drivers::PCF85063(i2c, PCF85063_ADDRESS); + auto eth = drivers::Ethernet("waveshare-test"); + Network.onEvent([ð](arduino_event_id_t event, arduino_event_info_t info) + { eth.onEvent(event, info); }); + + while (!eth.isConnected()) + { + LOG_WARN("Waiting for Ethernet"); + delay(1000); + } + // Set RTC time at startup + time_t ntpTime; + drivers::PCF85063::datetime_t dt; + eth.getNtpTime(ntpTime); + rtc.setDatetime(drivers::PCF85063::fromEpoch(ntpTime)); + //////////////////////////////////////// ///////// MAIN LOOP INSIDE LOOP //////// //////////////////////////////////////// - + while (true) { LOG_INFO("[", k++, "] Loop"); std::vector results; std::vector values; - - drivers::PCF85063::datetime_t dt; - rtc.readDatetime(dt); - LOG_INFO("Current Datetime", rtc.getTimeStr().c_str()); + eth.getNtpTime(ntpTime); + dt = drivers::PCF85063::fromEpoch(ntpTime); + LOG_INFO("Netwrok Datetime", rtc.datetime2str(dt).c_str()); + LOG_INFO("Current Datetime", rtc.getTimeStr().c_str()); if (bus.readHoldingRegisters(tempBoardAddr, baseRegister, 8, results)) { @@ -58,20 +69,8 @@ void loop() } results.clear(); } - delay(5000); - LOG_INFO("\n\n====>Write Status 1"); - bus.writeCoils(relayBoardAddr, 0x00, {true, false, true, false, true, false, true, false}); - bus.readCoils(relayBoardAddr, 0x00, 8, values); - printBool("====>Status 1", values); - - delay(5000); - LOG_INFO("\n\n====>Write Status 2"); - bus.writeCoils(relayBoardAddr, 0x00, {false, true, false, true, false, true, false, true}); - bus.readCoils(relayBoardAddr, 0x00, 8, values); - printBool("====>Status 2", values); - - delay(5000); + delay(100); LOG_INFO("\n\n====>Read Inputs"); bus.readInputs(relayBoardAddr, 0x00, 8, values); printBool("====>Inputs", values);