Added seneca powermeter driver

This commit is contained in:
Emanuele Trabattoni
2025-07-12 23:00:21 +02:00
parent 1ad98799b4
commit d2eba9085e
4 changed files with 200 additions and 10 deletions

View File

@@ -0,0 +1,114 @@
#include <S50140_Driver.h>
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<uint16_t> 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;
}
}

View File

@@ -0,0 +1,72 @@
#pragma once
#include <DebugLog.h>
#include <RS485_Driver.h>
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;
};
}