Good news! I got it working! Thanks again to all who helped me out.
I ended up having to do a ton of test scripts to get an understanding of what exactly Mach 4 was doing with the code I was running.
Here are the key snippets I figured out to make this work (and I am sure they were discussed above already):
- Mach 4 does not apply the changes made by calling mc.mcAxisSetHomeInPlace() until I later call mc.mcProfileSave()
- There is some short period of time in which Mach 4 does not respond to the changes to the "Home in Place" command
- This period of time is something greater than 10ms but less than or equal to 50ms
I figured this out by added 3 test buttons to the screen. One turned ON home in place, one ran the homing code, and one turned OFF home in place. If I clicked through these in sequence, the code worked great. If I put them together in a script, it didn't work at all. I was going to build a state machine, but figured I would try a raw delay first and that worked great (wx.wxMilliSleep()). This has yet to fail at 50ms, but if I set it to 10ms, some axes will home in place while others won't. I decided to play it safe and choose 100ms. There may be a cleaner way to do this, but execution time isn't important to me since it only runs one time at startup.
The code is executed while the axes are enabled. I can have the axes anywhere and they don't need to be moved. I get the current position of the motors from the drives which is tracked mechanically in the encoders while the machine is powered off. I throw this value into the homing offset then home in place. Finally the home offset and home in place values are returned to normal and the code ends. This still allows me to home to my switches like normal if I want. It is cool to see a tenth or two of movement when I disable and later re-enable. It is the closest thing to position feedback into Mach that I have.
Here is the code contained in the Ref All Home button:
--RefAllHome()
local e1 = 0
local HomeBox = wx.wxMessageBox("Do you wish to restore absolute position data from Servo Drives? \n \nChoose YES to restore homing data. \nChoose NO to Home to Limit Switches. \nChoose CANCEL to skip homing.", "Homing Type",18)
if HomeBox == 2 then
e1 = mcServo.AbsolutePositionRecovery()
if e1 ~= 0 then
wx.wxMessageBox("Home Position Recovery Failed! \n \n Axes must be referenced to switch before operation.", "Homing Failed",4)
else
wx.wxMessageBox("Home Position successfully read from Servo Drives", "Step 3/5 - Homing",4)
end
elseif HomeBox == 8 then
wait = coroutine.create (RefAllHome) --This is the code from the ref all home button
end
And the code for absolute homing using Allen Bradley Ultra 3000 servo drives, consuming data over RS485 Serial Host commands:
function mcServo.AbsolutePositionRecovery()
local rError = 0
local sError = 0
local xPosition = 0
local yPosition = 0
local zPosition = 0
local sPosition = 0
mc.mcAxisSetHomeInPlace(inst, 0, 1)
mc.mcAxisSetHomeInPlace(inst, 1, 1)
mc.mcAxisSetHomeInPlace(inst, 2, 1)
mc.mcAxisSetHomeInPlace(inst, 6, 1)
mc.mcProfileSave(inst)
wx.wxMilliSleep(100) --Sleep 100 milliseconds
local XctsInch = mc.mcMotorGetCountsPerUnit(inst, 0)
local YctsInch = mc.mcMotorGetCountsPerUnit(inst, 1)
local ZctsInch = mc.mcMotorGetCountsPerUnit(inst, 2)
local SctsInch = mc.mcMotorGetCountsPerUnit(inst, 6)
sError, xPosition = mcServo.GetPosition("00", XctsInch)
if sError ~= 0 then; rError = 1; return rError end
sError, yPosition = mcServo.GetPosition("01", YctsInch)
if sError ~= 0 then; rError = 1; return rError end
sError, zPosition = mcServo.GetPosition("02", ZctsInch)
if sError ~= 0 then; rError = 1; return rError end
sError, sPosition = mcServo.GetPosition("05", SctsInch)
if sError ~= 0 then; rError = 1; return rError end
mc.mcAxisSetHomeOffset(inst, 0, (xPosition*-1))
mc.mcAxisSetHomeOffset(inst, 1, (yPosition*-1))
mc.mcAxisSetHomeOffset(inst, 2, (zPosition*-1))
mc.mcAxisSetHomeOffset(inst, 6, (sPosition*-1))
mc.mcAxisHomeAll(inst)
wx.wxMilliSleep(100) --Sleep 100 milliseconds
mc.mcAxisSetHomeOffset(inst, 0, 0)
mc.mcAxisSetHomeOffset(inst, 1, 0)
mc.mcAxisSetHomeOffset(inst, 2, 0)
mc.mcAxisSetHomeOffset(inst, 6, 0)
mc.mcAxisSetHomeInPlace(inst, 0, 0)
mc.mcAxisSetHomeInPlace(inst, 1, 0)
mc.mcAxisSetHomeInPlace(inst, 2, 0)
mc.mcAxisSetHomeInPlace(inst, 6, 1) --Leave Spindle as Home in Place
mc.mcProfileSave(inst)
wx.wxMilliSleep(100) --Sleep 100 milliseconds
return rError
end
Thanks again to all!