Hi,
I’m using the ansi C server code in a meter. I have tried to connect two meters in the same RS485 bus over net. In the meters, I compare serverAddress with 1 in one case and 2 in the other in the isTarget method.
When connecting individually to them using GXDLMSDirector it works correctly, but when I connect both on the same bus and connect to meter A, read data from meter A, disconnect from meter A and connect to meter B it doesn’t respond. If I try to reconnect to meter A I get an error saying “Unaceptable frame”.
The frame when trying to reconnect it’s the following:
Standard: Standard.DLMS
TX: 14:20:57 7E A0 07 03 23 93 BF 32 7E
RX: 14:20:57 7E A0 1E 23 03 73 7B CF 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 04 00 00 00 01 53 3B 7E 7E A0 0F 03 23 30 F6 40 E6 E7 00 D8 01 02 A7 71 7E 7E A0 07 23 03 97 93 54 7E
TX: 14:20:57 7E A0 48 03 23 10 62 20 E6 E6 00 60 3A A1 09 06 07 60 85 74 05 08 01 01 8A 02 07 80 8B 07 60 85 74 05 08 02 01 AC 0E 80 0C 45 6E 65 72 63 6C 69 63 31 32 33 34 BE 10 04 0E 01 00 00 00 06 5F 1F 04 00 00 1E 5D FF FF 7F A6 7E
RX: 14:20:57 7E A0 37 23 03 30 D4 C9 E6 E7 00 61 29 A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00 A3 05 A1 03 02 01 00 BE 10 04 0E 08 00 06 5F 1F 04 00 00 1E 1D 02 00 00 07 7A ED 7E 7E A0 07 03 23 97 9B 74 7E 7E A0 07 23 03 97 93 54 7E
TX: 14:20:57 7E A0 19 03 23 32 DF EB E6 E6 00 C0 01 C1 00 03 01 01 1F 07 00 FF 02 00 09 E6 7E
RX: 14:20:57 7E A0 0F 23 03 52 EA 20 E6 E7 00 D8 01 02 A7 71 7E
Any idea why could it be?
Hi,
I did some more test; I used the methods svr_connected and svr_disconnected to ensure that only the connected meter would reply. With this “fix” when I connect and disconnect meter A meter B break, but meter A keep working.
My is target method is this: https://pastebin.com/6isMp4wt
Being METER_ID 1 for one meter and 2 for the other.
I’m missing something? Is it possible to have multiple servers in the same rs485 bus?
I believe that you don't check the server address on svr_isTarget method. You need to check the server address and if it's correct return 1, in other cases return 0.
Hi,
If I understand correctly this part of the code ensure that the client it’s correct and set return to 1.
if (oa_getByIndex(&objects, pos, (gxObject**)&a) == 0)
{
if (a->clientSAP == clientAddress)
{
ret = 1;
break;
Later with this part of the code:
if (!(serverAddress == METER_ID|| serverAddress == 0x3FFF || serverAddress == 0x7F ||
(serverAddress & 0x3FFF) == SERIAL_NUMBER % 10000 + 1000))
{
ret = 0;
}
I check the server Address, and if it is not broadcast, the serial number or METER_ID the return it’s 1.
I use physical server 1 or 2 and logical server 0 in GXDLMSDirector, and METER_ID it’s 1 in one device and 2 in the other.
I think that I’m checking the serverAddress correctly, I’m missing something?
Hi,
I’ve been investigating a bit more and found this thread: https://www.gurux.fi/node/16016
It’s very similar to my problem, in my case when I connect to meter A the meter B reply even if it’s not the target. In the screenshot isTarget it’s a global variable with the same value as ret in isTarget.
As you can see the reply has size != 0 even if the meter it’s not the target.
Hi,
I did another test, I configured one meter (meter A) isTarget method to always return 0 and it still reply to the other meter (meter B).
The step by step is:
Set a breakpoint after svr_handleRequest2 method and before sending the reply by uart in meter A.
Connect to meter B.
Meter A execution stop, the uart have received:
7E A0 37 23 05 30 04 9D E6 E7 00 61 29 A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00 A3 05 A1 03 02 01 00 BE 10 04 0E 08 00 06 5F 1F 04 00 00 1E 1D 02 00 00 07 7A ED 7E
handleRequest2 method return:
reply.data = 7E A0 07 01 01 97 A0 D1 7E
reply.size = 9
Maybe I’m missing something.
Is the server supposed to reply even if isTarget return 0? Any suggestion in how to fix this?
I have done some more tests,
I have done some more tests, and I think that the problem it’s that both meters respond even though the request it’s only for one of them.
If I connect to meter A when meter B is in the same bus:
First A and Client:
10:50:18 Send SNRM request.
TX: 7E A0 07 03 23 93 BF 32 7E
10:50:18
RX: 7E A0 1E 23 03 73 7B CF 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 04 00 00 00 01 53 3B 7E
10:50:18 Send AARQ request.
TX: 7E A0 48 03 23 10 62 20 E6 E6 00 60 3A A1 09 06 07 60 85 74 05 08 01 01 8A 02 07 80 8B 07 60 85 74 05 08 02 01 AC 0E 80 0C 45 6E 65 72 63 6C 69 63 31 32 33 34 BE 10 04 0E 01 00 00 00 06 5F 1F 04 00 62 1E 5D FF FF 44 11 7E
10:50:18
RX: 7E A0 37 23 03 30 D4 C9 E6 E7 00 61 29 A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00 A3 05 A1 03 02 01 00 BE 10 04 0E 08 00 06 5F 1F 04 00 00 1E 1D 02 00 00 07 7A ED 7E
Then B seems to receive:
7E A0 37 23 03 30 D4 C9 E6 E7 00 61 29 A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00 A3 05 A1 03 02 01 00 BE 10 04 0E 08 00 06 5F 1F 04 00 00 1E 1D 02 00 00 07 7A ED 7E
And reply:
7E A0 07 01 01 97 A0 D1 7E
I have added a breckpoint in the answer part of the server and the server that is not connected some times reply.
Maybe I'm doing something wrong, any suggestion?
BR
Hi,
Hi,
I did some more test; I used the methods svr_connected and svr_disconnected to ensure that only the connected meter would reply. With this “fix” when I connect and disconnect meter A meter B break, but meter A keep working.
My is target method is this:
https://pastebin.com/6isMp4wt
Being METER_ID 1 for one meter and 2 for the other.
I’m missing something? Is it possible to have multiple servers in the same rs485 bus?
BR
Hi,
Hi,
I believe that you don't check the server address on svr_isTarget method. You need to check the server address and if it's correct return 1, in other cases return 0.
BR,
Mikko
Hi,
Hi,
If I understand correctly this part of the code ensure that the client it’s correct and set return to 1.
if (oa_getByIndex(&objects, pos, (gxObject**)&a) == 0)
{
if (a->clientSAP == clientAddress)
{
ret = 1;
break;
Later with this part of the code:
if (!(serverAddress == METER_ID|| serverAddress == 0x3FFF || serverAddress == 0x7F ||
(serverAddress & 0x3FFF) == SERIAL_NUMBER % 10000 + 1000))
{
ret = 0;
}
I check the server Address, and if it is not broadcast, the serial number or METER_ID the return it’s 1.
I use physical server 1 or 2 and logical server 0 in GXDLMSDirector, and METER_ID it’s 1 in one device and 2 in the other.
I think that I’m checking the serverAddress correctly, I’m missing something?
BR
Hi,
Hi,
I’ve been investigating a bit more and found this thread:
https://www.gurux.fi/node/16016
It’s very similar to my problem, in my case when I connect to meter A the meter B reply even if it’s not the target. In the screenshot isTarget it’s a global variable with the same value as ret in isTarget.
As you can see the reply has size != 0 even if the meter it’s not the target.
https://imgur.com/a/kSCjTpS (screenshot)
Hi,
Hi,
I did another test, I configured one meter (meter A) isTarget method to always return 0 and it still reply to the other meter (meter B).
The step by step is:
Set a breakpoint after svr_handleRequest2 method and before sending the reply by uart in meter A.
Connect to meter B.
Meter A execution stop, the uart have received:
7E A0 37 23 05 30 04 9D E6 E7 00 61 29 A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00 A3 05 A1 03 02 01 00 BE 10 04 0E 08 00 06 5F 1F 04 00 00 1E 1D 02 00 00 07 7A ED 7E
handleRequest2 method return:
reply.data = 7E A0 07 01 01 97 A0 D1 7E
reply.size = 9
Maybe I’m missing something.
Is the server supposed to reply even if isTarget return 0? Any suggestion in how to fix this?