Hello Guest it is April 18, 2024, 08:10:58 PM

Author Topic: mcX360 Plugin for Lua  (Read 45288 times)

0 Members and 1 Guest are viewing this topic.

Offline DazTheGas

*
  •  778 778
  • DazTheGas
    • View Profile
Re: mcX360 Plugin for Lua
« Reply #30 on: December 25, 2016, 05:43:34 PM »
Sometimes I forget when converting from my screenset to the GUI, a long while ago leaving a timer running would cause a fault and still does in my own, the lua panels in the gui are actually c++ classes and prob destroyed inc timer on shutdown so the x360 timer prob no longer exists, although still worth including but like this,

if X360_Timer then X360_Timer:Stop() end

if anything does change at a later date in the core then at least this is already there.

DazTheGas
New For 2022 - Instagram: dazthegas
Re: mcX360 Plugin for Lua
« Reply #31 on: December 25, 2016, 07:47:50 PM »
Thanks Daz - I'll use that strategy. 

I noticed that the machine can be left in a state where the axis continues to jog even though the safety triggers are released.  This may be due to the strategy I used and may not be an issue for other people.  I included some code after the timer stop commands to prevent any possible movement after the safety triggers are released, just to be safe.

Once again, thanks for your help with this.  I'm not a LUA expert, but I feel like I've learned a lot.

Code: [Select]
----------------------------------------------------------------------------
--  X_360 Lua by DazTheGas - Last Updated 07/12/16 SDK 3233
----------------------------------------------------------------------------

-----------------Declares

local mInst = mc.mcGetInstance()
local Xenabled = false
local ESState = false
local JogInc = .001
local CState = false
local FHState = false
local RSState = false
local AIState = false
local XPState = false
local TXPState = false
local XNState = false
local TXNState = false
local YPState = false
local TYPState = false
local YNState = false
local TYNState = false
local ZPState = false
local TZPState = false
local ZNState = false
local TZNState = false
local islok = false
local DZ = 25 --Dead Zone Based on controller output value (-99 => 99)
local JIState = false
local JDState = false
local Jog_Rate = 0

-- X360 Init Panel
X360_Panel = wx.wxPanel( wx.NULL, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxDefaultSize)
X360_Timer = wx.wxTimer(X360_Panel)
-- EStop
EStop_Panel = wx.wxPanel( wx.NULL, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxDefaultSize)
EStop_Timer = wx.wxTimer(EStop_Panel)
-- Buttons
Btns_Panel = wx.wxPanel( wx.NULL, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxDefaultSize)
Btns_Timer = wx.wxTimer(Btns_Panel)

-----------------Functions
--Read XBox Controller Values
function GetXin(xinput)
    local hreg = mc.mcRegGetHandle(mInst, string.format("mcX360_LUA/%s", xinput))
    return mc.mcRegGetValueLong(hreg)
end
-- X Pos
function jog_XP(xpisinc,xpmove)
    if xpisinc == false then
        mc.mcSignalSetState (mc.mcSignalGetHandle (mInst, mc.ISIG_JOGXP), xpmove)
    end
    if xpisinc == true then
        if xpmove == 1 then
            JogInc=mc.mcJogGetInc(mInst,0) / 2. -- Diameter Mode for Lathe
            mc.mcJogIncStart(mInst, mc.X_AXIS, JogInc)
        else
            mc.mcJogIncStop(mInst, mc.X_AXIS,.0001)
        end
    end
end
-- X Neg
function jog_XN(xnisinc,xnmove)
    if xnisinc == false then
        mc.mcSignalSetState (mc.mcSignalGetHandle (mInst, mc.ISIG_JOGXN), xnmove)
    end
    if xnisinc == true then
        if xnmove == 1 then
            JogInc=mc.mcJogGetInc(mInst,0) / 2. -- Diameter Mode for Lathe
            mc.mcJogIncStart(mInst, mc.X_AXIS, JogInc * -1.)
        else       
            mc.mcJogIncStop(mInst, mc.X_AXIS,.0001)
        end
    end
end
-- Z Pos
function jog_ZP(zpisinc,zpmove)
    if zpisinc == false then
        mc.mcSignalSetState (mc.mcSignalGetHandle (mInst, mc.ISIG_JOGZP), zpmove)
    end
    if zpisinc == true then
        if zpmove == 1 then
            JogInc=mc.mcJogGetInc(mInst,2)
            mc.mcJogIncStart(mInst, mc.Z_AXIS, JogInc)
        else
            mc.mcJogIncStop(mInst, mc.Z_AXIS,.0001)
        end
    end
