Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

SCAN_Op does not allow to take only one sample per channel

Hello!

I'm using trad. NIDAQ with an 6024E board and when I call

NumChans   := 8;
Count      := 8;
SampleRate := 20000;
ScanRate   := 1250;

Status := SCAN_Op(DEV_NUM, NumChans, @Chans, PGains, PBuffer, Count, SampleRate, ScanRate);

I get the following error:

-10010    badCountError    The count is too small or too large for the specified counter, or the given I/O transfer count is not appropriate for the current buffer or channel configuration.

However,  if Count := 16 or another multiple of 8,
SCAN_Op behaves correctly.

I'm using Delphi, but I tried this with C++ with the same results.

Any thoughts ?

Thanks,
Daniel

0 Kudos
Message 1 of 8
(4,474 Views)
The point of SCAN_Op is to return multiple points per channel where each point is separated in time by a clock. When numchans is 8 and count is 8 you are just getting one point per channel. SCAN_Op enforces a minimum of 2 points per channel I believe. Try AI_VRead_Scan.
Message 2 of 8
(4,467 Views)
Thanks thayles,

Yes,  SCAN_Op forces me to make two conversions per channel at least, (the documentation doesn't mention this)

AI_Read_Scan does give me just one sample per channel, but only at half the maximum sample rate, so it's no better than SCAN_Op for my application

I need to acquire 8 channels within a 50us window, that is 160kHz sample rate

I thought I could do it with the 6024E, but now I'm not so sure

Perhaps NIDAQmx has some function that allows me to take just one point per channel, so I can sample at more than 100kHz?


0 Kudos
Message 3 of 8
(4,455 Views)
You might try using the SCAN_Setup and SCAN_Start pair of functions. You will have to satisfy the minimum count requirement here too but it's just a formality. By setting the 'scanTimebase' parameter to 0, you can control the scan timing yourself. Wire a DIO line to a pin you used as the external source for your scanTimebase (probably PFI 7). Set your 'sampTimebase' and 'sampInterval interval such that you get 50 uSec between samples (sampTimebase = 1 and sampInterval = 50 I believe). Then, when you want to capture a single 8 channel scan, toggle that DIO line once. You will capture just a single scan that way and at the inter-channel timing that you want.
Message 4 of 8
(4,449 Views)
Thanks, I will try that

just one thing: my 50 us window is for all 8 channels,  so that means 50/8 = ~6 us between samples
0 Kudos
Message 5 of 8
(4,439 Views)
Hi thayles,

i tried your suggestion but unfortunately it doesn't work

I can indeed capture a single scan (as before), but the problem is I get 2 points per channel, for a total of 16 points

what I want is simple: 8 channels, 8 analog-to-digital conversions, with 6us (or less) delay between channels

any suggestions?
0 Kudos
Message 6 of 8
(4,421 Views)

Here's code describing what I meant. I didn't compile and run this so forgive any typos. I noticed that setting the scanInterval to 0 in SCAN_Start would result in two samples per channel, so check that. If the default is not low to high on PFI7 then you shouldn't get any data.

// Single Scan via external scan clock control.

i16 status = 0;
i16 deviceNumber = 1;

// Configure port 0 for output
// Wire line 0 to PFI 7
i16 port = 0;
i16 mode = 0;
i16 direction = 1; // output
status = DIG_Prt_Config (deviceNumber, port, mode, dir);

// Make sure it is low
i16 line = 0;    // digital output line to write to
i16 state = 0;  
status = DIG_Out_Line (deviceNumber, port, line, state);

// Set up the 8 channel scan
i16 numChans = 8;
i16 chanVector [] = {0,1,2,3,4,5,6,7};
i16 gainVector [] = {1,1,1,1,1,1,1,1};
status = SCAN_Setup (deviceNumber, numChans, chanVector, gainVector);

// Start the scan specifying external scan control
i16 buffer [16] = {0};
u32 count = 16;        //I think this is the minimum for an 8 channel scan
i16 sampTimebase = 1;  // denotes the 1 MHz timebase
u16 sampInterval = 6;  // so this is a 6 uSec interval between channels
i16 scanTimebase = 0;  // enables external control, default is low to high on PFI7 I think
                                       // use the Select_Signal function to change that default
u16 scanInterval = 10; // doesn't really matter as long as it is not 0
status = SCAN_Start (deviceNumber, buffer, count, sampTimebase, sampInterval, scanTimebase, scanInterval);

i16 daqStopped = 0;
u32 retrieved = 0;
status = DAQ_Check (deviceNumber, &daqStopped, &retrieved);
// after this call daqStopped should be 0 and retrieved should be 0

// Send a rising edge to the scan clock
state = 1;  
status = DIG_Out_Line (deviceNumber, port, line, state);

status = DAQ_Check (deviceNumber, &daqStopped, &retrieved);
// after this call daqStopped should be 0 and retrieved should be 8

// you're done.
status = DAQ_Clear (deviceNumber);
state = 0;  
status = DIG_Out_Line (deviceNumber, port, line, state);

Message 7 of 8
(4,416 Views)
bad news first:

I've run your code, but it doesn't work 😞

the good news:

I've tracked down the problem 🙂

we must call Select_Signal(DEV_NUM, ND_IN_SCAN_START, ND_PFI_7, ND_LOW_TO_HIGH) before we call
SCAN_Setup, otherwise we wait forever for the scan to start

the reference for SCAN_Start says:

 "...with scanTimebase set to 0, you must call the function Select_Signal with the signal set to ND_IN_CHANNEL_CLOCK_TIMEBASE and source set to a value other than ND_INTERNAL_20_MHZ and ND_INTERNAL_100_KHZ before you call SCAN_Start with scanTimebase set to 0."

but I don't think this signal (
ND_IN_CHANNEL_CLOCK_TIMEBASE) is correct, at least it doesn't work for me

also,
scanInterval can be set to 0, because we're in control of the STARTSCAN signal

anyway, now I have what I wanted: 1 sample per channel per scan

thanks thayles!

now it's on to double-buffering 🙂
0 Kudos
Message 8 of 8
(4,410 Views)