Hello Guest it is October 13, 2019, 07:24:49 PM

Author Topic: Is it possible to call an M code from a different M code?  (Read 535 times)

0 Members and 1 Guest are viewing this topic.

Re: Is it possible to call an M code from a different M code?
« Reply #10 on: February 22, 2019, 05:45:17 PM »
In m6  I thought I had the M1000() call commented out, i didn't realize I erased it, but ithe M1000() line replace the SetDepth() call. I did this because M1000() call is hanging. So I copied the SetDepth function into the M6 file so I could run my machine.

Ideally SetDepth would only reside in the M1000() file and not in M6 at all. I want to call the M1000 from 3 different areas, From M6, from Gcode, and from a button. I don't want to have to maintain the same code in 3 different areas. I have 14 different bits I use regularly, and only have room to hold 7 tool. But a bunch of my jobs only require one tool so i won't need the autochanger, I'll just need to measure the bit depth and go.

I copied the line setting up the inst variable from the Mach 4 sample code. According to my understanding of LUA declaring those outside of the function does make the globals, and they seem to work that way. But I admitt I do not have a great understanding of the LUA nuances.

I made the change as you suggested adding the debug line, Unfortunately it never shows up.
Re: Is it possible to call an M code from a different M code?
« Reply #11 on: February 22, 2019, 08:36:13 PM »
Hi,
the fact that none of the wxMessageBox notifications have showed up mean that program control has NEVER progressed that far.
Thus your m6 program is never calling m1000.

Where did you get that m6 code from. It seems way wordy....and confusing. Lua code tend to be short, sharp and sweet.

Craig
My wife left with my best friend...
     and I miss him!

Offline smurph

*
  • *
  •  1,138 1,138
  • "That there... that's an RV."
    • View Profile
Re: Is it possible to call an M code from a different M code?
« Reply #12 on: February 23, 2019, 02:11:52 PM »
Again, a reminder to keep all M code function names and file names lower case. 

Steve
Re: Is it possible to call an M code from a different M code?
« Reply #13 on: February 24, 2019, 02:07:08 PM »
I wrote the M6 code. It's odd that the M1000 call isn't working everything works great when I run the code as is in the file I attached earlier in this thread.

When I step through the code it works great but when calling it from the M6 or the MDI window it doesn't work. Calling it from the MDI window the buttons just flash. As a test I tried turning M1000 in to the following:
 
Code: [Select]
function  m1000()
    mc.mcCntlSetLastError(0, "In m1000")
end

if(mc.mcInEditor() == 1) then
    -- If you are in the mcLua editor, this will cause your script to execute if you Run or Debug
    -- Make sure your Capitalization and numbers match that of the function you are calling
    m1000()
end

And this still does not work!

If you cut and paste this in to a file named m1000() on your machine does the message pop up in the box on the bottom of your screen?

I cut and pasted the 1st 61 lines in my M6 file from the sample code. The rest of the code I wrote. I'm not sure what I could do to shorten it. All of the moves are safe moves and I have to time the positions of the 3 axis with the 3 pneumatic valves. Unfortunately I can't toggle an output in a line of GCode, or I could coordinate the movements, and probably eliminate quite a bit of code. For example there is no reason to pause the motion to close the chuck, other than that is a limitation of how mach works.
Re: Is it possible to call an M code from a different M code?
« Reply #14 on: February 24, 2019, 03:19:30 PM »
Hi,
I have no doubt m1000() works but m6 doesn't call it.

I don't really want to put buggy code into my setup....I may try later today.

Run m6 (lowercase) and see if m1000() is called?.
Is SetDepth() then called?.....whether you use wxMessabe Box or some other method matter less than if you call
m6 then eventually SetDepth() should be called. You need to test the machine state at the time of
the mc.CntlGcodeExecuteWait() call.

Craig
My wife left with my best friend...
     and I miss him!
Re: Is it possible to call an M code from a different M code?
« Reply #15 on: February 24, 2019, 05:35:04 PM »
Hi,
I have gone through m6 and regrouped, I hope it might help you.

The main thing I have done is break m6 into several files, the m6() proper, releaseTool(), getTool() and setToolDepth().

Note that I have deliberately reduced the leading letter of each function to lowercase per smurph's recommendation. In truth
the interpreter will reduce subsequent characters to lowercase also but I have retained capitalization of some letters to maintain
readability.

The second thing I have done is on every occasion where a mcCntlGcodeExecuteWait() is called I have tested the return code to ensure
that the function completed. Should it not do so you get a wxMessageBox notification including a number that will help you identify
any particular call which failed and a second number corresponding to the MERROR.

It maybe that once you have worked out how to get all this code to work that you can either delete or comment out
all (24 or so) diagnostic statement groups.....but for the moment they will highlight any errors.

