LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Why is the generated wave frenquency diffrerent from the set frequency in the program?

Solved!
Go to solution

Hi all,

 

I hope to use triangle wave and a step wave to make galvo mirrors do a x-y scanning, and used a timer to inspect the scanning time for an image. But something wrong with the wave generating. When the wave (for x signal) frequency set  in the program is 1HZ,  the frequency getting from a oscilloscope is 5HZ. Also,  no signal from Y axis's output can be detected by the oscilloscope. Can you help me about this?

 

The test vi is attached.

 

Many thanks,

Mei

0 Kudos
Message 1 of 38
(3,162 Views)

A few questions to try nail this down:

  • Are you really using an AI (analog input) task?
  • What is a ULxIORefnumTag, and why not use the DAQmx Physical Channels control type for DAQmx Physical Channels?
  • What are you doing with the two nested For loops at the top? If they produce the output you want, you could do this instead:

nestedFor.png

but I'm not sure you really want the first "X samples" of your Y ramp, repeated once for each Y value (so with e.g. 3 X samples and 4 values of y, you have:

y0, y1, y2, y0, y1, y2, y0, y1, y2, y0, y1, y2.

If you have the same number of samples in both cases it might be ok, but I expect you're looking for a slightly different output, like "for each value of Y, scan over all values of X"

  • What outputs are you expecting?

GCentral
0 Kudos
Message 2 of 38
(3,142 Views)

Hi cbutcher,

 

Thanks. For your question:

1. I used a AO(analog output) connecting the golvo mirror to control it, I changed to AO task, but the time is still not right.

2. Now my Data acqusition card is from measurment computing, the ULxIORefnumTag belongs to its vi. The NI one is on the way, I will change to DAQmx when I get it.  How did you find ULxIORefnumTag? I think I changed all the ULx thing...

3. About the output, I hope to get output like this,

x1,x2,x3,...xn;     y1,y1,y1...y1; 

x1,x2,x3,...xn;     y2,y2,y2...y2;

      ......                        .....

x1,x2,x3,...xn;    ym,ym,ym...ym;

 

WAVE.PNG

Thanks,

Mei

0 Kudos
Message 3 of 38
(3,131 Views)

As so often happens, I think you are worrying about the "How" before thinking about the "What", as in "What do you want to do?" (as opposed to "How am I going to do something?").

 

You have two mirror, X and Y.  You want X to start at X0, and step through N steps by adding dx after each step, returning to X0 at the end.  You simultaneously want Y to start at Y0, and step (through an unspecified number of steps) by dy each time X "resets".  The basic time step (for X) is dt, and is constant for the entire routine.  [Note that some of these assumptions might be "wrong", or need to be modified, but this is an example ...]

 

Important question -- Given that you need to adjust X every time step dt, do you also want to adjust Y, or only change Y when it needs to change?  [There's no "Right" or "Wrong" answer here, but it does change the implementation].

 

Why is this important?  If you adjust both each time step, then you really want pairs of points, X, Y, at each time point so that you can "drive" both Axes at the same time.  Thus it makes much more sense to have an array of "points" (X, Y) than two arrays, one of X and one of Y.  On the other hand, if you adjust X every dt, but only adjust Y every N*dt, then having two arrays, X[] and Y[], may make sense.

 

Now that you have two "What?" scenarios to think about, how would their implementation, the "How?" differ?  In the "simultaneous" (first) scenario, you'd take the next (X, Y) pair and send it to two channels of your Analog Output device every dt.  In the "sequential" (second) scenario, you'd have a nested For Loop, the outer one for Y, and the inner one for X.  In the outer loop, you'd output the current Y point, then enter the inner loop where you'd (every dt interval) output the appropriate X point.  When the inner loop finishes, the outer loop will step to the next Y value, so having X and Y as separate Arrays makes sense for this scenario.

 

Note that (given the initial assumptions) you only need to generate one set of X and Y values -- it's how you choose to combine them (based on how you intend to drive your axes) that determines whether you have two arrays, X and Y, or one array of the pair (X, Y) (which could be an Array or, more logically, a Cluster).

 

Bob Schor

Message 4 of 38
(3,126 Views)

Hi Bob,

 

Thanks for your explaination. The Y signal only changes when the x singal finishes one period (or one row). So, I think there should be two arrays according to your words. Besides the scanning array, can you please help me find out why the detected freqency is 5 HZ while the set number is 1 HZ?

 

Thanks,

Mei

0 Kudos
Message 5 of 38
(3,112 Views)
Solution
Accepted by topic author M.Mei

Read my earlier reply (maybe twice).  Then come back here and we'll do an exercise together (but, please, read my earlier long remark first).  We're going to do Scenario 1, but we'll simplify it even more and only do one axis at a time, starting with the "difficult" axis, the X Axis.

 

I notice you were generating a Triangle Wave.  Do you know what this looks like?  Think of a sinusoid where you connect staight lines from the highest (peak) point to the lowest (trough) point and back to the next peak.  This is not the waveform you drew -- you drew an upward-sloping line that "snaps" back to the baseline and starts up again.  The Engineering Term for this is a Sawtooth Wave (even though the teeth of many saws are Triangular Waves).  So let's generate some Sawtooth Waves, and use this to learn about the parameters of the Waveform Generator.

 

Here's a Snippet of some (LabVIEW 2018) code.  I know you are using LabVIEW 2014, but it will be a Required Exercise for you to recreated it on your PC (I'm not kidding -- I want you to actually do this in LabVIEW, yourself, so you can really learn how this works!).  Here it is:

