Skip to content

Commit

Permalink
SDM230 reset readings when offline
Browse files Browse the repository at this point in the history
  • Loading branch information
curzon01 committed May 29, 2019
1 parent 9d78051 commit 1fb881a
Showing 1 changed file with 39 additions and 14 deletions.
53 changes: 39 additions & 14 deletions sonoff/xsns_23_sdm120.ino
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,20 @@

#define XSNS_23 23

// can be user defined in my_user_config.h
#ifndef SDM120_SPEED
#define SDM120_SPEED 2400 // default SDM120 Modbus address
#endif
// can be user defined in my_user_config.h
#ifndef SDM120_ADDR
#define SDM120_ADDR 1 // default SDM120 Modbus address
#endif


#include <TasmotaSerial.h>

enum SDM120_Error {SDM120_ERR_NO_ERROR=0, SDM120_ERR_CRC_ERROR, SDM120_ERR_WRONG_BYTES, SDM120_ERR_NOT_ENOUGHT_BYTES};

TasmotaSerial *SDM120Serial;

uint8_t sdm120_type = 1;
Expand Down Expand Up @@ -58,7 +70,7 @@ void SDM120_ModbusSend(uint8_t function_code, uint16_t start_address, uint16_t r
{
uint8_t frame[8];

frame[0] = 0x01; // default SDM120 Modbus address
frame[0] = SDM120_ADDR;
frame[1] = function_code;
frame[2] = (uint8_t)(start_address >> 8);
frame[3] = (uint8_t)(start_address);
Expand Down Expand Up @@ -87,26 +99,29 @@ uint8_t SDM120_ModbusReceive(float *value)
buffer[len++] = (uint8_t)SDM120Serial->read();
}

if (len < 9)
return 3; // SDM_ERR_NOT_ENOUGHT_BYTES

if (len == 9) {

if (buffer[0] == 0x01 && buffer[1] == 0x04 && buffer[2] == 4) { // check node number, op code and reply bytes count
if (len < 9) {
return SDM120_ERR_NOT_ENOUGHT_BYTES;
}

if (9 == len) {
if (0x01 == buffer[0] && 0x04 == buffer[1] && 4 == buffer[2]) { // check node number, op code and reply bytes count
if((SDM120_calculateCRC(buffer, 7)) == ((buffer[8] << 8) | buffer[7])) { //calculate crc from first 7 bytes and compare with received crc (bytes 7 & 8)

((uint8_t*)value)[3] = buffer[3];
((uint8_t*)value)[2] = buffer[4];
((uint8_t*)value)[1] = buffer[5];
((uint8_t*)value)[0] = buffer[6];

} else return 1; // SDM_ERR_CRC_ERROR
} else {
return SDM120_ERR_CRC_ERROR;
}

} else return 2; // SDM_ERR_WRONG_BYTES
} else {
return SDM120_ERR_WRONG_BYTES;
}
}

return 0; // SDM_ERR_NO_ERROR
return SDM120_ERR_NO_ERROR;
}

uint16_t SDM120_calculateCRC(uint8_t *frame, uint8_t num)
Expand Down Expand Up @@ -152,6 +167,7 @@ const uint16_t sdm120_start_addresses[] {

uint8_t sdm120_read_state = 0;
uint8_t sdm120_send_retry = 0;
uint8_t sdm120_nodata_count = 0;

void SDM120250ms(void) // Every 250 mSec
{
Expand All @@ -163,6 +179,7 @@ void SDM120250ms(void) // Every 250 mSec
bool data_ready = SDM120_ModbusReceiveReady();

if (data_ready) {
sdm120_nodata_count = 0;
uint8_t error = SDM120_ModbusReceive(&value);
if (error) {
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "SDM120 response error %d"), error);
Expand Down Expand Up @@ -233,6 +250,18 @@ void SDM120250ms(void) // Every 250 mSec
}
}
} // end data ready
else {
if (sdm120_nodata_count <= (1000/250) * 4) { // max. 4 sec without data
sdm120_nodata_count++;
} else if (sdm120_nodata_count != 255) {
// no data from modbus, reset values to 0
sdm120_nodata_count = 255;
sdm120_voltage = sdm120_current = sdm120_active_power = sdm120_apparent_power = sdm120_reactive_power = sdm120_power_factor = sdm120_frequency = sdm120_energy_total = 0;
#ifdef USE_SDM220
sdm120_phase_angle = sdm120_import_active = sdm120_export_active = sdm120_import_reactive = sdm120_export_reactive = sdm120_total_reactive = 0;
#endif
}
}

if (0 == sdm120_send_retry || data_ready) {
sdm120_send_retry = 5;
Expand All @@ -248,11 +277,7 @@ void SDM120Init(void)
sdm120_type = 0;
if ((pin[GPIO_SDM120_RX] < 99) && (pin[GPIO_SDM120_TX] < 99)) {
SDM120Serial = new TasmotaSerial(pin[GPIO_SDM120_RX], pin[GPIO_SDM120_TX], 1);
#ifdef SDM120_SPEED
if (SDM120Serial->begin(SDM120_SPEED)) {
#else
if (SDM120Serial->begin(2400)) {
#endif
if (SDM120Serial->hardwareSerial()) { ClaimSerial(); }
sdm120_type = 1;
}
Expand Down

0 comments on commit 1fb881a

Please sign in to comment.