Turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

Highlighted

10-15-2020 06:31 AM

Options

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

I would like to use the Quotient & Remainder function in a while loop (not SCTL) of a FPGA vi. Specifically, I want to use the Remainder output of the function for a modulo operation. The help leads me to believe that I can use the function as long as it is not in a SCTL. However, when I try to use it, I get the error that the data type is not supported for that function. It seems the Q&R function requires a double data type and will not work with a single data type, yet the FPGA implementation does not support double data types. Is there any work around to allow use of the Q&R function in a FPGA vi? Ultimately, I need to take a variable and perform a modulo 2pi operation on it. I'm open to other implementations to accomplish this task and would appreciate any recommendations.

Solved! Go to Solution.

Highlighted
Options

10-15-2020 06:43 AM - edited 10-15-2020 06:45 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

Hi John,

Q&R usually is used with integer datatypes. Which datatype do you want to use in this SCTL? In the FPGA you should stick with integers and FXP!

@johnsoja wrote:

Is there any work around to allow use of the Q&R function in a FPGA vi? Ultimately, I need to take a variable and perform a modulo 2pi operation on it.

Where does that "variable" value comes from?

You can replace Q&R by (repeated) comparisons&subtractions: IF greater than 2pi THEN subtract 2pi…

Or you could split that "2pi" into an integer and "pi" so you can simplify the Q&R operation only on the integer part. Or...

It all depends on your current implementation and your requirements!

Best regards,

GerdW

using LV2011SP1 + LV2017 (+LV2020 sometimes) on Win10+cRIO

GerdW

using LV2011SP1 + LV2017 (+LV2020 sometimes) on Win10+cRIO

Highlighted
Options

10-15-2020 07:17 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

Thanks John for the response.

The input to the modulo function is a FXP mechanical angle of a motor shaft. I need to perform mod 2pi on that angle to produce the electrical angle of the motor to feed a Park transform for Field Oriented Control.

Joel

Highlighted
Options

There are only two ways to tell somebody thanks: Kudos and Marked Solutions

Unofficial Forum Rules and Guidelines

"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5

10-15-2020 07:53 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

@johnsoja wrote:

The input to the modulo function is a FXP mechanical angle of a motor shaft. I need to perform mod 2pi on that angle to produce the electrical angle of the motor to feed a Park transform for Field Oriented Control.

Convert the 2*pi into the needed FXP before the Q&R.

There are only two ways to tell somebody thanks: Kudos and Marked Solutions

Unofficial Forum Rules and Guidelines

"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5

Highlighted
Options

10-15-2020 07:57 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

So the Q&R will accept FXP inputs?

Highlighted
Options

10-15-2020 08:46 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

You didn't attach any VIs or provide detailed information of what you are doing, but I'm going to make a few assumptions:

- You have a method of getting a Float (non-integer) value, probably sampled, of a shaft position in radians.
- It is not clear if the encoder you are using
__reports__values modulo 2 pi, or if it is more like an odometer, able to say "the shaft has turned by 100 radians (or about 16 times) since the last measurement". I'm going to__assume__it is like an odometer -- it is also fairly simple to handle if it is modulo 2 pi. - I'll assume that you make measurements a few times per revolution.

Assume you know the Last Shaft Position (LSP) and also the Last Shaft Position Modulo 2 Pi (LSPM). Calculate the difference between the Current Shaft Position (CSP) and the Last Shaft Position, which by Assumption 3 will always be < 2 pi. Add this to LSP and call it CSP. Now do the following:

- If CSP < 0, CSPM = CSP + 2 pi.
- Else If CSP >= 2 pi, CSPM = CSP - 2 pi.
- Otherwise CSPM = CSP.

Save CSPM in the LSPM Shift Register.

Now all you have to do is to initialize the LSPM Shift Register from the initial LSP. Apply the same algorithm to "brute force" compute LSP mod 2 pi without doing any division.

The above algorithm, which uses no floating point multiplication or division (expensive in an FPGA, I'm told), should be easy to implement and very fast.

Bob Schor

With these assumptions, the __difference__ between successive measurements gives you the __change__ in shaft position, which will always be < 2 pi.

in a Shift Register (initialize it with the starting Shaft Position).

Highlighted
Options

10-20-2020 03:32 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

Bob,

Thanks so much for the reply. I've got an incremental encoder with index (A,B,Z outputs) mounted on the motor shaft and I'm using the Labview SoftMotion Encoder function running in a SCTL, which provides an I32 output of counts representing mechanical position in a continuous fashion. The encoder function (I32 output) is not a read of delta position, but rather a continuous output counting up with rotation in one direction and counting down with rotation in the other direction. I take the I32 output into a flat sequence structure where I do my servo loop controls. In that structure I take the I32 position count output from the encoder function, convert it to FXP, multiply it by a scale factor to convert the counts to mechanical degrees. It is this output that I need to perform the mod 2pi on. Any other thoughts based on this info?

Thanks again!

Joel

Thanks,

Joel

Highlighted
Options

** LabVIEW Champion. It all comes together in GCentral **

**What does "Engineering Redefined" mean??**

Solution

Accepted by topic author johnsoja

10-20-2020 03:43 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

All you probably need to do is take the integer and use Q&R to divide by the number of counts for a full revolution. No need for any other datatype here. You can convert the result afterwards to whatever the next node expects.

Highlighted
Options

10-21-2020 04:06 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

@johnsoja wrote:The encoder function (I32 output) is not a read of delta position, but rather a continuous output counting up with rotation in one direction and counting down with rotation in the other direction.

..

In that structure I take the I32 position count output from the encoder function, convert it to FXP, multiply it by a scale factor to convert the counts to mechanical degrees. It is this output that I need to perform the mod 2pi on. Any other thoughts based on this info?

If you have an absolute integer encoder position, it seems weird to be to convert it to fxp and do a modulus. This seems dangerous, as 2*pi isn't an exact number so divide or modulus will sooner or later be wrong...

If you have integers, I'd stick to them as long as possible. If you have a relative integer position, you can simply get the absolute integer position by accumulating.

So instead of:

read integer.

to fxp

scale

modulus 2*pi

I'd:

read integer:

modulus counts per rotation -> get rotations and remainder

(remainder + rotations X cnt/rot) X scale = total position

(remainder) X scale = position

If you're lucky (people making encoders aren't stupid), the cnt/rot is 2^n. If so, you can replace the remainder with an AND, and the rotations with a shift.

LabVIEW Programming ((make LV more popular, read this)

Highlighted
Options

10-21-2020 03:55 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

If you have a rotary encoder, it probably has a "resolution" expressed as "Counts per revolution". That is, from whatever position it is in, if you rotate it exactly one revolution, it "counts" (say) 1000 edges (fill in the actual number here).

So count edges. If you are rotating "up", increment the "edge position", and if you are counting down, decrement it. If it goes over 999 (to 1000), change it to 0 (or subtract 1000), while if it goes < 0, add 1000. You now have "rotatory position" expressed as an integer from 0 to 999 (and with 1000 edges, that the maximum resolution possible). 0 = 0 radians, 1000 = two-pi radians. No need, really, for doing __any__ floating point nor quotient/remainder arithmetic, it seems to me ...

Bob Schor

Note -- replace "1000" with the number of edges of your encoder, which should be 1/resolution.