Hello Guest it is May 12, 2024, 01:03:03 PM

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - smurph

91
Mach4 General Discussion / Re: activate script on button from script
« on: September 21, 2021, 01:36:37 AM »
I did mention the module load file. 

In a file called MyToolbox.mcs in your profile's macros directory:
Code: [Select]
mt = require("MyToolboxModule") -- mt is the namespace by which you access the functions in the module.  Short for "My Toolbox". :)

There are several examples out here on the forum that use one file to load/require all modules that you want in the macro script environment.  But I like to put each require into their own separate file, named appropriately of course.  To me, it is a little more clear when you go looking at the stuff months from now.  :) 

Steve

92
Mach4 General Discussion / Re: activate script on button from script
« on: September 19, 2021, 02:47:26 PM »
Use mc.mcCntlSetLastError() to debug instead of wx.MessageBox().  That way you can see the history. 

Steve

93
Mach4 General Discussion / Re: activate script on button from script
« on: September 19, 2021, 12:52:25 PM »
Separate buttons == separate events.  That is why it worked.  Now you have one button with one event.  And here is the insidious part, the PLC cycle is an event!  So by running that one event, it prevents the PLC script from executing. 

So the rule of thumb is to not have long running processes in button or other screen elements.  This is accomplished by the use of a "state machine".  All the button script code would do is start the state machine. 

Button code:
Code: [Select]
StartRecording()

Screen Load script:
Code: [Select]
RecordingProcessState = 0 -- a global LUA variable for the state machine state.

function StartRecording()
    RecordingProcessState = 1 -- start the recording state machine.
end
function Execute0()
    --Gcode to execute the 0 degree stuff
    mc.mcGcodeExecute() (Don't use mc.mcGcodeExecuteWait() as you want to hand the task off to the interpreter and go!
    wxMilliSleep(50) -- give the G code a chance to start.end
function Execute2()
   --Gcode to execute the 2 degree stuff
    mc.mcGcodeExecute()
    wxMilliSleep(50)
end
function Execute4()
   --Gcode to execute the 4 degree stuff
    mc.mcGcodeExecute()
    wxMilliSleep(50)
end
function Execute6()
   --Gcode to execute the 6 degree stuff
    mc.mcGcodeExecute()
    wxMilliSleep(50)
end
function WaitForIdle()
    local state = mc.mcCntlGetState()
    if (state == mc.MC_STATE_IDLE) then
         return true
    end
    return false
end

function RecordingStateMachine()
    if (RecordingProcessState > 0) then
        if (RecordingProcessState == 1) then
            RecordingProcessState = 2
            Execute0()
        elseif (RecordingProcessState == 2) then
            -- wait for Execute0() to finish.
            if (WaitForIdle() == true) then
                RecordingProcessState = 3
            end
        elseif (RecordingProcessState == 3) then
            RecordingProcessState = 4
            Execute2()
        elseif (RecordingProcessState == 4) then
            -- wait for Execute2() to finish.
            if (WaitForIdle() == true) then
                RecordingProcessState = 5
            end
        elseif (RecordingProcessState == 5) then
            RecordingProcessState = 6
            Execute4()
        elseif (RecordingProcessState == 6) then
            -- wait for Execute4() to finish.
            if (WaitForIdle() == true) then
                RecordingProcessState = 7
            end
        elseif (RecordingProcessState == 7) then
            RecordingProcessState = 8
            Execute6()
        elseif (RecordingProcessState == 8) then
            -- wait for Execute6() to finish.
            if (WaitForIdle() == true) then
                RecordingProcessState = 9
            end
        elseif (RecordingProcessState == 9) then
            RecordingProcessState = 0
            -- The state machine has finished!!!  Maybe raise a signal or the like?
        end
    end
end

Then is your PLC script, call the state machine function

Code: [Select]
RecordingStateMachine()

The whole concept of a state machine lets you run long running processes without actually tying up the event loop with a while loop.  Generally speaking, while loops should be avoided at all costs in any of the screen scripts.  They are ok in M code scripts when you want to wait on the whole script to complete anyway. 

You will also want to put some sort of abort mechanism in case the operator wants to abort during the process (set RecordingProcessState = 0).  Notice that if you use Stop Cycle (which I hate), you will have to modify your screen to make the stop cycle button stop the cycle AND set RecordingProcessState = 0, otherwise, the state machine will see the machine go to the idle state and continue to the next phase! 

Steve

94
Mach4 General Discussion / Re: Mach4 Boss Probing Not Working
« on: September 18, 2021, 01:22:21 AM »
When I debug further, I see that the return code for the GCODE_EXECUTE_WAIT probing calls returns the dreaded MERROR_NOT_NOW error code !

MERROR_NOT_NOW means that you are trying to do something when the state of the machine is such that it cannot perform the task given.  So, what state is the machine in when you get MERROR_NOT_NOW?  mc.mcCntlGetState() and friends can tell you. 

Seems like there is a very common issue with many of the probing functions in the mcProbing.lua file. I dealt with a similar issue in the calibration and I'm just looking at the same issue in the external corner probing routine. Who ever wrote these scripts seems to have used a G31 command for moves that are just setup moves in some cases

Using G31 moves is VERY common when a probe is loaded into the spindle.  It is called a protected move.  What if you told the machine to move in a direction that would crash the probe with G00 or G01?  It would break your poor probe stylus and possibly your entire probe!!!  Not too good.  If you move the probe around with G31, even if you hit a workpiece clamp that you forgot to remove, the probe will simply stop and not grenade.

Steve

95
Glad I could help!  :)  And yeah, I'm a hard road traveler myself.  So I know...  I know.  LOL

