# Get Int, Get Float Problem



## Snoopy123123 (26 März 2009)

Bekomme das mit get int oder get float nicht hin. Was mache ich hier falsch ? Ich möchte aus dem DB9 dw0 z.b den af_at_cork auslesen ud anzeigen.

begin

NoDave.IPAddress:= '192.168.0.70';
NoDave.DBNumber:= 9;
NoDave.Active:= True;

af_at_cork:= NoDave.GetInt(0);
af_after_welding:= NoDave.GetInt(2);
cork_angle:= NoDave.GetFloat(4);
angle_after_welding:= NoDave.GetFloat(8);

label3.Caption:= IntToStr(af_at_cork);
label4.Caption:= IntToStr(af_after_welding);
label5.Caption:= FloatToStr(cork_angle);

NoDave.Active:= false;

end;

hat jemand ne Idee


----------



## MW (26 März 2009)

> begin
> 
> NoDave.IPAddress:= '192.168.0.70';
> NoDave.DBNumber:= 9;
> ...



Von welcher Programmierumgebung (-sprache) reden wir hier überhaupt ?

ich bin mir da nicht so ganz sicher, aber fehlt da nicht noch was, ala Verbindungsaufbau und Readbefehl ??


----------



## Ralle (26 März 2009)

MW schrieb:


> Von welcher Programmierumgebung (-sprache) reden wir hier überhaupt ?
> 
> ich bin mir da nicht so ganz sicher, aber fehlt da nicht noch was, ala Verbindungsaufbau und Readbefehl ??



Sieht aus wie Delphi und er benutzt die Delphikomponente für Libnodave.
Den Verbindungsaufbau macht wohl die Komponente intern, aber mir fehlt da nach der Aktivierung die Überprüfung, daß die Verbindung auch aufgebaut wurde. Außerdem ist es nicht so gut die Verbindung ständig auf- und abzubauen, das kostet enorm Zeit.


----------



## Snoopy123123 (26 März 2009)

Sorry, 
ist in Delphi geschrieben (V10.0)

Ich denke auch das WAS fehlt nur das was kann ich nicht lokalisieren !

Verbindungsaufbau sollte mit der zuletzt eingestellten IP Adresse erfolgen. 

Der verbindunsaufbau erfolgt mit

NoDave.active:= true;  //Das funktioniert auch schon soweit
af_at_cork:= NoDave.GetInt(0);  

//HIer sollte doch das Wort 0 im aufgerufenden DB (hier im DB9) der Variable af_at_cork zugewiesen werden. Leider wird in die Variabke eine 0 geschrieben :-(


----------



## Snoopy123123 (26 März 2009)

Ralle schrieb:


> Sieht aus wie Delphi und er benutzt die Delphikomponente für Libnodave.
> Den Verbindungsaufbau macht wohl die Komponente intern, aber mir fehlt da nach der Aktivierung die Überprüfung, daß die Verbindung auch aufgebaut wurde. Außerdem ist es nicht so gut die Verbindung ständig auf- und abzubauen, das kostet enorm Zeit.




Hallo Ralle,

wie überprüfe ich das die Verbindung auch aufgerufen wurde?

If Nodave.active then 

tue dies

else

showmessage'verbindung nicht aufgebaut'

end;


----------



## Ralle (26 März 2009)

Das muß ich passen, da ich nicht die Komponente nutze, sondern Libnodave direkt. Hast du dir mal das mitgelieferte Beispiel zu Komponente angesehen?


----------



## Ralle (26 März 2009)

Snoopy123123 schrieb:


> Hallo Ralle,
> 
> wie überprüfe ich das die Verbindung auch aufgerufen wurde?
> 
> ...



Ja, zum Beispiel so, obwohl die Message würde ich erstmal weglassen, könnte sein, daß der Verbindungsaufbau etwas dauert. Ich bin mit im Moment nicht sicher, ob Libnodave die Steuerung erst weder hergibt, wenn die Verbindung aufgebaut wurde, dann würde auch dein erster Code gehen, aber Überprüfen ist auf jeden Fall richtig.


----------



## Snoopy123123 (26 März 2009)

Ja mit dem Verbindung auf und abbauen gefäll mir auch gar nicht,
da ich aber auf verschiedene SPSsen (unterschiedliche IP Adressen) an der Zahl 12 Stück zugreifen muss dachte ich das ich immer dann bevor der wechsel auf eine andere IP Adresse folgt die verbindung abbaue und dann
NoDave.IPAddress:= 'XY' mache und dann die Verbindung wieder aufbaue.

Kann man das auch anders lösen ?!


----------



## Ralle (26 März 2009)

Snoopy123123 schrieb:


