AG_RECV und Pointer(SCL)

ditj_vitja

Level-1
Beiträge
36
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich versuche mit SCL
AG_RECV(ID := 1 // IN: INT
,LADDR := w#16#0100 // IN: WORD
,RECV := db1.dbw0 // IN: ANY
,NDR := recv_done // OUT: BOOL
,ERROR := recv_error// OUT: BOOL
,STATUS := recv_status // OUT: WORD
,LEN := recv_len // OUT: INT
); // VOID

ein Telegram zu empfangen.
mein DB1 ist bei DBW0 ein INT, ich versuche den Integerwert 102 zur sps zu schicken, das was da ankommt ist jedoch nur 10.. ich vermute es liegt an meiner RECV := db1.dbw0 Anweisung.
Ich weiss jedoch nicht wie ich da einen Pointer machen könnte wie zum Beispiel in AWL mit P#DB1.DBX0.0 Byte 2 bräuchte ich ja eigentlich aber ich weiss nicht wie ich das fertig machen kann...
Ich hoffe es kann mir wer helfen und danke schonmal vorab...
Die Informationen die ich bislang hier im Forum dazu gefunden habe konnten mir nicht wirklich weiterhelfen.. weil ich auch gerade erst mit SCL angefangen habe zu arbeiten.

Danke schonmal vorab!
 
Hallo,
ich denke, du vermutest schon richtig ... es wird ein ANY-Pointer auf einen Datenbereich erwartet und nicht eine einzelne Variable.
Vorschlag :
Du programmierst das Ganze in einem FB, legst im Bereich VAR einen Puffer an und übergibst den an den FB - da mußt du dann in SCL nicht mal mehr einen Pointer bauen - das macht es schon selbst ...

Code:
VAR
Puffer : Array [0..255] of byte ;
end_Var
 
und am Baustein-Aufruf dann :
 
AG_RECV(ID := 1 // IN: INT
,LADDR := w#16#0100 // IN: WORD
,RECV := [COLOR=red][B]Puffer[/B][/COLOR] // IN: ANY
,NDR := recv_done // OUT: BOOL
,ERROR := recv_error// OUT: BOOL
,STATUS := recv_status // OUT: WORD
,LEN := recv_len // OUT: INT
); // VOID
Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
würde das evtl auch so gehen?

receive: ANY;
NACH AT receive: STRUCT
ID : WORD;
NBR : INT;
DBN : INT;
PTR : DWORD;
END_STRUCT;

NACH.ID := 16#0100;
NACH.NBR := 2;
NACH.DBN := 1;
NACH.PTR:= INT_TO_DWORD (8*10) OR 16#8400_0000;
und dann den ag_recv aufrufen?!

AG_RECV(ID := 1 // IN: INT
,LADDR := w#16#0100 // IN: WORD
,RECV := receive // IN: ANY
,NDR := recv_done // OUT: BOOL
,ERROR := recv_error// OUT: BOOL
,STATUS := recv_status // OUT: WORD
,LEN := recv_len // OUT: INT
); // VOID

so??

weil deinen ansatz versteh ich grad nicht so auf die schnelle.. wie gesagt bin grad neu in der materie =)
 
würde ich so nicht machen (ich mag das Umgehen mit absoluten Aufrufen in SCL gar nicht) ... aber könnte funktionieren ... probier es aus ...

Mein Ansatz war, den Puffer, den du im DB1 abbildest direkt in dem SCL-Baustein abzubilden (das erspart dann die Pointerei und erspart die Fehlersuche) und dann die weitere Auswertung (die du ja sicherlich auch noch machen willst/mußt) dann auch gleich sauber hinzubekommen ...
Das ist aber halt meine Sicht der Dinge ...

Gruß
Larry
 
Hey.. dankeschön.. aber ich hab grad warum auch immer das Problem, dass aufeinmal die SF-Leuchte leuchtet.. und ich weiss nicht warum.. sobald ich die sps auf run stelle leuchtet sie los.. ich hab schon urlöschen versucht und dann das s7-programm wieder in die cpu zu laden und jedesmal wenn ich die sps wieder starte leuchtet die cpuleuchte rot.. was kann das denn nun sein?
 
sauber danke.. es lag wohl daran dass ich das mit den pointer versucht habe zu machen und denn sagt er mir dass der OB nicht mehr aufgerufen werden konnte..
 
