IP_CONTROL Frage zum Verbindungsabbau

Begonnen von phil19, 26. Juli 2020, 09:37:30

Vorheriges Thema - Nächstes Thema

0 Mitglieder und 2 Gäste betrachten dieses Thema.

phil19

Hallo,

ich nutze den Baustein IP_CONTROL um über eine Socket Verbindung meine Wärmepumpe (Luxtronic) abzufragen.
Das Protokoll besteht aus:
- Sende Paket 1 an WWP: 00 00 0b bc
- Sende Paket 2 an WWP: 00 00 00 00
- Empfange Daten 820 Bytes mit Werten


Das Programm funktioniert, die Daten in der ersten Ausführung an.
In der Zweiten Ausführung wird nur noch Paket 00 00 00 00 gesendet.
In der dritten Ausführung erhalte ich einen Error im IP_C.C_ERROR
In der vierten Ausführung klappts dann (meistens) wieder
usw. usw.

Ich vermute die State-Machine hat noch einen Fehler, oder ich habe irgendwas übersehen beim sauberen Verbindungsabbau?

Bin für jeden Tipp dankbar!

Das ist der Code:

(* IF the send command is active AND the system is busy, ignore the send request *)
IF xSend THEN
    (* Init status variables *)
       xSend := FALSE;
       xBusy := TRUE;
    iStep := 0;


    S_BUF.SIZE := 0; (* reset send-buffer *)


    IP_C.C_PORT := uiPort;
    IP_C.C_IP := IP4_DECODE('192.168.50.120');
    IP_C.C_MODE := 0;
    IP_C.TIME_RESET := TRUE;
    IP_C.R_OBSERVE := TRUE;
    IP_C.C_ENABLE := TRUE;
    IPClient.TIME_OUT := T#500ms;
END_IF


IF xBusy THEN
   CASE iStep OF
      0: (* SEND Paket 1 *)


        S_BUF.BUFFER[0] := 16#00;
        S_BUF.BUFFER[1] := 16#00;
        S_BUF.BUFFER[2] := 16#0B;
        S_BUF.BUFFER[3] := 16#BC;
        S_BUF.SIZE := 4;


        IPClient(IP_C := IP_C, S_BUF := S_BUF, R_BUF := R_BUF);
        R_BUF.SIZE := 0;
        IF IP_C.C_STATE = 255  THEN
            iStep := 1;
        END_IF


      1: (* SEND Paket 2 *)
        S_BUF.BUFFER[0] := 16#00;
        S_BUF.BUFFER[1] := 16#00;
        S_BUF.BUFFER[2] := 16#00;
        S_BUF.BUFFER[3] := 16#00;
        S_BUF.SIZE := 4;
        IPClient(IP_C := IP_C, S_BUF := S_BUF, R_BUF := R_BUF);
        R_BUF.SIZE := 0;
        IF IP_C.C_STATE = 255 OR IP_C.C_STATE = 1 THEN
            iStep := 2;
        END_IF
        IF IP_C.ERROR  = 0 THEN
            iStep := 10;
        END_IF


    2: (* CONVERT *)
        FB_CONVERT(VAR_IN := R_BUF.BUFFER[0], VAR_OUT => status);
        FB_CONVERT(VAR_IN := R_BUF.BUFFER[18], VAR_OUT => tempAussen);
        FB_CONVERT(VAR_IN := R_BUF.BUFFER[13], VAR_OUT => tempVorlauf);
        FB_CONVERT(VAR_IN := R_BUF.BUFFER[14], VAR_OUT => tempRuecklauf);
        FB_CONVERT(VAR_IN := R_BUF.BUFFER[15], VAR_OUT => tempVorlaufS);
        FB_CONVERT(VAR_IN := R_BUF.BUFFER[20], VAR_OUT => tempWWIst);
        FB_CONVERT(VAR_IN := R_BUF.BUFFER[21], VAR_OUT => tempWWSoll);
        FB_CONVERT(VAR_IN := R_BUF.BUFFER[24], VAR_OUT => tempMKVLIst);
        FB_CONVERT(VAR_IN := R_BUF.BUFFER[25], VAR_OUT => tempMKVLSoll);
        FB_CONVERT(VAR_IN := R_BUF.BUFFER[154], VAR_OUT => kwhHeizung);
        FB_CONVERT(VAR_IN := R_BUF.BUFFER[155], VAR_OUT => kwhWasser);
        iStep := 10;


    10:
        IP_C.C_ENABLE := FALSE;
        IF IP_C.C_STATE = 0 THEN
            xBusy := FALSE;
            iStep := 0;
        END_IF


     END_CASE;
