PXI

cancel
Showing results for 
Search instead for 
Did you mean: 

How Do I know if I am talking to PCI_MIO-16E-4 from C++ ?

Hello David,
Thanks for your help, I already have the same structure of the code as ypu suggested earlier, I just have higher number of samples that I am acquiring. First, I have an Analog Task that can read up to 8 channels and Gated by PFI7, then I have two other tasks of Counters, one task is using PFI7 as a Gate to get time reference, and the other is using PFI4 as a Gate for Once Per Revolution. Both are using 20 MHZ clock as Source. The problem I run into is when I run the RPM to a higher speed like 5000 rpm or more, I have seen two errors on 2 different occasions, "Data is overwritten before its read", and the other is something like " DMA failure, Ctr0 has started, please use CTR1, or use CTr0 task before AI task...) Do you have an idea what might be causing these two erros ? I would like to run the application without worrying about crashing at higher RPM.
Thanks
0 Kudos
Message 31 of 38
(2,473 Views)
Hello NewBe,

I have run David's code and noted the same error you mentioned when the rate of the pulse train exceeds the capabilities of the counter. Specifically, I ran the code with a PCI-MIO-16E-1 E Series DAQ device and when the frequency of the pulse train I am measuring exceeds about 94 kHz, I received the following error:

" NON-FATAL RUN-TIME ERROR:
  "Cnt-Buf-Cont-ExtClk.c", line 108, col 9, thread id 0x000014E8:
  Function DAQmxReadCounterU32: (return value == -200279 [0xfffcf1a9]). Measurements: Attempted to read samples that are no longer available. The requested sample was previously available, but has since been overwritten.

  Increasing the buffer size, reading the data more frequently, or specifying a fixed number of samples to read instead of reading all available samples might correct the problem.
  Property: DAQmx_Read_RelativeTo
 Corresponding Value: DAQmx_Val_CurrReadPos

  Property: DAQmx_Read_Offset
  Corresponding Value:

    Task Name: _unnamedTask<0>
    Status Code: -200279"

I would guess that you are receiving a similar error because the rate of the edges you are counting exceeds the capabilities of the counter. You mentioned that you are measuring RPM and that the maximum value you can measure without errors is approximately 500 RPM. Do you know how the RPM translates to the pulse train? How many edges do you count per revolution?

The error I encountered, and some other common errors, are discussed in a KnowledgeBase online here. In addition, it looks like a similar problem with RPM encoders and error -200279 was discussed in this discussion forum. That forum looks like it has some good information in it, but I would discourage you from posting there because it looks like it is an older thread.


Matt Anderson

Hardware Services Marketing Manager
National Instruments
0 Kudos
Message 32 of 38
(2,445 Views)

Hello Matt,

I am not reading the data as fast as its being acquired. There has to be a way or DAQmx property to somehow tell it to wait a certain number of time before it fills it again. The other problem I have is in the analog task and I am getting error -200019. My gate4 to Gate 7 ratio is 360:1. Each reading with Gate4 represents a rev (once every 360 edges). Here is the code I am using, I also varied the Acq rate to see if it makes a difference as well as the BufferSize, but none solved the problem.

Thanks for Your help.

DAQmxErrChk (DAQmxCreateTask(

"Pressure Task",&taskHandle[0]));

DAQmxErrChk (DAQmxCreateAIVoltageChan(taskHandle[0],

"Dev1/ai0:1","Pressure Channels",DAQmx_Val_RSE,m_MinVoltVal,m_MaxVoltVal,DAQmx_Val_Volts,NULL));

DAQmxErrChk (DAQmxCfgSampClkTiming(taskHandle[0],

"/Dev1/PFI7",20000,DAQmx_Val_Falling,DAQmx_Val_ContSamps,100000)); // Analog channel timing

// DAQmxErrChk(DAQmxSetAIConvRate(taskHandle[0],125000));

DAQmxErrChk (DAQmxStartTask(taskHandle[0]));

DAQmxErrChk (DAQmxReadBinaryI16 (taskHandle[0],BufferSize/NumberOfChannels, TimeOut, DAQmx_Val_GroupByChannel,HoldBuffer,BufferSize,&NumRead, NULL));

// Time Counter

DAQmxErrChk (DAQmxCreateTask(

"Counter Task1",&taskHandle[1]));

DAQmxErrChk (DAQmxCreateCICountEdgesChan(taskHandle[1],

"Dev1/ctr0","Counter1",DAQmx_Val_Falling,0,DAQmx_Val_CountUp)); // Counter 0

DAQmxErrChk (DAQmxSetCICountEdgesTerm(taskHandle[1],

"Dev1/Ctr0","/Dev1/20MHzTimebase")); // Sets 20MHz as source clock

