Q: the first analog input scan is delayed from the acquisition trigger in NI pci m-series

14 views
Skip to first unread message

Andrey

unread,
Oct 26, 2021, 7:39:08 AM10/26/21
to Comedi: Linux Control and Measurement Device Interface

Hello *,
 I've been trying to get a few AI scans within a pulse.

I've set up an acquisition trigger (from PFI0) to the start of the pulse.
 and wanted to get a few scans immediate (or at least with short delay)
  after the trigger so that I could get the ai values inside the pulse.
When I put scan_begin=TRIG_TIMER in the command struct
then comedi_command_test() insists on that scan_arg should be >= n_chan*dt;
(dt - is the delay between channels in the list of n_chan)

start_src = TRIG_EXT;
start_arg = 0;
scan_begin_src = TRIG_TIMER;
scan_arg = n_chan*dt;  //  if I put less then it's is always overridden with n_chan*dt
convert_src = TRIG_TIMER;
convert_arg = dt;
scan_end_src = TRIG_COUNT;
scan_end_arg = n_chan;
stop_src = TRIG_COUNT;
stop_arg = n_scan;

But this command results in the  first scan being delayed from the trigger
for scan_arg nanoseconds, which comedi_comand() requires/? to be not less than one scan time n_chan*dt .

Or using the picture
(if only I've got it right :)
seq_start - on external trigger from PF0
conversion_interval = dt
assuming that scan_delay = conversion_interval
and also setup_time = 0
  then would be
scan_interval = dt*n_chan
initialization_time  >= scan_interval ???
Though it doesn't seems a reasonable interpretation
  but it's rather forced to fit for my result :-)

It would be great, if someone could point me to where I am wrong
or where should I look into.

~$ comedi_board_info /dev/comedi0
overall info:
  version code: 0x00074c
  driver name: ni_pcimio
  board name: pci-6281
  number of subdevices: 14
subdevice 0:
  type: 1 (analog input)
  flags: 0x11f1b000
  number of channels: 16
  max data value: 262143
  ranges:
    all chans: [-10 V,10 V] [-5 V,5 V] [-2 V,2 V] [-1 V,1 V] [-0.5 V,0.5 V] [-0.2 V,0.2 V] [-0.1 V,0.1 V]
  command:
    start: now|ext|int
    scan_begin: timer|ext
    convert: timer|ext
    scan_end: count
    stop: none|count
  command structure filled with probe_cmd_generic_timed for 1 channels:
    start: now 0
    scan_begin: timer 1600
    convert: timer 1600
    scan_end: count 1
    stop: count 2

Thanks,
   Andrey

Ian Abbott

unread,
Oct 26, 2021, 8:50:02 AM10/26/21
to comed...@googlegroups.com, Andrey
> <http://comedi.org/doc/index.html#fig-acq-seq>
> (if only I've got it right :)
> seq_start - on external trigger from PF0
> conversion_interval = dt
> assuming that scan_delay = conversion_interval
> and also setup_time = 0
>   then would be
> scan_interval = dt*n_chan
> initialization_time  >= scan_interval ???
> Though it doesn't seems a reasonable interpretation
>   but it's rather forced to fit for my result :-)
>
> It would be great, if someone could point me to where I am wrong
> or where should I look into.

You might be able to achieve your goal by using the external trigger to
trigger the scan instead of triggering the start of acquisition. Then
increase the length of the scan to repeat each channel n_scan times. You
will need to provide a longer channel list with channels repeated n_scan
times.

Something like:

start_src = TRIG_NOW;
start_arg = 0;
scan_begin_src = TRIG_EXT;
scan_begin_arg = 0;
convert_src = TRIG_TIMER;
convert_arg = dt;
scan_end_src = TRIG_COUNT;
scan_end_arg = n_chan * n_scan;
stop_src = TRIG_COUNT;
stop_arg = 1;
chanlist_len = n_chan * n_scan;
chanlist contains n_scan sets of n_chan channels.

--
-=( Ian Abbott <abb...@mev.co.uk> || MEV Ltd. is a company )=-
-=( registered in England & Wales. Regd. number: 02862268. )=-
-=( Regd. addr.: S11 & 12 Building 67, Europa Business Park, )=-
-=( Bird Hall Lane, STOCKPORT, SK3 0XA, UK. || www.mev.co.uk )=-

Andrew

unread,
Oct 27, 2021, 9:06:48 AM10/27/21
to Ian Abbott, comed...@googlegroups.com

Thank you Ian !

But the result is no longer that simple :)
Well I can imagine why the first sample in the buffer isn't valid
- perhaps ADC needs some time for its initialization.
With two channels everything is alright (except that first sample)
  and with different number repetitions of them in channel list (kind of 'scans' in previous sense)
  read()  (seems to be) always returns the number of samples equal to the length of the channel list.
With three or more channels read() almost always  returns one additional sample.
   (even for one 'scan').
Sometimes read() does return the proper number of samples,
  but I couldn't find out any correlation with sampling rates, trigger repetitions, channel order etc.

I can live with that, but would of course appreciate any suggestion to clarify the situation

Thanks,
   Andrey

Ian Abbott

unread,
Oct 28, 2021, 5:13:20 AM10/28/21
to comed...@googlegroups.com, Andrew
Hi Andrew,

On 27/10/2021 14:06, Andrew wrote:
>
> Thank you Ian !
>
> But the result is no longer that simple :)
> Well I can imagine why the first sample in the buffer isn't valid
> - perhaps ADC needs some time for its initialization.

