Entwickler-Ecke

Sonstiges (Delphi) - Automatische anlauf eine Procedure


Omid - Di 06.04.10 20:09
Titel: Automatische anlauf eine Procedure
Hallo,
Ich versuche ein Programm in Delphi zu schreiben ( Anfänger). Ich will Daten von einer Anlage lesen und die bearbeiten. Die Daten sollen ständig gelesen und weiter verarbeitet werde. Wenn ich aber eine Form aufrufe, passier aber erst, wenn ich ein Button anklicke. Das hilft mir aber nicht. Meine Procedure soll bis auf beenden der Form weiter laufen. Wie kann ich das realisieren? Ich bedanke mich für jeder nützliche Hinweis.


platzwart - Di 06.04.10 20:16

Du könntest im OnCreate der Form (also beim erstellen der Form) einen Thread starten, der dann die Verarbeitung übernimmt.


Narses - Di 06.04.10 20:23

Moin und :welcome: im Forum!

Da du noch Anfänger bist, versuch doch mal mit der Suche in: Delphi-Forum, Delphi-Library TTIMER-Komponente regelmäßig eine Aktion auszuführen. :idea: Der Ansatz mit dem Thread ist sicher gut, aber sicher erst für Fortgeschrittene sinnvoll einsetzbar. ;)

cu
Narses


Omid - Mi 07.04.10 20:07

Guten Abend,
Danke für die schnelle Antwort. Mit dem Thread kann ich noch nicht anfangen. Die Lösung mit Timer dachte ich ,wäre einfacher. zu Früh gefreut. Meine Programm hat nur Form1 und Form2. Der Form1 ist die Maske und in dem Form2 habe ich ein Timer.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
Var
 Form2:Tform2
Implementation
{$R*.dfm}
Procedure Eingang;
Begin
// hier werden die Daten von Anlage geholt
End;

procedure Tform2.Timer1Timer(Sender:tobject);
Begin
Eingang;
End;
End.

Sobald ich den Form2 aus Form1 aufrufe kommt eine Fehlermeldung:
Ein Execption der Klasse EaccessViolation aufgetreten.........
Wenn ich die Eingabe von Timer procedure wegnehme ist okay, aber keine Ergebnisse.
Wo ist Bitte meine Fehler?

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


Xion - Mi 07.04.10 20:20

user profile iconOmid hat folgendes geschrieben Zum zitierten Posting springen:

Wenn ich die Eingabe von Timer procedure wegnehme ist okay, aber keine Ergebnisse.
Wo ist Bitte meine Fehler?

Ich würde sagen der Fehler ist in der procedure Eingabe...besonders wenns eine AccessViolation ist.


Omid - Do 08.04.10 13:24

Hallo
Vielen Dank für eure Hinweise. Das hat mir gut geholfen. Das Problem ist gelöst. Es gibt aber ein Phänomen, die sehr störend auf mein Programm wirkt. Sobald ich die Procedere Eingabe in der Timer Procedere aufrufe, wird das Programm sehr träge. Die Reaktion auf meine Befehle ist mit Verzögerung. Ich habe die Intervallzeit von Timer geändert, hat aber kein Einfluss. Diese Verzögerung wirkt auf gesamtes Programm, nicht nur der Form2, wo der Timer aufgerufen wird.
Ist das normal?


Tropby - Do 08.04.10 13:39

Wenn deine Procedure die von dem Timer aufgerufen wird etwas Zeit in anspruch nimmt dann ist das vollkommen normal. Da beide Formulare im gleichem Thread liegen wirst du da auch nicht viel machen können....

Du könntest probieren, zwischendurch in deiner Procedure mal Application.ProcessMessages aufzurufen um die anderen Programmteile ausführen zu lassen.


Omid - Do 08.04.10 19:44

Hi
ich habe ( Application.ProcessMessages) verwendet, hat nicht viel gebraucht. Meine Procedure Eingabe wird noch rechenaufwendiger. das bedutet mein Programm wird zu lagsam.
wenn es keine andere moeglichkeiten gibt, muss ich wohl mit Thread arbeiten. Ich arbeite sei paar tagen mit Delphi. Hat jemand eine Quelle fuer anfaenger, wo einfach erklaert ist, oder eine Einfache Beispiel mit thread.