DAQmxErrChk (DAQmxCfgSampClkTiming(taskHandle[1],

"/Dev1/PFI7",50000,DAQmx_Val_Rising,DAQmx_Val_ContSamps,100000)); // using PFI7 as gate

DAQmxErrChk (DAQmxStartTask(taskHandle[1]));

DAQmxErrChk (DAQmxReadCounterU32(taskHandle[1],BufferSize/NumberOfChannels,-1,TimeBuffer,(BufferSize*2),&NumberReadOnTimeCounter,NULL));

// Once Per Rev Counter

DAQmxErrChk (DAQmxCreateTask(

"Counter Task 2",&taskHandle[2]));

DAQmxErrChk (DAQmxCreateCICountEdgesChan(taskHandle[2],"Dev1/ctr1","Counter2",DAQmx_Val_Falling,0,DAQmx_Val_CountUp)); // Counter 1

DAQmxErrChk (DAQmxSetCICountEdgesTerm(taskHandle[2],

"Dev1/Ctr1","/Dev1/20MHzTimebase")); // Sets 20MHz as source clock

DAQmxErrChk (DAQmxCfgSampClkTiming(taskHandle[2],

"/Dev1/PFI4",50000,DAQmx_Val_Rising,DAQmx_Val_ContSamps,100000)); // using PFI4 as gate

DAQmxErrChk (DAQmxStartTask(taskHandle[2]));

DAQmxErrChk (DAQmxReadCounterU32(taskHandle[2],100,-1,OncePerRevBuffer,BufferSize,&NumberReadOnOncePerRevCounter,NULL));

0 Kudos
Message 33 of 38
(2,436 Views)
Hello NewBe,

There are a couple things I want to address. First, the error you mentioned has the following description:

"Error -200019 occurred at an unidentified location

Possible reason(s):

Measurements: ADC conversion attempted before the prior conversion was complete.

Increase the period between ADC conversions. If you are using an external clock, check your signal for the presence of noise or glitches."

I would recommend that you examine the provided methods to resolving this error. First, make sure that your convert clock provides enough time for the ADC to capture the data. I notice you have commented out the line, but it looks like you are trying to set the Convert Clock to the maximum rate of the device with the DAQmxSetAIConRate() function. Are you getting this message even with this line commented out? You will also make sure that your external clock is running at the rate you expect and is a sharp, noise-free signal that follows TTL specifications.

I also noticed that you have specified "/Dev1/PFI7" as the source for both your analog input and edge counting tasks. However, it seems that you have specified two different rates for the signal; for the analog input task you specified 20000 for the rate and for the edge count task you specified 50000. Do you know the rate of this pulse train? Is there a reason you are specifying different numbers.

I am also somewhat confused when you say:


@NewBe wrote:

Hello Matt,

I am not reading the data as fast as its being acquired. There has to be a way or DAQmx property to somehow tell it to wait a certain number of time before it fills it again...



What do you mean that you are not reading the data as fast as it is being acquired? Do you mean that your program is running slower than your sample clock? I'm also confused as to what you mean by "tell it to wait a certain number of time before it fills again". What is filling? Are you referring to the sample buffer? I think it might be beneficial to take a look at the flow for continuous analog input programming. This diagram can be found in the NI-DAQmx Help (Start>>All Programs>>National Instruments>>NI-DAQ) in the book called "Continuous Analog Input Programming Flowchart". I have copied the diagram below for your reference.


Finally, I am not sure if the code you posted is the exact code from your application, but as a general programming practice I would recommend that you perform the time critical sections of your program close to each other and repeat only those parts rather than the configuration functions. That means you should group all the DAQmxCreate...() and DAQmxCfg...() functions for your counter operations and your AI operations at the beginning of your program. Then, you will call the DAQmxStartTask() functions after you have called all the configuration functions. Finally, you will call the DAQmxRead..() functions consecutively (for the counter and AI operations) and repeatedly in a while loop or some other repetitive structure. The last functions you should call would be the DAQmxStopTask() and DAQmxClearTask() functions.

I notice that you posted earlier that you are using a PCI-MIO-16E-4 device. As you are using 2 counter operations and 1 analog input, I think you may want to consider some KnowledgeBases here and here to make sure you do not run in to any other problems with your application.


Message Edited by Matt A on 09-06-2007 08:27 PM


Matt Anderson

Hardware Services Marketing Manager
National Instruments
0 Kudos
Message 34 of 38
(2,424 Views)

Hello Matt,

Thanks for your reply. I do have the task functios grouped correctly not as posted. As a matter of fact my counters are configured before my AI task, because I need my analog readings to be gated. I have already ran into error 200078 which I can't seem to get around, I can't use interrupts and I can't put my AI task first, and I am not sure how to switch ctr0 and ctr1 or if that helps anyways, I did switch them in the application, but the application started to choke. To answer your question,  I am getting the message with & (without) the line commented out. Also I specified "" for the source for AI task, it didn't seem to help either. I am wondering if there is a way to get around this problem with still setting gates(ctr) before AI as i need my AI readings to be gated.