Simple XY Scanner DemoSimple XY Scanner Demo

I made the Sampling Info Cluster visible, and loaded it with the values Fs = 100 and #s = 200 (note -- you'll need to set these yourself in your Front Panel).  I set X Freq = 1, and I made X Amplitude = 1 (when writing Demo code for yourself, "round numbers" are often helpful as you can do the math in your head easier).  Pay attention to the 180 going into the Phase input -- I recommend you leave it unwired until you run the VI once, then add it in and see what difference it makes (and, I hope, understand why it makes a difference).  Notice that I left the Waveform Wire as a Waveform -- Waveforms are nice, they incorporate Time, very important when making Engineering Measurements!

 

Notice that blank bunch of code, above, with an empty Array coming in to a Build Array function as the second Element.  This is a Diagram Disable Structure, temporarily "hiding" code to make the Y Plot (which is why the Cluster comes in second in the Build Array, X, then Y).

 

Build this VI, then run it.   Don't forget to set the Front Panel Controls to the numbers I discussed above.

 

I've attached the Actual VI, saved as LabVIEW 2014 (which I believe has the Diagram Disable structure).  After you try to get your VI to work (and if you copy carefully, it should work), download the attached code and make sure it also works.

 

Now, before you peek, ask yourself how you would design the corresponding Y function, one that starts at Y Value (which you should set to 0) and each X Cycle increments by Y Step (which you should set to 1, for the purpose of a Simple Demo).  What complicated LabVIEW Waveform-generating Function will give you a constant step?  [This is a Trick Question!!]

 

Try to work this out for yourself.  Also, try to write code to do this and replace the empty Array shown in the Diagram Disable function.  Try your method out -- do you see a Step function superimposed over your Sawtooth?

 

When you want to see my version, click on the little triangle at the end of the word "Enabled", which should bring up the Disabled Case (somewhat Greyed-out).  Right-click on "Disabled", click the downward triangle, and choose Enabled.  Study the code and be sure you understand it, particularly how the parameters are calculated.  Then run it.

 

If you take the time (maybe 30-45 minutes) to work through this yourself, carefully, you will learn a fair amount of LabVIEW, and will be able to practice what you already know.

 

Bob Schor

Message 6 of 38
(3,092 Views)

Hi Bob,

 

Thanks for your pateience. I read all your replies again, tried what you said, and can understand the your code. The 'offset' parameter decides the start position of the wave. By coping and running it, I got a following result,

Capture.PNG

 

But the frequency problem is still here, if I set the frequency  1 HZ, the detected number is 5 HZ. I do know where is wrong..

 

Thanks,

Mei

0 Kudos
Message 7 of 38
(3,070 Views)

Why are you putting a sampling frequency of 100 but only taking 20 samples in your original code? Did you duplicate the code exactly as Bob explained? Could you post a copy of the new code instead of a partial screenshot that shows the problem but gives us no clue as to why you have the problem (Bob's code gives very different results than yours).

0 Kudos
Message 8 of 38
(3,061 Views)

When you mention the frequency from an oscilloscope, how are you measuring it?

 

Do you mean the sort of built-in measurements that some oscilloscopes offer, or are you reading the time-scale vs the number of pulses that you count?

I ask because we have quite a nice oscilloscope at work, but depending on the scaling and noise levels, sometimes it produces very curious readings for frequency...


GCentral
0 Kudos
Message 9 of 38
(3,057 Views)

Hi,

 

I used its Auto Run function to measure the frequency. The frequency is right when I meausred wave from a function generator. So, I think my method to use the oscilloscope and the insturment should be right.

 

Mei

0 Kudos
Message 10 of 38
(3,042 Views)