Skip to content

Commit

Permalink
SDM power meter: evaluate error code after polling value
Browse files Browse the repository at this point in the history
  • Loading branch information
schlimmchen committed Jun 27, 2024
1 parent 24f7010 commit 40423b0
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 12 deletions.
1 change: 1 addition & 0 deletions include/PowerMeterSerialSdm.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class PowerMeterSerialSdm : public PowerMeterProvider {

private:
static void pollingLoopHelper(void* context);
bool readValue(uint16_t reg, float& targetVar);
std::atomic<bool> _taskDone;
void pollingLoop();

Expand Down
70 changes: 58 additions & 12 deletions src/PowerMeterSerialSdm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,47 @@ void PowerMeterSerialSdm::pollingLoopHelper(void* context)
vTaskDelete(nullptr);
}

bool PowerMeterSerialSdm::readValue(uint16_t reg, float& targetVar)
{
float val = _upSdm->readVal(reg, _cfg.Address);

auto err = _upSdm->getErrCode(true/*clear error code*/);

switch (err) {
case SDM_ERR_NO_ERROR:
if (_verboseLogging) {
MessageOutput.printf("[PowerMeterSerialSdm]: read register %d "
"(0x%04x) successfully\r\n", reg, reg);
}

targetVar = val;
return true;
break;
case SDM_ERR_CRC_ERROR:
MessageOutput.printf("[PowerMeterSerialSdm]: CRC error "
"while reading register %d (0x%04x)\r\n", reg, reg);
break;
case SDM_ERR_WRONG_BYTES:
MessageOutput.printf("[PowerMeterSerialSdm]: unexpected data in "
"message while reading register %d (0x%04x)\r\n", reg, reg);
break;
case SDM_ERR_NOT_ENOUGHT_BYTES:
MessageOutput.printf("[PowerMeterSerialSdm]: unexpected end of "
"message while reading register %d (0x%04x)\r\n", reg, reg);
break;
case SDM_ERR_TIMEOUT:
MessageOutput.printf("[PowerMeterSerialSdm]: timeout occured "
"while reading register %d (0x%04x)\r\n", reg, reg);
break;
default:
MessageOutput.printf("[PowerMeterSerialSdm]: unknown SDM error "
"code after reading register %d (0x%04x)\r\n", reg, reg);
break;
}

return false;
}

void PowerMeterSerialSdm::pollingLoop()
{
std::unique_lock<std::mutex> lock(_pollingMutex);
Expand All @@ -112,27 +153,32 @@ void PowerMeterSerialSdm::pollingLoop()

_lastPoll = millis();

uint8_t addr = _cfg.Address;

// reading takes a "very long" time as each readVal() is a synchronous
// exchange of serial messages. cache the values and write later to
// enforce consistent values.
float phase1Power = _upSdm->readVal(SDM_PHASE_1_POWER, addr);
float phase1Power = 0.0;
float phase2Power = 0.0;
float phase3Power = 0.0;
float phase1Voltage = _upSdm->readVal(SDM_PHASE_1_VOLTAGE, addr);
float phase1Voltage = 0.0;
float phase2Voltage = 0.0;
float phase3Voltage = 0.0;
float energyImport = _upSdm->readVal(SDM_IMPORT_ACTIVE_ENERGY, addr);
float energyExport = _upSdm->readVal(SDM_EXPORT_ACTIVE_ENERGY, addr);

if (_phases == Phases::Three) {
phase2Power = _upSdm->readVal(SDM_PHASE_2_POWER, addr);
phase3Power = _upSdm->readVal(SDM_PHASE_3_POWER, addr);
phase2Voltage = _upSdm->readVal(SDM_PHASE_2_VOLTAGE, addr);
phase3Voltage = _upSdm->readVal(SDM_PHASE_3_VOLTAGE, addr);
float energyImport = 0.0;
float energyExport = 0.0;

bool success = readValue(SDM_PHASE_1_POWER, phase1Power) &&
readValue(SDM_PHASE_1_VOLTAGE, phase1Voltage) &&
readValue(SDM_IMPORT_ACTIVE_ENERGY, energyImport) &&
readValue(SDM_EXPORT_ACTIVE_ENERGY, energyExport);

if (success && _phases == Phases::Three) {
success = readValue(SDM_PHASE_2_POWER, phase2Power) &&
readValue(SDM_PHASE_3_POWER, phase3Power) &&
readValue(SDM_PHASE_2_VOLTAGE, phase2Voltage) &&
readValue(SDM_PHASE_3_VOLTAGE, phase3Voltage);
}

if (!success) { continue; }

{
std::lock_guard<std::mutex> l(_valueMutex);
_phase1Power = static_cast<float>(phase1Power);
Expand Down

0 comments on commit 40423b0

Please sign in to comment.