Thanks

0 Kudos
Message 35 of 38
(2,423 Views)
Hello NewBe,

I think we need to take a step back and reexamine your overall application. It seems that we have gotten tied up going back and forth over patches to particular errors and have lost sight of the overall application. I want to summarize your application, as I understand it, to provide some recommendations and allow you to provide corrections if I am incorrect in my assumptions.

Application:
You are trying to combine an RPM measurement with a multi-channel analog measurement. In order to perform your RPM measurement you are using two counters; one counter counts the ticks of the internal 20 MHz timebase to get a time reference and the other counter counts the ticks of the encoder to determine the rotations (either 360 or 720 ticks per revolution). In addition, you have added your AI task to measure different analog signals, including a pressure transducer.

Notes & Recommendations:
In general, I think we may have taken the wrong approach in this application. It seems that so far we have simply been trying to reproduce the exact behavior of the Traditional NI-DAQ code in NI-DAQmx. Rather than trying to replace the code line-by-line, I think we need to recognize the differences in functionality and leverage the increased performance that NI-DAQmx offers. For example:

Rather than using two counters to measure RPM (one for time and one for rotation), I think we should consider using a period measurement to count the number of timebase ticks per period of your encoder using one counter. Then, you can calculate your RPM by determining the number of ticks per revolution (either 360 or 720 periods). A period measurement counter input is created using the DAQmxCreateCIPeriodChan() function. You can find more about this function by searching the NI-DAQmx C Reference Help, and I have copied an excerpt of this below:


DAQmxCreateCIPeriodChan

int32 DAQmxCreateCIPeriodChan (TaskHandle taskHandle, const char counter[], const char nameToAssignToChannel[], float64 minVal, float64 maxVal, int32 units, int32 edge, int32 measMethod, float64 measTime, uInt32 divisor, const char customScaleName[]);

Purpose

Creates a channel to measure the period of a digital signal and adds the channel to the task you specify with taskHandle. You can create only one counter input channel at a time with this function because a task can include only one counter input channel. To read from multiple counters simultaneously, use a separate task for each counter. Connect the input signal to the default input terminal of the counter unless you select a different input terminal.


You can specify the return value of this function in seconds or ticks; either way you could determine RPM by counting the time for one complete revolution. That is, with a "two-stroke" encoder, you could use a continuous period measurement task to count the number of seconds for 360 periods. This would give you seconds/revolution; you could calculate revolutions/minute by inverting this measurement and then multiplying by 60:

(seconds/revolution)^(-1) * (60 seconds/minute)=revolution/minute

This change should simplify your measurement by eliminating the extra counter and minimizing the amount of calculation you have to perform to determine RPM.

One last thing I wanted to ask you about was when you say you need to "gate" you analog input. Do you mean you want to:

1. Take a sample of the analog input on every edge of the encoder? (external sample clock)
2. Start acquiring analog input on the first edge of the encoder? (external start trigger)
3. Only acquire analog input when the encoder is high? (pause trigger)

I think taking a step back and getting a higher level understanding of the application will help us determine the best way to implement the change to NI-DAQmx.


Matt Anderson

Hardware Services Marketing Manager
National Instruments
Message 36 of 38
(2,397 Views)
Hello Matt,
I agree totally with your suggestion, and it is the way I wanted to do it. However, due to restrictions and the fact that lots of code depend on the fact that it has to be done using the current approach, I am limited to this approach. You are correct on the purpose of my application, and the answer to the gated analog readings would be (3). To avoid Error 200078, I am following this approach, and let me know your feedback. I will set up Time reference (PFI7) as CTR1, then I will start my AI task, lastly, I will use RPM counter as CTR0). I just reversed the order as the AI task reserves CTR0. Hopefully I won't run into any timing problems.
Thanks
0 Kudos
Message 37 of 38
(2,394 Views)
Hello NewBe,

I can appreciate that sometimes you are limited in your development by forces outside your control. Let us know if you have any more questions about programming your device and we'd be more than happy to help. If you have a new question about some other aspect of DAQ programming, you may have better luck by starting a new thread since this one is a little older and is less likely to be checked by other programmers.

In regards to your analog input (AI) vs. counter issue, you should eliminate the error by starting the AI task first. This behavior is a result of shared resources in hardware between counters, analog input and analog output. In fact, if you are running a counter task on counter 1 and try to start an analog output task you will receive a similar error.


Matt Anderson

Hardware Services Marketing Manager
National Instruments
0 Kudos
Message 38 of 38
(2,382 Views)