end
-- Z Neg
function jog_ZN(znisinc,znmove)
    if znisinc == false then
        mc.mcSignalSetState (mc.mcSignalGetHandle (mInst, mc.ISIG_JOGZN), znmove)
    end
    if znisinc == true then
        if znmove == 1 then
            JogInc=mc.mcJogGetInc(mInst,2)
            mc.mcJogIncStart(mInst, mc.Z_AXIS, -1 * JogInc)
        else
            mc.mcJogIncStop(mInst, mc.Z_AXIS,.0001)
        end
    end
end

-----------------Event Timers
X360_Timer:Start(100)
X360_Panel:Connect(wx.wxEVT_TIMER, function (event)
if GetXin("LTR_Val") + GetXin("RTR_Val") > 400 and Xenabled == false then
        EStop_Timer:Start(50)
        Btns_Timer:Start(50) -- was 100
Xenabled = true
        mc.mcCntlSetLastError(mInst,"Pendant Enabeled")
elseif GetXin("LTR_Val") + GetXin("RTR_Val") < 100 and Xenabled == true then
        EStop_Timer:Stop()
        Btns_Timer:Stop()
Xenabled = false
        -- Stop all jogging if safety triggers are released
        jog_XP(isinc,0)
        jog_XN(isinc,0)
        jog_ZP(isinc,0)
        jog_ZN(isinc,0)
        --
        mc.mcCntlSetLastError(mInst,"Pendant Disabled")
end
end)

EStop_Panel:Connect(wx.wxEVT_TIMER, function (event)
if GetXin("Btn_B") == 1 and ESState == false then
local EStop = mc.mcSignalGetState (mc.mcSignalGetHandle (mInst, mc.ISIG_EMERGENCY))
if (EStop == 1) then
mc.mcSignalSetState (mc.mcSignalGetHandle (mInst, mc.ISIG_EMERGENCY), 0)
else
mc.mcSignalSetState (mc.mcSignalGetHandle (mInst, mc.ISIG_EMERGENCY), 1)
end
ESState = true
end
if GetXin("Btn_B") == 0 and ESState == true then
ESState = false
end
end)

Btns_Panel:Connect(wx.wxEVT_TIMER, function (event)
-- Cont or Inc Jog Mode
if GetXin("Btn_X") == 1 and AIState == false then
        if isinc == false then
            mc.mcSignalSetState (mc.mcSignalGetHandle (mInst, mc.OSIG_JOG_CONT), 0)
            mc.mcSignalSetState (mc.mcSignalGetHandle (mInst, mc.OSIG_JOG_INC), 1)
            isinc = true
        else
            mc.mcSignalSetState (mc.mcSignalGetHandle (mInst, mc.OSIG_JOG_INC), 0)
            mc.mcSignalSetState (mc.mcSignalGetHandle (mInst, mc.OSIG_JOG_CONT), 1)
            isinc = false
        end
        AIState = true
end
if GetXin("Btn_X") == 0 and AIState == true then
        AIState = false
end
-- Cycle_Start
if GetXin("Btn_A") == 1 and CState == false then
--CycleStart()
        --mc.mcCntlCycleStart (mInst)
            local rc;
            local tab, rc = scr.GetProperty("MainTabs", "Current Tab")
            local tabG_Mdione, rc = scr.GetProperty("nbGCodeMDI1", "Current Tab")
            --local tabG_Mditwo, rc = scr.GetProperty("nbGCodeMDI2", "Current Tab")
            --wx.wxMessageBox("tab == " .. tostring(tab) )
            --See if we have to do an MDI command
           
            if ((tonumber(tab) == 0 and tonumber(tabG_Mdione) == 1)) then --or (tonumber(tab) == 2 and tonumber(tabG_Mditwo) == 1 )) then
                local state = mc.mcCntlGetState(mInst);
                if (state == mc.MC_STATE_MRUN_MACROH) then
                    mc.mcCntlCycleStart(mInst);
                    mc.mcCntlSetLastError(mInst, "Do Cycle Start");
                else
                    if (tonumber(tab) == 0) then 
                        scr.ExecMdi('mdi1');
                        mc.mcCntlSetLastError(mInst, "Do MDI 1");
                    end
                end
            else
                --Do CycleStart
                mc.mcCntlSetLastError(mInst, "Do Cycle Start");
                mc.mcCntlCycleStart(mInst);
                --wx.wxMessageBox("Do Cycle Start")       
            end
        --mc.mcCntlSetLastError(mInst,"A_Button_Pressed")
        CState = true
end
if GetXin("Btn_A") == 0 and CState == true then
CState = false
end
-- Feed_Hold
if GetXin("Btn_Y") == 1 and FHState == false then
mc.mcCntlFeedHold(mInst)
        mc.mcCntlSetLastError(mInst,"Feed Hold")
        FHState = true
end
if GetXin("Btn_Y") == 0 and FHState == true then
FHState = false
end
-- Jog_Increase
    if GetXin("Btn_START") == 1 then
        Jog_Rate = Jog_Rate + 2
        if Jog_Rate > 100 then
            Jog_Rate = 100
        end
        mc.mcJogSetRate(mInst,mc.AXIS0,Jog_Rate)
        mc.mcJogSetRate(mInst,mc.AXIS2,Jog_Rate)
        --mc.mcCntlSetLastError(mInst,"Jog Rate Increase")
end
-- Jog_Decrease
    if GetXin("Btn_BACK") == 1 then
        Jog_Rate = Jog_Rate - 2
        if Jog_Rate < 1 then
            Jog_Rate = 1
        end
        mc.mcJogSetRate(mInst,mc.AXIS0,Jog_Rate)
        mc.mcJogSetRate(mInst,mc.AXIS2,Jog_Rate)
        --mc.mcCntlSetLastError(mInst,"Jog Rate Decrease")
end
-- Jog_Increment
if GetXin("Btn_RS") == 1 and RSState == false then
        --mc.mcCntlSetLastError(mInst,"Jog Increment Changed")
        local CurInc = mc.mcProfileGetInt(mInst,"Preferences","JogIncSet",0) --make a new setting in profile to hold our current inc number
        local SetInc = mc.mcProfileGetDouble(mInst,"Preferences","JogInc"..CurInc,0.00) -- fetch our inc value from the profile JogInc + 2 say = [Preferences][JogInc2]

        CurInc = CurInc + 1 -- increment our CurInc by 1
        if CurInc > 10 then CurInc = 1 end -- if our CurInc is greater than 10 then go back to 1
       
        mc.mcJogSetInc(mInst, mc.X_AXIS, SetInc) -- set inc for axis
        mc.mcJogSetInc(mInst, mc.Y_AXIS, SetInc) -- set inc for axis
        mc.mcJogSetInc(mInst, mc.Z_AXIS, SetInc) -- set inc for axis

        mc.mcProfileWriteInt(mInst,"Preferences","JogIncSet",CurInc) --set our profile to new CurInc

        RSState = true
end
if GetXin("Btn_RS") == 0 and RSState == true then
RSState = false
end
-- X++ DPAD
if GetXin("DPad_DOWN") == 1 and XPState == false and islok == false then
        jog_XP(isinc,1)
XPState = true
        islok = true
end
if GetXin("DPad_DOWN") == 0 and XPState == true then
        jog_XP(isinc,0)
XPState = false
        islok = false
end
-- X++ THUMB STICKS
if GetXin("LTH_Y_Val") <= (DZ*-1.) and TXPState == false and islok == false then
        jog_XP(isinc,1)
TXPState = true
        islok = true
end
if GetXin("LTH_Y_Val") > (DZ*-1.) and TXPState == true then
        jog_XP(isinc,0)
TXPState = false
        islok = false
end
-- X-- DPAD
if GetXin("DPad_UP") == 1 and XNState == false and islok == false then
        jog_XN(isinc,1)
XNState = true
        islok = true
end
if GetXin("DPad_UP") == 0 and XNState == true then
        jog_XN(isinc,0)
XNState = false
        islok = false
end
-- X-- THUMB STICKS
if GetXin("LTH_Y_Val") >= (DZ*1.) and TXNState == false and islok == false then
        jog_XN(isinc,1)
TXNState = true
        islok = true
end
if GetXin("LTH_Y_Val") < (DZ*1.) and TXNState == true then
        jog_XN(isinc,0)
TXNState = false
        islok = false
end
    -- Z++ DPAD
if GetXin("DPad_RIGHT") == 1 and ZPState == false and islok == false then
        jog_ZP(isinc,1)
ZPState = true
        islok = true
end
if GetXin("DPad_RIGHT") == 0 and ZPState == true then
        jog_ZP(isinc,0)
ZPState = false
        islok = false
end
-- Z++ THUMB STICKS
if GetXin("RTH_X_Val") >= (DZ*1.) and TZPState == false and islok == false then
        jog_ZP(isinc,1)
TZPState = true
        islok = true
end
if GetXin("RTH_X_Val") < (DZ*1.) and TZPState == true then
        jog_ZP(isinc,0)
TZPState = false
        islok = false
end
-- Z-- DPAD
if GetXin("DPad_LEFT") == 1 and ZNState == false and islok == false then
        jog_ZN(isinc,1)
ZNState = true
        islok = true
end
if GetXin("DPad_LEFT") == 0 and ZNState == true then
        jog_ZN(isinc,0)
        ZNState = false
        islok = false
end
-- Z-- THUMB STICKS
if GetXin("RTH_X_Val") <= (DZ*-1.) and TZNState == false and islok == false then
        jog_ZN(isinc,1)
TZNState = true
        islok = true
end
if GetXin("RTH_X_Val") > (DZ*-1.) and TZNState == true then
        jog_ZN(isinc,0)
TZNState = false
        islok = false
end
end)
Re: mcX360 Plugin for Lua
« Reply #32 on: February 05, 2017, 05:32:42 PM »
Installed and played with this a little bit today. Nice work getting everything into registers Daz, a very smart approach! Runs smooth!

I see you have registers for the rumble, i played with the numbers a little bit but didn't get any feedback from the controller. Be fun to vibrate on alarm or contact with a probe. Just playing games here ;)
Re: mcX360 Plugin for Lua
« Reply #33 on: February 06, 2017, 12:15:57 PM »
Has anyone tried this in the PMC? I played with it for an hour or two this morning. Found a couple little bugs that I forwarded off to the Artsoft gang, but all in all works pretty good. And easy to implement.

If you haven't used the pmc yet just drop these two files in the mach4>pmc folder. Then in the screen editor on the screen properties one of the options is pmc objects. Check the one you want to use and that is it.

I did this with the following functions:
Left joystick X and Y axis jog
DPad X and Y axis jog
Right joystick Z axis jog
Hold left button to enable continuous jogging (must be held down to jog any axis)
Hold right button to enable incremental jogging (must be held down to jog any axis)
Start cycles the jog increment
B is disable
Y is enable
A is cycle start
X is feed hold
Back is cycle stop

One of the bugs was I couldn't enter negative values. So I had to hack the .lua file to get a dead zone on the sticks. You'll see in the ladder of the pmc file the stick values are compared to 0, in the lua file i changed these zeroes to 30 and -30.
Re: mcX360 Plugin for Lua
« Reply #34 on: February 06, 2017, 12:27:58 PM »
And here is the module I whipped up yesterday. A little more basic, I spent most of the time getting some exponential curve on the joysticks. Left and right buttons enable continuous and incremental jog, respectively. Each needs to be held like a deadman switch.

To use this one just load the module in the screen load script and then call the modulename.PLC() function in the plc script. "modulename" is ofcourse whatever variable you assigned the module to.
Re: mcX360 Plugin for Lua
« Reply #35 on: February 07, 2017, 10:41:01 PM »
Hi.  Stupid question time.  Is the PMC the Mach4 version of the "Brains" in Mach3?  I haven't played with the PMC in Mach4.  When would you go PMC instead of LUA Script?

Thanks!
Re: mcX360 Plugin for Lua
« Reply #36 on: February 07, 2017, 11:53:17 PM »
Short answer, the PMC is a soft PLC in Mach4 that is programmed in ladder logic, and runs on a continuous loop, like a real PLC. So while it's not a version of Brains from Mach3 it is what Brains should have been.

I think the biggest reason for using the PMC over a lua script is your ability to program. If you know ladder, the PMC would make more sense. There is definitely more power and flexibility in lua, but you have to take the time to learn it. If you just want to get something like this up and running, without dealing with adding timers, potentially locking the gui, etc. than the PMC is the way to go. It is just another handy tool that does seem to be a bit under utilized.

Honestly, I've been doing a lot of work in Mach4 for a few years now, and this is the first time I've used the PMC. I saw this was a good opportunity to check it out and it worked great. I'll probably be using it more in the future now!

EDIT: And I should add that after you build the ladder the PMC Editor generates a Lua script that is run on a loop by Mach4, which is why i was able to hack it to get the values I needed. The input filer issue is being fixed, so that should not be necessary in future versions.
« Last Edit: February 08, 2017, 12:01:42 AM by TomL21 »

Offline DazTheGas

*
  •  778 778
  • DazTheGas
    • View Profile
Re: mcX360 Plugin for Lua
« Reply #37 on: February 08, 2017, 02:11:33 AM »
Didnt notice the rumblers wasnt  working i will have a look at the code and see why.

DazTheGas
New For 2022 - Instagram: dazthegas

Offline DazTheGas

*
  •  778 778
  • DazTheGas
    • View Profile
mcX360 Plugin for Lua Updated
« Reply #38 on: February 08, 2017, 09:26:20 AM »
Ok all sorted, they now work in percentage from 0 to 100%

Code: [Select]
local mInst = mc.mcGetInstance()

function SetXin(xinput, speed) -- 0 - 100%
    local hreg = mc.mcRegGetHandle(mInst, string.format("mcX360_LUA/%s", xinput))
    mc.mcRegSetValueLong(hreg, speed)
end

SetXin("LRumble", 100)

DazTheGas
New For 2022 - Instagram: dazthegas
Re: mcX360 Plugin for Lua
« Reply #39 on: February 14, 2017, 09:50:45 AM »
Hahaha. Nice work Daz.

This is becoming a very useful tool for dev, i'm using it for more and more stuff. Thanks for you hard work on this sir!