Hmm...
mit deiner Variante mit dem Puffer ist das genauso wie wenn ich den Pointer baue.. die CPUleuchte SF wird rot.. :(

oder ich habs immernoch falsch drin..


FUNCTION_BLOCK FB1

VAR_TEMP
// temporäre Variablen

recv_done: BOOL;
recv_error: BOOL;
recv_status: WORD;
snd_done:BOOL;
snd_error:BOOL;
snd_status: WORD;
sende: BOOL;
END_VAR
VAR
// statische Variablen
recv_len :INT ;
Puffer : Array [0..255] of byte ;
END_VAR


IF vor2in = true THEN
sende := true;
END_IF;
IF snd_done = true THEN
sendemerker := true;
END_IF;

IF sendemerker = true THEN
sende := false;
END_IF;
IF vor2in = false THEN
sende := false;
sendemerker := false;
END_IF;
// Anweisungsteil
AG_RECV(ID := 1 // IN: INT
,LADDR := w#16#0100 // IN: WORD
,RECV := puffer // IN: ANY
,NDR := recv_done // OUT: BOOL
,ERROR := recv_error// OUT: BOOL
,STATUS := recv_status // OUT: WORD
,LEN := recv_len // OUT: INT
); // VOID

AG_SEND(ACT := sende // IN: BOOL
,ID := 1 // IN: INT
,LADDR := w#16#0100 // IN: WORD
,SEND := db1.dbb9 // IN: ANY
,LEN := 1 // IN: INT
,DONE := snd_done // OUT: BOOL
,ERROR := snd_error // OUT: BOOL
,STATUS := snd_status // OUT: WORD
); // VOID

IF recv_done = true THEN
IF db1.dbw0 = 102 THEN
fb102.db102();
ELSIF db1.dbw0 = 103 THEN
fb103.db103();
ELSIF db1.dbw0 = 104 THEN
fb104.db104();
END_IF;
END_IF;

END_FUNCTION_BLOCK

ORGANIZATION_BLOCK OB1
VAR_TEMP
// reserviert
info : ARRAY[0..19] OF BYTE;
// temporäre Variab
END_VAR
// Anweisungen
fb1.db2();


END_ORGANIZATION_BLOCK


Das ist mein Code der zu dem CPUfehler führt.. ich versteh nicht was da los ist....Oo
 
alles aktualisiert und alles gespeichert....

der diagnosepufffer sagt sowas:


STOP-Ursache: STOP durch Programmierfehler (OB nicht geladen oder nicht möglich, bzw. kein FRB vorhanden )
Anlaufinformation:
- Anlauf ohne geänderten Systemausbau
- keine Soll-/Istdifferenz vorhanden
- Uhr für Zeitstempel bei letztem NETZ-EIN gepuffert
- Einprozessorbetrieb
Aktuelle/letzte durchgeführte Anlaufart:
- Neustart (Warmstart) durch MPI-Bedienung; letzter NETZ-EIN gepuffert
Zulässigkeit bestimmter Anlaufarten:
- manueller Neustart (Warmstart) zulässig
- automatischer Neustart (Warmstart) zulässig
Letzte gültige Bedienung oder Einstellung der automatischen Anlaufart bei NETZ-EIN:
- Neustart (Warmstart) durch MPI-Bedienung; letzter NETZ-EIN gepuffert
Angeforderter OB: Anlauf-OB (OB 100)
OB nicht vorhanden oder gesperrt oder nicht startbar im aktuellen Betriebszustand
kommendes Ereignis
22:35:56.565 07.03.1994
 
Code:
,STATUS := recv_status // OUT: WORD
,LEN := recv_len // OUT: INT
); // VOID

AG_SEND(ACT := sende // IN: BOOL
,ID := 1 // IN: INT
,LADDR := w#16#0100 // IN: WORD
,SEND := [COLOR="Red"][B][I][U]db1.dbb9 // IN: ANY[/U][/I][/B][/COLOR]
,LEN := 1 // IN: INT
,DONE := snd_done // OUT: BOOL
,ERROR := snd_error // OUT: BOOL
,STATUS := snd_status // OUT: WORD
); // VOID

Stimmt das denn so?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ja das senden funktioniert schon aber es hackt jetzt eben an dem send baustein und dem dazugehörigen pointer denke ich mal...