Omid :les:


MaPsTaR - Sa 10.04.10 10:49

Wie bereits von user profile iconXion erwähnt, wird der Fehler wohl in Eingabe liegen.
Allerdings wird dir, ohne den Code dieser Prozedur, niemand groß weiterhelfen können.

user profile iconOmid hat folgendes geschrieben Zum zitierten Posting springen:


Delphi-Quelltext
1:
2:
3:
4:
Procedure Eingang;
Begin
// hier werden die Daten von Anlage geholt
End;

...lässt eher wenig Möglichkeiten den Fehler zu finden.


Omid - Sa 10.04.10 17:23

Hallo
Mein Programm funktioniert ohne Probleme. Ich kann auch die Daten von der Anlage lesen.
Ich verwende ein Timer. Durch die Timer entstehende Zeitverzögerung ist zu groß. Ich muss meine Daten je 500ms lesen .“ ich habe ( Application.ProcessMessages) verwendet, hat aber nicht viel gebraucht.“.
Hier meine die Zeitverzögerung hat sich nicht geändert. Mein Problem ist also die Verzögerung durch die Timer.
Platzwart schlägt Verwendung von einem Thread. Ich habe über Threads etwas gelesen. Ob ein Thread mein Problem löst( die Zeit Verzögerung)?
Wenn ich meine Prozedur Eingabe in eine schleife aufrufen könnte, wäre ideal.
Das klappt aber nicht. In der Eingabe greife ich auf die serielle Schneistelle (Com 1) der Rechner. Ohne Verwendung von Schleife funktioniert mein Programm richtig. Sobald ich die Eingabe in einem schleife aufrufen reagiere das Programm nicht mehr. Kann man mit Delphi in einer Buttonklick Procedere ( Online) eine Schleife einbauen, und mit einer weiteren Buttonklick Procedere ( Offline) die schleifen beenden?


Tropby - Sa 10.04.10 17:36

Das würde ich dann über einen Thread machen. Der eine Button startet den Thread mit der Schleife in ihm und der zweite Button Beendet oder Pausiert den Thread.

Da es bei Delphi das Objekt TThread gibt ist das auch nicht gerade schwer zu machen. Ein Beispiel hab ich jedoch gerade nicht zur Hand....


Omid - So 11.04.10 05:02

Hi Tropby,
ich brauche genau das,was du beschrieben hast.

( Das würde ich dann über einen Thread machen. Der eine Button startet den Thread mit der Schleife in ihm und der zweite Button Beendet oder Pausiert den Thread.)

ich vesuche es mit Thread.muss ich aber erst lernen wie man so ein Thread difiniert und einsetzt. eine einfache Beispiel waere prima.

Vielen Dank


Tropby - So 11.04.10 10:37

Hier ist ein kurzes Tutorial: http://www.delphi-treff.de/tutorials/objectpascal/threads/page/7/

Da ist nur nicht so alles zu dem TThread erklährt.
Allgemein würde ich sagen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
uses
  classes;

type
  TMyThread = class(TThread)
    private
      { Private-Deklarationen }
    protected
      procedure Execute; override;
    end;

......


procedure TMyThread.Execute;
begin
  while not Self.Terminated do
  begin
    DoSomething();
    
  end;
end;


Und das zum starten:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
  MyThread : TMyThread;

  ...

  MyThread := TMyThread.create(true / false);
  MyThread.Resume;


Das ist alles nicht getestet... Sollte aber so oder so ähnlich funktionieren.


Xion - So 11.04.10 13:33

user profile iconOmid hat folgendes geschrieben Zum zitierten Posting springen:

Ich verwende ein Timer. Durch die Timer entstehende Zeitverzögerung ist zu groß. Ich muss meine Daten je 500ms lesen .“ ich habe ( Application.ProcessMessages) verwendet, hat aber nicht viel gebraucht.“.
Hier meine die Zeitverzögerung hat sich nicht geändert. Mein Problem ist also die Verzögerung durch die Timer.

Mal ne dumme Frage. Ist es nicht möglich, dass die Übertragung einfach nur länger als 500ms dauert? dann kannst du machen was du willst, du wirst es nicht schneller hinbekommen, da der COM-Port nicht sonderlich schnell ist.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
//Timer
var t: cardinal;
begin
  t:=GetTickCount;
  Eingabe;
  Form1.Caption:=inttostr(GetTickCount-t);
