diff --git a/docs/mi00383-11-en.pdf b/docs/mi00383-11-en.pdf new file mode 100644 index 0000000..bccc125 Binary files /dev/null and b/docs/mi00383-11-en.pdf differ diff --git a/lib/SENECA/S50140_Driver.cpp b/lib/SENECA/S50140_Driver.cpp new file mode 100644 index 0000000..ef48c88 --- /dev/null +++ b/lib/SENECA/S50140_Driver.cpp @@ -0,0 +1,114 @@ +#include + +namespace drivers +{ + + S50140::S50140(drivers::MODBUS &bus, const uint8_t address) : m_bus(bus), m_address(address) + { + } + S50140::~S50140() + { + } + + const S50140::powerinfo_t S50140::getAll() + { + powerinfo_t info; + info.v = getV(); + info.a = getA(); + info.pAct = getPact(); + info.pApp = getPapp(); + info.pRea = getPrea(); + info.f = getF(); + info.whTot = getWhTot(); + info.whPar = getWhPar(); + return info; + } + + const float_t S50140::getV() + { + return readFloatReg(REG_V); + } + const float_t S50140::getA() + { + return readFloatReg(REG_A); + } + const float_t S50140::getPact() + { + return readFloatReg(REG_Pact); + } + const float_t S50140::getPapp() + { + return readFloatReg(REG_Papp); + } + const float_t S50140::getPrea() + { + return readFloatReg(REG_Prea); + } + const float_t S50140::getF() + { + return readFloatReg(REG_Freq); + } + const float_t S50140::getWhTot() + { + return readFloatReg(REG_WhTot); + } + const float_t S50140::getWhPar() + { + return readFloatReg(REG_WhPart); + } + + void S50140::resetTotalCounters() + { + uint8_t retries(0); + const uint16_t resetAll = 0x0000; + while (retries++ < maxRetries) + { + if (m_bus.writeRegister(m_address, REG_TotCount, resetAll)) + return; + LOG_ERROR("Unable to Reset Powermeter Total Counters, device", m_address); + delay(10); + } + return; + } + void S50140::resetPartialCounters() + { + uint8_t retries(0); + const uint16_t resetAll = 0x0A03; + const uint16_t stopAll = 0x0A02; + const uint16_t startAll = 0x0A01; + while (retries++ < maxRetries) + { + bool ok(true); + ok &= m_bus.writeRegister(m_address, REG_TotCount, stopAll); + delay(10); + ok &= m_bus.writeRegister(m_address, REG_TotCount, resetAll); + delay(10); + ok &= m_bus.writeRegister(m_address, REG_TotCount, startAll); + if (ok) + return; + LOG_ERROR("Unable to Reset Powermeter Partial Counters, device", m_address); + delay(10); + } + return; + } + + float_t S50140::readFloatReg(const uint16_t reg) + { + uint8_t retries(0); + std::vector values; + + while (retries++ < maxRetries) + { + if (m_bus.readHoldingRegisters(m_address, reg, dataWords, values) && values.size() == dataWords) + { + floatval_t fv; // potrebbe essere il contrario, vedremo + fv.hi = values[0]; // magari va invertita ancora l'endianness + fv.lo = values[1]; + return fv.f; + } + LOG_ERROR("Unable to Read Powermeter values, device", m_address); + } + return MAXFLOAT; + } + +} \ No newline at end of file diff --git a/lib/SENECA/S50140_Driver.h b/lib/SENECA/S50140_Driver.h new file mode 100644 index 0000000..5d3d188 --- /dev/null +++ b/lib/SENECA/S50140_Driver.h @@ -0,0 +1,72 @@ +#pragma once + +#include +#include + +namespace drivers +{ + + class S50140 + { + private: + const uint8_t maxRetries = 5; + const uint8_t dataWords = 2; + const uint16_t REG_V = 0x100C; + const uint16_t REG_A = 0x1016; + const uint16_t REG_Pact = 0x1026; + const uint16_t REG_Papp = 0x102E; + const uint16_t REG_Prea = 0x1036; + const uint16_t REG_Freq = 0x1036; + const uint16_t REG_WhTot = 0x1106; + const uint16_t REG_WhPart = 0x1400; + const uint16_t REG_Serial = 0x0500; + const uint16_t REG_Regset = 0x0538; + const uint16_t REG_TotCount = 0x0516; + const uint16_t REG_PartCount = 0x0517; + + typedef union + { + float_t f; + uint16_t hi; + uint16_t lo; + } floatval_t; + + public: + typedef struct + { + float_t v; + float_t a; + float_t pAct; + float_t pApp; + float_t pRea; + float_t f; + float_t whTot; + float_t whPar; + } powerinfo_t; + + public: + S50140(drivers::MODBUS &bus, const uint8_t address); + ~S50140(); + + const powerinfo_t getAll(); + + const float_t getV(); + const float_t getA(); + const float_t getPact(); + const float_t getPapp(); + const float_t getPrea(); + const float_t getF(); + const float_t getWhTot(); + const float_t getWhPar(); + + void resetTotalCounters(); + void resetPartialCounters(); + + private: + float_t readFloatReg(const uint16_t reg); + + private: + const uint8_t m_address; + drivers::MODBUS &m_bus; + }; +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 5580e5a..6ffc7b3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -41,6 +42,7 @@ void loop() { const uint8_t tempBoardAddr(0xAA); const uint8_t relayBoardAddr(0x01); + const uint8_t senecadAddr(0xBB); const uint8_t baseRegister(0x00); uint16_t k(0); uint8_t ethRetries(0); @@ -56,6 +58,8 @@ void loop() delay(100); auto io = digitalIO(i2c, bus, {relayBoardAddr}); delay(100); + auto seneca = drivers::S50140(bus, senecadAddr); + delay(100); Network.onEvent([ð](arduino_event_id_t event, arduino_event_info_t info) { eth.onEvent(event, info); }); @@ -91,7 +95,7 @@ void loop() while (true) { LOG_INFO("[", k++, "] Loop"); - + eth.getNtpTime(ntpTime); dt = drivers::PCF85063::fromEpoch(ntpTime); LOG_INFO("Network Datetime", rtc.datetime2str(dt).c_str()); @@ -99,27 +103,27 @@ void loop() mqtt.publish("test/esp32-out", ("[" + std::to_string(k) + "] -> " + rtc.getTimeStr()).c_str()); uint8_t i(0); - delay(10); - for (auto v: tmp.getTempAll()) { + for (auto v : tmp.getTempAll()) + { LOG_INFO("Temperature channel", i++, "->", v); } - i=0; + i = 0; delay(10); - for (auto v : tmp.getCorrection()){ + for (auto v : tmp.getCorrection()) + { LOG_INFO("Temperature correction channel", i++, "tc", v); } for (auto j(0); j < io.getOutNum(); j++) { - //io.digitalIOWrite(j, true); + // io.digitalIOWrite(j, true); LOG_INFO("Input", j, io.digitalIORead(j) ? "True" : "False"); delay(500); + // io.digitalIOWrite(j, false); } - //for (auto j(0); j < io.getOutNum(); j++) - //{ - // io.digitalIOWrite(j, false); - //} + drivers::S50140::powerinfo_t pinfo = seneca.getAll(); + LOG_INFO("Power Info\nV:", pinfo.v, "\nA:", pinfo.a, "\nW:", pinfo.pAct, "\nWh_t:", pinfo.whTot, "\nWh_p:", pinfo.whPar); delay(5000); }