Yes, the GOOMBA is correct. MACRO B is the way this is done in the main stream and mc.mcCntlSetGcodeLineNbr() will not work when the machine is running (as stated in the API manual). This API is used by external scripts or GUIs to set the line number. As in where you click on a G code line in the G code list when the machine is IDLE. The IDLE state is important, otherwise, the user could click lines in the G code list while the machine is running and cause all sorts of mayhem and chaos.
And here is when I also get on my soap box about checking the API return codes. Because if the API was implemented in C/C++ but not implemented in LUA, it would simply be an unknow function to LUA (macro would produce a runtime error) OR the function call would return mc.MERROR_NOT_IMPLEMENTED. Either way, there would be no mystery why the API call didn't work.
All that being said, you could possibly use the mc.mcCntlSetGcodeLineNbr() when the machine is IDLE by first calling mc.mcCntlCycleStop(), then waiting on the state to become IDLE and then calling mc.mcCntlSetGcodeLineNbr() followed by mc.mcCntlCycleStart(). It was never meant to function like this, so your mileage may vary. You cannot jump to a N label in the G code with this. Only the physical line number. Obviously, this would NEVER work in MDI mode as there isn't a real notion of line numbers in MDI and the function would try and set the G code file line number instead. And you may have to wait a bit after the call to mc.mcCntlSetGcodeLineNbr() to allow the GUI to update its notion of the line number. I can't remember if the function is synchronous where the line is set by the time the function call completes or asynchronous where the line number is set lazily. Again, caveat emptor!
local inst = mc.mcGetInstance(inst, 'Trying to do the impossible script')
local lineNumber = 12 -- the G code line you want to jump to. It is base one, so 12 is line 12 and not line 13.
local rc = mc.MERROR_NOERROR
local state = 0
rc = mc.mcCntlCycleStop(inst)
-- Wait until the machine state is idle.
state, rc = mc.mcCntlGetState(inst)
while (rc == mc.MERROR_NOERROR) and (state ~= mc.MC_STATE_IDLE) do
wx.wxMilliSleep(10) -- Sleep for 10 milliseconds
state, rc = mc.mcCntlGetState(inst)
end
rc = mc.mcCntlSetGcodeLineNumber(inst, lineNumber)
if (rc == mc.MERROR_NOERROR) then
-- We got the proper return code from the API
-- telling us that there are no errors.
rc =mc.mcCntlCycleStart(inst)
if (rc ~= mc.MERROR_NOERROR) then
-- Some error happened.
end
-- if the code path gets here, the machine SHOULD be in File Running mode.
-- However, it is a good idea to check for the idle state at the end of any M code macro.
-- This lets you catch any action a user may have taken to stop the machine while the M code was running. E-Stop or Cycle Stop, etc...
state, rc = mc.mcCntlGetState(inst)
if rc == mc.MERROR_NOERROR) and (state == mc.MC_STATE_IDLE) then
-- The user must have aborted the G code!!!!! You can handle this gracefully if you needed to here.
end
end
Obviously, if you are trying to make API calls like this work, this means you are trying to make Mach do something that is doesn't do out of the box. Luckily we provide the API to make this possible but understand you are now programming. And you have to get your mindset right to program any device. It isn't a human. It isn't going infer anything. And it may make assumptions that you are not. So treat is like it is a 3 year old kid. You have to tell it to do everything step by step. I mean EVERYTHING. Including error checking.
Anyway, I hope this helps,
Steve