Hello Guest it is April 16, 2024, 04:47:02 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

311
You can also use mc.mcCntlGetState() and test with the mc.MC_STATE_* constants.  Glad you found it and have it running! 

Steve

312
It keeps the old scripts because there is a syntax error somewhere in your new script.  In the Zero Brane editor, Choose the menu path Project -> Compile.  It will tell you where the problem is. 

Make it a M6 macro.  Then you can call it from a button with mcCntlGcodeExecute(inst, "M6")  Also, when the code is in a macro, it is easier to debug.  I'm not saying that this is the best for ALL situations.  But for this challenge, making it a macro is the best way forward.

Steve

313
Notice the indentation in the code below.  It REALLY helps the readability of the code and it keeps you from starring so long.  :)
Also, although it is not required for a single expression, I like to wrap any expression in an if statement in parenthesis.

In a macro like M6, use mc.mcCntlGcodeExecuteWait() instead of the non wait function.  You don't want to ever use mc.mcCntlGcodeExecuteWait() in a screen or button script but here in a macro script, it is what you want. 

And remember (look at your line 22 "WAIT_MODE_Low"), all of the API functions and constants should be prefaced with mc.  And case is important.  It should be "mc.WAIT_MODE_LOW" instead of "WAIT_MODE_Low".

Line 3 improvement:
Code: [Select]
local inst = mc.mcGetInstance('M6 macro') -- This will allow logging the API calls with caller information.

Line 7 to 11 change.  You don't have use the the interpreter to turn the spindle off.  Use the API calls when you can in script!
If you have setup your ramp times in the spindle settings, they will be followed with the mc.mcSpindleSetDirectionWait().
Code: [Select]
locateSpindle, rc = mc.mcSignalGetHandle (inst, mc.OSIG_OUTPUT6) --Turn ON spindle lock.
rc = mc.mcSignalSetState(locateSpindle, 1) --Spindle lock ON
currentRPM, rc = mc.mcSpindleGetCommandRPM(inst) -- save the current RPM to restore later.
rc = mc.mcSpindleSetCommandRPM(inst, 15) -- use instead of execute M3 S15
--The possible values to use with the mc.mcSpindleSetDirectionWait() below
--mc.MC_SPINDLE_OFF
--mc.MC_SPINDLE_FWD
--mc.MC_SPINDLE_REV
rc = mc.mcSpindleSetDirectionWait(inst, mc.MC_SPINDLE_FWD)
-- Is there no input that tells you wen the keylock has engaged? 
wx.wxSleep (5) --Wait 5 seconds
rc = mc.mcSpindleSetDirectionWait(inst, mc.MC_SPINDLE_OFF) --Turn OFF spindle.

18 to 25 became:
Code: [Select]
-- Compound statements like your line 21 do not work well with LUA functions that return multiple items.  :( 
-- Break it up like so.  It makes the code easier to read and maintain in the future as well.
local hSig, state
hSig, rc = mc.mcSignalGetHandle (inst, mc.ISIG_OUTPUT5)
state, rc = mc.mcSignalGetState(hSig, mc.ISIG_OUTPUT5)
if (state == 1) then
rc = mcSignalWait(inst, mc.ISIG_INPUT5, mc.WAIT_MODE_LOW, 30) -- Wait on input 5 to go HIGH for at most 30 seconds.
-- Always put a timeout in you want to be able to catch errors instead of waiting indefinitely. 
-- If you want to wait on the input to go high, use mc.WAIT_MODE_HIGH.  Case is important!!! 
-- you really want to check the return code from EVERY API call for success/failure. 
-- Below will abort the script gracefully if there is an error.
if (rc ~= mc.MERROR_NOERROR) then
mc.mcCntlAlarm(inst, 100, "Timed out waiting for input 5 to go high.")
return(100) -- 100 here and above is just some number I dreamed up.  you could plan your own error number scheme.
end
mc.mcSignalSetState(CarouselOut, 0)
end

52 to 59 became:

Code: [Select]
--PNP input 4 switch activated to turn OFF OUTPUT4
--To turn output4 off:
hSig = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT4);
state = mc.mcSignalGetState(hSig);
if (state == 1) then
mc.mcSignalSetState(CarouselRetract, 0)
else -- not 0
wx.wxMessageBox ("INPUT 4 not triggered OFF")
end

314
Mach4 General Discussion / Re: Windows 10 - Disable Services
« on: April 01, 2020, 08:41:59 PM »
The simple answer is don't open a picture on that machine.  It is now a MACHINE controller when you are using it to control a MACHINE.  This is huge pet peeve of mine. 

