|
Registriert seit: 18. Aug 2008 Ort: Berlin 759 Beiträge Turbo Delphi für Win32 |
#4
@Uwe
Also zu deiner Frage, ich habe das wie folgt programmiert(die meisten Quellcodeteile stammen aus der DP-Suche und aus eigenen Threats hier).
Delphi-Quellcode:
So lasse ich das in der Mainform (TBedienForm) erstmal initialisieren. Im folgenden zeige ich mal die Konstruktoren und Initalisierungen Beispielhaft an einem Perepherie-Gerät (die anderen sind in gleicher Art und Weise aufgebaut):
var
BedienForm: TBedienForm; Protokoll: TProtokoll; Fehler: TFehler; V_Tische: TV_Tische; P_Tisch: TP_Tisch; ControlerBoard: TControlerBoard; bP_Tisch, bV_Tische, bDatenbank_verfügbar: boolean; implementation uses LoaderUnit; procedure TBedienForm.FormCreate(Sender: TObject); begin BedienForm.Enabled := false; // Die Sichtbarkeit der Bedienform ist in der Projektdatei ausgeschalten // Splashscreen öffnen LoaderForm := TLoaderForm.Create(Application); LoaderForm.Show; LoaderForm.Refresh; end; procedure TBedienForm.FormShow(Sender: TObject); begin Protokoll := TProtokoll.create; Fehler := TFehler.create; // ControlerBoard K8055 ControlerBoard := TControlerBoard.create; ControlerBoard.Fehlerevent_ausloesen := Fehler_verifizieren; ControlerBoard.Initialising; // Es wird eine Pause eingelegt, damit auch wirklich Spannung an den Ausgängen // des ControlerBoards und somit an den Controlern für die Tische und so weiter // anliegt. Es dauert zwar theoretisch nur Bruchteile von Sekunden, aber da // noch einiges an Schaltunfen da hinter liegt, soll der Spannung ausreichend Zeit // gegeben werden. sleep(1000); // Verschiebetisch 200mm V_Tische := TV_Tische.create; V_Tische.Fehlerevent_ausloesen := Fehler_verifizieren; bV_Tische := V_Tische.Initialising; // Piezoverschiebetisch 100µm P_Tisch := TP_Tisch.create; P_Tisch.Fehlerevent_ausloesen := Fehler_verifizieren; bP_Tisch := P_Tisch.Initialising; sleep(1000); // Splashscreen schließen LoaderForm.Close; LoaderForm.Free; BedienForm.Enabled := true; end; procedure TBedienForm.FormClose(Sender: TObject; var Action: TCloseAction); begin V_Tische.Free; P_Tisch.Free; ControlerBoard.Free; Fehler.Free; Protokoll.Free; end;
Delphi-Quellcode:
Ich hoffe das hilft euch, mir zu helfen. Ähm ich weiß die Verwendung der try/except-Blöcke ist wohl nicht ganz konform den Regeln und sind so eventuell auch nicht wirklich nötig, wurde ich schonmal drauf hingewiesen, konnte das nur noch nicht umsetzen. Weiterhin der Hinweiß, dass ich kein Fehlerhaftes Hochfahren bisher registriert habe, wenn ich ohne die Perepheriegeräte das Programm lade. Allerdings wird dann auch nur Teile der einzelnen Klassen ausgeführt. Ich weiß, ich muss deswegen sicherlich eine genaue Prüfung aller Klassen nochmal durchführen, hoffe ihr könnt mir aber eventuell helfen und schauen, ob irgendwo ein systematischer Fehler vorliegt.
constructor TControlerBoard.create;
var iIndex: integer; begin //Protokoll.Protokolleingang('ControlerBoard', 'Create'); digEingaenge_pruefen := TTimer.Create(Nil); digEingaenge_pruefen.OnTimer := fdigEingaenge_pruefen; digEingaenge_pruefen.Enabled := true; digEingaenge_pruefen.Interval := 30; for iIndex := 1 to 2 do Diodenhelligkeit[iIndex] := 150; bKamerabeleuchtung_angeschaltet := false; end; function TControlerBoard.DLLHandle_zuweisen: boolean; begin //Protokoll.Protokolleingang('ControlerBoard', 'DLLHandle-Fkt'); Fehlermeldung(300); try ControlerDLL := TDLL_Datei.create('K8055D.DLL'); if ControlerDLL.Vorhanden then begin DLL_Handle := ControlerDLL.Handle; result := true; end else begin Fehlermeldung(301); DLL_Handle := 0; result := false; end except Fehlermeldung(302); result := false; end; //Protokoll.Protokollausgang('ControlerBoard', 'DLLHandle-Fkt'); end; function TControlerBoard.DLLFunktionen_laden: boolean; begin //Protokoll.Protokolleingang('ControlerBoard', 'DLL-Fkt laden'); try if DLL_Handle <> 0 then begin // Es wurde festgestellt, dass nicht alle Funktionen, die in der DLL vorhanden // sind wirklich für die Umsetzung des Programmes benötigt werden. Deswegen // werden hier nur die wirklich verwendeten Funktionen eingebunden, um auch die // Resourcen für das Programm zu beschränken @OpenDevice := GetProcAddress(DLL_Handle, 'OpenDevice'); @CloseDevice := GetProcAddress(DLL_Handle, 'CloseDevice'); @ClearAllAnalog := GetProcAddress(DLL_Handle, 'ClearAllAnalog'); @ClearAllDigital := GetProcAddress(DLL_Handle, 'ClearAllDigital'); @ClearAnalogChannel := GetProcAddress(DLL_Handle, 'ClearAnalogChannel'); @ClearDigitalChannel := GetProcAddress(DLL_Handle, 'ClearDigitalChannel'); @OutputAnalogChannel := GetProcAddress(DLL_Handle, 'OutputAnalogChannel'); @SetDigitalChannel := GetProcAddress(DLL_Handle, 'SetDigitalChannel'); @ReadDigitalChannel := GetProcAddress(DLL_Handle, 'ReadDigitalChannel'); result := true; end else begin Fehlermeldung(303); result := false; end except Fehlermeldung(304); result := false; end; //Protokoll.Protokollausgang('ControlerBoard', 'DLL-Fkt laden'); end; function TControlerBoard.Initialising:boolean; begin try if (DLLHandle_zuweisen = true) and (DLLFunktionen_laden = true) then begin OpenDevice(0); ClearAllDigital; // Das ControlerBoard schaltet die Stromversorgung für die Tische, das // Spleißgerät und die Kamera ein. Deswegen muss es in der BedienForm als // erstes gestartet werden. Wenn es initialisiert wurde, müssen alle // digitalen und analogen Ausgänge eingeschaltet werden, damit eine // erfolgreiche Initialisierung der Tische überhaupt möglich ist. // Ich werde hier aufgrund der einfacheren Wartung für mögliche Nachfolger // direkte Funktionen zur Verfügung stellen, die genau die richtigen dig. // und analogen Ausgänge einschaltet. Damit muss sich später keiner mehr // gedanken machen, welcher Ausgang wohin gehört (Anhalt ist auch die Liste // im Kopf dieser Unit) und brauch gegebenenfalls nur die Funktionen an der // gewünschten Stelle aufrufen. {Liste der einzuschaltenen Geräte per Funktion hier einfügen} Stromversorgung_Verschiebetische_einschalten; Spleissgeraet_einschalten; Kamerabeleuchtung_einschalten; // Hier wird ein neues Konzept benötigt, welches die Gerätebeleuchtung rot // belässt und nur grün anzeigt, wenn das Gerät einsatzbereit ist. Geraetebeleuchtung_schalten(green); result := true; end else begin Fehlermeldung(305); result := false; end except Fehlermeldung(306); result := false; end; end; Destructor TControlerboard.Destroy; begin {Liste der auszuschaltenen Geräte per Funktion hier einfügen} alle_anaAusgeange_ausschalten; alle_digAusgang_ausschalten; digEingaenge_pruefen.Free; //Protokoll.Protokollausgang('ControlerBoard', 'Destroy'); end; @GHorn Also bei den ComPorts bestimme ich über folgender Funktion hier aus der DP welche belegt sind:
Delphi-Quellcode:
Mit dieser Liste teste ich dann, indem ich einen Befehl an das angeschlossene Gerät schicke und prüfe ob es eine Reaktion gibt (ist ein spezifischer Befehl für jedes einzelne der Perepheriegeräte). Wenn ich eine Reaktion bekomme, passte der Befehl zu dem Gerät und der Comport wird diesem Gerät zugeordnet. Wenn nicht, werden die restlichen Comports getestet. Dies funktioniert eigentlich sehr gut, hab in mehreren Tests immer gut detektieren können, welches Gerät angeschlossen ist und welches nicht.
function TComport.ComPort(ComPortNummer: byte): longbool;
var TestHandle : integer; begin TestHandle :=CreateFile(PChar('\\.\COM'+IntToStr(ComPortNummer)),GENERIC_READ or GENERIC_WRITE,0, nil,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,LongInt(0)); if (TestHandle <= 0) then Result := false else begin Result := true; CloseHandle(TestHandle); end; end; // Funktion, die alle ComPorts bis zu einer vom Programmierer festgelegten maximal // ComPortnummer anspricht. function TComport.ComportScan: boolean; var i: integer; aBuffer: array of Integer; begin SetLength(aComport,0); for i := 3 to 100 do begin if ComPort(i) = true then begin if Length(aComport) = 0 then begin SetLength(aComport,1); aComport[0]:= i; end else begin SetLength(aBuffer,Length(aComport)); ArrayInhaltinNeuesArray(aComport,aBuffer); SetLength(aComport,Length(aBuffer)+1); ArrayInhaltinNeuesArray(aBuffer,aComport); aComport[Length(aComport)-1] := i; end; end; end; if Length(aComport) = 0 then result := false else result := true; end; Vielen Dank BAMatze Ps.: Wie schon erwähnt, der Fehler tritt irgendwie nur sporadisch auf.
2. Account Sero
|
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |