Hello Guest it is March 28, 2024, 12:50:23 PM

Author Topic: MPG Surprise!  (Read 1194 times)

0 Members and 1 Guest are viewing this topic.

MPG Surprise!
« 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?
Re: MPG Surprise!
« Reply #1 on: May 30, 2021, 11:36:41 AM »
Here is my first kick at the cat. None of the signal numbers are right yet, but the logic should be good.

Code: [Select]
---------------------------------------------------------------
-- 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()
Re: MPG Surprise!
« Reply #2 on: May 31, 2021, 11:11:15 AM »
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

Code: [Select]
---------------------------------------------------------------
-- 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()
Re: MPG Surprise!
« Reply #3 on: May 31, 2021, 12:54:00 PM »
Found an API reference.

This should be close to the final deal.

Code: [Select]
---------------------------------------------------------------
-- 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()
« Last Edit: May 31, 2021, 12:56:23 PM by RecceDG »
Re: MPG Surprise!
« Reply #4 on: June 18, 2021, 02:04:41 PM »
  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. 
Re: MPG Surprise!
« Reply #5 on: June 20, 2021, 01:34:59 PM »
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.
Re: MPG Surprise!
« Reply #6 on: June 28, 2021, 10:28:02 AM »
The Feed Hold and Cycle Start buttons are working!

Cycle start even works as expected during tool changes.
Re: MPG Surprise!
« Reply #7 on: June 29, 2021, 07:05:07 AM »
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.