Modbus TCP Client for Kostal Inverter

Hi,

I am using Modbus_master_test Software to read several Registers of Kostal Solar Inverter. However it seems that only adress 4003 (Inverter Modbus On) is working properly. If I try to request adress 40005 I get meaningless values in the result array. (any non defined values). If I try to request higher adresses my Lan gets somehow disturbed..

Can anyone help me out?

regards
Markus

Kostal has SunSpec Modbus like my Fronius. I don't have time to see to Kostal details now, but you can check my project GitHub - jandrassy/Regulator: DIY Arduino consumption regulator build to use excess solar power for auxili

SunSpec registers (I could not find Kostal or general version)

Thanks for quick reply.

I did a test using CAS Modbus Scanner, which works properly

Request UID of Inverter, which shall be the value of Addr 04

Request:
$47 = ID of Inverter
$03 = function code
$04= addr
$01=Number of Bytes
[08:24:28] => Poll: 47 03 00 04 00 01

Response:
$47 = ID of Inverter
$03 = function code
$01=Number of Bytes
$47=Content of register
[08:32:49] <= Response: 47 03 02 00 47

Arduino Code: (Is this correct?)

int regs[100];
const int SMA_UID = 71;
res = modbusRequest(SMA_UID, 40003, 1, regs);
reg[0]=??? //shall be 71??

MaggoB:
Thanks for quick reply.

I did a test using CAS Modbus Scanner, which works properly

Request UID of Inverter, which shall be the value of Addr 04

Request:
$47 = ID of Inverter
$03 = function code
$04= addr
$01=Number of Bytes
[08:24:28] => Poll: 47 03 00 04 00 01

Response:
$47 = ID of Inverter
$03 = function code
$01=Number of Bytes
$47=Content of register
[08:32:49] <= Response: 47 03 02 00 47

Arduino Code: (Is this correct?)

int regs[100];
const int SMA_UID = 71;
res = modbusRequest(SMA_UID, 40003, 1, regs);
reg[0]=??? //shall be 71??

if you want the value of register “well-known value. 1 Uniquely identifies this as a SunSpec Common Model block” then use address 40002, because addresses in docs are 1 based and the system has them 0 based

Read Out Register 4
Arduino Code:
res = modbusRequest(SMA_UID, 40003, 1, regs);
Serial.print("Error :");Serial.println(res);
if (modbusError(res)) { return false;}
else { Serial.print("Register 4003 Content:");Serial.println(regs[0]);}

Kostal Doku
Addr (hex) Addr (dec) Description Unit Format N1) Access Function Code

0x04 4 MODBUS Unit-ID - U16 1 R/W 0x03

Result Serial Monitor
Error :0
Register 4003 Content:1 (shall be 71 !!)

MaggoB:
Read Out Register 4
Arduino Code:
res = modbusRequest(SMA_UID, 40003, 1, regs);
Serial.print("Error :");Serial.println(res);
if (modbusError(res)) { return false;}
else { Serial.print("Register 4003 Content:");Serial.println(regs[0]);}

Kostal Doku
Addr (hex) Addr (dec) Description Unit Format N1) Access Function Code

0x04 4 MODBUS Unit-ID - U16 1 R/W 0x03

Result Serial Monitor
Error :0
Register 4003 Content:1 (shall be 71 !!)

read 0x04 or 0x03 not 40003, if you want the uid register

registers over 40000 are SunSpec register

Hello Juraj,

thanks a lot for your great support. I can read the registers now!!!

Just another related problem: how to convert the 4 byte register into float varaible. See attached screenshot. I would need the float32 value in my code.

Screen Shot register100 into float.png

MaggoB:
Hello Juraj,

thanks a lot for your great support. I can read the registers now!!!

Just another related problem: how to convert the 4 byte register into float varaible. See attached screenshot. I would need the float32 value in my code.

  uint16_t reg1 = 28310;
  uint16_t reg2 = 16780;
  union {
    uint16_t ints[2];
    float f;
  } int2fUnion;
  int2fUnion.ints[0] = reg1;
  int2fUnion.ints[1] = reg2;
  float f = int2fUnion.f;

thank you very much for your great support