Machsupport Forum
Mach Discussion => Mach4 General Discussion => Topic started by: RecceDG on May 29, 2021, 09:23:19 PM
-
So I finally got around to wiring in the new control panel for my lathe.
General concept of ops is: https://warp9td.com/index.php/faq/faq-pendants-and-mpgs
I get as far as Step 6 in "How to wire a multi-wire pendant" and then I get a surprise - with the machine enabled, turning the jog handle jogs the X axis!
So on one hand - yay, it works! But on the other hand, I didn't edit any lua or any screens, so nothing should be enabled yet.
Where is the configuration for this located?
Here is what I want to have happen:
Jog Speed Rotary Switch:
- Set to 0.1
- Activate jog handle
- Turn on jog light
- Set speed to 0.1
- Set to 0.01
- Activate jog handle
- Turn on jog light
- Set speed to 0.01
- Set to 0.001
- Activate jog handle
- Turn on jog light
- Set speed to 0.001
- No speed selected (none of the 3 speed pins set high)
- Deactivate jog handle
- Turn off jog light
Jog Axis Switch
- X
- Set active jog axis X
- Z
-Set active jog axis Z
What is the best way to do this?
-
Here is my first kick at the cat. None of the signal numbers are right yet, but the logic should be good.
---------------------------------------------------------------
-- Added by DG May 30 2021 to enable the control panel
-- Monitor the switches on the Pendant.
-- We break the three different mechanical switches into three separate function calls, since each function has a separate job.
-- We don't need to assign the MPG wheel since Mach handles that for us.
---------------------------------------------------------------
SigLib = {
-------------
-- Axis Select Switch
-- Must always be X or Y
[mc.ISIG_INPUT0] = function (state) -- X Axis Select
PendantAxisChange()
end,
[mc.ISIG_INPUT1] = function (state) -- Y Axis Select
PendantAxisChange()
end,
-------------
-- Jog Enable / Speed
-- 4-position rotary switch
-- No active signals mean JOG OFF
[mc.ISIG_INPUT6] = function (state) -- Enable Jog Speed 0.1
PendantSpeedChange()
end,
[mc.ISIG_INPUT7] = function (state) -- Enable Jog Speed 0.01
PendantSpeedChange()
end,
[mc.ISIG_INPUT8] = function (state) -- Enable Jog Speed 0.001
PendantSpeedChange()
end,
-------------
-- EStop
[mc.ISIG_INPUT9] = function (state)
PendantEStopChange()
end,
-------------
-- Cycle Start
[mc.ISIG_INPUT10] = function (state)
InputCycleStart()
end,
--------------
-- Feed Hold
[mc.ISIG_INPUT11] = function (state)
InputFeedHold()
end,
---------------
-- Manual Spindle ON/OFF
[mc.ISIG_INPUT12] = function (state) -- Starts the spindle manually
InputManualSpindle()
end
}
---------------------------------------------------------------
-- Control Panel Cycle Start
---------------------------------------------------------------
function InputCycleStart()
local hRunLight
hRunLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1)
local hHoldLight
hHoldLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1)
mc.mcSignalSetState(hHoldLight, 0) -- Make sure the HOLD light is off
mc.mcSignalSetState(hRunLight, 1) -- Turn the RUN light on
CycleStart()
mc.mcCntlSetLastError(inst, "Control Panel Cycle Start")
end
---------------------------------------------------------------
-- Control Panel Feed Hold
---------------------------------------------------------------
function InputFeedHold()
local hRunLight
hRunLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1)
local hHoldLight
hHoldLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1)
mc.mcSignalSetState(hRunLight, 0) -- Make sure the RUN light is off
mc.mcSignalSetState(hHoldLight, 1) -- Turn the HOLD light on
CycleStop() -- Is this the right function? We want a "pause" not a hard stop.
mc.mcCntlSetLastError(inst, "Control Panel Feed Hold")
end
---------------------------------------------------------------
-- Control Panel Manual Spindle
---------------------------------------------------------------
function InputManualSpindle()
-- We don't turn any lights on for manual spindle operation
-- but if we are here, let's make sure they are off
local hRunLight
hRunLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1)
local hHoldLight
hHoldLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1)
local hJogLight
hJogLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1)
mc.mcSignalSetState(hRunLight, 0) -- Make sure the RUN light is off
mc.mcSignalSetState(hHoldLight, 1) -- Ditto HOLD
mc.mcSignalSetState(hJogLight, 1) -- And JOG
--- mc.mcSpindleSetDirection(inst, 0)
-- Need function to toggle spindle on/off
mc.mcCntlSetLastError(inst, "Control Panel Manual Spindle")
end
----------------------------
-- We use MPG 7
local MachMpgNumberForPendant = 7
local PendantStepSize = 0.001 --This is in your Mach4's units, mm or Inches, whichever one you have it set to
local PendantDistanceX1 = PendantStepSize * 1 --Multiply by one
local PendantDistanceX10 = PendantStepSize * 10 --Multiply by ten
local PendantDistanceX100 = PendantStepSize * 100 --Multiply by one hundred
--These shouldn't need to be modified, but they reduce the amount of apparently random numbers in the code:
local UnmapMPG = -1 --Use this one for when Axis selector switch is set to OFF
local AxisNumber_X = 0 -- Linear axis X (one of six coordinated motion axes)
local AxisNumber_Y = 1 -- Linear axis Y (one of six coordinated motion axes)
local AxisNumber_Z = 2 -- Linear axis Z (one of six coordinated motion axes)
local AxisNumber_UA = 3 -- Linear axis U or Rotational axis A
local AxisNumber_VB = 4 -- Linear axis V or Rotational axis B
local AxisNumber_WC = 5 -- Linear axis W or Rotational axis C
local AxisNumber_OB0 = 6 -- Out of Band axis 0 (NOT coordinated with motion)
local AxisNumber_OB1 = 7 -- Out of Band axis 1 (NOT coordinated with motion)
local AxisNumber_OB2 = 8 -- Out of Band axis 2 (NOT coordinated with motion)
local AxisNumber_OB3 = 9 -- Out of Band axis 3 (NOT coordinated with motion)
local AxisNumber_OB4 = 10 -- Out of Band axis 4 (NOT coordinated with motion)
local AxisNumber_OB5= 11 -- Out of Band axis 5 (NOT coordinated with motion)
--Coordinated motion means all six coordinated axes get to the destination point at the same time.
--Not coordinated with motion means that axis can be doing whatever, whenever. Like a conveyor belt that is always running.
---------------------------------------------------------------
-- The Pendant's Speed switch changed... Reconfigure appropriate settings in Mach4
-- This will process the Pendant's Rate/Speed Selection Switch
---------------------------------------------------------------
function PendantSpeedChange()
-- Switch handles
local hX1
local hX10
local hX100
local hAxis_X -- X Axis Select Switch
local hAxis_Z -- Z Axis Select Switch
local Step1
local Step10
local Step100
hX1, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT6) -- Speed 0.001
Step1, rc = mc.mcSignalGetState(hX1)
hX10, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT7) -- Speed 0.01
Step10, rc = mc.mcSignalGetState(hX10)
hX100, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT8) -- Speed 0.1
Step100, rc = mc.mcSignalGetState(hX100)
-- Light handle
local hJogLight
hJogLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1)
-- Figure out which axis is active by reading the axis select switch
local hAxis_X
local hAxis_Z
hAxis_X, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT0) -- If X is selected, activate X
SelectAxis_X, rc = mc.mcSignalGetState(hAxis_X)
hAxis_Z, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT2) -- If Z is selected, activate Z
SelectAxis_Z, rc = mc.mcSignalGetState(hAxis_Z)
-- TODO - This should really check that we have X || Z, but not neither or both!
if (SelectAxis_X == 1) then
mc.mcMpgSetAxis(inst, MachMpgNumberForPendant, AxisNumber_X) -- Map the MPG to control the X Axis
mc.mcCntlSetLastError(inst, "Jog Axis X Selected") -- Show a message in the Screen Set
elseif (SelectAxis_Z== 1) then
mc.mcMpgSetAxis(inst, MachMpgNumberForPendant, AxisNumber_Z) -- Map the MPG to control the Z Axis
mc.mcCntlSetLastError(inst, "Jog Axis Z Selected") -- Show a message in the Screen Set
end
local msg
if (Step1 == 1) then
mc.mcMpgSetInc(inst, MachMpgNumberForPendant, PendantDistanceX1 )
mc.mcSignalSetState(hJogLight, 1) -- Turn Jog light on
msg = "Jog Active X1 = " .. PendantDistanceX1
mc.mcCntlSetLastError(inst, msg) --Show a message in the Screen Set
elseif (Step10 == 1) then
mc.mcMpgSetInc(inst, MachMpgNumberForPendant, PendantDistanceX10)
mc.mcSignalSetState(hJogLight, 1) -- Turn Jog light on
msg = "Pendant Distance X10 = " .. PendantDistanceX10
mc.mcCntlSetLastError(inst, msg) --Show a message in the Screen Set
elseif (Step100 == 1) then
mc.mcMpgSetInc(inst, MachMpgNumberForPendant, PendantDistanceX100)
mc.mcSignalSetState(hJogLight, 1) -- Turn Jog light on
msg = "Pendant Distance X100 = " .. PendantDistanceX100
mc.mcCntlSetLastError(inst, msg) --Show a message in the Screen Set
else
-- If we got here, it means the one of the speed inputs changed, but none are active
-- That means "JOG OFF"
mc.mcMpgSetInc(inst, MachMpgNumberForPendant, 0 ) -- Can we set the jog distance to 0?
mc.mcSignalSetState(hJogLight, 0) -- Turn Jog light off
mc.mcMpgSetAxis(inst, MachMpgNumberForPendant, UnmapMPG ) -- Unmap the MPG, so it won't control any axes
mc.mcCntlSetLastError(inst, "Jog Handle Disabled") -- Show a message in the Screen Set
end
end
---------------------------------------------------------------
-- The Pendant's Axis switch changed.
-- Need to handle this for when the axis switch is flipped while jogging is active
---------------------------------------------------------------
function PendantAxisChange()
-- handles
local hAxis_X
local hAxis_Z
local SelectAxis_X
local SelectAxis_Z
hAxis_X, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT0)
SelectAxis_X, rc = mc.mcSignalGetState(hAxis_X)
hAxis_Z, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT2)
SelectAxis_Z, rc = mc.mcSignalGetState(hAxis_Z)
--Now actual axis Selection Switch processing code
if (SelectAxis_X == 1) then
mc.mcMpgSetAxis(inst, MachMpgNumberForPendant, AxisNumber_X) --Map the MPG to control the X Axis
mc.mcCntlSetLastError(inst, "Pendant Axis X Selected") --Show a message in the Screen Set
elseif (SelectAxis_Z== 1) then
mc.mcMpgSetAxis(inst, MachMpgNumberForPendant, AxisNumber_Z) --Map the MPG to control the Z Axis
mc.mcCntlSetLastError(inst, "Pendant Axis Z Selected") --Show a message in the Screen Set
else
-- This is a problem, because the axis select switch is one or the other
-- We have no high pin - so shut off jogging
mc.mcMpgSetAxis(inst, MachMpgNumberForPendant, UnmapMPG ) --Unmap the MPG, so it won't control any axes
mc.mcCntlSetLastError(inst, "ABEND - no valid axis selected on control panel!") --Show a message in the Screen Set
end
end
--We will now call the three functions we made
--This is so the functions will be initalized to the current pendant values
--When the Screen is loaded by Mach4
PendantSpeedChange()
PendantAxisChange()
-
Some changes to handle the fact that my controls are momentary pushbuttons.
I couldn't find an API reference online, so I'd appreciate someone looking at the code
---------------------------------------------------------------
-- Added by DG May 30 2021 to enable the control panel
-- Monitor the switches on the control panel.
-- We break the three different mechanical switches into three separate function calls, since each function has a separate job.
-- We don't need to assign the MPG wheel since Mach handles that for us.
---------------------------------------------------------------
SigLib = {
-------------
-- Axis Select Switch
-- Must always be X or Y
[mc.ISIG_INPUT0] = function (state) -- X Axis Select TODO set correct signal number
PendantAxisChange()
end,
[mc.ISIG_INPUT1] = function (state) -- Y Axis Select TODO set correct signal number
PendantAxisChange()
end,
-------------
-- Jog Enable / Speed
-- 4-position rotary switch
-- No active signals mean JOG OFF
[mc.ISIG_INPUT6] = function (state) -- Enable Jog Speed 0.1 TODO set correct signal number
PendantSpeedChange()
end,
[mc.ISIG_INPUT7] = function (state) -- Enable Jog Speed 0.01 TODO set correct signal number
PendantSpeedChange()
end,
[mc.ISIG_INPUT8] = function (state) -- Enable Jog Speed 0.001 TODO set correct signal number
PendantSpeedChange()
end,
-------------
-- Cycle Start Panel Button
[mc.ISIG_INPUT10] = function (state) -- TODO set correct signal number
InputCycleStart()
end,
--------------
-- Feed Hold Panel Button
[mc.ISIG_INPUT11] = function (state) -- TODO set correct signal number
InputFeedHold()
end,
---------------
-- Manual Spindle ON/OFF Panel Button
[mc.ISIG_INPUT12] = function (state) -- Starts the spindle manually TODO set correct signal number
InputManualSpindle()
end
}
---------------------------------------------------------------
-- Control Panel Cycle Start
---------------------------------------------------------------
function InputCycleStart()
-- Momentary pushbutton, so we get TWO signals with each button press:
-- an "ON" and an "OFF"
-- So check state and ignore the "OFF"
local hStartButton
local StartButtonState
hStartButton, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT8) -- TODO set correct signal
StartButtonState, rc = mc.mcSignalGetState(hStartButton)
if (StartButtonState == 1) then
local hRunLight
hRunLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1) --TODO set correct signal number
local hHoldLight
hHoldLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1) --TODO set correct signal number
mc.mcSignalSetState(hHoldLight, 0) -- Make sure the HOLD light is off
mc.mcSignalSetState(hRunLight, 1) -- Turn the RUN light on
CycleStart()
mc.mcCntlSetLastError(inst, "Control Panel Cycle Start PRESS")
else
mc.mcCntlSetLastError(inst, "Control Panel Cycle Start RELEASE")
end
end
---------------------------------------------------------------
-- Control Panel Feed Hold
-- One push for Feed Hold, two pushes for Cycle Stop
---------------------------------------------------------------
function InputFeedHold()
-- Momentary pushbutton, so we get TWO signals with each button press:
-- an "ON" and an "OFF"
-- So check state and ignore the "OFF"
local hHoldButton
local HoldButtonState
hHoldButton, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT8) -- TODO set correct signal
HoldButtonState, rc = mc.mcSignalGetState(hHoldButton)
if (HoldButtonState == 1) then
local hRunLight
hRunLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1) -- TODO set correct signal number
local hHoldLight
hHoldLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1) -- TODO set correct signal number
mc.mcSignalSetState(hRunLight, 0) -- Make sure the RUN light is off
mc.mcSignalSetState(hHoldLight, 1) -- Turn the HOLD light on
-- TODO Need an API call here to check program run state.
-- If we are running a program, pause
-- If we are already paused, stop
CycleStop() -- TODO Is this the right function? We want a "pause" not a hard stop.
mc.mcCntlSetLastError(inst, "Control Panel Feed Hold PRESS")
else
mc.mcCntlSetLastError(inst, "Control Panel Feed Hold RELEASE")
end
end
---------------------------------------------------------------
-- Control Panel Manual Spindle
---------------------------------------------------------------
function InputManualSpindle()
-- Momentary pushbutton, so we get TWO signals with each button press:
-- an "ON" and an "OFF"
-- So check state and ignore the "OFF"
local hSpindleButton
local SpindleButtonState
hSpindleButton, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT8) -- TODO set correct signal
SpindleButtonState, rc = mc.mcSignalGetState(hSpindleButton)
if (SpindleButtonState == 1) then
-- We don't turn any lights on for manual spindle operation
-- but if we are here, let's make sure they are off
local hRunLight
hRunLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1) -- TODO set correct signal number
local hHoldLight
hHoldLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1) -- TODO set correct signal number
local hJogLight
hJogLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1) -- TODO set correct signal number
mc.mcSignalSetState(hRunLight, 0) -- Make sure the RUN light is off
mc.mcSignalSetState(hHoldLight, 0) -- Ditto HOLD
mc.mcSignalSetState(hJogLight, 0) -- And JOG
local hsig = mc.mcSignalGetHandle(inst, mc.OSIG_SPINDLEFWD)
local spinstate = mc.mcSignalGetState(hsig)
if (spindstate == 0) then -- If spindle is off, turn it on
mc.mcSignalSetState(hsig, 1)
else -- Otherwise, turn it off
mc.mcSignalSetState(hsig, 0)
end
mc.mcCntlSetLastError(inst, "Control Panel Manual Spindle PRESS")
else
mc.mcCntlSetLastError(inst, "Control Panel Manual Spindle RELEASE")
end
end
----------------------------
-- We use MPG 7
local MachMpgNumberForPendant = 7
local PendantStepSize = 0.001
local PendantDistanceX1 = PendantStepSize * 1 -- Multiply by one (0.001)
local PendantDistanceX10 = PendantStepSize * 10 -- Multiply by ten (0.01)
local PendantDistanceX100 = PendantStepSize * 100 -- Multiply by one hundred (0.1)
-- Constants for readability
local UnmapMPG = -1 -- Use this one for when Axis selector switch is set to OFF
local AxisNumber_X = 0 -- Linear axis X
local AxisNumber_Z = 2 -- Linear axis Z
---------------------------------------------------------------
-- Jog Speed/Enable Rotary Switch
---------------------------------------------------------------
function PendantSpeedChange()
local hX1
local hX10
local hX100
-- Need to get current state of axis selector switch so we move the right axis
local hAxis_X -- X Axis Select Switch
local hAxis_Z -- Z Axis Select Switch
local Step1
local Step10
local Step100
local msg
hX1, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT6) -- Speed 0.001 TODO set correct signal
Step1, rc = mc.mcSignalGetState(hX1)
hX10, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT7) -- Speed 0.01 TODO set correct signal
Step10, rc = mc.mcSignalGetState(hX10)
hX100, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT8) -- Speed 0.1 TODO set correct signal
Step100, rc = mc.mcSignalGetState(hX100)
-- Jog Active Light handle
local hJogLight
hJogLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1) -- TODO set correct signal
-- Figure out which axis is active by reading the axis select switch
hAxis_X, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT0) -- If X is selected, activate X TODO set correct signal
SelectAxis_X, rc = mc.mcSignalGetState(hAxis_X)
hAxis_Z, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT2) -- If Z is selected, activate Z TODO set correct signal
SelectAxis_Z, rc = mc.mcSignalGetState(hAxis_Z)
-- TODO - This should really check that we have X || Z, but not neither or both!
if (SelectAxis_X == 1) then
mc.mcMpgSetAxis(inst, MachMpgNumberForPendant, AxisNumber_X) -- Map the MPG to control the X Axis
mc.mcCntlSetLastError(inst, "Jog Axis X Selected") -- Show a message in the Screen Set
elseif (SelectAxis_Z== 1) then
mc.mcMpgSetAxis(inst, MachMpgNumberForPendant, AxisNumber_Z) -- Map the MPG to control the Z Axis
mc.mcCntlSetLastError(inst, "Jog Axis Z Selected") -- Show a message in the Screen Set
end
if (Step1 == 1) then
mc.mcMpgSetInc(inst, MachMpgNumberForPendant, PendantDistanceX1 )
mc.mcSignalSetState(hJogLight, 1) -- Turn Jog light on
msg = "Jog Active X1 = " .. PendantDistanceX1
mc.mcCntlSetLastError(inst, msg) -- Show a message in the Screen Set
elseif (Step10 == 1) then
mc.mcMpgSetInc(inst, MachMpgNumberForPendant, PendantDistanceX10)
mc.mcSignalSetState(hJogLight, 1) -- Turn Jog light on
msg = "Pendant Distance X10 = " .. PendantDistanceX10
mc.mcCntlSetLastError(inst, msg) -- Show a message in the Screen Set
elseif (Step100 == 1) then
mc.mcMpgSetInc(inst, MachMpgNumberForPendant, PendantDistanceX100)
mc.mcSignalSetState(hJogLight, 1) -- Turn Jog light on
msg = "Pendant Distance X100 = " .. PendantDistanceX100
mc.mcCntlSetLastError(inst, msg) --Show a message in the Screen Set
else
-- If we got here, it means the one of the speed inputs changed, but none are active
-- That means "JOG OFF"
mc.mcMpgSetInc(inst, MachMpgNumberForPendant, 0 ) -- TODO Can we set the jog distance to 0?
mc.mcSignalSetState(hJogLight, 0) -- Turn Jog light off
mc.mcMpgSetAxis(inst, MachMpgNumberForPendant, UnmapMPG ) -- Unmap the MPG, so it won't control any axes
mc.mcCntlSetLastError(inst, "Jog Handle Disabled") -- Show a message in the Screen Set
end
end
---------------------------------------------------------------
-- The Pendant's Axis switch changed.
-- Need to handle this for when the axis switch is flipped while jogging is active
---------------------------------------------------------------
function PendantAxisChange()
-- handles
local hAxis_X
local hAxis_Z
local SelectAxis_X
local SelectAxis_Z
-- Before we do anything, we need to check if the jog handle is assigned to axis -1
-- If it is, jog is DISABLED, so we do nothing (the act of enabling jog will read the axis switch)
-- Otherwise we enable jog, which is BAD
-- TODO - need a function to check which axis is assigned
-- This is a guess!
local AxisState
AxisState, rc = mc.mcMpgGetAxis(inst, MachMpgNumberForPendant)
if (AxisState ~= UnmapMPG) then
hAxis_X, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT0)
SelectAxis_X, rc = mc.mcSignalGetState(hAxis_X)
hAxis_Z, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT2)
SelectAxis_Z, rc = mc.mcSignalGetState(hAxis_Z)
-- Now actual axis Selection Switch processing code
if (SelectAxis_X == 1) then
mc.mcMpgSetAxis(inst, MachMpgNumberForPendant, AxisNumber_X) -- Map the MPG to control the X Axis
mc.mcCntlSetLastError(inst, "Pendant Axis X Selected") -- Show a message in the Screen Set
elseif (SelectAxis_Z== 1) then
mc.mcMpgSetAxis(inst, MachMpgNumberForPendant, AxisNumber_Z) -- Map the MPG to control the Z Axis
mc.mcCntlSetLastError(inst, "Pendant Axis Z Selected") -- Show a message in the Screen Set
else
-- This is a problem, because the axis select switch is one or the other
-- We have no high pin - so shut off jogging
mc.mcMpgSetAxis(inst, MachMpgNumberForPendant, UnmapMPG ) -- Unmap the MPG, so it won't control any axes
mc.mcCntlSetLastError(inst, "ABEND - no valid axis selected on control panel!") -- Show a message in the Screen Set
end
else
mc.mcCntlSetLastError(inst, "Changed axis select while jog disabled - IGNORED")
end
end
-- Set jog state when the Screen is loaded by Mach4
PendantSpeedChange()
-
Found an API reference.
This should be close to the final deal.
---------------------------------------------------------------
-- Added by DG May 30 2021 to enable the control panel
-- Monitor the switches on the control panel.
-- We break the three different mechanical switches into three separate function calls, since each function has a separate job.
-- We don't need to assign the MPG wheel since Mach handles that for us.
---------------------------------------------------------------
SigLib = {
-------------
-- Axis Select Switch
-- Must always be X or Y
[mc.ISIG_INPUT0] = function (state) -- X Axis Select TODO set correct signal number
PendantAxisChange()
end,
[mc.ISIG_INPUT1] = function (state) -- Y Axis Select TODO set correct signal number
PendantAxisChange()
end,
-------------
-- Jog Enable / Speed
-- 4-position rotary switch
-- No active signals mean JOG OFF
[mc.ISIG_INPUT6] = function (state) -- Enable Jog Speed 0.1 TODO set correct signal number
PendantSpeedChange()
end,
[mc.ISIG_INPUT7] = function (state) -- Enable Jog Speed 0.01 TODO set correct signal number
PendantSpeedChange()
end,
[mc.ISIG_INPUT8] = function (state) -- Enable Jog Speed 0.001 TODO set correct signal number
PendantSpeedChange()
end,
-------------
-- Cycle Start Panel Button
[mc.ISIG_INPUT10] = function (state) -- TODO set correct signal number
InputCycleStart()
end,
--------------
-- Feed Hold Panel Button
[mc.ISIG_INPUT11] = function (state) -- TODO set correct signal number
InputFeedHold()
end,
---------------
-- Manual Spindle ON/OFF Panel Button
[mc.ISIG_INPUT12] = function (state) -- Starts the spindle manually TODO set correct signal number
InputManualSpindle()
end
}
---------------------------------------------------------------
-- Control Panel Cycle Start
---------------------------------------------------------------
function InputCycleStart()
-- Momentary pushbutton, so we get TWO signals with each button press:
-- an "ON" and an "OFF"
-- So check state and ignore the "OFF"
local hStartButton
local StartButtonState
hStartButton, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT8) -- TODO set correct signal
StartButtonState, rc = mc.mcSignalGetState(hStartButton)
mc.mcCntlSetLastError(inst, "Control Panel Cycle Start PRESS")
if (StartButtonState == 1) then
local hRunLight
hRunLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1) --TODO set correct signal number
local hHoldLight
hHoldLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1) --TODO set correct signal number
mc.mcSignalSetState(hHoldLight, 0) -- Make sure the HOLD light is off
mc.mcSignalSetState(hRunLight, 1) -- Turn the RUN light on
CycleStart()
mc.mcCntlSetLastError(inst, "Control Panel CYCLE START")
else
mc.mcCntlSetLastError(inst, "Control Panel Cycle Start RELEASE")
end
end
---------------------------------------------------------------
-- Control Panel Feed Hold
-- One push for Feed Hold, two pushes for Cycle Stop
---------------------------------------------------------------
function InputFeedHold()
-- Momentary pushbutton, so we get TWO signals with each button press:
-- an "ON" and an "OFF"
-- So check state and ignore the "OFF"
local hHoldButton
local HoldButtonState
hHoldButton, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT8) -- TODO set correct signal
HoldButtonState, rc = mc.mcSignalGetState(hHoldButton)
if (HoldButtonState == 1) then
local hRunLight
hRunLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1) -- TODO set correct signal number
local hHoldLight
hHoldLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1) -- TODO set correct signal number
mc.mcCntlSetLastError(inst, "Control Panel Feed Hold PRESS")
-- If we are running a program, pause
-- If we are already paused, stop
local Running
local Paused
Running, rc = mc.mcCntlIsInCycle(inst)
Paused, rc = mc.mcCntlFeedHoldState(inst)
if (Running) then -- We are running, so pause
mc.mcSignalSetState(hRunLight, 0) -- Make sure the RUN light is off
mc.mcSignalSetState(hHoldLight, 1) -- Turn the HOLD light on
rc = mc.mcCntlFeedHold(inst) -- Should this maybe be FeedHold()?
mc.mcCntlSetLastError(inst, "Control Panel FEED HOLD")
elseif (Paused) then -- We are paused, so stop
mc.mcSignalSetState(hRunLight, 0) -- Make sure the RUN light is off
mc.mcSignalSetState(hHoldLight, 1) -- Turn the HOLD light on
CycleStop()
mc.mcCntlSetLastError(inst, "Control Panel CYCLE STOP")
else
-- Spurious button press
mc.mcCntlSetLastError(inst, "Not running or paused - IGNORE ME")
end
else
mc.mcCntlSetLastError(inst, "Control Panel Feed Hold RELEASE")
end
end
---------------------------------------------------------------
-- Control Panel Manual Spindle
---------------------------------------------------------------
function InputManualSpindle()
-- Momentary pushbutton, so we get TWO signals with each button press:
-- an "ON" and an "OFF"
-- So check state and ignore the "OFF"
local hSpindleButton
local SpindleButtonState
hSpindleButton, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT8) -- TODO set correct signal
SpindleButtonState, rc = mc.mcSignalGetState(hSpindleButton)
if (SpindleButtonState == 1) then
-- We don't turn any lights on for manual spindle operation
-- but if we are here, let's make sure they are off
local hRunLight
hRunLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1) -- TODO set correct signal number
local hHoldLight
hHoldLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1) -- TODO set correct signal number
local hJogLight
hJogLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1) -- TODO set correct signal number
mc.mcCntlSetLastError(inst, "Control Panel Manual Spindle PRESS")
mc.mcSignalSetState(hRunLight, 0) -- Make sure the RUN light is off
mc.mcSignalSetState(hHoldLight, 0) -- Ditto HOLD
mc.mcSignalSetState(hJogLight, 0) -- And JOG
local hsig = mc.mcSignalGetHandle(inst, mc.OSIG_SPINDLEFWD)
local spinstate = mc.mcSignalGetState(hsig)
if (spindstate == 0) then -- If spindle is off, turn it on
mc.mcSignalSetState(hsig, 1)
mc.mcCntlSetLastError(inst, "Control Panel Manual Spindle ON")
else -- Otherwise, turn it off
mc.mcSignalSetState(hsig, 0)
mc.mcCntlSetLastError(inst, "Control Panel Manual Spindle OFF")
end
else
mc.mcCntlSetLastError(inst, "Control Panel Manual Spindle RELEASE")
end
end
----------------------------
-- We use MPG 7
local MachMpgNumberForPendant = 7
local PendantStepSize = 0.001
local PendantDistanceX1 = PendantStepSize * 1 -- Multiply by one (0.001)
local PendantDistanceX10 = PendantStepSize * 10 -- Multiply by ten (0.01)
local PendantDistanceX100 = PendantStepSize * 100 -- Multiply by one hundred (0.1)
-- Constants for readability
local UnmapMPG = -1 -- Use this one for when Axis selector switch is set to OFF
local AxisNumber_X = 0 -- Linear axis X
local AxisNumber_Z = 2 -- Linear axis Z
---------------------------------------------------------------
-- Jog Speed/Enable Rotary Switch
---------------------------------------------------------------
function PendantSpeedChange()
local hX1
local hX10
local hX100
-- Need to get current state of axis selector switch so we move the right axis
local hAxis_X -- X Axis Select Switch
local hAxis_Z -- Z Axis Select Switch
local Step1
local Step10
local Step100
local msg
hX1, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT6) -- Speed 0.001 TODO set correct signal
Step1, rc = mc.mcSignalGetState(hX1)
hX10, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT7) -- Speed 0.01 TODO set correct signal
Step10, rc = mc.mcSignalGetState(hX10)
hX100, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT8) -- Speed 0.1 TODO set correct signal
Step100, rc = mc.mcSignalGetState(hX100)
-- Jog Active Light handle
local hJogLight
hJogLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1) -- TODO set correct signal
-- Figure out which axis is active by reading the axis select switch
hAxis_X, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT0) -- If X is selected, activate X TODO set correct signal
SelectAxis_X, rc = mc.mcSignalGetState(hAxis_X)
hAxis_Z, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT2) -- If Z is selected, activate Z TODO set correct signal
SelectAxis_Z, rc = mc.mcSignalGetState(hAxis_Z)
-- TODO - This should really check that we have X || Z, but not neither or both!
if (SelectAxis_X == 1) then
mc.mcMpgSetAxis(inst, MachMpgNumberForPendant, AxisNumber_X) -- Map the MPG to control the X Axis
mc.mcCntlSetLastError(inst, "Jog Axis X Selected") -- Show a message in the Screen Set
elseif (SelectAxis_Z== 1) then
mc.mcMpgSetAxis(inst, MachMpgNumberForPendant, AxisNumber_Z) -- Map the MPG to control the Z Axis
mc.mcCntlSetLastError(inst, "Jog Axis Z Selected") -- Show a message in the Screen Set
end
if (Step1 == 1) then
mc.mcMpgSetInc(inst, MachMpgNumberForPendant, PendantDistanceX1 )
mc.mcSignalSetState(hJogLight, 1) -- Turn Jog light on
msg = "Jog Active X1 = " .. PendantDistanceX1
mc.mcCntlSetLastError(inst, msg) -- Show a message in the Screen Set
elseif (Step10 == 1) then
mc.mcMpgSetInc(inst, MachMpgNumberForPendant, PendantDistanceX10)
mc.mcSignalSetState(hJogLight, 1) -- Turn Jog light on
msg = "Pendant Distance X10 = " .. PendantDistanceX10
mc.mcCntlSetLastError(inst, msg) -- Show a message in the Screen Set
elseif (Step100 == 1) then
mc.mcMpgSetInc(inst, MachMpgNumberForPendant, PendantDistanceX100)
mc.mcSignalSetState(hJogLight, 1) -- Turn Jog light on
msg = "Pendant Distance X100 = " .. PendantDistanceX100
mc.mcCntlSetLastError(inst, msg) -- Show a message in the Screen Set
else
-- If we got here, it means the one of the speed inputs changed, but none are active
-- That means "JOG OFF"
mc.mcMpgSetInc(inst, MachMpgNumberForPendant, 0 ) -- TODO Can we set the jog distance to 0?
mc.mcSignalSetState(hJogLight, 0) -- Turn Jog light off
mc.mcMpgSetAxis(inst, MachMpgNumberForPendant, UnmapMPG ) -- Unmap the MPG, so it won't control any axes
mc.mcCntlSetLastError(inst, "Jog Handle Disabled") -- Show a message in the Screen Set
end
end
---------------------------------------------------------------
-- The Pendant's Axis switch changed.
-- Need to handle this for when the axis switch is flipped while jogging is active
---------------------------------------------------------------
function PendantAxisChange()
-- handles
local hAxis_X
local hAxis_Z
local SelectAxis_X
local SelectAxis_Z
-- Before we do anything, we need to check if the jog handle is assigned to axis -1
-- If it is, jog is DISABLED, so we do nothing (the act of enabling jog will read the axis switch)
-- Otherwise we enable jog, which is BAD
-- TODO - need a function to check which axis is assigned
-- This is a guess!
local AxisState
AxisState, rc = mc.mcMpgGetAxis(inst, MachMpgNumberForPendant)
if (AxisState ~= UnmapMPG) then
hAxis_X, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT0)
SelectAxis_X, rc = mc.mcSignalGetState(hAxis_X)
hAxis_Z, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT2)
SelectAxis_Z, rc = mc.mcSignalGetState(hAxis_Z)
-- Now actual axis Selection Switch processing code
if (SelectAxis_X == 1) then
mc.mcMpgSetAxis(inst, MachMpgNumberForPendant, AxisNumber_X) -- Map the MPG to control the X Axis
mc.mcCntlSetLastError(inst, "Pendant Axis X Selected") -- Show a message in the Screen Set
elseif (SelectAxis_Z== 1) then
mc.mcMpgSetAxis(inst, MachMpgNumberForPendant, AxisNumber_Z) -- Map the MPG to control the Z Axis
mc.mcCntlSetLastError(inst, "Pendant Axis Z Selected") -- Show a message in the Screen Set
else
-- This is a problem, because the axis select switch is one or the other
-- We have no high pin - so shut off jogging
mc.mcMpgSetAxis(inst, MachMpgNumberForPendant, UnmapMPG ) -- Unmap the MPG, so it won't control any axes
mc.mcCntlSetLastError(inst, "ABEND - no valid axis selected on control panel!") -- Show a message in the Screen Set
end
else
mc.mcCntlSetLastError(inst, "Changed axis select while jog disabled - IGNORED")
end
end
-- Set jog state when the Screen is loaded by Mach4
PendantSpeedChange()
-
I have a machmotion system and I am afraid those folks won't help me cause they really want me to buy a wireless pendant. I have a MPG ( A, /A, B /B, VCC, Gnd) hooked up on my mill X moves beautifully, but I can't get the machine to know when I want Y or Z to move. Any ideas? Won't work using the included machmotion Pokeys selector, and neither using on screen jog. But, the on screen jog does let me change the step size. BTW I am not a basic C++ or any of that stuff programmer. Thanks guys.
-
I got a chance to test this.
The code as written, once the input signals were set up right (and it would be easier with constants - a TODO) jogging worked as did the manual spindle once I switched off the direct API call to the spinCW() script the UI button uses. The lights don't work yet, nor do Cycle Start or Feed Hold.
I'm going to start new threads specific to the problems I have.
-
The Feed Hold and Cycle Start buttons are working!
Cycle start even works as expected during tool changes.
-
https://www.youtube.com/watch?v=n1SCNOw1tVE
- moved jog light to Output 5 and enabled it in the script.
Using the built-in program running and feed hold outputs for the status light.
The logic that is supposed to make a double press of the feed hold button be a cycle stop isn't working - that's the next debug.