Fixed RTC and Ethernet drivers, with NTP

This commit is contained in:
Emanuele Trabattoni
2025-07-10 21:48:30 +02:00
parent 7fd4a284af
commit 208f5f7534
5 changed files with 160 additions and 26 deletions

72
lib/ETH/ETH_Driver.cpp Normal file
View File

@@ -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;
}
}
}

46
lib/ETH/ETH_Driver.h Normal file
View File

@@ -0,0 +1,46 @@
#pragma once
#include <DebugLog.h>
#include <Arduino.h>
#include <Network.h>
#include <NTPClient.h>
#include <ETH.h>
#include <SPI.h>
// 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;
};
}

View File

@@ -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(&currentTime);
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));
}

View File

@@ -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);
};

View File

@@ -6,15 +6,11 @@
#include <RS485_Driver.h>
#include <TCA9554PWR_Driver.h>
#include <PCF85063_Driver.h>
#include <ETH.h>
#include <ETH_Driver.h>
#include "utils.h"
/////////////// GLOBALS ///////////////
uint16_t k(0);
bool v(true);
void setup()
{
Serial.begin(9600);
@@ -33,7 +29,22 @@ 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([&eth](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 ////////
@@ -45,11 +56,11 @@ void loop()
std::vector<uint16_t> results;
std::vector<bool> values;
drivers::PCF85063::datetime_t dt;
rtc.readDatetime(dt);
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))
{
for (auto i(0); i < results.size(); i++)
@@ -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);