I have bundled the module load statement in m6.

Note also that ALL four files need to be saved in the Macros folder of your current profile.

Save as m6.mcs
Code: [Select]
function  m6()
local ZGageBlockHeight = 3.3091
local inst = mc.mcGetInstance()
package.path = wx.wxGetCwd() .. "\\Profiles\\AXYZ\\Modules\\?.lua;"
if(package.loaded.ToolChangePositions == nil) then
tcp = require "ToolChangePositions"
end
    local SelectedTool = mc.mcToolGetSelected(inst)
    local CurrentTool = mc.mcToolGetCurrent(inst)
    local rc=mc.mcCntlGcodeExecuteWait(inst, "m5\n")
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 1 MERROR="..tostring(rc))
do return end
end
local CurFeed = mc.mcCntlGetPoundVar(inst, 2134)
    local CurFeedMode = mc.mcCntlGetPoundVar(inst, 4001)
    local CurAbsMode = mc.mcCntlGetPoundVar(inst, 4003)
    local ToolData = tcp.GetToolData(CurrentTool)
    if (ToolData ~= nil) then
        Num1 = ToolData.Tool_Number
        XPos1 = ToolData.X_Position
        YPos1 = ToolData.Y_Position
        ZPos1 = ToolData.Z_Position
    else
        mc.mcCntlEStop(inst)
        mc.mcCntlSetLastError(inst, "ERROR: Tool number out of range!")
        do return end
    end
    local ToolData = tcp.GetToolData(SelectedTool)
    if (ToolData ~= nil) then
        Num2 = ToolData.Tool_Number
        XPos2 = ToolData.X_Position
        YPos2 = ToolData.Y_Position
        ZPos2 = ToolData.Z_Position
    else
mc.mcCntlEStop(inst)
        mc.mcCntlSetLastError(inst, "ERROR: Tool number out of range!")
        do return end
    end
    local GCode = ""
    GCode = GCode .. "G00 G90 G53 Z0\n"
    GCode = GCode .. string.format("G00 G90 G53 X%.4f Y%.4f\n", XPos1, YPos1)
    local rc=mc.mcCntlGcodeExecuteWait(inst, GCode)
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 2 MERROR="..tostring(rc))
do return end
end
GCode = ""
    GCode = GCode .. string.format("G00 G90 G53 Z%.4f\n", ZPos1)
    local rc=mc.mcCntlGcodeExecuteWait(inst, GCode)
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 3 MERROR="..tostring(rc))
do return end
end
    ------ Release the current tool ------
    releaseTool(CurrentTool)
    ------ Move to next tool change position ------
    GCode = ""
    GCode = GCode .. string.format("G00 G90 G53 X%.4f Y%.4f\n", XPos2 + 2, YPos2)
    local rc=mc.mcCntlGcodeExecuteWait(inst, GCode)
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 4 MERROR="..tostring(rc))
do return end
end
    ------ Get the new tool ------
    getTool(SelectedTool)
    ------ Set Tool Depth ------
    setToolDepth()
    ------ Move Z to home position ------
    local rc=mc.mcCntlGcodeExecuteWait(inst, "G00 G90 G53 Z0\n")
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 5 MERROR="..tostring(rc))
do return end
end
    ------ Reset state ------
    mc.mcCntlSetPoundVar(inst, 2134, CurFeed)
    mc.mcCntlSetPoundVar(inst, 4001, CurFeedMode)
    mc.mcCntlSetPoundVar(inst, 4003, CurAbsMode)
    ------ Set new tool ------
    mc.mcToolSetCurrent(inst, SelectedTool)
    CurrentTool = mc.mcToolGetCurrent(inst)
    mc.mcCntlSetLastError(inst, string.format("Tool changed, now using tool: %.0f", CurrentTool))
end
if (mc.mcInEditor() == 1) then
m6()
end

