08-31-2022 12:37 PM
I'm using a 9203 cDAQ module in a 9189 chassis to drive a 4-20mA device with either selectable setpoint (1samp) or configurable waveform function generator (Nsamp). The application starts in setpoint (1samp on demand) mode and I'm able to transition on the fly successfully to waveform (Nsamp continuous). I'm somewhat successfully able to stop waveform generation and switch to on demand mode, though this generates a signal routing error -89137. However subsequent 1samp writes do not show up on the output and generate an error -88700 each time. The only way to proceed seems to be to end the task and re-create the channel. Am I skipping something? Is this not possible?
Initialization - create channel
Setpoint update - 1samp
Switch to waveform Nsamp
switch to setpoint 1samp
Error -89137 occurred at DAQmx Start Task.vi:7220001
Possible reason(s):
Specified route cannot be satisfied, because it requires resources that are currently in use by another route.
Source Device: cDAQ9189-206EB40
Source Terminal: Software
Destination Device: cDAQ9189-206EB40
Destination Terminal: Slot2/ConvertPulse
Required Resources in Use by
Source Device: cDAQ9189-206EB40
Source Terminal: ao/SampleClock
Destination Device: cDAQ9189-206EB40
Destination Terminal: Slot2/ConvertPulse
Task Name: _unnamedTask<E3>
Write 1samp
08-31-2022 12:43 PM
Typically you don't switch between 1 Sample and N sample, could you please post an example code of your implementation?
08-31-2022 01:13 PM
Here is some example code
08-31-2022 05:06 PM
Can you back-save the code to something like LV 2018? I can't open version 2021.
I think the error text is technically true, but fails to explain the forest for the trees. You might be able to clear this up with a call to DAQmx Control Task to "unreserve" task resources after stopping the task and before changing the sample timing mode. Just an educated guess though, I didn't test with a similar simulated device.
Other options:
1. call DAQmx Clear after calling DAQmx Stop. But then you'd need to fully reconfigure the task before starting it again. Lots more overhead and latency time, but pretty sure to work.
2. approach the whole app differently. Always put yourself in clocked output mode. Depending on your needs, things split into easy or hard at this point. See below.
2A. Easy: set a buffer size that lets you regenerate your function generator waveform repeatedly. Most devices I'm familiar with will default to be in regeneration mode -- when they get to the end of the buffer of data, they start over from the beginning. So you only need to write one full cycle of the waveform to the buffer and start the task -- it'll just keep repeating. Then when you just want to write a single new output value, instead create an task-buffer-sized array filled with that same # and write it to the task. Now that constant value will keep regenerating until it's time to write the waveform again.
Note: if the latency time between writing to the task and seeing the physical output signal change is too big for your needs, there may be ways to reduce it by manipulating DAQmx properties related to the device's onboard buffer and something called the "data transfer request condition". Dealing with that moves the easy method toward medium or kinda hard.
2B. Hard: plan to keep servicing your task by writing data to it "just in time". A good way to keep your software timing in sync with the task is to use the DAQmx Event "Every N Samples Transferred From Buffer". Prewrite at least 2*N samples to the buffer, after that write the next N samples every time you receive that event. Note: you might also have to work with those DAQmx properties mentioned earlier.
This approach puts more programming demand on you to have a task-servicing loop that keeps track of what the "next chunk" of data needs to be, writing it to the task at a pace that keeps you just a little ahead of the physical output signal. (The DAQmx event helps a lot with that part.)
-Kevin P
08-31-2022 05:37 PM
Here's an older version FWIW
08-31-2022 05:44 PM
Kevin_Price, for my application it's probably easiest to do more or less as you advise - my waveforms are just regenerated single-cycle arrays so I can just replace them as needed with a new array of constant value. However I'd like to know the real solution here unless this is truly a shortcoming. As for killing the task and re-creating, that may work depending what it does to the output of the device in the interim, but this is controlling a physically actuated system that would not respond well to drop-offs during control update so otherwise this wouldn't be an option