> Ja mit dem Verbindung auf und abbauen gefäll mir auch gar nicht,
> da ich aber auf verschiedene SPSsen (unterschiedliche IP Adressen) an der Zahl 12 Stück zugreifen muss dachte ich das ich immer dann bevor der wechsel auf eine andere IP Adresse folgt die verbindung abbaue und dann
> NoDave.IPAddress:= 'XY' mache und dann die Verbindung wieder aufbaue.
> 
> Kann man das auch anders lösen ?!



Man kann mehrere Verbindungen gleichzeitig aufbauen, ich mache das auch. Dann brauchst du aber für jede Verbindung eine eigene Komponente (die könnte man ja auch zur Laufzeit erzeugen, ist ja ein Objekt, im Prinzip). Allerdings weiß ich nicht, ob es ein Maximum an Verbindungen gibt. Ich stelle also mehrere Verbindungen her und frage dann nacheinander die Daten ab. Das mit mehreren Komponenten ist nur eine Idee, keine Ahnung ob das so geht, vielleicht hab ich deshalb damals direkt mit der Libnodave.dll gearbeitet, dann geht es auf jeden Fall.


----------



## Snoopy123123 (26 März 2009)

Ralle schrieb:


> Man kann mehrere Verbindungen gleichzeitig aufbauen, ich mache das auch. Dann brauchst du aber für jede Verbindung eine eigene Komponente (die könnte man ja auch zur Laufzeit erzeugen, ist ja ein Objekt, im Prinzip). Allerdings weiß ich nicht, ob es ein Maximum an Verbindungen gibt. Ich stelle also mehrere Verbindungen her und frage dann nacheinander die Daten ab. Das mit mehreren Komponenten ist nur eine Idee, keine Ahnung ob das so geht, vielleicht hab ich deshalb damals direkt mit der Libnodave.dll gearbeitet, dann geht es auf jeden Fall.



Dachte auch schon daran mehre Komponenten auf die Form zu ziehen und die Verbindungen alle mit mit nem Knopf oder mit OnCreate einmal aufbauen und nur mit dem schliessen der Form wieder abbaue. Dann würde ich mir auch das ständige ändern der IP Adressen während der Laufzeit ersparen. Trotzdem verstehe ich nicht warum mit noDave.getint(0) nicht das DW0 aus dem DB 9 geladen wird und stattdessen ne Null drinn steht. Im Simatic Manager sehe ich das ganz sicher keine Null drinn steht.


----------



## Ralle (26 März 2009)

Snoopy123123 schrieb:


> Dachte auch schon daran mehre Komponenten auf die Form zu ziehen und die Verbindungen alle mit mit nem Knopf oder mit OnCreate einmal aufbauen und nur mit dem schliessen der Form wieder abbaue. Dann würde ich mir auch das ständige ändern der IP Adressen während der Laufzeit ersparen. Trotzdem verstehe ich nicht warum mit noDave.getint(0) nicht das DW0 aus dem DB 9 geladen wird und stattdessen ne Null drinn steht. Im Simatic Manager sehe ich das ganz sicher keine Null drinn steht.



Probier mal das Beispiel aus (ich glaub da ist ne Exe dabei). Am Code siehst du dann auch, was los ist. Kann es sein, daß du im DB eine DINT hast und eine Int auslesen willst? Dann würde glaube ich auch eine Null auftauchen.


----------



## Snoopy123123 (26 März 2009)

Habs jetzt nochmal versucht. Eigene Komponente nur für diese IP Adresse angelegt. Verbindung aufgebaut. Verbindung Steht auch ohne Fehler.

begin
if Dave.Active then
begin
Dave.DBNumber:= 9;

label10.Caption:= IntToStr(Dave.GetInt(0));


end
else
end;

Dave.GetInt gibt mir aber ne knallharte Null zurück. Im DB steht auch nur ein INT und kein DINT ! Werde mir auf jedenfall die Demo.exe nochmal anschauen, aber soweit ich die ganzen Variablen aufrufe versteh wird das doch da genau so gemacht.


----------



## MW (26 März 2009)

Blöde Frage: Im DB steht aber auch ein Wert der ungleich null ist, oder ???


Da ich mich nicht mit Delphi und schon garnicht mit der Delhicomponente auskenne, muss ich doch mal fragen ob man da garkein "read"-befehl benötigt ? wie bekommt man den dann immer aktuelle Werte ?


EDIT: Extra für unseren Hochadel (von der Reparatur) der mich dazu zwingt ;-)

Draußen ist es ganz schön kalt, soll das der Frühling sein ? ich glaub es kaum
Aber nicht verzagen es wird bald wärmer !


----------



## Snoopy123123 (26 März 2009)

Tja ich kenn mich leider auch nicht damit aus, deshalb diese Krämpfe.

Da ja Delphi eventorientiert arbeitet habe ich ein Timer mit dem OnTimer Event der jede Sekunde die Procedure abarbeitet.

Eigentlcih dachte ich das GetInt die Werte liest (sprich der REad Befehl von dem du sprichst) Ist das nicht so ?


----------



## Ralle (26 März 2009)

