Data acquisition technology plays an important role in industrial control and automation and other fields. The general process of data collection is as follows:
①Send the channel selection command to the capture card. ②Select the channel number to be collected. ③Start A/D conversion. ④Wait until the conversion is completed. ⑤Read data from the acquisition card. For multi-channel acquisition, two methods are generally used in program design. Query method or interrupt method. The so-called query method is to use a loop to collect each data channel in sequence. The advantage of the query method is that the program is simple and easy to implement; the disadvantage is that during the collection process, the CPU spends most of its time waiting, resulting in a waste of resources. The interrupt method adopts the form of hardware interrupt - first start the A/D conversion, and send an interrupt signal at the end of the conversion - the CPU reads out the collected data when responding to the interrupt of the acquisition card. data. In this way, while waiting for conversion, the CPU can perform other calculations without being in a waiting state. The advantage of the interrupt method is that resources can be fully utilized; however, the program design is complex, especially when the system's hardware interrupt resources are tight, it is easy to cause interrupt conflicts; in addition, in operating systems such as Windows or Win95, users are not allowed to install interrupt handlers time, it cannot be achieved.
---- The two methods discussed above are both methods under DOS; under Win95, there is now a better method - multi-threading technology. Now, we can take advantage of multi-threading technology for data collection.
---- 1. Advantages of using multi-threading for data collection
---- The most popular thing about Win95/98, besides the beautiful interface, is multi-threading and multi-tasking. In the DOS environment, the executing program can monopolize all resources; in the Windows environment, although it is a slightly rudimentary multi-tasking environment, your program can still control all the CPU time as long as you like. However, in Windows95 and Windows NT, a program cannot monopolize all CPU execution time. Moreover, a program is not one line from beginning to end. On the contrary, a program can be divided into multiple program fragments during execution and executed simultaneously. These program fragments that can be executed simultaneously are called threads. In Windows 95 and Windows NT, the operating system can take turns executing multiple programs at the same time, which is multitasking.
---- Using multi-threading for data collection can effectively speed up the response speed of the program and increase the efficiency of execution. General programs must process user input, but compared to the execution speed of the CPU, the user's input speed is like walking or flying. In this way, the CPU will waste a lot of time waiting for user input (such as in a DOS environment). If multi-threading is used, one thread can be used to wait for user input; the other thread can perform data processing or other work. For data collection programs, a separate thread can be used for data collection. In this way, the real-time nature of collection can be guaranteed to the greatest extent, while other threads can respond to user operations or perform data processing in a timely manner. Otherwise, the program cannot respond to user operations when collecting data; it cannot collect data when responding to user operations. Especially when the amount of data collected is large and the data processing task is heavy, the long wait during collection is very acceptable if multi-threading is not used.
---- However, multithreading is much more complex than ordinary programming. Since multiple threads may be executing at the same time at any time, many variables and data may be modified by other threads. This is the most critical synchronization control issue between threads in multi-threaded programs.
---- 2. Problems that should be solved by multi-threading for data collection
---- In fact, the complexity of multi-threaded programming is temporary; if you use traditional C for multi-threaded design, then you must control the synchronization between threads yourself. That would be complicated. However, if you use object-oriented design methods and use Delphi for multi-threaded programming, the problem will be much simpler. This is because Delphi has handled the complexity of multi-threading for us, and all we have to do is inherit.
---- Specifically, multi-threaded data collection needs to complete the following work:
---- ① Derive your own class SampleThread from the TThread class. This is the class we use for data collection. When collecting, simply create an instance of SampleThread.
---- ② Overload the Execute method of the super class TThread. In this method, the data collection task will be specifically performed.
---- ③ If you want to collect and display at the same time, write several processes for displaying the collection progress for the Execute method to call.
----The most commonly used attributes/methods in the TThread class are as follows:
Create method: constructor Create
(CreateSuspended: Boolean);
----The CreateSuspended parameter determines whether the thread will be executed immediately when it is created. If True, the new thread is suspended after creation; if False, the thread is executed immediately after creation.
FreeOnTerminate property:
PRoperty FreeOnTerminate: Boolean;
---- This attribute determines whether the programmer is responsible for canceling this thread. If this property is True, VCL will automatically destroy the thread object when the thread terminates. Its default value is False.
OnTerminate properties:
property OnTerminate: TNotifyEvent;
---- This attribute specifies an event that occurs when the thread terminates.
---- Let's look at a specific example:
---- 3. Implementation of multi-threaded data collection
---- This is a program developed by the author to measure the performance diagram of a pumping unit. Its function is to collect the load and displacement data of the suspension point of the pumping unit, and then make a work diagram of the pumping unit after processing. Figure 1 (omitted) shows the interface during data collection. After clicking the "Collect Data" button, the program will create a new thread and set its properties. This new thread will complete the data collection task. The procedure is as follows:
ProcedureTsampleForm.
DoSampleBtnClick(Sender: TObject);
Begin
ReDrawBtn.Enabled := True;
DoSampleBtn.Enabled := False;
FFTBtn.Enabled := True;
TheSampler := SampleThread.Create(False);
Create collection thread
TheSampler.OnTerminate := FFTBtnClick;
Tasks to be performed after the collection is completed
TheSampler.FreeOnTerminate := True;
Undo after collection is complete
End;
----The class definition of the collection thread is as follows:
Type
SampleThread = class(TThread)
Public
function AdRead(ach: byte): integer; safecall;
Function to read A/D card
procedure UpdateCaption;
Display the collection time
private
{Private declarations}
protected
thes, thep: real;
dt: real;
id: integer;
st, ed: LongInt;
procedure Execute; override;
This is the key.
End;
---- In this class, a function AdRead is defined for operating the A/D card, and the two processes are used to display the progress and time of collection. It should be noted that the AdRead function is written in assembly, and the parameter calling format must be safecall.
----The code of the key overloaded method Execute is as follows:
Procedure SampleThread.Execute;
Begin
StartTicker := GetTickCount;
id := 0;
Repeat
thes := Adread(15) * ad2mv * mv2l;
Acquire channel 15
thep := Adread(3) * ad2mv * mv2n;
Acquire channel 3
dt := GetTickCount - StartTicker;
sarray[id] := thes;
parray[id] := thep;
tarray[id] := dt;
inc(id);
Synchronize(UpdateCaption);
Note: Display collection progress
Until id >=4096;
ed := GetTickCount;
Synchronize(ShowCostTime);
Note: Show the time spent
end;
---- As can be seen from the above code, there is no essential difference between Execute and ordinary code. The only difference is that when displaying the collection progress and displaying the elapsed time, the respective procedures cannot be called directly, but indirectly by calling Synchronize. This is done to maintain synchronization between processes.
---- 4. Conclusion
----The above program is programmed using Delphi 4.0 and implemented on AMD-K6-2/300. The test results are as follows: using multi-threading, it generally takes 10 to 14 seconds to collect 4096 points; if multi-threading is not used, it takes 1 minute to 1 and a half minutes. It can be seen that multi-threading can significantly improve the execution efficiency of the program.