Simpson:
Just had a refresher on how I did that in the threading module. I figure a better explanation is in order of exactly how I
manage single point threading. I tend to agree on the face of it with those that say its impossible, but when I developed it
I wasnt aware of that. :-) , so I did as cloase as I think could be done given the restrictions in architecture.
So we have to accept certain givens..
1) Motion is preplanned, in a buffer of steps. This buffer can be considered an endless array of bytes. most of the time each entry will be zero. Each interrupt cycle.. at 25000 times a second, an array iten is retirved, and analysed, if a bit 0, for example is a 1, a step is put out on the X motor. If its a zero, no step is put out, if -1, a backwards setp is put out. That array item is delted, and next interrupt we get the next one( This is all simplified for examplication. )
2) Due to this, the driver of course knows nothing about speed, acceleration, or even if a motor is stepping or not, we simply have an array of bytes, and we step though that array one byte at a time. Mach3 continuously refills this array of bytes so the next stepo will be correct.
3) TO measure RPM, we count how many interrupts between each index pulse. This is divied out to find the rpm. ( The advanced threading uses time as the measurement)
Ok, so we have those limitations, we have no idea what speed any motor is moving.. or even if it is. BUT, we know time is linear, counting at 25000 steps a second. We know prior to the threading starting that the spindle is hitting index every 11345 interrupts. ( for example).
So when threading starts, we start a counter.. we count the number of interrupts between each suceeding index pulse and place it in a var called CURRPM.. Then, every interrupt we add CURRPM to our originally zeroed counter, we then subtract the reference index pulse count. If this number is greater than the reference count, we skip an interrupt processing. This is a bresenham divider time relinearisation of the pulse streams time, not the motor motion directly. A motor moving at full speed, would then have 1 step delayed till next interrupt, but normally, this operation would be a small fraction of one step of a motor in time.
Thats a bit hard to understand.. consider this sequence of events..
Kernal speed 25000. Threading is commanded and spindle RPM is 120. An index occurs every 12500 interrupts. Threading begins..
On each interrupt counter = (counter + currpm) - refrpm
we start with..
Counter : 0 CurRPM: 12500 RefRPM: 12500
The counter wont change for 1 full rotation, its always getting 12500 added to it, and 12500 subtracted from it..
Now the next interrupt comes in at 12900..
So on that interrupt, the counter is now 12900 - 12500 = 400.
Eachinterrupt this number will increase by 400. When it hits 12500, an interrupt is skipped. Not a motor step, an interrupt.
This means time is stretched, the motor motions, all equally are slowed by 1/25000 of their time base. The ref is then subtratce from the counter and it all continues.
This means that as each rotation slows..or even maintains its new speed, the error count grows, and is compunded by further slowdowns
so it actually has a sense of history. Time corrections are also applied linearly across the motion for this correction. And since the number subtracted when an interrupt is skipped is the ref rpm, fractional counts are kept, and spread across the next rotation. As the speed increases to normal speed, the counter approaches equilibriam again with its total zero.. and no further time intervals are skipped.
This is all necessary due to the way motion is planned before the threading begins, so all we can alter is time itself, not anything to
do with motor motion.
You question is well put though, if the spindle has slowed by 1%, we can then pretty much anticipate that the next will also be 1%, so why not double down and correct at 2% for the first slow rotation. You cant really do that though as you cant really make that assumption. It could be just a slightly slow index input for example.. so its best to stay exactly one rotation behind at all times. Mathmatically its the best one can do with a single input, If the RPM is, indeed ,slow on the next by 1% again, then it hasnt changed, nor will the algorithms slowdown, it will be exacly 1 rev behind, but if for whatever reason the rpm increases back to normal, ( VFD self correction for example ), then the algorithm will automatically speed back up to normal and we'll be exactly 1 rev behind it again.
The only way we get fooled is if the vfd speeds up to a speed greater then the start reference speed, in which case the error from the previosu rev cannot be corrected, and will be forever locked in, and will grow on each rev that is faster than reference. However, since remainders are taken into account by the bresenham, its counter goes negative by the uncorrected amount, and should the rpm slow down, the algorithm will not slow down to compensate until the over speed that was uncorrected is eaten up.
Its a pretty simple algoritm, simple enough to be very smart. Overspeeds will be corrected when and if they can, underspeeds will be 1 rev behind at all times, and very small fractions are accounted for. Its why its actually possible to do this without knowing anything about the motors motion, its simply the matching of two varying time bases by a counter than keeps track of total time with no capability of rollover.
Hope this explanation helps, it actually helped me to write it and get reaquainted with how the heck the code works in the first place.
Thx
Art