Ich hab mit noch mal die Komponente angesehen. Hast du das richtige Protokoll gewählt? Da gibt es doch schon ein Interval in der Komponente. Port muß 102 sein bei einem Siemens-CP, Protocol "daveProtoISOTCP". Du hast Ereignisse, OnConnect und OnRead, programmier dafür mal eine Routine und laß dir etwas anzeigen (zähl was hoch) damit du siehst, ob da was passiert. Auch ein Breakpoint in den Routinen zeigt dir das. Im Beispiel zur Komponente wird das GetInt im OnRead-Ereignis ausgeführt, also immer, wenn Daten von der SPS gelesen wurden. Noch mal, schau dir das Beispiel an.

Auch Area (daveDB) und BufLen müssen richtig belegt werden!


----------



## Snoopy123123 (26 März 2009)

Das Protokoll ist richtig, habe vergessen zu erwähnen das andere Funktionen wie dave.writebit oder dave.getdbsize funktioieren. Das bedeutet ja das die Kommunikation stehen muss.

Aber BufLen habe ich nicht belegt. Wann wird OnRead ausgeführt ? Zur Zeit nutze ich dieses Event nicht. Hatte alles mit dem TTimer Event gemacht. Wird on Read über die dave.interval Zeit Zyklisch ausgeführt ? Wie muss BufKen der Komponente belegt werden, bin mir schon ziemlich sicher das da mein Problem liegt !

Danke für eure Hilfe


----------



## Snoopy123123 (27 März 2009)

Hallo,

so ich habs jetzt am laufen. Es ist tatsächlich so das man den den Interval Timer der Komponente Setzen mussen und die Variablen über das OnRead event der Komponente auslesen muss. 

Danke für deinen Hinweis Ralle. 

Viele Grüsse


----------



## Snoopy123123 (27 März 2009)

Da die get bit funktion nun funktionert stosse ich schon wieder auf mein nächstes Problem

Den ersten Datensatz möchte ich aus dem DB 9 auslesen. Dann möchte ich noch Daten aus dem DB 65 auslesen. Wie macht man das richtig. 

Ich dachte ich könnte das in meine DaveOnRead Ereignis machen aber der will nicht wirklcih so wie ich will.


procedure TForm3.NoDaveRead(Sender: TObject);


begin


NoDave.DBNumber:= 9;
NoDave.BufLen:=  68;

label5.caption:= IntToStr(NoDave.getint(0));
.
.
.

//Dann Umschalten auf DB 65 
NoDave.DBNumber:= 65;
NoDave.BufLen:= 54;

label44.Caption:= IntToStr(NoDave.GetInt(0));

end;


Was genau mache ich hier falsch ?


----------



## marcengbarth (30 März 2009)

Hi,

du musst die Bytes auch erst von der Steuerung in den Buffer einlesen.


```
NoDave.ReadBytes();
```


----------



## Ralle (30 März 2009)

Ich denke, du kannst den DB nicht im OnRead-Ereignis umstellen und dann gleich Daten daraus lesen wollen. Denn das Ereigniss feuert ja in dem Moment, wo die Komponente die Daten gelesen hat, aber halt aus dem "alten" DB! Also außerhalb umstellen oder vielleicht beim Verlassen von OnRead und dann, wenn OnRead feuert in der OnRead-Procedure als erstes den eingestellten DB ermittlen und danach die entsprechenden Lesefunktionen aufrufen.


----------



## afk (31 März 2009)

Um das Ganze mal aufzuklären:

Mit den Properties der Komponente werden nur Vorgaben für den Aufruf von ReadBytes gesetzt. Aus Performancegründen wird die Methode Readbytes aber nicht automatisch bei Änderungen der Properties aufgerufen. 

Wenn immer nur der gleiche Block aus der SPS gelesen werden soll, dann kann man einfach die Properties setzen, den Interval einstellen, und im OnRead-Event die gelesenen Daten auswerten, das ist in diesem Fall die schnellste und einfachste Lösung.

Wenn aber aus verschiedenen Bereichen bzw. DBs gelesen werden soll, dann ist es sinnvoller, nur die Verbindungsparameter in der Komponente zu setzen (eine Komponente pro SPS), die Verbindung zu aufzubauen, und dann über ein externes Interval (z.B. TTimer) zuerst die Methode ReadBytes (die Variante mit den vielen Parametern) mit den ensprechenden Einstellungen für Bereich, DB-Nr, Adresse usw. aufzurufen, und danach jeweils die gelesenen Daten mit den Methoden der Komponente auszuwerten.

Was in keinem Fall geht, ist die Properties der Komponente zu setzen, und dann direkt die Werte auswerten zu wollen, ohne vorher ReadBytes aufzurufen. Dann hat die Komponente die Werte ganz einfach noch nicht gelesen, und liefert dementsprechend zwangsläufig falsche Werte.


Gruß Axel


----------

