Hello Guest it is May 14, 2021, 04:05:01 AM

Author Topic: Mach sometimes ignores mcCntlGcodeExecuteWait() without an error  (Read 121 times)

0 Members and 1 Guest are viewing this topic.

I have a complex M6 script for a mill. The script moves over to the tool rack and releases the current tool, then moves over to the requested tool and grabs it.

Sometimes the script just seems to jump over the "move" part of itself - it doesn't execute G-code, but does set (some) outputs as if nothing had happened. This is weird, as I do actually check the return value of all mcCntlGcodeExecuteWait() statements I issue and essentially halt if it's anything but 0.

Here's the G-code execution wrapper function I use:
Code: [Select]
function toolchange_callGcode(gcode)
    if toolchange_is_action_allowed()==true then
        local inst = mc.mcGetInstance()
        mc.mcCntlSetLastError(inst, gcode)
        --wait for the machine to be
        local rc = mc.mcCntlGcodeExecuteWait(inst, gcode)
        if rc ~=0 then
            toolchange_stop_safely()
            mc.mcCntlSetLastError(inst, "Something went wrong with executing G-code from within M6. The machine was disable for safety. Error state: "..rc)
        end
    end
end


toolchange_stop_safely() is a function that sets a global variable toolchange_action_allowed_flag to false. I read that flag in toolchange_is_action_allowed(), before any calls that impact the machine (like switching output signals or executing G-code, as shown above):
Code: [Select]
function toolchange_is_action_allowed()
    local inst = mc.mcGetInstance()
    if (toolchange_action_allowed_flag==true and toolchange_machine_enabled()==true) then
        --mc.mcCntlSetLastError(inst, "Action allowed")
        return true
    else
        --mc.mcCntlSetLastError(inst, "Action not allowed")
        return false
    end
end

I've had a similar issue in the past (https://www.machsupport.com/forum/index.php?topic=36577.20), where the script didn't stop execution after a "stop" or "disable" but that behaviour was completely deterministic and always happened. This was solved and the complete solution is in the last post.

The current issue, however, only happens rarely, both in MDI and from G-code programs, and Mach seems to get stuck in this state. It keeps jumping over the G-code calls until I restart the whole machine (including the DSMPC motion controller). Mach4 is version 4.2.0.2872, which is quite old. Here's the whole M6 script, for which I'm happy to provide additional explanations for: https://pastebin.com/244jsUyR.

Are there any other errors I should check for, or am I missing something basic? I'd also be thankful for any other suggestions for making my script error-proof.

Offline smurph

*
  • *
  •  1,402 1,402
  • "That there... that's an RV."
    • View Profile
Re: Mach sometimes ignores mcCntlGcodeExecuteWait() without an error
« Reply #1 on: April 19, 2021, 07:45:48 PM »
4.2.0.2872...  Quite old is an understatement!  I would try something newer.  Use 4612 if you can. 

BTW, no scripts are stopped or killed when the stop button is pressed or the control is disabled.  What if the script needed to do something to handle that event?  So you, the programmer, need to handle all avenues and code paths in the scripts.  It is why I harp on testing the API function return codes all of the time.  Because return codes like mc.MERROR_NOT_NOW can be a clue that your script isn't going to end up like you thought because something went all pear shaped.   

Steve
Re: Mach sometimes ignores mcCntlGcodeExecuteWait() without an error
« Reply #2 on: April 21, 2021, 07:15:01 AM »
I agree that the script shouldn't be stopped by Mach, it was just a bit of a surprise back when I wrote the script, as the custom M6 example in the manual makes no mention of this.

This time, however, the API function doesn't even seem to set an error. I'll see if updating Mach solves this.

In order to totally fool-proof the script, I thought of adding checks to make sure that the machine really is at the destination after a move. If it isn't, I'd stop the machine. I'd implement this by reading the actual machine coordinates and checking if they are within a small enough distance from the requested location. This comes with quite a bit of added complexity, though, so if anyone has any suggestions, I'd be happy to hear them.