end;

Das zeigt dir an wieviele ms deine procedure Eingabe braucht. Ist das mehr als 500ms, dann kannst du auch mit threads nix erreichen. Vielleicht wäre es auch besser, den Timer abzustellen

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
//Timer
var t: cardinal;
begin
  Timer.Enabled:=False;
  t:=GetTickCount;
  Eingabe;
  Form1.Caption:=inttostr(GetTickCount-t);
  Timer.Enabled:=True;
end;

damit du nicht mehrmals "gleichzeitig" die procedure aufrufst, wenn die procedure mehr als 500ms braucht.


Omid - So 11.04.10 19:55

Hallo und danke für die Information.

Also, etwas über meine Prozedur Eingabe: Ich lese / schreibe die Daten aus /in eine S7 über MPI Schnittstelle ( Simatic Prodave). Der Zykluszeit meine SPS Programm ist 500ms. Es muss aber nicht jeder Zyklus gelesen werden . Je 4. Zyklus wurde auch reichen.

@ Xion

Ich habe die Zeitmessung wie du geschrieben hast, durchgeführt. Meine Prozedur Eingabe braucht 5949 ms. Wenn ich die Timer abstellen ändert sich die zeit nicht viel (ca. 15 ms).

@Tropby

Mit deine Information habe ich meine alle erste Thread versuche gestartet. Die Zeit wird nicht viel kleiner aber mein Programm ist nicht mehr träger. Es funktioniert.Immer hin gut.
Hier ist die Delphi Quelltext:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
unit Unit2;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls,prodave;
type
  TMYThread=class(TThread)
      protected
      procedure Execute; Override;
      end;
  TForm2 = class(TForm)
    ende: TButton;
    Timer1: TTimer;
    Edit1: TEdit;
    Edit2: TEdit;
    Online: TButton;
    Offline: TButton;
    procedure endeClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure OnlineClick(Sender: TObject);
    procedure OfflineClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
var
  Form2: TForm2;
implementation
{$R *.dfm}
uses pvar;
procedure Eingabe;
Var
Abbyte,Anzahl:integer;
Begin
 // Werte Holen
     Abbyte:=124;
     Anzahl:=1;
     Res_R:= load_tool(1, addr(sps_name),addr(sps_adr_table[0]));
      if Res_R=0 then
      E_field_read(Abbyte,Anzahl,RW_byte);
      Res_R:=Unload_Tool;
end;
//--------------------------------Werte holen
procedure Tmythread.Execute;
Begin
while not self.terminated do
begin
 Eingabe;
 Form2.Edit2.Text:=intToStr(RW_byte[0]);
 end;
end;
//---------------------------Erstmal ohne Timer
procedure TForm2.Timer1Timer(Sender: TObject);
Var t:cardinal;
begin
 { Timer1.Enabled:=False;
    t:=GetTickCount;
    Eingang;
    Form2.Edit2.Text:=intToStr(RW_byte[0]);
    Timer1.Enabled:=True;
    Edit1.Text:=intTostr(GetTickcount-t);    }

end;
//--------------------------Thread Aktivieren
procedure TForm2.OnlineClick(Sender: TObject);
Var
Thread: TmyThread;
begin
 Thread:=Tmythread.Create(True);
 Thread.Resume;  // ich weiß nicht was das hier macht?
 end;
//-------------------------Thread Beenden
procedure TForm2.OfflineClick(Sender: TObject);
Var Thread:TmyThread;
begin
  Thread:=Tmythread.Create(False);
  
end;
//------------------------Form schliessen
 procedure TForm2.endeClick(Sender: TObject);
 begin
 close;
 end;
end.

Es passiert aber etwas nicht gutes. Wenn ich paar Mal zwischen Online und offline Umschalte kommt eine Fehlermeldung: (Eine Exception der Klasse EexternalException aufgetreten).
Woher kommt der Fehler?
Kann ich irgendwie die zeit noch verkürzen?


:rofl:

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


ALF - So 11.04.10 21:44