Perhaps doing a software read of the first channel in the list before
setting up the acquisition would fix that.

> With two channels everything is alright (except that first sample)
>   and with different number repetitions of them in channel list (kind of
> 'scans' in previous sense)
>   read()  (seems to be) always returns the number of samples equal to
> the length of the channel list.
> With three or more channels read() almost always  returns one additional
> sample.
>    (even for one 'scan').
> Sometimes read() does return the proper number of samples,
>   but I couldn't find out any correlation with sampling rates, trigger
> repetitions, channel order etc.
>
> I can live with that, but would of course appreciate any suggestion to
> clarify the situation

The Comedi file "read" handler only blocks (except in non-blocking mode)
if no data is available the Comedi data buffer and then copies what is
available into the user's buffer. But it doesn't keep blocking to fill
up the user's buffer, so the "read" can return less than the requested
amount.

The device driver is responsible for making data available in the Comedi
data buffer for the Comedi "read" handler to use. For most drivers
(including the ni_pcimio), data is only made available in the Comedi
data buffer during interrupt handling.

For the ni_pcimio driver, the CMDF_WAKE_EOS (or TRIG_WAKE_EOS) flag in
the acquisition command will have cause an interrupt to be generated at
the end of a scan, otherwise it will happen when the FIFO is half full
or at the end of acquisition.

CMDF_WAKE_EOS probably won't do much in your case if the acquisition
consists of a single scan (comprised of several mini scans!).

Andrey

unread,
Oct 28, 2021, 10:04:40 AM10/28/21
to Comedi: Linux Control and Measurement Device Interface
On Thursday, 28 October 2021 at 11:13:20 UTC+2 Ian Abbott wrote:
Hi Andrew,

On 27/10/2021 14:06, Andrew wrote:
>
> Thank you Ian !
>
> But the result is no longer that simple :)
> Well I can imagine why the first sample in the buffer isn't valid
> - perhaps ADC needs some time for its initialization.

Perhaps doing a software read of the first channel in the list before
setting up the acquisition would fix that.


Oh yes,
but it is also a delay from a trigger for the conversion interval.
 
> With two channels everything is alright (except that first sample)
>   and with different number repetitions of them in channel list (kind of
> 'scans' in previous sense)
>   read()  (seems to be) always returns the number of samples equal to
> the length of the channel list.
> With three or more channels read() almost always  returns one additional
> sample.
>    (even for one 'scan').
> Sometimes read() does return the proper number of samples,
>   but I couldn't find out any correlation with sampling rates, trigger
> repetitions, channel order etc.
>
> I can live with that, but would of course appreciate any suggestion to
> clarify the situation

The Comedi file "read" handler only blocks (except in non-blocking mode)
if no data is available the Comedi data buffer and then copies what is
available into the user's buffer. But it doesn't keep blocking to fill
up the user's buffer, so the "read" can return less than the requested
amount.


Yes, sure.
But I send the comedi command and then read (in blocking mode)  until EOF
and most of the time I get n_chan*n_miniscan+1 samples
for the command with the chanlist of n_chan*n_miniscan entries and one scan.

Even more strange:
for 1-channel list and just one scan in 2933  reads I've got always 1 sample
for 2-channel list and just one scan in 2476  reads I've got
2 samples - 2462 times
3 samples - 14 times

for 3-channel list and just one scan in 758  reads I've got
3 samples - 327 times
4 samples - 431 times

for 4-channel list and just one scan in 2056 reads I've got
4 samples - 6 times
5 samples - 21 times
6 samples - 2029 times

for 5-channel list and just one scan I've got mostly 6 samples
sometimes 7 and never (in ~2000 reads) 5

The device driver is responsible for making data available in the Comedi
data buffer for the Comedi "read" handler to use. For most drivers
(including the ni_pcimio), data is only made available in the Comedi
data buffer during interrupt handling.

For the ni_pcimio driver, the CMDF_WAKE_EOS (or TRIG_WAKE_EOS) flag in
the acquisition command will have cause an interrupt to be generated at
the end of a scan, otherwise it will happen when the FIFO is half full
or at the end of acquisition.

CMDF_WAKE_EOS probably won't do much in your case if the acquisition
consists of a single scan (comprised of several mini scans!).


It seems there is no difference in my case between
cmd->flags=TRIG_WAKE_EOS,   cmd->flags=TRIG_ROUND_UP | TRIG_WAKE_EOS
or just cmd->flags=TRIG_ROUND_UP (at it was before)

Although in NI628xSpecifications-371292g.pdf
"Scan list memory .............................4,095 entries"
comedi_command() allows the chanlist not more than 512 entries.
So I can't get more than 512 samples (hw buffer 2k samples).

Reply all
Reply to author
Forward
0 new messages