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: 

Create PWM using a NI 9402 with phase shift

Solved!
Go to solution

@cbutcher wrote:

 

If you read the specification for the cDAQ chassis mentioned you'll see for parallel IO modules (like the 9402) the FIFO for regeneration allows 2047 samples for DO.

 

Available counter tasks are typically far fewer and running two tasks for such a (in principle simple) problem seems fairly wasteful.


Good call on the FIFO size.  I was reading it from the AO section of the specs instead of DO.  D'oh.

 

As for the counters being "wasteful", that's really a matter of opinion and depends on what else the application demands.  In the case of a single slot 9171 chassis with a single 9402, I figure it's unlikely that the user is going to be using two digital outputs for this PWM control plus four counters.  (I'm definitely prepared to be wrong, so if the OP plans on using the counters for other things, let us know.)  Either way, the counter approach is definitely easier and more user-friendly from an API perspective.  There are literally inputs for the frequency and duty cycle and doesn't involve any buffering.  The counters can also achieve a much smaller duty cycle resolution should future application requirements demand it.

Message 21 of 43
(1,020 Views)

@OnlyOne wrote:

Hi Croohcifer,

Can you create an example on how to do this what you describe?

Thanks


I could, but I prefer the "teach a person to fish" approach.  Open the example finder, and in the DAQmx examples, find a counter output continuous frequency example.  There you'll see all of the major functions you need.  Mainly, Create Virtual Channel, DAQmx Timing (configured for implicit timing and continuous output), DAQmx Trigger, Start, Stop, and Clear.  Make two such tasks.  The "slave" task (the one with the delay) should start after the "master" task and use the master's start trigger terminal (or just the first pulse on whatever PFI line you export the master task to) as the start trigger.  That should get you pretty far.

 

Post your code if you get into trouble, and we can help out.  You'll learn a lot more about the driver and LabVIEW by coding it yourself using examples as a starting point.

Message 22 of 43
(1,016 Views)

Hi Croohcifer,

i found the mentioned example and added the initial delay.

Then i copied the file to _A.vi and_B.vi to execute it two times.

In a new VI i call the two A and B subvis with different parameters.

 

This is working very good, also the initial delay. I testes with bith channels 1Hz and 1sec delay. This can be seen then also on the scope.

I also but the trigger as input parameter for the subvi.

The idea was to set Task_A to "No trigger" and Task_B to "DigitalStart". This is set to the output Terminal of TaskA (PFI0).

But when doing this then i get error

"Specified route cannot be satisfied, because it reqeuires resources that are currently in use by another route"

 

This is correct as the output Terminal is set in TASK_A.

 

What can i do here?

 

Thx

 

0 Kudos
Message 23 of 43
(992 Views)

@OnlyOne wrote:

The idea was to set Task_A to "No trigger" and Task_B to "DigitalStart". This is set to the output Terminal of TaskA (PFI0).

But when doing this then i get error

"Specified route cannot be satisfied, because it reqeuires resources that are currently in use by another route"


Sounds like a cDAQ limitation. My guess is that with parallel cDAQ modules, since the PFI line has to get buffered for one direction or another, if you output a signal on it with one task and then ask that same PFI line to be a trigger input with another, it can't buffer it both ways, so it throws that error.  You wouldn't see the same behavior on X Series.

 

Either way, the most robust way to trigger one task from another would be to query the master task for its start trigger terminal and use that as the start trigger for the slave.  So, after configuring the master task's channel and timing (but before starting the task), drop a DAQmx Trigger Property Node.  Look for the property Start>>Terminal.  Then wire that purple wire into the DAQmx Trigger VI on your slave task.  Then start the slave and then the master, and the triggering scheme should work.  It should look something like this:

 

capture.png

 

You could just wire a constant of "/cDAQ_Name_Here/CtrxInternalOutput" (where x is master's counter number) into the Trigger VI on the slave task, and many people do, but this can break easily if you ever change the name of the cDAQ or which counter you use.  The method I showed above gets the start trigger dynamically, so it will always follow changes to which counter the master uses or any name changes to your cDAQ or module.  You can do the same for sample clocks and loads of other timing signals with the Timing and Triggering property nodes.

 

(P.S., I only have access up to LV 2018, so I can't open your 2019 code to provide further comment.  If you could backsave your code to 2018 or earlier in future attachments, more people would be able to see your code and help out :))

Message 24 of 43
(981 Views)

This is almost working. Attached a version saved in LV18.

Only one thing:

If i set Task A to: counter 0 and Terminal PFI0

and Task B to: counter 1 and Terminal PFI1 -> everything is fine and trigger works

 

If i set Task A to: counter 1 and Terminal PFI1

and Task B to: counter 0 and Terminal PFI0 ->Only Task_A starts and does not trigger Task-B

 

What is the difference?

 

Edit: Now first thing is also not triggering any more. I am sure it used to work 😞

0 Kudos
Message 25 of 43
(963 Views)

Do you get an error when it doesn't trigger?  If so, please share which error.

 

If not, my hunch is that it might have to do with the digital state of the line prior to reservation.  I don't know why it would be different between counters, but give this a go:  Try adding the "DAQmx Control Task" VI to the master task immediately after the trigger property node and set the input action to "Commit".  This should force the master task to reserve the counter and arm the trigger terminal to the correct digital "off" state before the slave starts looking at it.

Message 26 of 43
(953 Views)

No i dont get any errors.

I added the commit vi but this makes no difference.

0 Kudos
Message 27 of 43
(948 Views)

So, it was working with ctr0 as master and ctr1 as slave, then it didn't work when you swapped master/slave counters, and now neither works?  Is that correct?

 

I'd make sure all of your names are correct on your block diagram.  (Make sure they're not pointing to a simulated device, for example.)  If they're correct and they match what is in MAX, try using a MAX test panel to toggle the outputs and see if you see that on your scope.  

Message 28 of 43
(945 Views)

Yes thats correct.

The Counter names and terminal names are correct. if i skip the trigger-vi then both freqeuncys are visible.

 

0 Kudos
Message 29 of 43
(935 Views)

The code looks correct.  I was inclined to suspect a signal routing constraint under cDAQ to explain why it mattered which counter played which role in your app.   But the lack of any error code seems to point away from that.  On the other hand, the fact that you get pulses when you bypass the Trigger config suggests it might be worth double-checking the signal routing.

 

...time passes...

 

Intrigued, I made a simulated cDAQ to match yours (9171 chassis, 9402 module).  I went into MAX to look at the "Device Routes" tab for the chassis.  Interestingly, there are rows to show available routes for the counters' "Arm Start Trigger" signals but no such rows for the regular "Start Trigger" signals.

 

In the DAQmx Trigger property node where you presently query the Start Trigger terminal, try changing it to the Arm Start Trigger terminal.  Left-click the property, then in the context menu choose "More-->Arm Start-->Terminal."   Let's see if that works.

 

I have no particular theory why DAQmx didn't throw an error or why it seemed to work initially, then stop working.

 

 

-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 30 of 43
(924 Views)