That being said, most machines run windows 10 and Mach 4 without issue.  Mach 4 is developed on Windows 10.  I would suspect some buggy driver for your motherboard.  See if there are any updates for any and all devices (ehternet, video, chipset, etc..).  Either that or the OS may be virused up.  I have seen that before! 

Steve

315
I would pose this question to Warp 9 on their forums.  You will likly get a better response.  But not that there are already some nice BOBs out there.  PMDX-126, MB3, etc...  literally too many to list.  You may be re-inventing the wheel. 

Steve

316
mc.mcSignalWait()  Look through the API manual in the Doc folder.  The section on Signals. 

Steve

317
Mach4 General Discussion / Re: Mach 4 G-Code File Extension?
« on: April 01, 2020, 08:27:12 PM »
Open the configuration dialog.  Then set the extensions you want to use.  The "tap" extension is popular.  It is short for "tape", as old NC machine ran from a paper tape program.  Then a couple of other popular extensions are "nc" and "cnc".  But you do you.  :) 

Steve

318
Don't do long running code in the event scripts.  Windows only supports ONE event loop for a program.  If you click a button, that is an event that needs to run to completion before another event is processed.  So long running code WILL prevent screen refreshes (DRO updates) etc...  So how do you do that?  Typically, is it implemented as a state machine in the PLC script.  Or a LUA co-routine.  Or by running a private script. 

I won't go into LUA co-routines, as that is a subject all of its' own. 

Depending on how complex the operation that you want to do it, you may be able to do the complete operation in a private script.  A private script basically launches a thread to run the script.  It will NOT have access to any of the global function in the screen scripts!  However, you can load a module and run module code in them. 

Private script method:

To make a script "private", simply put --PRIVATE as the first line of the script.  I would suggest developing and debugging the script first before adding the --PRIVATE line.  The end result will be a script that is launched from a new thread and return control immediately to the Windows event loop.  How do you know it is done?  The machine state will become idle.  (mcCntlGetState()).

State machine method:

Instead of doing the whole long running code in a button script, just use the button script to set a flag.  Then the PLC script should watch that and launch the LUA co-routine or start a state machine that is implemented in the PLC script.

Also, use the G code interpreter as a means to offload script duties that require movement.  Do not wait on the G code to finish in the script, but rather let the G code interpreter launch the movement asynchronously. e.g. do not use mcCntlGcodeExecuteWait() but rather use mcCntlGcodeExecute(), which return immediately.  Then determine the completion by looking at the sate of the machine with mcCntlGetState().  Look for it to go from running to idle. 

Here is a pseudo code representation of a simple state machine

if flag set then
    // do the first movement
    myProcessState = 1
    mcCntlGcodeExecute()
    unset the flag
    loop mcCntlGetState() until no longer idle.  This means the G code has started. 
end

if myProcessState == 1 then
    if mcCntlGetState() == idle then
        myProcessState = 2
    end
end

if myProcessState == 2 then
    // do the second movement
    mcCntlGcodeExecute()
    loop mcCntlGetState() until no longer idle.  This means the G code has started. 
    myProcessState = 3
end

etc... 

Now, your PLC script is going to get hairy looking real fast.  So I would suggest implementing these state machines in LUA modules.  These modules can be put in the Modules directory.  They can then be "required" once in the screen load script and the accessed by the PLC script.

coner = require "myCornerFindingModule" -- now the PLC can access the functions in the myCornerFindingModule with corner

The button script may call a function that starts the state machine like:

corner.stateMachineStart()

and in the PLC script would call the state machine implementation like this:

corner.stateMachine(inst) -- the implementation.  Basically a no op when it hasn't been started. 

Steve

319
Mach4 General Discussion / Re: Remapping pin in script?
« on: March 29, 2020, 07:40:56 PM »
Seems like 5mA is less than 24mA?  What motion controller are you using? 

If it gets too complicated on the hardware side, go with the software solution.  Like I said, use the best method for your machine.  You are the one retrofitting it and would know best.  I was just pointing out that there can be more than one way to solve a problem. 

Steve.

320
Try changing this:

mc.mcCntlGcodeExecute(inst, g_code)

to

mc.mcCntlGcodeExecuteWait(inst, g_code)

M30 in MDI is basically a no op if you don't have a pallet changer.  The other thing M30 does is rewind the file, but MDI isn't a file and MDI will not rewind.  So I'm thinking that the MDI is just plain ignoring the M30 and the ends process before the G code gets started.  Hence why I'm thinking the Wait variant of the call should be used. 

Try it and see.

Also, I see you are not checking the return code from the API call.  A lot of mysteries are solved by checking the return codes. 

Steve