Before commenting read Forum rules
Don't comment the topic if you have a new question.
You can create a new topic selecting correct category from Gurux Forum and then create a new topic selecting "New Topic" from the top left.
Before commenting read Forum rules
Don't comment the topic if you have a new question.
You can create a new topic selecting correct category from Gurux Forum and then create a new topic selecting "New Topic" from the top left.
Hi,
I am trying to read Application Association of a ISKRA MT372 using ansi C.
On frame #34 I can see that there is a control byte 0x7E sent by my meter:
....
33: 7E A0 08 02 23 C9 F1 F0 03 7E
<HDLC len="A" >
<!-- Logical address:1, Physical address:17 -->
<TargetAddress Value="91" />
<SourceAddress Value="64" />
<!-- S frame. -->
<FrameType Value="F1" />
<Command Value="NextFrame" />
</HDLC>
34: 7E A8 64 C9 02 23 7E 16 3E 06 16 03 00 02 03 0F 07 16 01 00 02 03 0F 08 16 01 00 01 02 02 02 0F 01 03 01 02 02 0F 02 03 01 02 04 12 00 07 11 01 09 06 00 00 15 00 01 FF 02 02 01 08 02 03 0F 01 16 01 00 02 03 0F 02 16 01 01 02 0F 01 0F 02 02 03 0F 03 16 03 00 02 03 0F 04 16 03 00 02 03 0F 05 16 03 27 7D 7E
<HDLC len="63" >
<TargetAddress Value="64" />
<!-- Logical address:1, Physical address:17 -->
<SourceAddress Value="91" />
<FrameType Value="7E" />
<NextFrame Value="0616030002030F0716010002030F08160100010202020F01030102020F0203010204120007110109060000150001FF0202010802030F0116010002030F02160101020F010F0202030F0316030002030F0416030002030F051603" />
</HDLC>
I can see that the FrameType is "7E"
0x7E -> 01111110 -> I frame with:
N(R) = 011= 6
P/F = P = 1
N(S) = 111 = 7
Reviewing the C code in file "communication.c":
int com_readSerialPort(
connection *connection,
unsigned char eop)
{
//Read reply data.
int pos;
unsigned char eopFound = 0;
unsigned short lastReadIndex = 0;
uint8_t data[500] = {0};
uint16_t i = 0;
/* Clears the FIFO UART RX buffer*/
__HAL_UART_FLUSH_DRREGISTER(&huart2);
do
{
io_read(connection->io, connection->data.data, 1);
connection->data.size += 1;
//Search eop.
if (connection->data.size > 5)
{
//Some optical strobes can return extra bytes.
for (pos = connection->data.size - 1; pos != lastReadIndex; --pos)
{
if (connection->data.data[pos] == eop)
{
eopFound = 1;
break;
}
}
lastReadIndex = pos;
}
} while (eopFound == 0);
return DLMS_ERROR_CODE_OK;
}
I have seen the same log this using GXDDLMSDirector and it can handle this type of frames without problems, I mean apparently it does not break and eventually I can read all meter objects. This is a part of the Director log.
Get next frame.
Collecting objects
7E A0 08 02 23 C9 F1 F0 03 7E
<HDLC len="A" >
<TargetAddress Value="91" />
<SourceAddress Value="64" />
<FrameType Value="F1" />
<Command Value="NextFrame" />
</HDLC>
11:03:50.636 Sent 7E A0 08 02 23 C9 F1 F0 03 7E
11:03:50.686 Received 7E A8 64 C9 02
11:03:50.696 Received 02 23 7E 16 3E 02 02 01 02 02 03
11:03:50.716 Received 00 01 00 02 04 12 00 01 11 02 03 01 02 02 0F
11:03:50.734 Received 11 00 09 06 00 00 60 01 00 FF 02 02 01 02 02 03
11:03:50.745 Received 0F 01 16 01 00 02 03 0F 02 16 03 00 01 00 02
11:03:50.766 Received 04 12 00 01 11 00 09 06 00 00 60 01 01 FF 02
11:03:50.776 Received 02 01 02 02 03 0F 01 16 01 00 02 03 0F 02 16 03
11:03:50.796 Received 00 01 00 6F DE
7E A8 64 C9 02 23 7E 16 3E 02 02 01 02 02 03 0F 01 16 01 00 02 03 0F 02 16 01 00 01 00 02 04 12 00 01 11 00 09 06 00 00 60 01 00 FF 02 02 01 02 02 03 0F 01 16 01 00 02 03 0F 02 16 03 00 01 00 02 04 12 00 01 11 00 09 06 00 00 60 01 01 FF 02 02 01 02 02 03 0F 01 16 01 00 02 03 0F 02 16 03 00 01 00 6F DE 7E
<HDLC len="63" >
<TargetAddress Value="64" />
<SourceAddress Value="91" />
<FrameType Value="7E" />
<NextFrame Value="0202010202030F0116010002030F0216010001000204120001110009060000600100FF0202010202030F0116010002030F0216030001000204120001110009060000600101FF0202010202030F0116010002030F021603000100" />
</HDLC>
I can see that the problem in my case seems to be that eop = 0x7E. In this frame is byte #8 FrameType, so the "for loop" detects the end of packet and breaks the loop stopping the reception.
The picture shows where the code stops while reading frame #34 of the first log.
I think I can fix this myself just looking at the frame size so I can modify the "for loop".
I hope this helps,
Best regards!
Hi,
Hi,
This part is handling received serial data. The purpose of this check is to make the reading faster and
cl_getData is not called after every read byte.
Actual parsing is done later in cl_getData. If the frame is not fully received and com_readSerialPort is called again when the rest of the data is read.
Is this frame causing the reader to stop? Let me know if it is and I'll check if there is something else.
BR,
Mikko
Hi Mikko,
Hi Mikko,
I am pretty sure that the reception stops because a byte 0x7E is found in frameType field.
In order to adapt the reception mechanism to my platform, just to make it easy, i have created a uint8_t data[500] buffer so I read byte a byte in blocking mode and then I copy them to connection->data gxbuffer. This works well, SNMR, AARQ and read_clock work ok. You can see the code and received data.
In the enclosed picture you can see, the code on the left, the communication sniffer on the right, and at the bottom, the area of internal memory where the received bytes are copied in data buffer. You can see that the 10 bytes are copied to the buffer but when it executes the code inside the:
if (connection->data > 9)
{
...
}
it breaks because at some point the if condition:
if (connection->data.data[pos] == 0x7E) becomes true.
therefore the do while loop breaks and data is not copied to the buffer anymore because the code thinks that 0x7E in this case is the end of the HDLC frame.
If you confirm that my arguments are right, since all received that is going to be encapsulated in HDLC frames, a fix could be to parse a few HDLC bytes until the size of the frame is received and the modify this do while loop...
I do not quite understand the comment you add saying that some optical strobes return some extra bytes... do they send then after the 0x7E eop byte?
Thanks a lot for the great support
Hi Mikko,
Hi Mikko,
I tried to check just for the EOP after byte 8 and in fact I could get over this frame, but I came accross with another issue, one of the FCS bytes with 0x7E, was causing the communication to stop. See enclosed picture.
I just chaged the the com_readSerialPort to wait for a reception timeout, that is a time without receiving any byte, so this time the entire frame is stored to be properly parsed... With this modification I can also get over this 0x7E byte in FCS field. Now the execution stops in another places with a ret = 260 DLMS_ERROR_CODE_OUTOFMEMORY but this is another issue that I have to look at...
Best regards,
Hi Mikko,
Hi Mikko,
I wonder if you had the chance to look at this issue. I could fix it by just get rid of the searching for the 0x7E end of frame, and instead using a recepction timeout...
All the best.