ich habe einen DB1 mit einem INT und möchte diese variable füllen..

jedoch weiss ich wiegesagt nicht, wie ich den AG_RECV baustein aufrufen muss mit dem richtigen Pointer...
in AWL ist P#DB1.DBX0.0 BYTE 2 nun muss ich diesen Pointer in scl überführen.. aber weiss nicht wie...

gruß
 
------------------------------
Gelöscht!
------------------------------
Habe nicht zu ende gelesen, das ging ja noch weiter
 
Zuletzt bearbeitet:
Kannst den Puffer auch für send anlegen


Code:
snd_done:BOOL;
snd_error:BOOL;
snd_status: WORD;
sende: BOOL;
END_VAR
VAR
// statische Variablen
recv_len :INT ;
Puffer : Array [0..255] of byte ;
[B][COLOR="Red"]
send_len :INT ;
Puffer2 : Array [0..255] of byte ;
END_VAR
[/COLOR][/B]

IF vor2in = true THEN
sende := true;
END_IF;
IF snd_done = true THEN
sendemerker := true;
END_IF;

IF sendemerker = true THEN
sende := false;

sollte doch genauso gehen
 
ich bekomme das telegramm empfangen, jedoch nur 2 von 3 stellen....
und genau dafür brauche ich den pointer p#db1.dbx0.0 byte 2, denke ich zumindest..

ich will einen int wert von 102 an die sps schicken und er bekommt nur die 10
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ich bekomme das telegramm empfangen, jedoch nur 2 von 3 stellen.... [...]
ich will einen int wert von 102 an die sps schicken und er bekommt nur die 10
Das ist bei einem INT-Format nicht möglich.

Entweder Du empfängst noch garnichts,
oder Du sendest nicht 102 im INT-Format,
oder Du beobachtest falsch.

Wenn Du sicher bist, daß Dein AG_RECV nun fehlerfrei genau 2 Byte empfängt, dann
untersuche den Datensender, dann sendet der was anderes als eine 102 im INT-Format.

Und benutze zum Test der Übertragung besser den INT-Wert 12345, damit lassen sich
eventuelle Übertragungsprobleme besser analysieren.

Harald
 
Hey ho,

ob du es glaubst oder nicht :) aber ich bekomme anstatt der 102 wirklich nur die 10.. nun habe ich anstatt des pointers bei dem ag_recv baustein einfach den datenbereich größer gemacht mit db1.dbd0 und schon bekomme ich in den ersten 3 stellen 102 die letzten stellen sind zwar Murks, aber ich greif mit db1.dbb0 -2 einfach die ersten 3 stellen raus und alles ist super.. danke für die Hilfe, auch wenn keiner von euch mir nun den gewünschten Pointer gegeben hat ;)


Gruß
Viktor
 
Hey ho,

ob du es glaubst oder nicht :) aber ich bekomme anstatt der 102 wirklich nur die 10.. nun habe ich anstatt des pointers bei dem ag_recv baustein einfach den datenbereich größer gemacht mit db1.dbd0 und schon bekomme ich in den ersten 3 stellen 102 die letzten stellen sind zwar Murks, aber ich greif mit db1.dbb0 -2 einfach die ersten 3 stellen raus und alles ist super.. danke für die Hilfe, auch wenn keiner von euch mir nun den gewünschten Pointer gegeben hat ;)

Weil du dafür ein SCL keinen Any Pointer brauchst.
Wenn du an den AG_RECV Baustein in SCL ein "DB1.DBW0" heranschreibst, macht er dir daraus einen Any-Pointer vom Typ:
P#DB1.DBX0.0 WORD 1

Wenn du im DB1 an Adresse 0 eine Integer-Variable anlegst, und dann in SCL symbolisch darauf zugreifst wie z.B. "DatenDB1".iVar1 dann macht dir SCL wenn du das so am AG_RECV anschaltest einen Any-Pointer vom Typ:
P#DB1.DBX0.0 INT 1

Den Unterschied sollte man gerade bei den Bausteinen zum Datenaustausch beachten, da es einige Bausteine gibt die bei unterschiedlichen Datentypen auf beiden Seiten nicht korrekt arbeiten. Auch wenn die Länge der Daten in beiden Fällen gleich ist (2 Byte).
 
Zurück
Oben