Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Ramp down a signal before stopping

Solved!
Go to solution

I have a task that involves an analog output that causes an LED to flash on and off repeatedly in a particular pattern. I need AO because the intensity of the LED needs to be set via the DAQ. The flashing continues until user interruption. I could achieve what I describe by storing the waveform in the device buffer and cycling through it repeatedly in regen mode. However, I am stumped by an additional constraint. If the task ends with the LED beam on, I need to ramp down intensity gradually over about 100 ms. This must only happen at the end of the task and not during the on/off cycling. I can not predict predict when this needs to happen. I believe this may be hard or impossible to do using buffered acquisition (at least no way that does not involve an interruption or a latency); is this the case?

 

One solution I am contemplating is to add an optional RC circuit to the LED AO control line to filter the offset and so add a decay. I am thinking of gating the AO signal through this circuit using a transistor or a relay that I activate with a TTL signal when the user terminates the process. Is something like this the only option I have?

0 Kudos
Message 1 of 16
(2,424 Views)

What software are you using?

 

0 Kudos
Message 2 of 16
(2,396 Views)

You can do it without *interruption*, but probably not without *latency*.

 

In older times, you couldn't write new data to a regenerating AO task but I was surprised to learn a few years ago that it had become possible.  I don't really know when the support was added to DAQmx, I hadn't bothered trying for many years prior.

 

Anyway, you should be able to do 2 full-buffer writes back to back to accomplish what you need.

- write a full buffer that includes the ramp-down to zero from whatever was the last value in the original regenerating buffer.  Pad with more zeros at the end if needed.

- write a second full buffer of nothing but zeros

- wait long enough to know that your ramp & zeros have worked through the task buffer and the device FIFO, then stop the task.

 

The amount of latency will be a combo of your task buffer size, where your generation task is within that buffer at the time you want to initiate the ramp-down, and the size & fill state of the device's onboard FIFO buffer (which is often configurable with DAQmx properties).

   I've found that different devices use different methods to control the FIFO buffer.  For some, it's a direct property to set the buffer size.  For others, you get fuzzy control with the "data transfer request condition" which can be one of (less than full, half full, almost empty).  There are yet other related properties that apply to USB-connected devices that I know less about.

 

 

-Kevin P

ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
Message 3 of 16
(2,393 Views)

I'm using DAQmx via thin wrappers in MATLAB or maybe also NI's library in Python. 

0 Kudos
Message 4 of 16
(2,376 Views)

 

Anyway, you should be able to do 2 full-buffer writes back to back to accomplish what you need.

- write a full buffer that includes the ramp-down to zero from whatever was the last value in the original regenerating buffer.  Pad with more zeros at the end if needed.

- write a second full buffer of nothing but zeros

 

Hmmm... So you are saying I can simply write to the buffer without stopping the task and this will play out what I need? That could well do what I need as I can keep the buffer small. I was planning on using a USB DAQ but I'd think again if it didn't work with one of these. 

0 Kudos
Message 5 of 16
(2,375 Views)
Solution
Accepted by topic author bobcampbell
... So you are saying I can simply write to the buffer without stopping the task and this will play out what I need?

Yes.  Here's a few more tidbits of info about DAQmx & buffer management:

 

1. The size of the task buffer is typically set by the # of samples you write to the task prior to starting it.

 

2. Continuous output tasks default to regeneration mode, treating the task buffer as circular, starting over from the beginning when it gets to the end.

 

3. DAQmx *also* manages the process of transferring data from the buffer down to the device, remembering where it left off.  It knows which samples have been transferred (and are thus eligible for being overwritten from your app code) and which haven't (and are thus *ineligible*).

 

3. DAQmx will remember where you left off writing and subsequent writes will start at the next sample position.  So if your initial write (prior to starting) sets the buffer size and fills the buffer, the next write will replace samples starting at the beginning of the buffer. 

 

4. If your attempt to write samples would overwrite existing samples that had not yet been transferred to the device, DAQmx will try to wait for space to free up to allow the write to succeed. 

 

This is why I suggest to write a whole buffer full that starts with a ramp down and pads with zeros if needed, followed by immediately writing another full buffer of zeros.  The first write makes the ramp down start from the beginning of the buffer whenever the generation task gets back around to the beginning again.  Because that first write fills the buffer, the second write will wait for space as it replaces the ramp with zeros (preventing you from wrapping around to start a 2nd ramp down).

 

Try to get that much of things functional and working, then come on back if you need to address latency issues.  Those may require more advanced settings related to the device's onboard FIFO buffer and parameters that control the way DAQmx feeds the board with data, trading off latency with robustness.

 

 

-Kevin P

ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.