Servo Rev-Count Math

roxusa

Lifetime Supporting Member
Join Date
Nov 2008
Location
NJ
Posts
994
Using a 1766 Micrologix 1400 What is easiest way to break out pulses to Rev's & Remaining Pulses. Each Revolution is 10000 pulses, The programming Modbus has an address for each. how can I add up pulses with math in PLC and break that down to rev's + remaining pulses. I did a complicated one where I
turned float to integer then had to determine if it rounded up or down & then more math but it looked like there should have been something simpler.
like a divide by 10000 and the remainder being somewhere else. Anyone have a suggestion. Thanks
 
Such as if I have a Long number, how can I separate the last 4 digits to be my remaining pulses and use the upper digits to be my rev's
 
I noticed the same thing: there is no modulo function in MicroLogix; and the quotient is automatically rounded if put back into a integer location, as if I am to stupid to know what to do with the result.


You could always write it to a decimal string, parse the last four characters to [remaining pulses], and the characters before that to revs. But that is going to be uglier than what you have. If you post an image or .zip of what you have now, maybe someone will do some code golf on it.



Personally, I would see if I could set the pulses per revolution to be a power of 2 (8192 or 16384); then a bit-wise AND with 1FFFH or 3FFFH would be equivalent to a modulo operation.
 
Heh.



  1. Start with total number of pulses, REV*10000+RemPulses
  2. TOD: Convert that from binary to BCD.
  3. AND: 0FFFFH with that BCD in binary to get BCD RemPulses
  4. FRD: Convert BCD RemPulses back to binary RemPulses
  5. SUB: Subtract binary RemPulses from total to get DkREVs
  6. DIV: Divide DkREVs by 10000 to get REVs
Whoops: TOD and FRD work on integers, not on longs.


And it's still ugly.
 
I have a very old (1996) instruction set manual for the SLC and MicroLogix 1000 which describes the Double Divide (DDV) function. According to that manual, The unrounded quotient of the DDV is placed in S:13 and the remainder in S:14. Was the DDV implemented in the ML1400?
 
When you do an integer divide, is there an S-bit that tells you if the quotient was rounded up?


Would this work?


Number of Revs = Pulse count divided by 10000
If rounded up, Number of Revs = Number of Revs - 1


Temp1 = Number of Revs * 10000


Counts in partial rev = Pulse count - Temp1
 
Steve
Although the 1400 does not support DDV I notice now that the remainder is stored in S:13
perhaps I can configure that int my rung and eliminate a lot of nonsense. Although what i pasted in the zip works it just seems like a long way around.
 
I looked at the ML1400 reference manual. If I'm reading it correctly, you only get the remainder in S:13 if you're doing the DIV with INTs. If you use LONGs you get the rounded result.


Since I didn't see a bit to indicate roundup, a slight modification of my method.


Number of Revs = Pulse count divided by 10000
Temp1 = Number of Revs * 10000


Temp2 = Pulse Count - Temp1


If Temp2 is negative:
Number of Revs = Number of Revs - 1
Counts in partial rev = 100,000 + Temp2
Else:
Counts in partial rev = Pulse count - Temp1
 
1) What is the highest number of REVs you expect e.g. does it get reset at some point, or does it roll over after 2,147,483,647?



1.1) Does it ever decrease, other than a reset to zero?



2) How long after the PLC powers up do you need/want these numbers to be available?


2.1) Specifically, would it be okay if the numbers were TBD for a brief period on startup, and/or occasional brief periods after that?



3) What is the maximum pulse rate?
 
See attached .ZIP, containing an alternate algorithm for [pulses MODULO 10000] application.


It is not any less of "a long way around" than the floating-point algorithm you already have, but it will work past the 16M pulse limit, and give the correct answer for 16,777,215 pulses.


It's almost recursive.
 
if you have the total counts as a real datatype number
create an INT array of 2
then device by your 10000 (PPR)
with the result as a real datatype
then COP the result to the INT array [0] with a length of 2
you remaining pulse count should be in INT[1]
actually with the 1400 you don't nee to create an array the data table is already an array the copy will automatedly use the next word in the copy
 
Last edited:

Similar Topics

Hi, I'm working on Mitsubishi MR-J5-70A amplifier, and need some advice on selecting fuse size. Main power is 1ph 240VAC, and in the manual, it...
Replies
1
Views
52
Good morning, We've had an issue with a couple of servo valves and was wondering if anyone had seen anything similar. After a drop in pressure...
Replies
2
Views
93
Hello all, I'm currently working on a servo motor linear positioning system (ball screw). I'm all set up regarding communication between my HMI...
Replies
1
Views
90
Hi all, I am having a machine with old 802d sl siemens controller. I am trying to tune servo by Siemens starter software. Anyone experienced...
Replies
0
Views
69
Hi, I'm thinking about using commands for Melservo J5 controller via HMI without PLC. Have you guys done this kind of control configuration for...
Replies
3
Views
139
Back
Top Bottom