IP_CONTROL & IP_FIFO mehrere Daten senden und auswerten.

Begonnen von Redkanoon, 05. Mai 2019, 17:53:05

Vorheriges Thema - Nächstes Thema

0 Mitglieder und 1 Gast betrachten dieses Thema.

Redkanoon

Hallo zusammen,

ich werde nicht richtig schlau aus den OSCAT Bausteinen IP CONTROL und IP FIFO, und hoffe das ihr mir helfen könnt.
Ich versuche mit meiner Beckhoff CX5020 meine Fritzbox nach der Anwesenheit verschiedener Devices abzufragen.

Ich habe es bestimmt nicht ganz sauber durchprogrammiert, aber ich habe versucht den POST der hinter GetSpecificHostEntry steckt ( zu finden auf "https://avm.de/service/schnittstellen/" und dort "hostsSCPD.pdf") nach zu programmieren.

Mit einem Device funktioniert das ganze auch nur sobald ich zwei devices abfragen will, sehe ich das immer nur das Kommando für das 2te device versendet wird.

Main
PROGRAM MAIN
VAR
tmrSend: TON;
repeatTime: TIME;

fbOnlineDevice: FB_ONLINE_DEVICE;
fbGetSpecificHostEntry1: FB_GetSpecificHostEntry;
fbGetSpecificHostEntry2: FB_GetSpecificHostEntry;
END_VAR

tmrSend(IN:= NOT tmrSend.Q, PT:=repeatTime);

