11-20-2015 04:38 PM
@Sam_Sharp wrote:
Do you have a simple VI that shows what you're doing? I tried to see if there was an example of using the buffer generation but I'm interested in having a look - I was wondering if there is a property node or something that allows you to change the buffer position?
Rather than try to send the entire waveform to the DAQ device, could you not generate and stream it in parts from the windows VI? So rather than send the full waveform, break it up into chunks to transfer to the hardware. I think if you turn generation off, it will append it to the end of your current buffer.
Hi Sam,
I've put together a simple VI showing the issue, though haven't been able to test it to ensure it generates the error i'm getting in my main application (as I'm not near my rig). If you set the 3 channels as analogue outs, it should say that it doesn't like that the array sizes in each of the clustered waveforms are different lengths. Would be good if there was some way of limiting the length of the buffer on individual channels within a task!
I've worked out a workaround, generating an array long enough to make them all periodic with each other then loading this into the task. I believe that daqMX then automatically shifts this chunk by chunk into the actual hardware output buffer, but I'm not entirely sure of this.
Thanks again for your help,
Tom
07-08-2021 04:49 PM - edited 07-08-2021 04:50 PM
I have this same issue with outputting multiple waveforms of arbitrary frequencies on different channels, from the same unit, NI 9263. In case you happen to read this 6 years later, just wondering if you found a better way to go about it than making the buffer obscenely long so everything's periodic haha. Thanks!
07-08-2021 05:23 PM
You can either use an enormous buffer or just turn off regeneration. There are some good examples in the example finder, but you basically just keep track of the buffer in code, and update the Write buffer when there's space available. I think the name is something like "Continuous AO- nonregeneration" or something. You basically just continue writing new chunks of data to the buffer a few times a second. I do it very frequently. It takes more code than regenerating does, but it lets you output all sorts of arbitrary data.
The short answer is that no, you can't give them multiple buffers. cDAQ chassis only have one AO task, and you can only have one buffer per task (though that buffer CAN have multiple channels, they just all have to be the same length).
07-08-2021 06:07 PM
Thank you so much for your response Bert! Very much appreciated. I get the general idea of what you mean.
I am actually a very green student, with no experience with Labview, and my project team has chosen to use the nidaqmx python library for control (not very well documented for a beginner imho). Have you used that at all?
In any case, I wonder if you'd be willing to share a snippet of your code that displays this functionality, to help me piece together the sequence of commands necessary in my python script? I would be eternally grateful!
07-09-2021 11:14 AM
No need to look at my code, it's in one of the built-in examples. Go to Help -> Examples, then Hardware Input and Output -> DAQmx -> Analog Output -> Voltage (non-regeneration)- Continuous Output.
That example does literally exactly what this thread was talking about, multiple analog output channels at multiple sine frequencies (same sample rate, of course).
The Python library will use the same function calls as the LabVIEW one. It should transfer fairly easily. Push Ctrl-H to get the Help popup, then mouse-over the different functions in that example to see their names. The names should be very similar in the Python toolkit. I've never used it myself but all of the DAQmx stuff works the same way regardless of using .NET, LabVIEW, Python, etc.
07-11-2021 05:02 PM
While I endorse (and kudo'ed) BertMcMahan's suggestion to solve this by continuously writing to a non-regenerating task, I figured I'd give you some food for thought for another approach that writes just once to a regenerating task.
Background: on a modern-day PC, my threshold for an "obscenely long" buffer would probably be north of ~100 MB. 10's of MB just isn't that big a deal these days.
That said, here's a way to constrain and simplify your problem: simply decide that you will only support frequencies that are rounded to the nearest 0.1 Hz. And here's why that helps. If every frequency is constrained that way, then a 10 sec (= 1/0.1 Hz) buffer will *necessarily* hold an integer # of cycles. And then you just write that whole buffer once and let the task run in regeneration mode (which is the default).
What's that do to your buffer size? Well that'll be (10 sec)*(samples per sec)*(3 channels)*(8 bytes/sample/channel) = 240*(samples per sec) bytes. Even at 100 kHz sample rate, that means "only" 24 MB. And you'd be able to generate any arbitrary frequency to the nearest 0.1 Hz.
Tweak the math as needed for your desired frequency resolution, sample rate, and max buffer size. Sorry, I'm no help at all with python DAQmx syntax.
-Kevin P
07-20-2021 03:35 AM
Hey sorry for the delayed response, but I just wanted to say thank you guys so much for your help! I'm really impressed by this community so far.
FYI (and for anyone else) I was able to make some headway with python non-regeneration, with the help of this guy's code, which is the only example of how to do it in python that I could find on the web (another thread where Kevin also provided helpful insight):
I was working out the kinks of it when Kevin dropped his knowledge bomb, and I realized there was no reason to be doing this the hard way haha. The 10 second buffer with 0.1 Hz resolution fits my needs very well. So thank you again for that Kevin. 🙂