Steve

96
thanks not really sure how you mean to point to dro register I'm still in an early lua learning process..

What I mean is edit your screen, click on the DRO that is named "Tool2DRO" and edit the Rregister property to point to your "gRegs0/ToolInPos1" register.  Done.  Use whatever format in the Format you wish.  No LUA code required. 

Steve

97
It is hard to tell what is what in that script because some of it was remarked out and the last two lines are confusing.  But anyway, without even trying to determine what is wrong with the script, you can fix this easily but just pointing your DRO to that register with the DRO's Register property and use whatever format you want with the DRO's Format Property.  :)

Steve

98
Mach4 General Discussion / Re: activate script on button from script
« on: September 16, 2021, 12:47:02 PM »
Code: [Select]
scr.ButtonClick(ctrlName)
scr.ButtonDown(ctrlName)
scr.ButtonUp(ctrlName)

Yeah, I put those functions in there because Mach3 had something similar.  But I do so regret it!  Because it is not the best way to handle this type of thing in Mach4.  This is going to be a long one, so sit back with some coffee or something.  :)

The best way is to put the functions that do your actions into the screen load script.  There would be one function for each of your current buttons.  Then on each button's up script event, simply call the appropriate function.  Then in your multi-function button, call all of the functions in the order you wish.

In the screen load script:
Code: [Select]
function MyButtonFunction1()
    --some code to perform the action
end

function MyButtonFunction2()
    --some code to perform the action
end
In the button1 up script event:
Code: [Select]
MyButtonFunction1()
In the button2 up script event:
Code: [Select]
MyButtonFunction2()
In the multiple function button up script event:
Code: [Select]
MyButtonFunction1()
MyButtonFunction2()

Basically, you build a tool box of functions in the screen load script.  The you just call those functions from any screen element.  It just takes a bit more planning but ultimately it is WAY worth it. 

But wait, there's more!  :)  What if you might want to call these tool box functions from M code macro scripts as well?  This is where LUA modules come into the picture.  If you write a module and put your tool box functions in there, then "require" that module in you screen load script and your macro scripts, you can use all of the functions in that module from both screen elements AND macro scripts.  The caveat is that global variables cannot be used.  However, one can get around that by using Mach registers as your global data storage if you need it. 