Save as releaseTool.mcs
Code: [Select]
function releaseTool(CurrentTool)
local inst=mc.mcGetInstance()
    -- Set special casses
    if(CurrentTool == 7) then
        ------ Lower to drop off position ------
        local GCode = ""
        GCode = GCode .. "G00 G53 x36 Y2\n"
        GCode = GCode .. "G00 G53 x39.6 Y2\n"
        GCode = GCode .. "G00 G53 z-6.11\n"
        GCode = GCode .. "G01 G91 Y-2 F100\n"
        local rc=mc.mcCntlGcodeExecuteWait(inst, GCode)
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 6 MERROR="..tostring(rc))
do return end
end
    else
        ------ Lower to drop off position ------
        local rc=mc.mcCntlGcodeExecuteWait(inst, "G01 G91 X2 F100\n")
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 7 MERROR="..tostring(rc))
do return end
end
    end
    ----- Open Drawbar ------
    local DrawbarOPEN = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1)
    mc.mcSignalSetState(DrawbarOPEN, 1)
    ------ Move to Clear position turn off drawbar------
    local rc=mc.mcCntlGcodeExecuteWait(inst, "G00 G91 Z.75\n")
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 8 MERROR="..tostring(rc))
do return end
end
    mc.mcSignalSetState(DrawbarOPEN, 0)   
    ------ Close Drawbar ------
    local DrawbarCLOSE = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT2)
    mc.mcSignalSetState(DrawbarCLOSE, 1)
    local rc=mc.mcCntlGcodeExecuteWait(inst, "G04 P200\n")
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 9 MERROR="..tostring(rc))
do return end
end
    mc.mcSignalSetState(DrawbarCLOSE, 0)
    ------ Move to clear tool position ------
    local rc=mc.mcCntlGcodeExecuteWait(inst, "G00 G90 G53 Z-3.0")
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 10 MERROR="..tostring(rc))
do return end
end
end
if (mc.mcInEditor()==1)then
releaseTool()
end

Save as getTool.mcs
Code: [Select]
function getTool(SelectedTool)
local inst=mc.mcGetInstance()
    ------ Lower to blow off start position ------
    if(SelectedTool == 7) then -- Set special casses
        ------ Lower to drop off position ------
        local GCode = ""
        GCode = GCode .. "G00 G53 x39.6\n"
        GCode = GCode .. "G00 G91 Y-2.75\n"
        local rc=mc.mcCntlGcodeExecuteWait(inst, GCode)
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 11 MERROR="..tostring(rc))
do return end
end
    end
    local rc=mc.mcCntlGcodeExecuteWait(inst, "G00 G91 Z-1.75\n")
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 12 MERROR="..tostring(rc))
do return end
end
   
    ------ Turn on Blow off  ------
    local BlowOff = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT0)
    mc.mcSignalSetState(BlowOff, 1)
    ------ Lower to pick up start position shut off blow off, turn on drawbar------
    local rc=mc.mcCntlGcodeExecuteWait(inst, "G00 G91 Z-1\n")
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 13 MERROR="..tostring(rc))
do return end
end
    mc.mcSignalSetState(BlowOff, 0)
    local DrawbarOPEN = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1)
    mc.mcSignalSetState(DrawbarOPEN, 1)
    ------ Move to pickup position position ------
    local rc=mc.mcCntlGcodeExecuteWait(inst, "G00 G91 Z-.5\n")
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 14 MERROR="..tostring(rc))
do return end
end
    ------ Turn off  open drawbar ------
    mc.mcSignalSetState(DrawbarOPEN, 0)
    ------ Close Drawbar ------
    local DrawbarCLOSE = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT2)
    mc.mcSignalSetState(DrawbarCLOSE, 1)
    local rc=mc.mcCntlGcodeExecuteWait(inst, "G00 G91 Z.2\n")
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 15 MERROR="..tostring(rc))
do return end
end
    ------ Stop Closing drawbar ------
    mc.mcSignalSetState(DrawbarCLOSE, 0)
    ------ Move to final tool change position ------
    local GCode = ""
        if(SelectedTool == 7) then
        GCode = GCode .. "G01 G91 Y2 F100\n" -- Clear fork
        GCode = GCode .. "G00 G90 G53 Z0\n" -- Go up
    else
        GCode = GCode .. "G01 G91 X-2 F100\n" -- clear fork
        GCode = GCode .. "G00 G90 G53 Z0\n" -- Go up
        GCode = GCode .. "G00 G53 X33 Y2.75\n" -- Go to clear position read to measure       
    end
    local rc=mc.mcCntlGcodeExecuteWait(inst, GCode)
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 16 MERROR="..tostring(rc))
do return end
end
end
if (mc.mcInEditor()==1)then
getTool()
end

Save as setToolDepth.mcs
Code: [Select]
function setToolDepth()
local inst=mc.mcGetInstance()
local ZGageBlockHeight = 3.3091
    ------ Auto Depth Setting ------ 
    local rc=mc.mcCntlGcodeExecuteWait(inst, "G00 G53 X35.93 Y2.75\n") -- go to point over depth setter
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 17 MERROR="..tostring(rc))
do return end
end
    local rc=mc.mcCntlSetLastError(inst, 'Setting Tool Height')
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 18 MERROR="..tostring(rc))
do return end
end
    local rc=mc.mcCntlGcodeExecuteWait(inst, "G91 G31 Z-4 F50") --probe the new tool
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 19 MERROR="..tostring(rc))
do return end
end
    local rc=mc.mcCntlGcodeExecuteWait(inst, "G91 G0 Z+0.1") --Retract from the probe
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 20 MERROR="..tostring(rc))
do return end
end
local rc=mc.mcCntlGcodeExecuteWait(inst, "G91 G31 Z-0.15 F5") --Probes at slow speed
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 21 MERROR="..tostring(rc))
do return end
end
local measure_1 = mc.mcAxisGetPos(inst,2) --Saves probed Z position

