Motion Control and Motor Drives

cancel
Showing results for 
Search instead for 
Did you mean: 

SoftMotion Express VIs vs. Function Blocks

Solved!
Go to solution

Hi,

 

Are there any differences between SoftMotion's express VIs and the function blocks? I plan to drive a servomotor via an NI 9505. The NI examples show how to use the function blocks, but I've been advised to use the Express VIs instead, to work around strange behaviour when using a simulated axis (http://forums.ni.com/t5/LabVIEW/SoftMotion-quot-Update-Buffer-quot-VI-refuses-to-take-more/m-p/22508...

 

Thanks!

Certified LabVIEW Developer
0 Kudos
Message 1 of 4
(7,457 Views)
Solution
Accepted by topic author JKSH

Hi JKSH,

 

If I were starting a new application, I would use Express VIs over function blocks. Here are a list of things to consider when choosing:

 

  1. By default, function blocks are asynchronous. They execute on the rising edge of the 'execute' input and are done when the 'done' output goes high. They do not block and a function block architecture will almost always involve calling the same function blocks over and over in a loop. You control the execution flow with the 'execute' and 'done' input and output. Express VIs, on the other hand, are by default synchronous. They do not have an 'execute' input and instead begin execution as soon as they are called. They also block until finished. Express VIs can be converted to asynchronous by right clicking on them and changing the 'timing model.' When you change the timing model to asynchronous, the Express VI will now act exactly like a function block.
  2. In general, you should never mix asynchronous and synchronous APIs. Your entire application should be one or the other. While it is possible to safely have both synchronous and asynchronous calls, you have to be very careful and really know what you're doing.
  3. In my experience, writing simple applications is easier with a synchronous API and more complex applications are better suited for an asynchronous API. Since synchronous calls are blocking, you need more loops in your application and it can become difficult to maintain.
  4. There is also the property/invoke node API, upon which both function blocks and Express VIs are built. You can right click on either a function block or Express VI and convert it to a subVI to see the underlying code. While function blocks and Express VIs can be nice to work with, sometimes you need the lower level control that is offered by the property and invoke nodes.

I looked at your other post and it looks like you are encountering one of the subtleties of asynchronous calls. In point 1 above, I mentioned that function blocks are rising edge sensitive on the execute line. In both your modified example and the original example, the 'Update Buffer' function block is executed when the 'space available' becomes greater than or equal to the 'Size of the Contour Data.' In the original example, the table size is 40, but in your example, it is 100. Let's trace the flow through the example:

 

  1. We don't do anything in the first iteration since we don't see a rising edge on the 'execute' signal of 'Initialize Buffer' until the second iteration.
  2. At the beginning of the second iteration, we initialize the table with 20 points, leaving 20 spaces available. This function block may take more than one iteration to complete, so the loop may run several cycles before the 'Done' output is true. When this happens, the next block executes.
  3. Next we start the contour move. No point gets taken from the buffer yet; that happens in in the non user code portion of the scan.
  4. Next we see that there are 20 spaces available,, so we add 20 more points to the buffer, leaving us with 0 spaces available. This means that in the next iteration of the loop, the 'execute' signal of the 'Update Buffer' function block will go false. This is critical to the operation of the example
  5. Since there is no abort called, we loop back around. 
  6. Every scan, SoftMotion is taking one point from the buffer. Eventually, the number of points available will climb back to 20. When this happens, the 'execute' input will toggle from false to true on the 'Update Buffer' function block and 20 more points will be added to the buffer. This cycle continues until you stop.

So what was wrong with your modification? You made the table size 100 points. If you look at the steps above, you'll see that in the example, we put 40 points into the buffer before taking any points out. If you increase the table size to 100, that means that there will be 60 spaces available. However, 60 is still greater than 'size of contour data' (which is 20) and so the 'execute' input of the 'Update Buffer' function block never goes false; we always have more space available than the 'size of contour data.' Since 'execute' is rising edge sensitive, we're never actually putting new data into the buffer and therefore you only get out the two cycles that you originally put in. I agree that this is tricky, but it is exactly as function blocks are supposed to operate and is definitely something to think about when using the asynchronous API. 

 

Thanks,

Message 2 of 4
(7,451 Views)

Hi PaulRB,

 

You answered both my questions so thoroughly and clearly, plus you gave additional info that I didn't even think of looking for. Thank you so much!

 

I was making the wrong assumption that the function blocks "execute when true", rather than "execute on rising edge".

 

Yes, I think I will stick to the synchronous express VIs for now; this application is quite small, and the synchronous model fits nicer with LabVIEW's dataflow model. I'd just like to clarify: Is it correct to say that, once I initialize my buffer and start the continuous contour move, the "start" VI won't return until the buffer runs dry? So, unlike the function blocks' single-chain layout, I should call the "start" VI in parallel with the loop that calls "Update Points"?

Certified LabVIEW Developer
0 Kudos
Message 3 of 4
(7,446 Views)

Hi JKSH,

 

You are correct. You should call the 'Start' VI in parallel with the 'Update Points' VI. The 'Start' VI doesn't even have to be in a loop (and in fact probably shouldn't be in a loop) because it will block forever as long as you never let the buffer run dry. The 'Update Points' VI should be run in a loop and should be called before your buffer is empty, but not until you have enough space in your buffer.

 

Thanks,

0 Kudos
Message 4 of 4
(7,416 Views)