reaper7 / SDM_Energy_Meter

reading SDM72 SDM120 SDM220 SDM230 SDM630 modbus energy meters from arduino (esp8266, esp32, avr)
247 stars 97 forks source link

Reading multiple Devices with readvalues cause Issues #86

Open PanterSoft opened 3 weeks ago

PanterSoft commented 3 weeks ago

Hi,

I have a strange problem. When I want to read multiple registers from a Eastron SDM120M Device this works fine when only one meter is attached but if there are multiple devices and I try reading each device in a for loop some values of some devices are wrong or missinterpreted. but no error gets thrown.

the normal readVal works fine for multiple devices. but is a lot slower then reading all registers at once.

Unfortuanatly I cannot use Serial prints to debug because modbus uses my only serial port. Did anyone else have such a problem ?

my code is following:

`#include "modbus.h"

include "config.h"

include

include

// Define arrays for each variable float voltage[NUM_SLAVES], current[NUM_SLAVES], power[NUM_SLAVES], apparentPower[NUM_SLAVES], reactivePower[NUM_SLAVES], powerFactor[NUM_SLAVES], frequency[NUM_SLAVES], importActiveEnergy[NUM_SLAVES], exportActiveEnergy[NUM_SLAVES], importReactiveEnergy[NUM_SLAVES], exportReactiveEnergy[NUM_SLAVES], totalActiveEnergy[NUM_SLAVES], totalReactiveEnergy[NUM_SLAVES];

String MBError = ""; bool modbusStatus = false; // Variable to store the status of Modbus communication bool read_done = false;

// Use HardwareSerial instead of SoftwareSerial HardwareSerial& sdmSerial = Serial; SDM sdm(sdmSerial, SDM_UART_BAUD, DERE_PIN, SDM_UART_CONFIG, SDM_RX_PIN, SDM_TX_PIN);

uint8_t current_slaveID = slaveIDs[0];

void setupModbus() { //Serial.begin(SDM_UART_BAUD, SDM_UART_CONFIG, SDM_RX_PIN, SDM_TX_PIN); sdm.begin(); }

void get_result(uint16_t reg, float val) { switch (reg) { case SDM_PHASE_1_VOLTAGE: voltage[current_slaveID] = val; break; // SDM_PHASE_1_VOLTAGE 0x0000 case SDM_PHASE_1_CURRENT: current[current_slaveID] = val; break; // SDM_PHASE_1_CURRENT 0x0006 case SDM_PHASE_1_POWER: power[current_slaveID] = val; break; // SDM_PHASE_1_POWER 0x000C case SDM_PHASE_1_APPARENT_POWER: apparentPower[current_slaveID] = val; break; // SDM_PHASE_1_APPARENT_POWER 0x0012 case SDM_PHASE_1_REACTIVE_POWER: reactivePower[current_slaveID] = val; break; // SDM_PHASE_1_REACTIVE_POWER 0x0018 case SDM_PHASE_1_POWER_FACTOR: powerFactor[current_slaveID] = val; break; // SDM_PHASE_1_POWER_FACTOR 0x001E case SDM_FREQUENCY: frequency[current_slaveID] = val; break; // SDM_FREQUENCY 0x0046 case SDM_IMPORT_ACTIVE_ENERGY: importActiveEnergy[current_slaveID] = val; break; // SDM_IMPORT_ACTIVE_ENERGY 0x0048 case SDM_EXPORT_ACTIVE_ENERGY: exportActiveEnergy[current_slaveID] = val; break; // SDM_EXPORT_ACTIVE_ENERGY 0x0162 case SDM_IMPORT_REACTIVE_ENERGY: importReactiveEnergy[current_slaveID] = val; break; // SDM_IMPORT_REACTIVE_ENERGY 0x0180 case SDM_EXPORT_REACTIVE_ENERGY: exportReactiveEnergy[current_slaveID] = val; break; // SDM_EXPORT_REACTIVE_ENERGY 0x004E case SDM_TOTAL_ACTIVE_ENERGY: totalActiveEnergy[current_slaveID] = val; break; // SDM_TOTAL_ACTIVE_ENERGY 0x0156 case SDM_TOTAL_REACTIVE_ENERGY: totalReactiveEnergy[current_slaveID] = val; break; // SDM_TOTAL_REACTIVE_ENERGY 0x0158 default: MBError = "Unknown register: " + String(reg); break; } }

void alternativeRead(uint8_t slaveid, uint8_t slaveindex) { voltage[slaveindex] = sdm.readVal(SDM_PHASE_1_VOLTAGE, slaveid); current[slaveindex] = sdm.readVal(SDM_PHASE_1_CURRENT, slaveid); power[slaveindex] = sdm.readVal(SDM_PHASE_1_POWER, slaveid); //apparentPower[slaveindex] = sdm.readVal(SDM_PHASE_1_APPARENT_POWER, slaveid); //reactivePower[slaveindex] = sdm.readVal(SDM_PHASE_1_REACTIVE_POWER, slaveid); powerFactor[slaveindex] = sdm.readVal(SDM_PHASE_1_POWER_FACTOR, slaveid); //frequency[slaveindex] = sdm.readVal(SDM_FREQUENCY, slaveid); //importActiveEnergy[slaveindex] = sdm.readVal(SDM_IMPORT_ACTIVE_ENERGY, slaveid); //exportActiveEnergy[slaveindex] = sdm.readVal(SDM_EXPORT_ACTIVE_ENERGY, slaveid); //importReactiveEnergy[slaveindex] = sdm.readVal(SDM_IMPORT_REACTIVE_ENERGY, slaveid); //exportReactiveEnergy[slaveindex] = sdm.readVal(SDM_EXPORT_REACTIVE_ENERGY, slaveid); //totalActiveEnergy[slaveindex] = sdm.readVal(SDM_TOTAL_ACTIVE_ENERGY, slaveid); //totalReactiveEnergy[slaveindex] = sdm.readVal(SDM_TOTAL_REACTIVE_ENERGY, slaveid); }

String translateError(uint8_t error) { switch (error) { case 0: // SDM_ERR_NO_ERROR return "No error"; case 1: // SDM_ERR_ILLEGAL_FUNCTION return "Illegal function"; case 2: // SDM_ERR_ILLEGAL_DATA_ADDRESS return "Illegal data address"; case 3: // SDM_ERR_ILLEGAL_DATA_VALUE return "Illegal data value"; case 5: // SDM_ERR_SLAVE_DEVICE_FAILURE return "Slave device failure"; case 11: // SDM_ERR_CRC_ERROR return "CRC error"; case 12: // SDM_ERR_WRONG_BYTES return "Wrong bytes"; case 13: // SDM_ERR_NOT_ENOUGHT_BYTES return "Not enough bytes"; case 14: // SDM_ERR_TIMEOUT return "Timeout"; case 15: // SDM_ERR_EXCEPTION return "Exception"; case 16: // SDM_ERR_STILL_WAITING return "Still waiting"; default: return "Unknown error"; } }

void readModbusData() { read_done = false; for (uint8_t i = 0; i < NUM_SLAVES; i++) { current_slaveID = slaveIDs[i];

// Somehow sdm.readValues() is not working correctly it reads false values from the SDM device
uint8_t error = sdm.readValues(SDM_PHASE_1_VOLTAGE, SDM_TOTAL_REACTIVE_ENERGY, current_slaveID, get_result);

if (error) {
  MBError = translateError(error);
  modbusStatus = false;
} else {
  MBError = "";
  modbusStatus = true;
}

/*if (true) {
  alternativeRead(current_slaveID, i); // Read data from the SDM device
  MBError = "";
  modbusStatus = true;
} else {
  MBError = "Error";
  modbusStatus = false;
}*/

} read_done = true; }`