Hi, sei so nett und packe den Code in Delphi-Tags ein, findest Du unter "Bereiche" oder schreibe
[delphi] dein Code [/delphi] sieht schöner aus :wink:

Schau Dir das hier [http://wiki.delphigl.com/index.php/Tutorial_Multithreading] mal an.
So wie Du es gemacht hast wird es nichts würde ich mal sagen.
Wobei ich fast der Meinung bin, das dies weniger mit Threads zu tun hat, als mit den ganzen Prodave wie Du es nutzen tust.

Gruss Alf


Delete - So 11.04.10 22:04

Zeige uns doch endlich mal den Code von Eingabe. Eventuell lässt sich da noch was optimieren.


Xion - So 11.04.10 22:09

user profile iconOmid hat folgendes geschrieben Zum zitierten Posting springen:
@ Xion
Ich habe die Zeitmessung wie du geschrieben hast, durchgeführt. Meine Prozedur Eingabe braucht 5949 ms. Wenn ich die Timer abstellen ändert sich die zeit nicht viel (ca. 15 ms).

Die Übertragung dauert 6 Sekunden. Dann ist ja logisch, dass du nicht alle 500ms und auch nicht alle 4*500ms = 2sekunden abrufen kannst. Egal welche Tricks dein Programm auch immer beherrscht.

user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Zeige uns doch endlich mal den Code von Eingabe. Eventuell lässt sich da noch was optimieren.

Jo, das wäre die einzige Möglichkeit. Oder du kannst die "Anlage" so umstellen, dass sie nicht so viele Daten senden soll. Mehr ist nicht drin.

Das ist wie wenn du schlechtes Internet hast, und dann deinen Browser umprogrammieren willst, damit du statt 1000er DSL plötzlich 16.000er DSL hast. Da kannst du lange am Browser basteln, das bringt nix ^^


Narses - So 11.04.10 22:57

Moin!

user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Zeige uns doch endlich mal den Code von Eingabe. Eventuell lässt sich da noch was optimieren.
user profile iconOmid hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure Eingabe;
Var
Abbyte,Anzahl:integer;
Begin
 // Werte Holen
     Abbyte:=124;
     Anzahl:=1;
     Res_R:= load_tool(1, addr(sps_name),addr(sps_adr_table[0]));
      if Res_R=0 then
      E_field_read(Abbyte,Anzahl,RW_byte);
      Res_R:=Unload_Tool;
end;
:nixweiss:

cu
Narses


Xion - So 11.04.10 23:42

Naja, das ist wohl kaum alles. E_field_read wäre interessant zu sehen


Omid - Mo 12.04.10 04:28

Hi

@ Luchie und Xion

Narses hat recht. das ist alles (Eingabe). Die Funktion E_field_read gehoert Pradve.dll von siemens. Da habe ich nur die Funktion aufgerufen.
Das hat auch mit der Anlage nicht zu tun. Hier lese ich nur ein Byte! Was im Dll passiert weiss ich nicht.


Xion - Mo 12.04.10 08:44

Da ist was faul...warum braucht die Funktion 6Sekunden für ein byte...gibts zu der DLL andere Demo-Anwendungen? Brauchen die auch so lange? Evtl funktioniert was nicht und 6 Sekunden ist der TimeOut.


ALF - Mo 12.04.10 12:24

Ich verstehe nur nicht, warum er uns die initialierung der Schnittstelle nicht zeigt!
So viel ich weis gibt es da ein Protokoll für das ganze, bevor ich das so aufrufen kann.
Zu mal ein weiterer Aufruf nur Sinn macht, wenn ich die Daten auch verarbeitet habe!
Egal ob es nur ein Byte ist, ne ganze DBtabelle oder Messdaten.

Irgendwie ist das nicht ganz Durchsichtig?
Kann sein das ich mich irre :gruebel: weil sonst nicht nachvollziehbar mhh...

hier [http://webcache.googleusercontent.com/search?q=cache%3ABj3sv66NeSwJ%3Ahttps%3A%2F%2Fa248.e.akamai.net%2Fcache.automation.siemens.com%2Fdnl_iis%2FTMyMjM0MTMA_1135655_HB%2Fprodav_d.pdf+Prodave.dll&hl=de&gl=de] habe ich mal ne Info uber das ganze. :wink:

Gruss Alf


SvenAbeln - Mo 12.04.10 13:55

Müssen load_tool und Unload_Tool; wirklich bei jedem Zugriff neu aufgerufen werden, reicht es nicht diese nur einmal beim Start und Ende des Programms aufzurufen?
Vielleicht verbraucht dies schon deine ganze Zeit.

Zu deinen Threads und der Accessviolation:

Du solltest dir eine Private Eigenschaft FThread: TmyThread; in deinem Form machen, dann kannst du immer wieder auf deinen Thread zugreifen und ihn anhalten oder weiterlaufen lassen (suspend/resume/terminate)


Omid - Di 13.04.10 04:41

Hallo,
@ Alf
das Protokoll und die Port zugreife sind alle im dll eingepackt.
@ SevenAblen
Es wahr ein Fehler in Offlineclick . Habe es geändert. Das hat aber sich nichts geändert. Mit dem Onlineclick starte ich mein Thread und mit Offlinclick beende ich das.

@ Xion

Hier liegt wahrscheinlich das Problem.. Es stimmt nicht mit License key. Obwohl ich die License Key installiere, findet Automation License Manager das auf die platte nicht. Etwas stimmt nicht.

Ich werde mich bei Siemens erkundigen.

Ich danke euch alle. Ich habe vieles bei euere hinweise über Delphi gelernt.

Omid


ALF - Di 13.04.10 09:37

Deine DLL alleine nützt Dir gar nichts, wenn Du die Inintialisierung nicht richtig machst!
Schau Dir mal den lnk [http://www.sps-forum.de/showthread.php?t=7284] und diesen lnk [http://www.spsforum.com/showthread.php?t=8329] dazu an.
Ich befürchte, das Du es so oder in ähnlicher Form nicht gemacht hast.

Zumal Du uns Deine Form1, wo die Initiallisierung stattfinden muss, nie gezeigt hast!
Das meine ich mit Protokoll!

Gruss ALf


Omid - Mi 14.04.10 06:52

Hi
@ Alf
sorry, ich dachte meine form1 ist nicht so wichtig. Hier wird nur die Form2 aufgerufen. Hier die Code:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Ende: TButton;
    lesen: TButton;
    procedure EndeClick(Sender: TObject);
    procedure lesenClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.EndeClick(Sender: TObject);
begin
close;
end;
procedure TForm1.lesenClick(Sender: TObject);
begin
Form2.show;
end;

end.


die Initialisierung wird in PVar aufgerufen:
code:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
unit pvar;
 interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

Var
  //-------------------------------------SPS
  sps_adr_table: Array[0..15of byte;
  SPS_name:Array[0..256of Char;
  RW_Byte:Array[0..256of byte;
  RW_Word:Array[0..512of word;
  Res_R,Res_w:longint;
  amount: longint;
  m:integer;
 implementation

  Begin
     Sps_adr_table[0]:=2;
     Sps_adr_table[1]:=0;
     Sps_adr_table[2]:=2;
     Sps_adr_table[3]:=0;
     Sps_adr_table[4]:=0;
     Strcopy(sps_name,'S7ONLINE');
     for M:=0 to 512 do RW_byte[M]:=0;
     M:=0;
end.

user profile iconALF hat folgendes geschrieben Zum zitierten Posting springen:
Deine DLL alleine nützt Dir gar nichts, wenn Du die Inintialisierung nicht richtig machst!
Schau Dir mal den lnk [http://www.sps-forum.de/showthread.php?t=7284] und diesen lnk [http://www.spsforum.com/showthread.php?t=8329] dazu an.

der lnk habe ich angeschaut. Fast habe ich das gleiche gemacht.

Mein Programm funktioniert. ich kann die Daten von der sps lesen. No Problem.
Ich brauche 6 ms Um ein Byte zu lesen. Das ist das Problem. Warscheinlich liegt an meine Prodave.
omid

Moderiert von user profile iconNarses: Zitat kenntlich gemacht.


ALF - Mi 14.04.10 16:49

Kannst Du mir mal sagen was Du hier machst?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
var
....
.... 
RW_Byte:Array[0..256of byte; //256 (257)
.....  
implementation
Begin     
......
......
......
 for M := 0 to 512 do   //512 (513)?
     RW_byte[M]:=0;

 M := 0;
end.

Du bist Dir wirklich sicher das es Daten sind die Du auch wirklich anfordest!!!
Kann ich nicht glauben :?
Ich sehe nur zusammen copierten Code ohne Zusammenhang, Keine Verarbeitung der Daten, noch eine Fehlerbehandlung die hier dringend anzuraten ist!
Und sage mir nicht, steht alles in der DLL/Prodave.pas drin!
Ich will Dir nicht's in Abrede stellen aber
wenn es so simple ist, frage ich mich, warum andere es so kompliziert schreiben! :?
Was Deine Zeitangaben betreffen, hast Du beide Schnittstellen angepast! 38400?

Gruss Alf


Chemiker - Mi 14.04.10 23:42

Hallo Omid,

zudem ist es wichtig mit welcher S7 man arbeitet. Bei einer S7/200 gibt es erhebliche Schwierigkeiten.

Bis bald Chemiker


Omid - Do 15.04.10 00:08

Hallo Alf

Ich bin ein delphi Anfänger, bitte vergiss das nicht. Seit ca 2 Wochen bin ich dabei. Eigentlich war ich begeistert, weil mein Programm funktionierte. Wenn ich in der Anlage nicht so schnell etwas ändern wollte, wäre okay gewesen. Das ist aber nicht.
Im Unit Pvar habe ich mein Variabel sowie die SPS Adressen definiert

Die RW_Byte gebe ich die E_Field_read Funktion von dll. Hier bekomme ich meine daten.

Delphi-Quelltext
1:
E_field_read(Abbyte,Anzahl,RW_byte);                    


Ich kann aus ein DB 256 Byte lesen oder in DB schreiben.
In der For schleife initialisiere ich die Felder. Hier ist ein Fehler. Die Schleife muss bis 256 laufen. Danke.
Um die Baurate muss ich mich nicht kümmern. (MPI )

Es muss nicht immer alles so kompliziert sein. Du hast recht, manche mache es so komplizieret.
PS.
Kennst du dich bitte mit Libnodave aus?

Gruss Omid


ALF - Do 15.04.10 05:26

Libnodave ist leider etwas komplizerter, aber der Support ist super!
Zumal es dort auch nen Tool gibt zum Testen von Verbindungen und so.
Empfehlen kann ich es Dir, weil das Forum dort sehr gut ist was libnodave betrifft.
Weil es ja Doch etwas anderes ist.

@Chemiker hat Dir ja auch noch was geschrieben, wo ich nicht nachgefragt habe z.B.! Du siehst alles was damit zu tun hat ist wahrscheinlich dort besser Aufgehoben.

Delphi ist natürlich hier besser :wink:

Was nun aber Deine permanente Abfrage betrifft, so würde ich sagen ist der Ansatz falsch.
Nicht das Connect um Daten zu lesen muss Du in einer Schleife legen, sonder das Datenlesen!
Erst wenn das lesen und verarbeiten der Daten fertig ist und Du keine Daten mehr benötigst kannst Du Res_R:=Unload_Tool aufrufen.

Was Du jetzt machst, ist ja jedesmal das s7online Protokoll zu initialisieren und das kostet Zeit!
Hat Dir @SvenAbeln Auch schon geschrieben.

Was Dein Port betrifft, so solltest Du nicht die MPI an Dein Port anpassen, sondern den Port an das MPI.

Gruss Alf


Omid - Fr 16.04.10 07:47

Hallo Alf,

ich arbeite mit eine S7 300. CPU 315 2DP.

So soll meine Dlephi Programm Ablaufen.

1- Ich gebe erst die Parameter für Produktion.
2- Delphi macht Berechnungen und passt die Parameter für die Maschine (Sollwerte)
3- Die Sollwerte werden in die SPS Datenbaustein geschrieben
4- Delphi macht eine Form_Soll_Ist auf in dem die Sollwerte und die Istwerte dargestellt werden.
Eine Regelung wird hier nicht gemacht. Der Operator kann die Istwerte ändern und an die Sollwertre anpassen ( Drehzahl Vorgaben).

Für Position 3 spielt die Zeit um die daten in SPS zu schreiben keine rolle. Hier läuft die Produktion noch nicht. Hier kann ich die Verbindung aufbauen. Daten rein schreiben. Verbindung beenden.

Für Position 4 soll die daten ständig aktualisiert werden bis die Anlage ausgeschaltet oder mit andren Parameter produziert wird .
Ich soll hier die Verbindung aufbauen und die daten ständig aktualisieren. die Verbindung soll bei beenden von Form_soll_ist abgebaut werden.

Eigentlich war die Idee mit dem Timer gut. Der Timer macht aber das ganze Programm Träger. Kann man der Timer per ButtonClick aktivieren, wenn man ihn braucht? Zum Beispiel in Form_Soll_ist?

Gruss Omid


platzwart - Fr 16.04.10 08:17


Delphi-Quelltext
1:
2:
Timer1.Enabled:= True; // aktivieren
Timer1.Enabled:= False; // deaktivieren


ALF - Fr 16.04.10 09:05

Hi alles klar. :)

Da Du in Pos4 in "echtzeit arbeitest" solltest Du dies nicht mit Timer machen sondern mit Threads
Und genau hier kommt das, was andere schon geschrieben haben.

1.Hauptform starten und Initialisierung der Schnittstelle/Prüfen.
Dabei werden noch keine Daten gelesen oder geschrieben.
2.Dann "ButtonDatenSchreiben"
=>(neue Form mit den Eingabemasken als Thread starten!! Daten anpassen "ButtonOK" berechnen/Prüfen wenn ok, =>Fertige Daten ans HauptFormular geben Anzeigen lassen) ist alles Ok dann!
3."ButtonDaten senden" ist alles OK dann
4."ButtonProzess Starten" und Datenlesen (Wieder als Thread!!!) Empfangene Daten ans Hauptformular geben Anzeigen lassen.
Hier kannst Du jetzt auch Korrekturen für ist/soll vornehmen. Wobei sich die Frage stellt, sollen die Korrekturen an den Prozess geendet werden?????? oder werden nur die soll Werte korregiert!

5."ButtonProzess Beenden".

6.Programm Beenden Verbindung trennen.

Warum so, weil Du jetzt im HauptFormular die gesendeten Daten und die Empfangen Daten siehst und vergleichen kannst. Übersichtlicher!!

Ist jetzt erst mal nur ne Vorlage für ein Prozess. Die Optische Vorlage musst Du natürlich entscheiden wie es aussehen soll :wink:

So würde ich es umsetzen 8)

Gruss Alf


Omid - Sa 17.04.10 09:19

Hallo Alf,
Vielen Dank für die ausführliche Beschreibung. Nach deiner Vorlage werde ich es probieren.
Die Korrektur an meine Ist/sollwerte wird ändere gemacht. Der Operator ändert eine Drehzahl per Schalter in der Anlage. Dieser Wert wird von SPS an Delphi weiter gegeben. Der Operator gleicht die Istwert mit Sollwert.

Gruß
Omid


ALF - Sa 17.04.10 10:27

user profile iconOmid hat folgendes geschrieben Zum zitierten Posting springen:
....Der Operator ändert eine Drehzahl per Schalter in der Anlage. ......

Oha, ist aber nicht gerade Automatisiert!
Oder ist die Steuerung der Drehzahl nicht intigriert, im System?
Na ja, kann ja noch kommen :wink:

Du hast auch nicht gesagt was für einen MPI. Intern oder Extern.
Den Hinweis von mir 38400, bezog sich auf eine externe. Also die MPI nicht an den Port anpassen, sondern versuchen den Port an die MPI anzupassen. Ist zwar etwas mühselig, aber hat den Vorteil, das Du die Externe MPI nicht zustark ausbremmst!?

Gruss Alf


Omid - So 18.04.10 07:03

Hi Alf

Die Anlage wurde so konzipiert. Das habe ich aber nicht geplant. Ich mach die Steuerung, wobei die Planung und die Verkabelung vorhanden war. Ich verwende Externe MPI. Auf dem Umsetzer ist ein Schalter. 38400 und 19200. mit 38.4 ist ca. 1 Sekund schneller. Das ist immer noch die alte Version von meinem Programm. Ich habe deine letzte Anweisungen noch nicht eingesetzt. (Zeit Mangel.
Ich muss das Programm anderes schreiben.

Gruß Omid