LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

multiple-frequency continuous pulse generation

Solved!
Go to solution

Hi,

 

I have an application in that I have to control the input of a multiplexer. The multiplexer has six addressing lines and as I do sequential addressing the signal frequencies of the addressing lines have to be divided by two like f_in, f_in/2, f_in/4, f_in/8, f_in/16 and f_in/32.

I've seen in the Community that using "CO Pulse Ticks" it is possible to divide the input frequency by N but it is done only for one counter / OnBoardClock(s) and I cannot generate multiple divided signals.

As I use PXIe-6358 I thought of cascading the counters and somehow get out the divided frequencies.

 

Is there an efficient way to do such an application? 

 

Krivan

0 Kudos
Message 1 of 17
(3,817 Views)
Solution
Accepted by krivan

Hi Krivan,

 

There are only 4 counters on the 6358 so the divide-down approach is probably not going to work out.

 

This problem is acutally surprisingly easy if you instead use the Digital Output lines to generate your signal.  They can be clocked out at up to 10 MHz on the PCIe-6358. Here is a stripped-down example of what the code would look like in LabVIEW to step through all 64 combinations of your MUX in sequential order:

 

 

Mux Control.png

 

 

I hope this helps!

 

 

Best Regards,

John Passiak
Message 2 of 17
(3,810 Views)

I modified your code to provide the signal continuously but yes, it is an easy and fantastic solution!

 

Just a question more. At the border of the for cycle there is a [] sign that as far as I know means that the numbers counted in the for loop are stored in an array and outputted at once likewise. This solution is good and works but wouldn't it be easier to send each number directly to the DAQmx Write.vi?

 

Thanks a lot,

Krivan

0 Kudos
Message 3 of 17
(3,786 Views)

Hi Krivan,

 

You are correct that the "[ ]" sign (which indicates that "auto-indexing" is enabled) means that the numbers are being stored to an array. The array looks something like:

 

    [0, 1, 2, 3, 4, ... , 62, 63]

 

 

In binary (showing the last 6 digits), these numbers are:

 

    [000000, 000001, 000010, 000011, 000100, ... , 111110, 111111]

 

 

So, the pattern of increasing integers corresponds in binary to the pattern that you wanted on your MUX.  It sounds like you've picked this up, I just wanted to make it clear.  Writing an integer to a digital DAQmx Task will set the corresponding bits on the DO lines in your task (e.g. every bit in a U32 corresponds to one of the lines on port 0, like in your case).  If the line is not included in your DO task, the bit is masked out and the line will not be driven.

 

When you call DAQmx Write with an array of U32, this sends the array of patterns to be generated to the "DAQmx Buffer" (a space in kernel memory that the driver can directly access).  The driver will automatically transfer data from the DAQmx Buffer to the on-board FIFO as your generation is taking place.  By default, for a continuous task the driver will regenerate the data from the DAQmx Buffer (that is, it will loop the data over and over again).  If you make your task continuous, it's most efficient to write the array of data to be generated ahead of time (the overall structure should look like this example) and let the driver handle the rest.

 

If you were to send a single sample to DAQmx Write every time, you are limited by the execution speed of your applicaiton software (LabVIEW in this case) as well as the overhead of making the driver calls.  Generally, writing a larger array of data one time is much more efficient than writing a single sample multiple times.  Since you know ahead of time what pattern you want to generate, there is no reason not to load it into kernel memory and then let the driver deterministically clock it out based upon the internal sample clock of the 6358.

 

 

Best Regards,

John Passiak
Message 4 of 17
(3,772 Views)

Hi John,

 

I tried to extend the code you suggested in a way that it generates other digital output as well. Like in an array I have to handle multiple multiplexers, so if the digital code of the first multiplexer got from the 0...0 to F...F [line0:5] then the second multiplexer [line13:14] has to step one further and it starts again. Apart from that I have to feed in digital [square] waveforms at other output pins as well.

 

You can see how I did it in the VI attached. The problem is that I can measure the signals that are generated by the inner loop [line0:5] but I cannot measure any activity at the other pins. I tried to synchronise them using the DAQmx sample clocks at the same rate but it didn't seem to be the good solution.

 

Can you please help where I did it wrong.

 

Thanks.

0 Kudos
Message 5 of 17
(3,730 Views)

Hi krivan,

 

All the clocked DO lines have to be in the same task in order for them to run at the same time.

 

From the way you describe your additional multiplexer, it sounds like you just need to increment it after the original MUX has completed its cycle.  The easiest way to do this is to use consecutive digital lines and extend on the previous idea.  You would just need to add more lines to the task (as necessary) and increase the number of samples to generate (you need 2^N samples for N total channels).  For example, to add 3 additional lines to the 6 that were already there:

 

        Continuous MUX.png

 

 

The reason you have to use consecutive lines is that the bits of the U32 correspond to the lines on port 0 (0:31).  While you can write whatever bits you want, it is much easier to build the loop in the above way and use consecutive lines.

 

Is the timing of the square waves pre-determined?  Perhaps I can give further suggestions on these if you can provide a timing diagram of how these square waves relate to the current multiplexer control outputs.

 

 

Best Regards,

John Passiak
0 Kudos
Message 6 of 17
(3,720 Views)

Hi John,

 

yes thanks! It does work now if I increase the number, I can generate the other signals as well. 

 

However apart from this multiplexer thing and following your explanation is it possible to generate say four independent square waves even at different frequencies if I define the input data sets as U8 instead of U32? In this case I would have four for loops running up to maximum 256 and would have to include four sample clocks as well. Or am I wrong?

0 Kudos
Message 7 of 17
(3,716 Views)

Hi krivan,

 

As mentioned, everything has to be in the same task so you can only have one sample clock for DO.

 

You can however break up the generation of your waveform into 8-bit segments and combine all of these bits into a single U32.  In the end, you have to write a single array of U32 to your DAQ device if you want to use integers.  Here's one way that you can combine multiple 8-bit segments into a single U32:

 

        Merge U8 to U32.png

 

 

The LabVIEW primitive used in the snippet above is called Join Numbers.

 

 

There is also a digital waveform datatype that might be useful for you, but the datatype you use is really up to personal preference.  I personally prefer to use U8/U32 when I can.

 

 

Best Regards,

John Passiak
Message 8 of 17
(3,713 Views)

Oh I see, OK, so there are no exceptions, everything has to be included in one task. I created a VI that joins the output of the four for loops and so the result should be U32. As at the moment I'm trying to write all pins on the port0 I have set the number of samples to 2^32=4294967296 which is the max for a 32bit unsigned integer. The sample clock denies it and changes it basically to half the value [2147483647]. The first 8 pins of port0 are written correctly but from port0.8 onwards I see no activity. As I join up the numbers I can't see why the complete binary number is not sent off to the cards...

0 Kudos
Message 9 of 17
(3,704 Views)

The Samples per Channel uses an I32, so this explains why the maximum you can set is half of the U32 value.

 

Keeping in mind that every sample is 32 bits (4 Bytes) of data, 2 billion samples would require an 8 GB contiguous block of memory.  4 billion, like you were trying to set earlier, would be 16 GB.

 

If you're trying to write this much data, you'll need to break it up into smaller chunks and write as the generation is taking place.  In these cases, it is best to use non-regeneration to prevent repeating old samples.  This is a little more complicated than what we have done so far, do you actually need to do this or are you just testing things out?

 

 

Best Regards,

John Passiak
0 Kudos
Message 10 of 17
(3,694 Views)