(*
IP_FIFO(FIFO:=IP_C.FIFO,STATE:=IP_STATE,ID:=IP_ID);
IP_C.FIFO:=IP_FIFO.FIFO;
IP_STATE := IP_FIFO.STATE;
IP_ID:=IP_FIFO.ID;


*)
END_IF


Variablen

PROGRAM PRG_LWP_SOCKET
VAR_INPUT
   xSend            : BOOL := FALSE;
END_VAR
VAR
       (* Relevante Werte *)
       (* siehe globale Variablenliste *)
    IP_C                    : IP_C;
    IP_FIFO                : IP_FIFO;
    IPClient                : IP_CONTROL;
    IPClient2                : IP_CONTROL;
    IP_STATE                : BYTE;
    IP_ID                    : BYTE;
    R_BUF                : NETWORK_BUFFER;
    S_BUF                       : NETWORK_BUFFER;
    xBusy                    : BOOL := FALSE;
    iStep                    : UINT := 0;
    FB_CONVERT           : FB_BYTESWAP_DWORD;
    FB_SOCK_ERROR    : SysSockGetLastError;
END_VAR

phil19

kann leider den Beitrag oben nicht editieren, in iStep 2 muss es natürlich heissen

IF IP_C.C_ERROR <> 0 THEN iStep := 10 ...... anstelle von 
IF IP_C.C_ERROR = 0 THEN iStep := 10

iStep = 10 sollte die Verbindung beenden. 
So ist es auch auf der Steuerung hinterlegt, allerdings mit genau obig beschriebenem Verhalten :-(

peewit

ja deine statemaschine ist etwas wackelig


der xSend schritt ist nicht teil der schrittkette
wenn die schrittkette läuft kann xsend alles übersteuern

du wartest auch nie das die daten gesendet worden sind 0
erst wenn S_BUF.SIZE = 0 ist sind die daten sicher versendet

wenn es einen fehler gibt was durchaus sein kann das es normal ist musst du die verbindung wieder neu initialisiernen

das beste wäre es also wenn der xsend block schon teil der echten schrittkette ist somit muss alles der reihe nach ablaufen
und immer am anfang und nach fehler die verbindung neu initialisieren

phil19

Vielen herzlichen Dank peewitt, werde das nachher ausprobieren!

Noch eine Frage zum Empfangsbuffer R_BUF.SIZE - obwohl ich Daten empfange und in dem Array definitiv Werte enthalten sind, ist SIZE immer 0.
Wie kann ich abfragen ob Werte erhalten wurden - klar, ich kann einen Index im Array abfragen, bei dem ich sicher weiss, dass er einen Wert haben muss <> 0, aber eleganter wäre es über "SIZE".

Danke!

peewit

hallo

natürlich gibt es noch mehr fehler...

       S_BUF.BUFFER[1] := 16#00;
        S_BUF.BUFFER[2] := 16#0B;
        S_BUF.BUFFER[3] := 16#BC;
        S_BUF.SIZE := 4;


        IPClient(IP_C := IP_C, S_BUF := S_BUF, R_BUF := R_BUF);
        R_BUF.SIZE := 0;

1. vor dem senden solltest R_BUF_SIZE := 0 machen und nicht nach dem IP_Client aufruf denn nach dem Aufruf könnten theoretisch schon daten empfangen werden und dann knallst du R_BUF_SIZE := 0 drüber

Aber das ist nicht das hauptproblem

der Baustein IP_CONTROL arbeitet azyklisch - der baustein muss unabhängig deiner schritte zyklisch immer aufgerufen werden
sonst würde deine sps ja sofort abstürzen wenn der ip_control solange warten würde bis eine antwort kommt

schau dir doch die diversen demo bausteine an dort ist es auch immer so der der ip_control am baustein ende immer zyklisch durchlaufen wird

kurz gesagt deine konstruktion wirfst du am besten weg und schau dir die vorhandenen bausteine mal in ruhe an