This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430AFE253: Issue with serial communication protocol to show the Voltage and etc. (Chinese protocol - DL/T645)

Part Number: MSP430AFE253

Here is a test report for MSP430AFE253.

www.ti.com/.../slaa488.pdf

On the page 22 of this document we will have "GUI Read Out Metering Parameter" which say by sending 6100 you will receive Phase one information out of the energy meter.

I've wrote a code with Win32 Console APP. in C++ to Read/Write the serial port. 6100 or technically 61 hex and 00 hex are the digits that I need to send toward the meter, right? But for some reasons this my meter is not responding!

Am I doing something wrong?

The GUI (given by the following link) on the other hand, is getting all the voltages from all phases: 0x61 0x62 0x63. 

  www.ti.com/.../slaa488.zip

Therefore, this tells me that I am not sending the right character to the serial port and perhaps missing other characters!

Can you please advise?

  • Hello,

    I'm looking into your question and will respond shortly.

    Regards,

    James

    MSP Customer Applications
  • Thank you James,

    To be more specific and detailed here is what I send according to the pdf file.

    char   lpBuffer[15] = { 0x68, 0x99,0x99,0x99,0x99,0x99,0x99,0x68,0x23,0x06,0x61,0x00,0x01,0x00,0x16};

    In my meter, I can see only the last character (0x16)

    I believe that there must be something missing in here!

  • Hello,

    Thank you for the additional details and especially for the exact packet that you're trying to send.

    First, looking at the SLAA488 Test Report document, there seems to be a discrepancy for the nR/W (Notify Command Direction) byte. In Section A.2 on page 21, it says that 0x80 denotes a command from GUI to F4481, 0x00 denotes F4481 feedback to GUI. However, in Section A.2.1 on page 22, the command from GUI to F4481 uses 0x00, and the command from F4481 to GUI uses 0x80. Perhaps this byte represents where the next command will come from instead of the present command? I'm not really sure, since I don't have the hardware to test this on.

    Since you're sending this command from the PC to the F4481, I see that you're using 0x00. I don't think this is the main issue, but you could try using 0x80 instead and see if that works. If it does, I'll need to submit feedback to have the document updated accordingly.

    More importantly, I think that there are two other issues that are preventing this command from working properly.

    1. First, you're setting the Length byte as 0x06 when you're only sending one byte of data, 0x01. Try changing the Length byte to 0x01.
    2. Next, you've set the CS (checksum) byte to 0x00. This byte equates the algorithm sum of the Packet_body (from 0 to len+9). Here, the checksum would be calculated across the H_CMD byte (0x61), the nR/W byte (0x00 or 0x80, see my comments about this above), and the Data byte(s) (0x00). Try changing the CS byte to the checksum.

    Perhaps, you could put a logic analyzer on the UART lines to sniff what the packets from the GUI look like too.

    Hopefully this helps.

    Regards,

    James

    MSP Customer Application

  • James,

    So far I corrected my array according to what you said.

    char lpBuffer[15] = { 0x68, 0x99,0x99,0x99,0x99,0x99,0x99,0x68,0x23,0x01,0x61,0x80,0x01,0x00,0x16};

    However, I don't get the checksum part.
  • Can please advise the data and sum?

    H CMD: 0x61  Voltage phase 1
    nR/W: 0x80 as you said
    Data: ??
    Sum: ??
  • Would you mind if you type the whole array for me please? I am totally confused!
  • I'd definitely recommend searching online for the DL/T645 Multi-function watt-hour meter communication protocol documentation. It talks about the protocol structure and framework in great detail. After looking through these, I found that 0x00 denotes Master to Slave direction and 0x80 denotes Slave to Master direction. Let's keep the nR/W byte as 0x00 for now.

    Now, the checksum is calculated over all the bytes in the Packet_body field. Basically, the checksum is the sum of all bytes, then mod by 256. So, let's try this packet.

    char lpBuffer[14] = {0x68,0x99,0x99,0x99,0x99,0x99,0x99,0x68,0x23,0x02,0x61,0x00,0x61,0x16};

    I removed the single data byte 0x01 from before, which didn't seem to be necessary. Also, I changed the Length byte to 0x02 because we're using the H_CMD and nR/W bytes. Lastly, (0x61 + 0x00) mod 256 equals 0x61 for the CS byte.

    Edit: The checksum (CS) byte is equal to the sum of all bytes from frame start byte to last data byte, then mod this result with 0x100 (256). Please see my answer on the next page for a complete explanation.

    Regards,

    James

    MSP Customer Applications

  • James,

    I searched a lot about this chinese protocol. There is only two sources availablr. One is TI and the other one a Chinese Website. But unfortunately there is no good example avilable.

    I will test your code on Tues. as I am not at work right now and we are off for 3 days unfortunately! Thank you for your help. I appreciate that. It is not easy to get a hold of someone who is really savvy about this. I will keep you posted for sure.

  • 1 year ago, I used energy library code and rebuilt it to see if I can recreate the executeable file for the gui to develope it using Cygwin. That failed as changing in one file needed changes in other files at thecsame time which was really confusing. After all, dlt645 was a mysterious protocol to understand how it works. Hopefully I will get back to you with good news!
  • James Evans said:

    char lpBuffer[14] = {0x68,0x99,0x99,0x99,0x99,0x99,0x99,0x68,0x23,0x02,0x61,0x00,0x61,0x16};

    James,

    I just tested your code, unfortunately it did not get back to me with any characters!

    0x61 is supposed to give me phase 1 readings.

    What else do you recommend me to try? 

  • James,

    Can you please clarify something for me?

    There is something that I don't understand. When you send "123" in the firmware I can only see the last character when I put a break-point in the code.

    I am guessing that I might need to change the way that I am sending the characters?

    I am totally confused!

  • Hello,

    I'm looking into your latest feedback and will respond shortly.

    Regards,

    James

    MSP Customer Applications
  • I'm sorry to hear that my recommended packets didn't work correctly. Since we already referred to the documentation about this, I'll assume that the packets are correct, but perhaps something else is causing the issue.

    First, can you please confirm that you're using a 9600 baud rate? If not, I'd recommend using this slow data rate.

    To rule out anything related to C++, timings, etc., let's try a helpful (free) program called Serial Port Utility to send the DLT645 packets to the F4481 device instead. It allows you to easily construct the multi-byte packets and send them over the terminal interface.

    Next, place a breakpoint in the 'emeter-dlt645.c' file at the "switch()" statement on Line 423. If your code gets to this point after sending the packets, that's a good start. Basically, Line 423 is checking the received command, and based on this command, the state machine will do certain things. If you sent the command 0x61 (HOST_CMD_GET_READINGS_PHASE_1), we would expect the code to execute the "send_AFE_reading(0)" function on Line 581. If you run the code to this point, you could check the contents of the "rx_msg->uint8[]" array. As a side note, some related #defines for the 'emeter-dlt645.c' file can be found in the 'emeter-dlt645.h' file, which you may know already.

    If you aren't able to reach this point in the code, then the packets could be wrong. You can even try to reach these breakpoints when you use the default GUI and then read the "rx_msg->uint8[]" array to see exactly what's being sent.

    Hopefully this helps point you in the right direction. Let me know what you find, and we can dig deeper.

    Regards,

    James

    MSP Customer Applications

  • James!

    Good news! Even though I still need your help.

    Here is what i did. I used your SpU program and send a character to the meter and as I did not have your previous recommendation packet I try a packet and received nothing. Then ran the GUI and realized that my package is as follows.

    689999999999996823026400EF165916BC9AF0DE2B16

    Then, wondered why my packet is so long and tried shorten it as follows.

    689999999999996823026400EF16

    even this worked and I received something on my screen using your software as well as my C++ version of code ( with a different format)

    Then, I was wondering why GUI has used 64 command which is HOST_CMD_GET_CSG_NEUTRAL. Why not using 0x61 to get Phase_1 information?

    I tried:

    689999999999996823026100EF16 

    and was confused why EF is used as data!

    I am still wondering why 0x61 or 0x62 or 0x63 are not working?

    But I have all the voltage readings populated in the GUI's table?

    So, how can I ask the meter to give me the packet for voltage then I can filter and clean up what I have received!

    Any idea on this?

    My explanation is clear enough for you?

  • So, finally I figured this out. For phase I which is 0x61 you need to send out the following packet:

    char lpBuffer[80] = { 0x68, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x68, 0x23, 0x02, 0x61, 0x00, 0xEC, 0x16 };

    and for 0x62

    char lpBuffer[80] = { 0x68, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x68, 0x23, 0x02, 0x62, 0x00, 0xED, 0x16 };

    Even with my C++ version I am able to see the received message but I need to filter out what I need which is the voltage as hex and convert it to decimal.

    GUI and break point was so helpful.

    Many thanks to your useful replies.

    Having said these, do we need to change the pdf of file of DLT645 as it is said SUM.

    I still don't figure out that why I have EF ED EC ?

    But I understand why I have 2 bytes for data!

    0x02

  • Hello,

    I'm sorry for the late reply, but I wanted to answer your last question. First, let me say that I was calculating the checksum improperly. According to Appendix A.1 in the MSP430AFE253 Test Report for China State Grid Specification (SLAA488), the Checksum (CS) byte is equal to the algorithmic sum from 0 to len+9 in the frame. However, this value can only be 8 bits or 1 byte, so CS equals the sum mod 256 (0x100). Using the Calculator program in Programmer mode on my PC, I entered the modulo as 0x256 instead of 0x100 when I originally calculated the checksum, which gave me wrong results.

    Let me use your first packet as an example to make sure everything makes sense.

    char lpBuffer[80] = { 0x68, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x68, 0x23, 0x02, 0x61, 0x00, 0xEC, 0x16 };

    sum = (0x68 + 0x99 + 0x99 + 0x99 + 0x99 + 0x99 + 0x99 + 0x68 + 0x23 + 0x02 + 0x61 + 0x00) = 0x4EC
    CS = sum [mod] 0x100 = 0x4EC [mod] 0x100 = 0xEC

    For the data bytes, you're correct - there are 2 bytes here. The first 2 bytes in the data field of a command are CMDH and CMDL, which defines the command and the parameters that follows. Here, CMDH is the command byte (e.g. 0x61), and CMDL is the Notify Command Direction byte (e.g. 0x00).

    Hopefully this all makes sense and clears up any confusion that other users may have.

    Regards,

    James

    MSP Customer Applications

**Attention** This is a public forum