in a file called MyToolboxModule.lua that is in the Mach Modules directory:
Code: [Select]
local MyToolbox = {}

function MyToolbox.MyButtonFunction1()
--some code to perform the action
end

function MyToolbox.MyButtonFunction2()
--some code to perform the action
end
return MyToolbox
In your screen load script, put this at the top of the script:
Code: [Select]
mt = require("MyToolboxModule") -- mt is the namespace by which you access the functions in the module.  Short for "My Toolbox". :)
In a file called MyToolbox.mcs in your profile's macros directory:
Code: [Select]
mt = require("MyToolboxModule") -- mt is the namespace by which you access the functions in the module.  Short for "My Toolbox". :)
Now, back to the button scripts themselves. In the button1 up script event:
Code: [Select]
mt.MyButtonFunction1() -- notice the mt. prefix! 
In the button2 up script event:
Code: [Select]
mt.MyButtonFunction2()
In the multiple function button up script event:
Code: [Select]
mt.MyButtonFunction1()
mt.MyButtonFunction2()
And finally, a macro script that uses the tool box functions. In a file called m114.msc in the Macros directory:
Code: [Select]
function m114()
    mt.MyButtonFunction1()
    mt.MyButtonFunction2()

end

if (mc.mcInEditor() == 1) then
    m114()
end

It is a lot to take in, but it does demonstrate the power of the Mach LUA integration.  It makes code reuse easy too.  Say you have another machine that needs the same functions.  Or another screen/profile.  All you have to do is move the module code over and "require" it.  :) 

Steve

99
Mach4 General Discussion / Re: Macro or script for A axis
« on: September 09, 2021, 06:41:42 PM »
Could an OB axis be used for this? Just set it to jog and then run a gcode?
SwiftyJ is on a roll!  It could be possible, but not simple or easy, if all of the requirements line up.  First, your motion controller will have to support the use of out of band axes.  Not all do.  Then you would have to use the motor mapping API calls and unmap the motor from the A axis and map it to an out of band (OB) axis.  But you would have to set the feed rate for the OB axis with the API, meaning you can't set it with the F word in G code.  And you will have to manually set the machine up in the screen load script so that the machine starts up with a known motor configuration, as changing the motors on the fly will play havoc at shutdown or if some external plugin or script saves the Mach settings. 

Here are the API calls that would need to be used, at a minimum.  (remember to check your API function return codes)

mc.mcAxisUnmapMotors(inst, axis)
mc.mcAxisMapMotor(inst, axis, motor)
mc.mcMotionSync(inst) -- to be used when the motor is mapped BACK to the A axis.
mc.mcJogSetFeedRate(inst, axis, unitsPerMin)
mc.mcJogVelocityStart(inst, axis, dir)
mc.mcJogVelocityStop(inst, axis)

Steve

100
Mach4 General Discussion / Re: Turn Backlash OFF in a script?
« on: September 09, 2021, 06:15:52 PM »
It's Mach4 that's sending bad backlash commands to my ESS when jogging.

Mach4 decides when a backlash move is needed the ESS only does what it's told.  Have a look at the attached log file to see what I mean.
I'm told that lines like this in the log file come from Mach4
++++++++ Motor 0: Pick up the Backlash from an ALL STOP before going Positive ++++++++

Sorry guys, but there must be a misunderstanding somewhere.  Mach4 doesn't send backlash commands.  All Mach 4 does is provide a place to put the backlash into the motor settings.  It is up to the motion controller 100% to implement the backlash compensation.

SwiftyJ hit the nail on the head with this one: 
Backlash compensation is handled by the motion controller so you will probably have to speak to the manufacturer of the one you use to see if there is a register or something that turns it on/off

One more thing...  It may look like Mach is controlling the backlash because that message appeared in the Mach diagnostics log.  But plugins can and do write to that log as well.  Even scripts can write to the log with the mc.mcCntlLog() API function. 

Steve