Datenerfassungstechnologie spielt eine wichtige Rolle in der industriellen Steuerung und Automatisierung und anderen Bereichen. Der allgemeine Prozess der Datenerfassung ist wie folgt:
①Senden Sie den Kanalauswahlbefehl an die Capture-Karte. ②Wählen Sie die zu erfassende Kanalnummer aus. ③Starten Sie die A/D-Wandlung. ④Warten Sie, bis die Konvertierung abgeschlossen ist. ⑤Daten von der Erfassungskarte lesen. Für die Mehrkanalerfassung werden im Programmdesign im Allgemeinen zwei Methoden verwendet. Abfragemethode oder Interrupt-Methode. Die sogenannte Abfragemethode besteht darin, jeden Datenkanal mithilfe einer Schleife nacheinander zu erfassen. Der Vorteil der Abfragemethode besteht darin, dass das Programm einfach und leicht zu implementieren ist. Der Nachteil besteht darin, dass die CPU während des Erfassungsprozesses die meiste Zeit mit Warten verbringt, was zu einer Verschwendung von Ressourcen führt. Die Interrupt-Methode übernimmt die Form eines Hardware-Interrupts: Starten Sie zuerst die A/D-Wandlung und senden Sie am Ende der Wandlung ein Interrupt-Signal. Die CPU liest die gesammelten Daten aus, wenn sie auf den Interrupt der Erfassungskartendaten reagiert. Auf diese Weise kann die CPU während des Wartens auf die Konvertierung andere Berechnungen durchführen, ohne sich in einem Wartezustand zu befinden. Der Vorteil der Interrupt-Methode besteht darin, dass die Ressourcen vollständig ausgenutzt werden können. Das Programmdesign ist jedoch komplex, insbesondere wenn die Hardware-Interrupt-Ressourcen des Systems knapp sind. Außerdem kann es in Betriebssystemen wie Windows oder Windows leicht zu Interrupt-Konflikten kommen In Win95 dürfen Benutzer keine Interrupt-Handler installieren, was nicht möglich ist.
---- Die beiden oben besprochenen Methoden sind beide Methoden unter DOS; unter Win95 gibt es jetzt eine bessere Methode – die Multithreading-Technologie. Jetzt können wir die Multithreading-Technologie für die Datenerfassung nutzen.
---- 1. Vorteile der Verwendung von Multithreading für die Datenerfassung
---- Das beliebteste an Win95/98 ist neben der schönen Benutzeroberfläche Multithreading und Multitasking. In der DOS-Umgebung kann das ausführende Programm alle Ressourcen beanspruchen; in der Windows-Umgebung kann Ihr Programm, obwohl es sich um eine etwas rudimentäre Multitasking-Umgebung handelt, immer noch die gesamte CPU-Zeit steuern, solange Sie möchten. Unter Windows 95 und Windows NT kann ein Programm jedoch nicht die gesamte CPU-Ausführungszeit für sich beanspruchen. Darüber hinaus besteht ein Programm nicht aus einer Zeile vom Anfang bis zum Ende. Im Gegenteil: Ein Programm kann während der Ausführung in mehrere Programmfragmente aufgeteilt und gleichzeitig ausgeführt werden. Diese gleichzeitig ausführbaren Programmfragmente werden Threads genannt. In Windows 95 und Windows NT kann das Betriebssystem abwechselnd mehrere Programme gleichzeitig ausführen, was als Multitasking bezeichnet wird.
---- Die Verwendung von Multithreading zur Datenerfassung kann die Reaktionsgeschwindigkeit des Programms effektiv beschleunigen und die Effizienz der Ausführung steigern. Allgemeine Programme müssen Benutzereingaben verarbeiten, aber im Vergleich zur Ausführungsgeschwindigkeit der CPU entspricht die Eingabegeschwindigkeit des Benutzers dem Gehen oder Fliegen. Auf diese Weise verschwendet die CPU viel Zeit mit dem Warten auf Benutzereingaben (z. B. in einer DOS-Umgebung). Wenn Multithreading verwendet wird, kann ein Thread verwendet werden, um auf Benutzereingaben zu warten; der andere Thread kann Datenverarbeitung oder andere Arbeiten ausführen. Für Datenerfassungsprogramme kann ein separater Thread zur Datenerfassung verwendet werden. Auf diese Weise kann die Echtzeitcharakteristik der Erfassung weitestgehend gewährleistet werden, während andere Threads zeitnah auf Benutzervorgänge reagieren oder die Datenverarbeitung durchführen können. Andernfalls kann das Programm beim Sammeln von Daten nicht auf Benutzeroperationen reagieren. Insbesondere wenn die erfasste Datenmenge groß und die Datenverarbeitungsaufgabe umfangreich ist, ist die lange Wartezeit während der Erfassung durchaus akzeptabel, wenn kein Multithreading verwendet wird.
---- Multithreading ist jedoch viel komplexer als gewöhnliche Programmierung. Da jederzeit mehrere Threads gleichzeitig ausgeführt werden können, können viele Variablen und Daten von anderen Threads geändert werden. Dies ist das kritischste Problem bei der Synchronisationssteuerung zwischen Threads in Multithread-Programmen.
---- 2. Probleme, die durch Multithreading für die Datenerfassung gelöst werden sollten
---- Tatsächlich ist die Komplexität der Multithread-Programmierung vorübergehend; wenn Sie traditionelles C für Multithread-Design verwenden, müssen Sie die Synchronisation zwischen Threads selbst steuern. Das wäre kompliziert. Wenn Sie jedoch objektorientierte Entwurfsmethoden verwenden und Delphi für die Multithread-Programmierung verwenden, wird das Problem viel einfacher. Das liegt daran, dass Delphi die Komplexität des Multithreadings für uns übernommen hat und wir nur noch erben müssen.
---- Insbesondere muss die Multithread-Datenerfassung die folgenden Arbeiten ausführen:
---- ① Leiten Sie Ihre eigene Klasse SampleThread von der TThread-Klasse ab. Dies ist die Klasse, die wir zur Datenerfassung verwenden. Erstellen Sie beim Sammeln einfach eine Instanz von SampleThread.
---- ② Überladen Sie die Execute-Methode der Superklasse TThread. Bei dieser Methode wird die Datenerfassungsaufgabe gezielt ausgeführt.
---- ③ Wenn Sie gleichzeitig sammeln und anzeigen möchten, schreiben Sie mehrere Prozesse zum Anzeigen des Sammlungsfortschritts für die aufzurufende Execute-Methode.
----Die am häufigsten verwendeten Attribute/Methoden in der TThread-Klasse sind wie folgt:
Create-Methode: Konstruktor Create
(CreateSuspended: Boolean);
----Der Parameter CreateSuspended bestimmt, ob der Thread sofort ausgeführt wird, wenn er erstellt wird. Bei „True“ wird der neue Thread nach der Erstellung angehalten; bei „False“ wird der Thread sofort nach der Erstellung ausgeführt.
FreeOnTerminate-Eigenschaft:
PROperty FreeOnTerminate: Boolean;
---- Dieses Attribut bestimmt, ob der Programmierer für den Abbruch dieses Threads verantwortlich ist. Wenn diese Eigenschaft „True“ ist, zerstört VCL das Thread-Objekt automatisch, wenn der Thread beendet wird. Der Standardwert ist False.
OnTerminate-Eigenschaften:
Eigenschaft OnTerminate: TNotifyEvent;
---- Dieses Attribut gibt ein Ereignis an, das auftritt, wenn der Thread beendet wird.
---- Schauen wir uns ein konkretes Beispiel an:
---- 3. Implementierung einer Multithread-Datenerfassung
---- Dies ist ein vom Autor entwickeltes Programm zur Messung des Leistungsdiagramms einer Pumpeinheit. Seine Funktion besteht darin, die Last- und Verschiebungsdaten des Aufhängungspunkts der Pumpeinheit zu sammeln und nach der Verarbeitung ein Arbeitsdiagramm der Pumpeinheit zu erstellen. Abbildung 1 (weggelassen) zeigt die Schnittstelle während der Datenerfassung. Nachdem Sie auf die Schaltfläche „Daten sammeln“ geklickt haben, erstellt das Programm einen neuen Thread und legt dessen Eigenschaften fest. Dieser neue Thread wird die Datenerfassungsaufgabe abschließen. Das Verfahren ist wie folgt:
ProcedureTsampleForm.
DoSampleBtnClick(Sender: TObject);
Beginnen
ReDrawBtn.Enabled := True;
DoSampleBtn.Enabled := False;
FFTBtn.Enabled := True;
TheSampler := SampleThread.Create(False);
Sammelthread erstellen
TheSampler.OnTerminate := FFTBtnClick;
Aufgaben, die nach Abschluss der Sammlung ausgeführt werden sollen
TheSampler.FreeOnTerminate := True;
Nach Abschluss der Erfassung rückgängig machen
Ende;
----Die Klassendefinition des Sammlungsthreads lautet wie folgt:
Typ
SampleThread = class(TThread)
Öffentlich
Funktion AdRead(ach: byte): integer;
Funktion zum Lesen der A/D-Karte
Prozedur UpdateCaption;
Zeigt die Abholzeit an
Privat
{Private Erklärungen}
geschützt
thes, thep: echt;
dt: real;
ID: Ganzzahl;
st, ed: LongInt;
Prozedur ausführen;
Das ist der Schlüssel.
Ende;
---- In dieser Klasse wird eine Funktion AdRead zum Betreiben der A/D-Karte definiert und die beiden Prozesse werden verwendet, um den Fortschritt und die Zeit der Erfassung anzuzeigen. Es ist zu beachten, dass die AdRead-Funktion in Assembly geschrieben ist und das Parameteraufrufformat Safecall sein muss.
----Der Code der schlüsselüberladenen Methode Execute lautet wie folgt:
Prozedur SampleThread.Execute;
Beginnen
StartTicker := GetTickCount;
id := 0;
Wiederholen
thes := Adread(15) * ad2mv * mv2l;
Erfassen Sie Kanal 15
thep := Adread(3) * ad2mv * mv2n;
Erfassen Sie Kanal 3
dt := GetTickCount - StartTicker;
sarray[id] := thes;
parray[id] := thep;
tarray[id] := dt;
inc(id);
Synchronisieren(UpdateCaption);
Hinweis: Sammlungsfortschritt anzeigen
Bis ID >=4096;
ed := GetTickCount;
Synchronisieren(ShowCostTime);
Hinweis: Zeigt die aufgewendete Zeit an
Ende;
---- Wie aus dem obigen Code ersichtlich ist, gibt es keinen wesentlichen Unterschied zwischen Execute und gewöhnlichem Code. Der einzige Unterschied besteht darin, dass bei der Anzeige des Sammlungsfortschritts und der Anzeige der verstrichenen Zeit die jeweiligen Prozeduren nicht direkt, sondern indirekt über den Aufruf von Synchronize aufgerufen werden können. Dies geschieht, um die Synchronisierung zwischen Prozessen aufrechtzuerhalten.
---- 4. Fazit
----Das obige Programm wurde mit Delphi 4.0 programmiert und auf AMD-K6-2/300 implementiert. Die Testergebnisse lauten wie folgt: Bei Verwendung von Multithreading dauert es im Allgemeinen 10 bis 14 Sekunden, um 4096 Punkte zu sammeln. Wenn Multithreading nicht verwendet wird, dauert es 1 Minute bis 1,5 Minuten. Es ist ersichtlich, dass Multithreading die Ausführungseffizienz des Programms erheblich verbessern kann.