Modbus CHNT DDSU666 power meter

Hello all! Good day everyone! I have here a power meter that is kind of strange when it comes to its Modbus parameters (or maybe I am doing it wrong). Its name is CHNT DDSU666 power meter, may I kindly ask for some guidance regarding on Modbus for this instrument. I will attach a manual for this specific meter since it is hard to get one. I am using PAC Control to communicate with this meter and an Opto22 Learning Center with SNAP SCM 485-422 module.

P.S I am apparently unable to attach a PDF file of the manual maybe I could just link this instead.

P.S.S Here is a little optoscript that I made to communicate with the instrument, but I am apparently getting a 1.#QNAN. I already set my Modbus parameters to 8n1 and my baud to 9600.

SetCommunicationHandleValue("tcp:", SCM1);

Comm_Status = OpenOutgoingCommunication(SCM1);

Req_Message = "";

Req_Message += chr(1); // START ADDRESS 01H
Req_Message += chr(3); // FUNCTION CODE 03H
Req_Message += chr(20); // REGISTER ADDRESS HIGH 20H
Req_Message += chr(0); // REGISTER ADDRESS LOW  00H
Req_Message += chr(0); // NO.OF REGISTERS HIGH  00H
Req_Message += chr(2);  // NO.OF REGISTERS LOW 02H

GetSubstring(Req_Message, 0, 6, Req_Message_Str); 
GetSubstring(Req_Message, 6, 2, Req_Message_Crc); 

Crc_check = GenerateReverseCrc16OnString(-1, Req_Message_Str); 
NumberToFormattedHexString(Crc_check, 4, Crc_Hex);  

GetSubstring(Crc_Hex, 0, 2, Crc_Low); 
GetSubstring(Crc_Hex, 2, 2, Crc_High);

Crc_IntHigh = HexStringToNumber(Crc_High); 
Crc_IntLow  = HexStringToNumber(Crc_Low);  

Crc_HiLo = chr(Crc_IntHigh) + chr(Crc_IntLow);

Crc_Test = CompareStrings(Crc_HiLo, Req_Message_Crc); 

Req_Message = Req_Message + Crc_HiLo;

Have you looked at using the integration kit for modbus?

It isn’t the simplest kit to use, but it is easier than rolling your own as you are doing.

Thank you for the reply! I found the answer while looking at my transmit and receive messages seems to be a wrong function call :smiley: I can read the instrument now

A few other notes.

20H means hexadecimal and would be 32 decimal. You can use chr(0x20) or chr(32), but not chr(20) as that is a different number.

With the modbus kit you would take the address you want to read (2000h) and add 1 to it to get the register number (Silly modbus quirk - your doc starts at 0 and the modbus kit is 1 based so you need to add 1 to whatever is in the docs.) So you would want to read 2001h which in OptoScript would be 0x2001 or 8193. You would use the float subroutine from the modbus kit since your device returns values as a “single precision floating decimal”.

With the kit you would do something like this:

//Setup the parameter table
param[0] = 0; //Serial RTU
param[1] = 1; //slave id
param[2] = 1000; //timeout ms
param[3] = 1; //big endien

//Call the subroutine
O22Modbus03ReadHoldingRegistersAsFloat(SCM1, param, 0x2001, ftResults, 1, status);

//Result in ftResults[0] if status is 0, otherwise lookup the error.

The only unknown is if the floats are stored in “big endian” or “little endian” format. Your documentation doesn’t specify. Most of the time it is big endian. This is a parameter setting in the kit subroutine. If the value you get doesn’t make sense, then change param[3] to 0 and see if the value returned makes sense.

1 Like

Haha that is exactly the problem I found out today, thanks again!

Glad you got it working. Are you using the kit? If not, I would recommend giving it a try - it will simplify your code.

I used my code but will try the kit to test it out thanks again!

If you wrote your own code and got it to work, you will have no problems with the kit!

1 Like