I posted this in my Holey Calibration thread, but figure I would start a new thread.
I tried to speed up my calibration process and feed out an integral number of links when I reset the chain. With my 12 foot motor mount, I found a distance of 2032 would feed out precisely 320 links (2032/6.35 = 320). Since that’s divisible by 10, the zero tooth should return to 12 o’clock. However, it didn’t. It returned a bit past 12 o’clock. This happened for both motors. When I went to set the chains back to zero, I pressed automatic and the sprocket moved the zero tooth back to 12 o’clock. So, for some reason, 2032 mm isn’t feeding out the correct amount and Maslow knows it’s not where its supposed to be.
Chain tolerance is turned off (it’s not even used in SingleAxisMove routine that is used to feed out the chain. distPerRot is set to 63.5 mm for both left and right motors). The only thing I noticed from the log was that the encoder steps per revolution was reported as $12=8113.73046875 whereas GC reports it as 8113.73. I know when we had an issue last year, it was with the encoder steps value we were using… I think we used 8113.7 (which is still listed as the default in the firmware even though it gets updated by GC). So I think there may be an issue with how the values are sent from GC to the controller and how the controller parses it. I’ve not touched anything regarding encoder steps so not sure why it’s off.
I just redid the process with encoder steps hard coded as 8113.73 in the firmware and got the same results. it went a little past 12 o’clock and when I hit automatic on the zero page, it went back to 12 o’clock. Somehow it seems that 2032mm isn’t coming out as 2032mm
This is floating point math in operation, it can’t accurately represent 8113.73,
so it comes ‘close’
we would have to switch the math to use a fixed point library instead of
floating point math to fix this (we probably should due to other issues we are
running into with single precision floating point). We do know from a prior
test that this will slow things down a little bit (the prior test was trying to
do this to speed things up)
You might be/likely are hitting the limits of the arduino’s single precision floating point. Maybe isolate the necessary calculations into a small sketch and see if you can duplicate it. Wonder if you can duplicate it on a PC, didn’t look to see if the number of exponent/mantissa bits are the same. Or worse, maybe the Arduino library plays tricks to up the speed; something’s fishy if it beats fixed point
I reran the B02 command that feeds out the chain length from GC and at the end, it printed the final location (in the log). It reported 2030.91 mm. This is rather striking since it is supposed to report 2032…
I then went to set the sprockets to zero and when I used the automatic command, the program reads the current chain distance and figures out how much to subtract from it to get the zero tooth back to 12 o’clock. Well, when it read it, it read: [Measure: 2032.95] in the log… So first, FW is reporting it short by 1.09 mm when it’s done and then later reports 2032.95 (0.95 mm long). I believe the second value is more correct because the sprocket had rotated too far.
When I do the G09 L2032 command and go to set zero, it reported a distance of 2032.01 mm (can’t complain about being off .01 mm).
So, I think I know what’s up. The originalChainLength (the value that holds how much chain to feed out… my case it’s 2032) is an unsigned int. I think we either have a problem with it getting assigned a float value in settings.cpp (maybe gets rounded down or up?) or a problem when that value is passed to singleAxisMove…
Could it be because with the B02 command, a uint gets passed for endPos (and results in an issue) whereas in a G09 command, a float gets passed (and works)?
I did notice that the MMPerMin in the B02 command is set to maxFeed*0.9 whereas in the G09 L2032 command, a speed of 800 mm/min is used (default return value in firmware subroutine).
I modified the firmware to print endPos and it comes out at 2032.00mm as desired. I changed the firmware to use maxFeed*1.0 to see if it results in a difference and it didn’t… still overshot.
Could it be because with the B02 command, a uint gets passed for endPos (and results in an issue) whereas in a G09 command, a float gets passed (and works)?
That is one good reason for the difference
I did notice that the MMPerMin in the B02 command is set to maxFeed*0.9 whereas in the G09 L2032 command, a speed of 800 mm/min is used (default return value in firmware subroutine).
So, could a differing speed be the problem?
If you are actually loosing pulses, it would probably happen more at high speed.
I’ll look at it more tomorrow… the same command is issued (singleAxisMove) and it looks as if the same values are sent to it… but the results differ. The only difference I see (assuming the controller is in relative mode, which I believe it is) is that the B09 command reads the axis and then adds the distance to it whereas the B02. just sends the distance (I guess because it assumes the axis is at zero). If the axis has just been zero’ed, then shouldn’t axis report zero when read?
I’m a bit dumbfounded why the results are different. The main difference I see with the B02 behavior is at the end, the axis read reports a value less than 2032 but it actually overshoots 2032 and the firmware knows it because when the axis is read later, its shown to be greater than 2032.
This is very interesting, I am excited to see what you learn. I don’t have anything to contribute other than that everything you said seems logically sound and I agree that both commands should have the same behavior under those conditions. I agree that it sounds like a software bug to me.
Just wish I could find it. Nothing is making sense. The fact that an axis.read happens after the singleAxisMove reports a value less than the target distance but one that happens a little later (when you go to automatically reset the sprockets) reports a distance that is greater than the target … and representative of actually where the sprocket is.
I would say it doesn’t matter since the controller truly knows how long the chain is and that’s what matters. But if there’s a glitch here, I just get worried there’s a glitch somewhere else that results in overshooting the target during a cut (out of round circles, for instance). I’d say it might be because the distance moved is so high (2032 mm) in the singleAxisMove, but issuing a B09 for the same distance works fine… It’s baffling.
I guess one question I have is this isolated to something in my setup?
Here’s the logs. First I did an set zero on the sprockets (I had already did auto adjustment to 12 o’clock), followed by an adjust left chain. The brackets variables indicate the print statements I added to report the variables of singleAxisMove.
Sent: B06 L0 R0
B06 L0 R0
Setting Chain Lengths To:
Left: 0.00mm
Right: 0.00mm
ok
Sent: B02 L1 R0
B02 L1 R0
Measuring out left chain
2032.00mm [endPos]
800.00mm [MMPerMin]
2032.00mm [moveDist]
15239steps [finalNumberOfSteps]
0.13mmpermin [stepSizeMM]
2030.67mm [value reported from axis.read at end of calibrate chain lengths]
Then I did another automatic and set zero. The error from 12 o’clock was 1.17 mm
Sent: B10 L
B10 L
ok
Sent: B10 R
B10 R
ok
Sent: G91
G91
ok
Sent: B09 L-1.17
B09 L-1.17
2032.00mm [endPos]
800.00mm [MMPerMin]
-1.17mm [moveDist]
8steps [finalNumberOfSteps]
-0.13mmpermin [stepsizeMM]
ok
Sent: B09 R-0.0
B09 R-0.0
ok
Sent: G90
G90
Sent: B06 L0 R0
B06 L0 R0
Setting Chain Lengths To:
Left: 0.00mm
Right: 0.00mm
ok
Message: Notice: Exiting the calibration process early may result in incorrect calibration.Sent: ~
ok
If there isn’t any rounding going on with how the variables are being reported to the log, it makes no sense for the same values to provide differing results.