12-10-2013 05:55 PM
I am a first time user of the NI USB-6361. I am programming in .NET (C#) and using the NationalInstruments.DAQmx class.
What I am trying to do is the following:
Using a digital output port, generate a wave starting from 0 and counting up to 31 and then stopping with an output of 0. Each count is 12.5 microseconds long. This wave needs to be generated 15 times, once every 1 millisecond. i.e. 15 waves in 15 milliseconds
While this is going on, I want to sample an analog input port 10 milliseconds from the rising edge of the digital output wave. To achieve this, I plan to sample the analog input at 2 MHz.
I believe I can handle the analog input by following the supplied examples. It is the digital output which I am having some trouble with.
I can see that if I created an array of 80 (1000 microseconds / 12.5 microseconds) values, starting at 0, increasing to 31 and the remaining values set to 0. Then I could use this waveform continously with a 80 kHz clock.
What I would like to know is if there is a simpler or more elegant solution. i.e. if I wanted to easily vary the maximum count (from 31) value or number of wave forms to be generated (from 15).
For example, could I use a retriggerable DO to start a finite waveform?
Or could I get rid of my wave form all together and use a counter?
I'm not sure if these (or any other) solutions would be appropriate, and how I go about implementing them. I am having some trouble finding appropriate C# examples.
Any assistance would be greatly appreciated.
Solved! Go to Solution.
12-11-2013 02:06 PM
I need further clarification on what you are trying to do. From the first post it appears that you want to step up the output voltage over time. That is not possible with a digital output. With a digital output the only possible values are 0 and 1. You can hold the value for a set time and then have it return to zero but there is no way to make it step up in values. If you are trying to step the voltage up over time you will need to use an Analog Out. You would set up the frequency of the waveform and then apply an array of the values that you want it to do over the time period.
Once we have a clearer understanding of what you want to have the program do we can look into the specifics if you need further help.
12-11-2013 02:52 PM - edited 12-11-2013 02:53 PM
Do you mean you want to clock out something like this at 80 kHz?
00000000 (0) 00000001 (1)
00000010 (2)
00000011 (3)
00000100 (4)
...
00011111 (31)
And then repeat this pattern a certain number of times?
I would allocate an array of U8 of the appropriate size (32 in the above case, though you could pad it with extra 0s at the end if you want downtime between your cycles) and populate it with consecutive integers. On your DAQ task, set the sample clock to 80 kHz, finite mode, and the number of samples equal to N*the array size (N is the number of times the output will be repeated). Write the array to the DAQ card's buffer.
When you run your task the card should output the entire buffer N times.
If this doesn't describe what you were looking to achieve then you'll have to clarify.
Best Regards,
12-11-2013 04:07 PM
Hi John,
Yes I am outputting a pattern across multiple digital output lines. I currently have an array of size 80 as I want some down time between the pattern.
I am currently using ContinousSamples; I'll also give the Finite Samples & Samples Per Channel a go.
This is working for me so I might just run with it. I had thought that there might be other or better ways to do this.
12-11-2013 04:17 PM
Hi Alex,
In my response to John, I think i've explained myself better.
The next step I need to do is read an analog interface which is the response to the outputted digital pattern. Every time the digital output patter increments, I need to have recorded the analog input around 10 microseconds later. Currently, I read the analog interface as fast as I can (1-2 MHz). As part of analysis, I need to know what part of the recorded analog input corresponds to the rising edge of the digital output.
To do this, do I need to ensure my input and output tasks start at the same time i.e. using a trigger? Or is there sufficient time information in the recorded input - but will this require me additionally recording the outputted digital signal i.e. specifically the timing of the rising edges?
Currently, I am starting my digital output task using Start() and my analog input task using BeginReadWaveForm(). Any suggesstions on how to best end up with recorded analog data which is correlated to my digital pattern?
12-11-2013 04:54 PM
Ah ok...
You might find this approach a little more intuitive:
Configure a continuous (or finite if you only want to repeat the pattern a certain number of times) counter output task at the frequency want to repeat the digital output pattern.
Instead of buffering the digital output task with 0s, make the buffer end with the 32 stamples (or however many you want to generate). Configure the task to be "finite" and make the number of samples equal to the number in your buffer (e.g. 32). Configure a digital start trigger for the task, and use the counter's internal output as the trigger source. Set the trigger to be retriggerable.
Set the analog task to be finite, and of length that you are interested in. Configure the start trigger exactly the same as you did for the digital output task (including making it retriggerable). You can set the delay from start trigger property to allow your input task to wait for however long after the start of the output sequence to begin acquiring.
You could run the analog input continuously (using the 0s as a buffer in your digital output task as well) and avoid having to use the counter. To make this work you would need to synchronize the start of the tasks together (e.g. use the ai start trigger to trigger the digital output task) and then keep track of the sample count on the input task in order to know where the timing windows are that you are interested in. The timing will not drift since each task derives its clock from the same timebase (just be sure that you select output rates that are divisors of 100 MHz).
Best Regards,
12-11-2013 08:28 PM
Thanks for the help so far John. I think I'll run with your first suggesstion.
I'm having a fair bit of trouble mapping your steps to the DAQmx classes. I believe I have correctly created the timer Task using the COChannels.CreatePulseChannelFrequency and Timer.ConfigureImplicit functions.
I am now working on modifying my digital task. Using the Triggers.StartTrigger.ConfigureDigitalEdgeTrigger function, Ive set the source to "/Dev1/PFIO"; is this what you meant by "use the counter's internal output as the trigger source"?
What function do I need to use to set the trigger to be retriggerable?
Where should I be looking to understand the DAQmx API? I've been trawling through the examples which we installed on my machine, and its slow going...
12-12-2013 09:22 AM
It sounds like you're on the right track with the counter task.
For the counter internal output, use "/Dev1/Ctr0InternalOutput" (or whatever counter you are using) instead of "/Dev1/PFI0" (that's a zero by the way, the "/Dev1/PFIO" that you linked uses the letter O which isn't a channel).
To set the retriggerable property, it should be something like this in C#:
myTask.Triggers.StartTrigger.Retriggerable = true;
The examples are probably your best bet for learning the API to be honest. You might also try searching ni.com and the .NET help. You can always ask here if you get stuck.
Best Regards,
12-12-2013 11:08 PM
Thanks for your help John. I believe I have got everything working.