fbGetSpecificHostEntry1(send:=tmrSend.Q, onlineDevice:= System.phone1);
fbGetSpecificHostEntry2(send:=tmrSend.Q, onlineDevice:= System.phone2);
fbOnlineDevice(onlineDevice:=System.phone1, name:='Phone 1', errorTime:=T#5S);
fbOnlineDevice(onlineDevice:=System.phone2, name:='Phone 2', errorTime:=T#5S);


FB_GetSpecificHostEntry
FUNCTION_BLOCK FB_GetSpecificHostEntry
VAR_IN_OUT
onlineDevice: ONLINE_DEVICE;
END_VAR
VAR_INPUT
send: BOOL;
END_VAR
VAR_OUTPUT
END_VAR
VAR
sendTrig: R_TRIG;
enable: BOOL;
state: BYTE;
ipState: BYTE;
ipID: BYTE;
ipConnection: IP_C;
fbIPControl: IP_CONTROL;
fbIPFIFO: IP_FIFO;

receiveBuffer: NETWORK_BUFFER;
sendBuffer: NETWORK_BUFFER;
END_VAR

sendTrig(CLK:=send);
enable := sendTrig.Q;

CASE state OF
00: (* auf Freigabe warten *)
IF enable THEN
state := 10;
ipState := 1; (* Anmelden *)
END_IF;

10: (* Warten auf Zugriffsfreigabe zum Verbindung aufbauen und Datensenden *)
IF ipState = 3 THEN (* Zugriff erlaubt ? *)

(* IP Datenverkehr einrichten *)
ipConnection.C_PORT := 49000; (* Port-Nummer eintragen *)
ipConnection.C_IP := IP4_DECODE('192.168.1.62'); (* IP eintragen *)
ipConnection.C_MODE := 0; (* Mode: TCP+AKTIV+PORT+IP *)
ipConnection.C_ENABLE := TRUE; (* Verbindungsaufbau freigeben *)
ipConnection.TIME_RESET := TRUE; (* Zeitüberwachung rücksetzen *)
ipConnection.R_OBSERVE := TRUE; (* Datenempfang überwachen *)

(* Empfangslänge rücksetzen *)
receiveBuffer.SIZE := 0;

(* Sendedaten eintragen und Sendelänge eintragen *)
sendBuffer.SIZE := FC_BufferGetSpecificHostEntry(sendBuffer:= sendBuffer, macAddress:=onlineDevice.macAddress);

state := 30;
END_IF;

30: (* Daten- oder Fehlerauswertung durchführen *)
IF ipConnection.ERROR <> 0 THEN
(* Abmelden â€" Zugriff wieder für andere freigeben *)
ipState := BYTE#4;
state := 00;
ELSIF sendBuffer.SIZE = 0 AND receiveBuffer.SIZE >= 345 THEN
(* Empfangene Daten auswerten *)
FC_EvaluateGetSpecificHostEntry(receiveBuffer:=receiveBuffer, onlineDevice:=onlineDevice);

(* Abmelden â€" Zugriff wieder für andere freigeben *)
ipState := BYTE#4;
state := 00;
END_IF;
END_CASE;

(* IP_FIFO und IP_CONTROL Zyklisch aufrufen *)
fbIPFIFO(FIFO:=ipConnection.FIFO, STATE:=ipState, ID:=ipID);
fbIPControl(IP_C:=ipConnection, S_BUF:=sendBuffer, R_BUF:=receiveBuffer);


Ich könnte mir vorstellen, dass mein Problem ist, dass ich jetzt zwei Instanzen dieser Baustein aufrufe und somit auch zwei Instanzen von IP_FIFO und IP_CONTROL habe, weis aber nicht ob das erlaubt ist oder nicht und wenn nicht?

Wäre sehr froh wenn mir jemand da mal auf die Sprünge helfen könnte.
Liebe Grüße.

peewit

hallo


das einfachste wäre doch wenn du die beiden device gezielt hintereinander abrufst !

teste mal beide einzelnen deviceabfrgaben einzeln
wenn das funktioniert dann musst du ja nur diese gezielt hintereinander aufrufen

ein mögliches problem ist eventuell das eben beiden abfragen gleichzeitig laufen

was genau an der netzwerkschnittstelle passiert könnte man mit einen wireshark mitschnitt ja feststellen
der mitschnitt lässt sich normalerweise auf über die fritzbox durchführen

aber obere idee ist wahrscheinlich die einfachte problemumgehungsvariante

Redkanoon

#2
Hi peewit,

das stimmt, die einfachste Lösung wäre eine Statemaschine und die beiden abfragen nacheinander abzuarbeiten, danke.

Hatte mir aber überlegt das ganze etwas modularer aufzubauen, und mir auch keine Gedanken machen zu müssen wann das Senden ausgelöst wird.

Ich denke, dass wie du beschreibst tatsächlich beide Abfragen gleichzeitig laufen, und somit nur der S_BUF vom zweiten Kommando zum senden an die Schnittstelle geht.
Hatte zumindest die Doku so verstanden, dass der IP_FIFO Baustein die Koordination übernimmt. Und die Kommandos nacheinander raus schickt. (Und vielleicht sogar die Antworten richtig zuordnet.) Ist das Falsch?

Was mir aufgefallen ist, ist das in beiden Instanzen die IP_FIFO.ID gleich ist 16#01, deswegen bin ich mir nicht sicher ob ich zumindest den Baustein nicht nur einmal im ganzen Programm (pro Schnittstelle) haben darf.

Redkanoon

Hi,

nochmal die Frage in die Runde kann mir jemand das Zusammenspiel von IP_FIFO und IP_CONTROL erklären?
Sind die Bausteine Multiinstanz fähig oder darf es immer nur einen Aufruf geben?
Wie schaffe ich es das ich bei einem zweiten Aufruf von IP_FIFO eine neue ID zugewiesen bekomme?
Hat vielleicht jemand ein Beispiel indem mehrere Kommandos gesendet werden?
Kann der IP_FIFO Baustein bei mehrer ausgehenden Nachrichten die Antworten zuweisen?

Grüße
Red

peewit

du kannst mehrere ip_control haben
manche netzwerkzugriffe benötigen nur zeitweise den netzwerkzugriff
um bei kleinen steuerungen schonend mit den ressourcen umzugehen besteht die möglichkeit das man die anfragen seriell abarbeitet
dazu muss man die verschiedenen ip_control zugriffe koordinieren

dazu kann der ip_fifo verwendet werden
diese steuert aber nicht direkt den zugriff sondern ist nur das mittels zum zweck

in der doku vom ip_contol ist ja auch eine exemplarischer Ablauf in ST-Code dargestellt


ip_fifo
du benötigst pro ip_control eine eigene IP_FIFO instanz und diese müssen mit den gleichen IP_FIFO_DATA verlinkt sein
sonst kann das ja nicht funktionieren
dann sollten sich auch bei jeder instanz eine jweils höhe ID ergeben
solange das nicht ist hast du etwas flasch gemacht !