libnodave: Ausgänge und Eingänge gleichzeitig lesen/schreiben

HelmiMUC

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

ich hab libnodave in ein Delphi-Projekt von mir eingefügt.
In diesem Projekt bilde ich mir eine Siemens-Maschinensteuertafel nach.

Ich lese mir 8 Datenbytes an Ausgänge aus und schreibe 8 Eingangbytes.
Soweit so gut.

Wenn ich nur Ausgänge lese, dann funktioniert perfekt - es kommt alles so an wie es ankommen soll.
wenn ich nur Eingänge schreibe, so funktioniert dies auch.
Nur wenn ich Eingänge schreibe dann wird im OnRead der NoDave-Komponente meines Erachtens nicht mehr die eigenetlichen Ausgänge ausgelesen, sondern die Bytes die beim Schreiben der Eingänge verwendet werden, was dann natürlich zu Fehl-Anzeigen der Ausgänge führt.

Wie könnt ich so was unterbinden?
Vielleicht fehlt ja eine Einstellung in NoDave.

mfg
Helmi
 
Nur wenn ich Eingänge schreibe dann wird im OnRead der NoDave-Komponente meines Erachtens nicht mehr die eigenetlichen Ausgänge ausgelesen, sondern die Bytes die beim Schreiben der Eingänge verwendet werden, was dann natürlich zu Fehl-Anzeigen der Ausgänge führt.
Ich vermute mal, Du verwendest die Eigenschaft Interval von TNoDave, damit die Komponente das zyklische Lesen der Daten aus der SPS übernimmt. Dabei wird in jedem Lesezyklus anhand der Eigenschaften ermittelt, was aus der SPS gelesen werden soll. Durch den Aufruf der Methode WriteBytes werden diese Eigenschaften jedoch beeinflußt, wodurch das zyklische Lesen ab dann auf den gleichen SPS-Bereich zugreift, auf den gerade geschrieben wurde.

Wie könnt ich so was unterbinden?
Vielleicht fehlt ja eine Einstellung in NoDave.
Eine Einstellung fehlt da nicht, das ist durchaus so beabsichtigt. Das zyklische Lesen ist im Grunde genommen nur für ganz einfache Anwendungsfälle, in denen immer nur aus dem gleichen Bereich der SPS Daten gelesen werden sollen. Sobald aus verschiedenen Bereichen der SPS gelesen, oder auch schreibend auf die SPS zugegriffen wird, sollte die Eigenschaft Interval auf 0 gesetzt werden, und das Anwendungsprogramm die entsprechenden Daten durch zyklische Aufrufe der Methode ReadBytes aus der SPS lesen.


Gruß Axel
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du meinst also ich soll den Interval der NoDave-Komponente auf 0 setzen und das eigentliche Auslesen der Ausgänge in einem eigenen Timer machen?

Das liese sich tun.

Muss ich mal ausprobieren
 
Hallo,

ich hab jetzt das Lesen mittels NoDave.GetBytes in einem Timer ausprobiert.
Leider ist das gleiche Verhalten festzustellen, als wenn ich es im OnRead der NoDave-Komponente mache.

Nun hab ich noch einen anderen Vorschlag:
Was wäre, wenn ich zwei NoDave-Komponenten verwende?
Eine nur zum Schreiben der Eingänge, die Zweite nur zum Lesen der Ausgänge.

Würde das gehen oder kann es sein, dass sich die beiden in die Querre kommen?
 
ich hab jetzt das Lesen mittels NoDave.GetBytes in einem Timer ausprobiert.
Leider ist das gleiche Verhalten festzustellen, als wenn ich es im OnRead der NoDave-Komponente mache.
Das ist logisch, mit GetBytes wird ja nur aus dem Pufferspeicher gelesen, und nicht aus der SPS. Du mußt in Deinem Timer vorher erst mit ReadBytes die Daten aus der SPS in den Puffer einlesen, und dabei mußt Du jedesmal an ReadBytes übergeben, aus welchem Bereich der SPS du lesen willst.

Nun hab ich noch einen anderen Vorschlag:
Was wäre, wenn ich zwei NoDave-Komponenten verwende?
Eine nur zum Schreiben der Eingänge, die Zweite nur zum Lesen der Ausgänge.

Würde das gehen oder kann es sein, dass sich die beiden in die Querre kommen?
Ist IMHO keine gute Idee, denn jede Komponente belegt eine Verbindung in der SPS. Beim Netlink (nicht beim NL-PRO) und einigen VIPAs hast Du z.B. mit 2 Verbindungen per ISO-over-TCP schon das Limit erreicht, und kommst dann mit Step7 auf dem gleichen Weg schon nicht mehr online.


Gruß Axel
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie würde das dann in Code-Form aussehen?

so etwa:

var
i : Integer;
Buffer: Pointer;
begin

//Timer beenden
Timer_Ausgaenge.Enabled := false;

//
NoDave.Area := daveOutputs;

//alle Bytes - je nach Länge (Daten_Anzahl) auslesen
with Verbindung do
begin
for i := Rec_Offset to Rec_Anzahl + Rec_Offset do
begin
//(Schleifenvariable * Größe) + Offset //Größe bei Byte = 1
NoDave.ReadBytes(Buffer);

//LED´s beschreiben
LEDs_beschreiben(NoDave.GetByte(i, Buffer, 0, Rec_Offset), i);

??
 
Wie würde das dann in Code-Form aussehen?
Ich erkläre es natürlich gerne auch noch zum dritten Mal ... :rolleyes:

NoDave.ReadBytes(Buffer);
Die ReadBytes-Methode ist überladen, d.h. die gibt es in 2 Varianten, eine mit vielen Parametern und eine mit nur einem Parameter. Du nimmst am besten die ReadBytes-Methode mit den vielen Parametern (für Area, Offset, Länge usw.), und in den Parametern übergibst Du den Bereich der SPS, aus dem die Daten gelesen werden sollen. Danach kannst Du aus dem Buffer die Werte mit den Get...-Methoden auslesen. Das geht zwar auch mit der ReadBytes-Methode ohne die vielen Parameter, aber dann mußt Du vor jedem Aufruf von ReadBytes die ganzen Eigenschaften der Komponente entsprechend einstellen, und das ist IMHO umständlicher und fehlerträchtiger.


Gruß Axel
 
Zurück
Oben