Re: how to create a timer controlled analog-in command

On 16/06/06 00:26, hhumphre wrote:
> I am trying to understand cmd.c and use something similar to that.  I have 
> read chapter 4 of the comedilib documentation, but it still doesn't completely 
> make sense to me.  I would like to run comedi_to_phys(), but I don't have all 
> of the arguments I need.  Is it possible to use the higher level commands, as 
> in tut2.c, in a timing controlled manner?

You can use comedi_to_phys() inside the loop to convert each read datum
into a voltage.  You can't use comedi_data_read() as you'll get the data
from the read() system call instead.  You can use things like
comedi_get_range() outside the data fetching loop, not much point doing
it inside the loop if the range remains constant.  (If you have a
different range for each channel in your channel list, you can store the
ranges in an array.

> In cmd.c, inside the loop where the data are printed, I don't really see how 
> it associates the right channel with the corresponding voltage.

The raw data get read in the same order as they appear in the channel
list, repeating until end of acquisition.  The size of each raw datum
depends on the SDF_LSAMPL flag, so will be sizeof(sampl_t) if SDF_LSAMPL
is not set, or sizeof(lsampl_t) if SDF_LSAMPL is set (typically 2 bytes
or 4 bytes, respectively).

So for example, if your channel list is set up to read four channels 2,
3, 7, and 8 and the subdevice's SDF_LSAMPL flag is not set, then
assuming sizeof(sampl_t) is 2, the first 2 bytes read will contain the
raw datum for channel 2 from the first scan, the next 2 bytes will
contain the raw datum for channel 3 from the first scan, the next 2
bytes for channel 7, the next 2 bytes for channel 8, then it will repeat
for the second scan.

You can try and read as much or as little as you like, but the return
value from read() may be less than the amount you asked for.

> Also, I don't really know the most efficient way to add my serial commands to 
> a file structured like cmd.c (or possibly a separate file using a makefile), 
> and to specify the time allotted for those commands.

You could do one of the following:

1) Read a small amount of data at a time (say 1 channel or 1 scan's
worth) and interleave your serial commands with that.

2) Use fcntl() to set the O_NONBLOCK flag on the comedi device's file
descriptor to make it "non-blocking".  This makes the read() call return
an error (errno == EAGAIN) when no data is currently available, in which
case the code has opportunity to do other stuff while waiting for data
to become available.  (If your loop then spends most of its time waiting
for non-blocking reads to return data and non-blocking writes to accept
data, use the select() or poll() calls to sleep until something is
ready.)  You may need to find a good book on UNIX system calls or read
the man pages.

3) Write a multi-threaded application and run the data acquuisition code
and serial control code in separate threads.  You may need to find a
good book on the pthreads library or read the man pages!

-- 
-=( Ian Abbott _at_ MEV Ltd.    E-mail: <abbotti_at_mev.co.uk>        )=-
-=( Tel: +44 (0)161 477 1898   FAX: +44 (0)161 718 3587         )=-

Received on 2006-06-16Z13:10:49