3.4.  Asynchronous acquisition

Of special importance is the so called "asynchronous data acquisition" where Comedi is sampling in the background at a given sample rate. The user can retrieve the data whenever it is convenient. Comedi stores the data in a ring-buffer so that programs can perform other tasks in the foreground, for example plotting data or interacting with the user. This technique is used in programs such as ktimetrace or comedirecord.

There are two different ways how a sequence of channels is measured during asynchronous acquisition (see also the Figure in the introduction):

How your Comedi device handles the asynchronous acquisition can be found out with the command comedi_board_info -v.

The program demo/tut3.c demonstrates the asynchronous acquisition. The general strategy is always the same: first, we tell Comedi all sampling parameters such as the sampling rate, the number of channels and anything it needs to know so that it can run independently in the background. Then Comedi checks our request and it might modify it. For example we might want to have a sampling rate of 16kHz but we only get 1kHz. Finally we can start the asynchronous acquisition. Once it has been started we need to check periodically if data is available and request it from Comedi so that its internal buffer won't overrun.

In summary the asynchonous acquisition is performed in the following way:

The program below is a stripped down version of the program cmd.c in the demo directory. To compile it run:

      gcc tut3.c -lcomedi -lm -o tut3
    

It requests data from two channels at a sampling rate of 1kHz and a total of 10000 samples. which are then printed to stdout. You can pipe the data into a file and plot it with gnuplot. As mentioned above, central in this program is the loop using the standard C read command which receives the buffer contents. Below is an extract from tut3.c showing the relevant commands:

      <xi:include></xi:include>
    

For advanced programmers the function comedi_get_buffer_contents is useful to check if there is actually data in the ringbuffer so that a call of read can be avoided for example when the data readout is called by a timer call-back function.