Machsupport Forum
Mach Discussion => Mach4 General Discussion => Topic started by: RecceDG on July 03, 2021, 04:32:48 PM
-
Here is my final (?) code that got my control panel et al working.
--------------------------------------------------------------
-- 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_INPUT5] = function (state) -- X Axis Select signal 5
PendantAxisChange()
end,
[mc.ISIG_INPUT4] = function (state) -- Z Axis Select signl 4
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 signal 6
PendantSpeedChange()
end,
[mc.ISIG_INPUT7] = function (state) -- Enable Jog Speed 0.01 signal 7
PendantSpeedChange()
end,
[mc.ISIG_INPUT8] = function (state) -- Enable Jog Speed 0.001 signal 8
PendantSpeedChange()
end,
-------------
-- Axis driver Alarms
-- Each motor driver has an alarm line that goes high
-- if ********* goes south
-- Stop machine and recover using external reset switches
[mc.ISIG_INPUT9] = function (state) -- X Axis
mc.mcCntlSetLastError(inst, "X Axis driver ALARM - STOPPING")
eStop()
end,
[mc.ISIG_INPUT10] = function (state) -- Z axis
mc.mcCntlSetLastError(inst, "Z Axis driver ALARM - STOPPING")
eStop()
end,
-------------
-- Cycle Start Panel Button
[mc.ISIG_INPUT1] = function (state) -- Signal 1
InputCycleStart()
end,
--------------
-- Feed Hold Panel Button
[mc.ISIG_INPUT2] = function (state) -- Signal 2
InputFeedHold()
end,
---------------
-- Manual Spindle ON/OFF Panel Button
[mc.ISIG_INPUT3] = function (state) -- Starts the spindle manually signal 3
InputManualSpindle()
end,
----------------
-- Feed Hold Light
-- We waant to blink this during tool change
-- So watch the native FEED HOLD signal
-- And toggle the LED if Mach changes state
[mc.OSIG_FEEDHOLD] = function (state)
local inst = mc.mcGetInstance()
local hSig = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT6) -- Output 6
if( state == 1) then
mc.mcSignalSetState(hSig, mc.MC_ON)
else
mc.mcSignalSetState(hSig, mc.MC_OFF)
end
end,
--------------------
-- Tool Change
--- So we can blink the panel light
[mc.OSIG_TOOL_CHANGE] = function (state)
local inst = mc.mcGetInstance()
if( state == 1) then
--Start timer to flash feed hold LED 500ms interval
FeedHoldTimer:Start(500, false)
else
--Stop timer and turn off feed hold LED in case it's still on.
FeedHoldTimer:Stop()
local hSig = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT6) -- Output 6
mc.mcSignalSetState(hSig, mc.MC_OFF)
end
end
}
---------------------------------------------------------------
-- Tool Change LED blink function
---------------------------------------------------------------
FeedHoldTimerPanel = wx.wxPanel (wx.NULL, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxSize( 0,0 ) )
FeedHoldTimer = wx.wxTimer(FeedHoldTimerPanel)
FeedHoldTimerPanel:Connect(wx.wxEVT_TIMER,
function (event)
local inst = mc.mcGetInstance()
local hSig = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT6) -- Output 6
local sSig = mc.mcSignalGetState(hSig)
if sSig == mc.MC_ON then
mc.mcSignalSetState(hSig, mc.MC_OFF)
else
mc.mcSignalSetState(hSig, mc.MC_ON)
end
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_INPUT1) -- signal 1
StartButtonState, rc = mc.mcSignalGetState(hStartButton)
mc.mcCntlSetLastError(inst, "Control Panel Cycle Start PRESS")
if (StartButtonState == 1) then
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_INPUT2) -- signal 2
HoldButtonState, rc = mc.mcSignalGetState(hHoldButton)
if (HoldButtonState == 1) then
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.mcCntlGetState(inst)
Paused, rc = mc.mcCntlFeedHoldState(inst)
if (Paused == 1) then -- We are paused, so stop
CycleStop()
mc.mcCntlSetLastError(inst, "Control Panel CYCLE STOP")
elseif ((Running == mc.MC_STATE_FRUN ) or (Running == mc.MC_STATE_MRUN)) then -- We are running, so do something.
-- Have to check both File and MDI because
-- Mach differentiates between them!
rc = mc.mcCntlFeedHold(inst)
mc.mcCntlSetLastError(inst, "Control Panel FEED HOLD")
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_INPUT3) -- signal 3
SpindleButtonState, rc = mc.mcSignalGetState(hSpindleButton)
if (SpindleButtonState == 1) then
mc.mcCntlSetLastError(inst, "Control Panel Manual Spindle PRESS")
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)
SpinCW()
mc.mcCntlSetLastError(inst, "Control Panel Manual Spindle ON")
else -- Otherwise, turn it off
-- mc.mcSignalSetState(hsig, 0)
SpinCW()
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_INPUT8) -- Speed 0.001 signal 8
Step1, rc = mc.mcSignalGetState(hX1)
hX10, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT7) -- Speed 0.01 signal 7
Step10, rc = mc.mcSignalGetState(hX10)
hX100, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT6) -- Speed 0.1 signal 6
Step100, rc = mc.mcSignalGetState(hX100)
-- Jog Active Light handle
local hJogLight
hJogLight, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT5) -- Jog Light Signal 5
-- Figure out which axis is active by reading the axis select switch
hAxis_X, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT4) -- If X is selected, activate X signal 4
SelectAxis_X, rc = mc.mcSignalGetState(hAxis_X)
hAxis_Z, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT5) -- If Z is selected, activate Z signal 5
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_INPUT4)
SelectAxis_X, rc = mc.mcSignalGetState(hAxis_X)
hAxis_Z, rc = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT5)
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've been working on some lathe jobs since the control panel was installed and programmed, and Sweet Mother of Lob was all that worth it!
The increase in productivity between the jog handle and the program run controls is just off the charts. Setup is just so much less fiddly.