local rc=mc.mcCntlGcodeExecuteWait(inst, "G91 G0 Z+0.1") --Retracts from the probe
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 22 MERROR="..tostring(rc))
do return end
end
local rc=mc.mcCntlGcodeExecuteWait(inst, "G91 G31 Z-0.15 F5") --Probes at slow speed
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 23 MERROR="..tostring(rc))
do return end
end
local measure_2 = mc.mcAxisGetPos(inst,2) --Saves probed Z position
   
local measured_average = (measure_1 + measure_2)/2 --Averages two probed values
    local offSet = measure_2 - measured_average
local adjustedHeight = ZGageBlockHeight + offSet

    mc.mcAxisSetPos(inst,2,adjustedHeight) --Sets current Z postion to gage block height with measured offset

GCode = ""
    GCode = GCode .. "G00 G90 G53 Z0\n" --Retract
    GCode = GCode .. "G00 G53 X33 Y2.75\n" -- Move to clear spot
    local rc=mc.mcCntlGcodeExecuteWait(inst, GCode)
if rc~=0 then
wx.wxMessageBox("mcCntlGcodeExecuteWait() did not progress 24 MERROR="..tostring(rc))
do return end
end
end
if (mc.mcInEditor()==1)then
setToolDepth()
end

Scan the code and see what you think. Note that M1000() occurs nowhere. Should you want to call setToolDepth() from
from the main Gcode job, not m6, but the main program, THEN use m1000 and create a function m1000() in your Macros
folder that explicitly calls setToolDepth(). In this way setToolDepth() will exist as only one file but may be called by different
procedures.

Craig

 
My wife left with my best friend...
     and I miss him!
Re: Is it possible to call an M code from a different M code?
« Reply #16 on: February 25, 2019, 09:05:56 AM »
Craig, Thanks. I really appreciate all your effort! I will test this tonight and let you know how it goes.
Re: Is it possible to call an M code from a different M code?
« Reply #17 on: February 26, 2019, 06:14:49 PM »
Ok, I had a chance to work on this tonight. I made the files and loaded the code in them. When I step through the m6 command as soon as I get to the line:
Code: [Select]
releaseTool(CurrentTool)
The debugging session ends, The debug window displays:

Code: [Select]
Program starting as '"C:\Mach4Hobby\ZeroBraneStudio\bin\lua52.exe" -e "io.stdout:setvbuf('no')" "C:\Users\CNC\AppData\Local\Temp\.8EAC.tmp"'.
Program 'lua52.exe' started in 'C:\Mach4Hobby' (pid: 5432).
Debugging session started in 'C:\Mach4Hobby\'.
Profiles/AXYZ/Macros/m6.mcs:61: attempt to call global 'releaseTool' (a nil value)
stack traceback:
Profiles/AXYZ/Macros/m6.mcs:61: in function 'm6'
Profiles/AXYZ/Macros/m6.mcs:90: in main chunk
Debugging session completed (traced 2 instructions).
Program completed in 6.82 seconds (pid: 5432).

It's stating that 'releaseTool' is a nil value. It appears it can't find 'releaseTool'! How do I debug this? The releaseTool file is in the folder "C:\Mach4Hobby\Profiles\AXYZ\Macros"
Re: Is it possible to call an M code from a different M code?
« Reply #18 on: February 26, 2019, 06:30:31 PM »
Hi,
when you are in the editor the external function call fails.

If you run Mach then all the functions in the Macros folder get compiled into the chunk and are therefore available
to any other function within the chunk.

The simplest way to get over that is to include the code for the required function in the same file as m6, it would
then be compiled with m6 and available to it.

I thought to separate each function from m6 to reduce the confusion and should you wish to make some changes
it would be easier to find.

When I single stepped through each function but I stepped 'over' the function calls in m6 to avoid calling a none existent
function. As far as the editor is concerned the external functions are 'nil'.

Craig
My wife left with my best friend...
     and I miss him!
Re: Is it possible to call an M code from a different M code?
« Reply #19 on: February 28, 2019, 05:51:20 PM »
I ran the code split in to the files like you suggested. And it works great! I added an m1000 file that just calls the setToolDepth function. And it works as desired.

Thank you so much for your help! I hope I can help you one day.

The next step is tying the M1000()  command to the empty button in the tool information section.