From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Generate AO with NI DAQ 9260 in a lock-in amplifier, ERROR 200288

Solved!
Go to solution
Solution
Accepted by topic author jinch

It's possible I'm still missing a key detail (especially relating to synchronisation, phases, ensuring sync, etc) but could you try the following?

cbutcher_0-1617175540416.png

Here only the bottom loop is shown, but the key change is removing the Start/Stop cycling and instead using Regeneration and Continuous Samples to ensure you don't have a problem if the bottom loop doesn't receive a new value quickly enough.

Probably you'd want to implement some sort of sync between these loops (or maybe just move them into a single loop? Hmm, that usually causes more problems, but it might work here?) but this works with the hardware you're using in a simulated sense (which of course doesn't tell us anything about timing, but does validate property node usage etc).

 

I've replaced the queue with the DBL datatype to simplify the bottom loop (I also had to implement an In Range and Coerce function in the top, because the simulated DAQmx has values out of range for the output otherwise).

My modified VI is attached (backsaved to 2016 like Kevin's, on which this was based).


GCentral
Message 11 of 16
(530 Views)

@jinch wrote:

5. Slowing down the top seems to work better, but the dead zone is quite annoying. Because the labview system works in a feedback loop: the output of the DUT and the reference are sampled and multiplied (lock-in) to generate an error signal to control the DUT, so that the output of DUT follows the reference. Even though I can make the loop slower, the dead zone may not be desirable as it creates a sudden jump.

 

So now the problem is if we can get rid of this dead zone and increase the speed if possible. If not, I will probably try to get a non delta-sigma DAC module.

 


I think my alternative in the previous post (I guess I was writing as you posted this, so I just saw your responses) might help with the 'dead-zone', but you'll have to check carefully synchronization.

If the processing in the top loop is slower, maybe move it back to the bottom - I moved it mostly for the screenshot simplicity, but obviously that's less important than a working VI!


GCentral
0 Kudos
Message 12 of 16
(529 Views)

Buncha thoughts, many might be wrong, I'll share anyway.

 

1. Sorry, I tried to follow what you were saying about the "dead time" but couldn't really piece together what I was seeing and you were saying.  Neither graph shows the steady ramp-like increase you said should be expected from an integrator.  There's no indication of what your reference signal might be (b/c apparently we're looking at the AO output only?). 

 

2. I went back to review the beginning of the thread.  I've heard of the term "lock-in amplifier" and that's pretty much the extent of my knowledge in the field.  But my vague memories and suspicions are that *phase* will matter a lot in determining whether you succeed with your attempt at "lock-in".

   If that's the case, then latency is your mortal enemy.  You're going to need to understand (and then explain) what your phase and latency requirements are.  For example, do you need your output signal phase to follow your input to within 1 millisec?  Sorry, that simply won't be possible over a USB-connected cDAQ.  That'd definitely be a case that called for FPGA work on a cRIO.  (And a non Delta-Sigma D/A converter).

 

3. BTW, your first post said you're new to LabVIEW and DAQ.  Congrats!  It's clear you've absorbed quite a lot in a big hurry!  I've seen plenty of threads with much worse code and analysis from people who've dabbled for years.

 

4. Try out cbutcher's code for continuous AO generation.  Be prepared to tweak a bit.  He tried to minimize latency by making the smallest conceivable buffer size of 1 sample.  (Buffer size for continuous output tasks is determined by how much data is written before the task is started.)

   I have a vague (and quite possibly wrong) recollection that the minimum buffer size allowed by DAQmx is 2.  But beyond that, I further kinda suspect that a buffer size of 2 still won't be enough for a USB-connected device, except perhaps for fairly slow sample rates.

   But definitely work with it and try some tweaks -- it should help you learn some things.  And let us know what you find.

 

5.  But coming all the way back to my initial assumption, if your lock-in success requires very low latency, you probably need to avoid ALL of: task stops & restarts, buffered AO, Delta-Sigma based AO.  Quite possibly also: the Windows OS.

 

6. 24-bit resolution for your output may not be as important as you fear.  As part of closed-loop control, it would *probably* only matter at a true steady-state condition with an unusually constant system.  Most real-life systems won't demand the extra resolution.  The systems aren't all that constant (else, why the closed loop in the first place?).

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
Message 13 of 16
(520 Views)

Actually by using regeneration and continuous samples, the problem is solved. Meanwhile, as Kevin points out that there seems to be a minimal size of the buffer. What I found is that the analog write function outside the loop requires an array with minimal 2 samples, while the analog write function inside the loop can be set either 1 samples or multiple samples. This may be device specific, but for now the program is working as intended. I have tested the speed from 1 iter per sec to 100 iters to sec and they all work perfectly.

jinch_0-1617241229267.png

Finally, here is code that works.

0 Kudos
Message 14 of 16
(503 Views)

1. Sorry I have misled you about the dead time. Let me explain by the following sketch.

jinch_0-1617242436082.png

Left is the output of an integrator assuming a constant input. And if we zoom in we will see that the curve is in the shape of a staircase because the output is updated once every cycle. What I showed in the previous post is the waveform of AO in ONE cycle. So if it works as expected, we would see a flat line in each cycle(This is what I observe after I fix the code following cbutcher's advice). But what was strange was that using the previous code (finite sample with start and stop in each iteration), there was a period when the AO is zero. What causes the output to return to zero is something I don't understand.

jinch_1-1617242845072.png

Although I have a working piece of code now, I'm still curious why the previous code does not work.

2. So actually my code only implements half of the lock-in function: because a general lock-in amplifier has two paths (an in-phase and a quadrature) to mix with the DUT signal. This is to recover both the amplitude and phase of the DUT signal with respect to the reference signal. But in my specific case the DUT signal is always in phase with the reference, so all I am interested in is simply amplitude. And therefore no need to have a quadrature path. 

3. The latency itself (from the input to the output) seems to be less of a concern, it was the iteration speed of the AO loop limited by the latency that was undesirable in the previous code. Since cbutcher's solution solves the problem in which the iteration speed can be fast enough, latency is no longer an issue.

 

Thanks.

0 Kudos
Message 15 of 16
(496 Views)
Solution
Accepted by topic author jinch

The "dropout" down to 0V output is showing you the time when the AO task was interrupted and not running.  This is a characteristic of Delta-Sigma D/A converters.  I wasn't thinking of this before, it just came back to mind now.  (Many of NI's other common devices buffer and hold outputs so their final voltage is retained after a task stops.  I've dealt with those a lot more than with Delta-Sigma D/A's.)

 

The spec sheet suggests about 31 msec of Delta-Sigma filter delay with your 1000 Hz sample rate.  That appears to explain almost all of the observed dropout period when you ran my code with the "commit" action.  Whatever little bit is left would be the (now smaller) stop/restart overhead.

 

But even this somewhat brief dropout is no good for a control app.   I suspect cbutcher was ahead of me in considering the Delta-Sigma dropout when he set up the continuous task that's working for you.

 

While a buffer size of 2 seemed to work for you, I'd still probably advise making it a little bigger. That size and your AO sample rate determine the max interval between data transfers that DAQmx will have to manage repeatedly in the background.  2 samples at 1000 Hz means DAQmx must keep doing this at 500 Hz.  USB DAQ devices tend to work more reliably when a given data bandwidth is delivered less frequently in larger blocks at a time.

   I have no hard data and it's ultimately going to be system dependent anyway, but I think I'd aim for a buffer size closer to 10 msec to reduce the DAQmx service demand down to 100 Hz.   So try a buffer size of 10.

 

The other thing is that you probably better write a *full* buffer size worth of data in the AO loop.  If you only write 1 sample, you're leaving other old ones behind in the buffer to be reverted back to.  So when you calculate your value, build a size-10 array of it to feed to DAQmx Write.

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
Message 16 of 16
(488 Views)