Machsupport Forum

Mach Discussion => Mach4 General Discussion => Topic started by: BR549 on May 25, 2014, 10:51:32 PM

Title: MACH4 Mcode testing
Post by: BR549 on May 25, 2014, 10:51:32 PM
Has anyone gotten a NEW Mcode to work properly. I was doing a simple test to see IF I could create a new Mcode.

I tried it this way, AND that errored out in the editor

-- Serial Number Engrave
function m100()
inst=mc.mcGetInstance();
mc.mcCntlSetLastError(inst, 'Serial Number Engrave')
mc.mcCntlGcodeExecute(inst, "G0X10 ");
mc.mcCntlGcodeExecute(inst, "G0X0 ");
end


SO I tried it this way. It will run from the EDITOR if you step though it but not from a M100 call in MACH4.  OR will not run with RUN in the editor.

-- Serial Number Engrave
inst=mc.mcGetInstance();
mc.mcCntlSetLastError(inst, 'Serial Number Engrave')
mc.mcCntlGcodeExecute(inst, "G0X10 ");
mc.mcCntlGcodeExecute(inst, "G0X0 ");


Can we create Mcodes for Mach4 ??

Does anyone have an example that works??

, (;-) TP
Title: Re: MACH4 Mcode testing
Post by: smurph on May 25, 2014, 11:53:49 PM
Did you name the file m100.mcs?   Go look at m3.mcs.  It is NAMED m3.mcs, there is a function NAMED m3.mcs, and then there is a piece of code at the bottom of the script that tests to see if it is being run from the editor.  If it is running in the editor, if calls the m3() function inside that if block.

In a file called m100.mcs, put:
Code: [Select]
function m100()
    inst=mc.mcGetInstance();
    mc.mcCntlSetLastError(inst, 'Serial Number Engrave')
    mc.mcCntlGcodeExecute(inst, "G0X10 ");
    mc.mcCntlGcodeExecute(inst, "G0X0 ");
end

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

It is like that for a reason.  It has to be that way where the scripts run in compiled mode as part of a larger "chunk" in Mach 4 and it also enables you to run the "snippet" inside the editor to debug it.

Steve
Title: Re: MACH4 Mcode testing
Post by: BR549 on May 26, 2014, 02:09:07 AM
You mean this ??    NONE of the Mcodes in the macro DIR  here have that piece of script, I just looked.

 if (mc.mcInEditor() == 1) then
    m100()


Title: Re: MACH4 Mcode testing
Post by: BR549 on May 26, 2014, 02:17:10 AM
Steve it still does not work even with your code. It tries to run it BUT it only moves about .236" of the first line of Gcode then BLOWS right on past the REST of the Gcode lines and ENDS.

NOW ONLY IF you step though the code in the LUA editor will it complete the Motion. USE RUN and you get the same problem.

TP

Title: Re: MACH4 Mcode testing
Post by: smurph on May 26, 2014, 02:40:44 AM
Try combining the two Gcode executes.  Like:

mc.mcCntlGcodeExecute(inst, "G0X10\nG0X0");

I wasn't looking too closely at your original script and I didn't catch that.  If you'll take a look at the m6 macro, you'll see where we did the same sort of thing that combines a lot of lines of G code into one call to mc.mcCntlGcodeExecute().

The technical reason is that each call to mc.mcCntlGcodeExecute() fires up it's own interpreter.  It is not like feeding a new line to the same interpreter.  It executes the code as a unit of work.  If you want the script to wait on the G code to complete before moving on, call mc.mcCntlGcodeExecuteWait() instead.

Steve
Title: Re: MACH4 Mcode testing
Post by: BR549 on May 26, 2014, 03:53:49 AM
OK that worked for the simple stuff  one or two lines of Gcode. Have you ever tried running a Sub or Gcode Macro from the Mcode. such as

mc.mcCntlGcodeExecuteWait(inst, "M98 P9020 ");

or

mc.mcCntlGcodeExecuteWait(inst, "G65 P9020 A10 B1.125");

I have an sequential serial number engraving function that works well from a SUB or G65 macro and I am trying to get it to run as a Mcode using the G65 call for inside the Mcode.

TP

The cgode is over 200 lines and uses condition redirection a LOT.
Title: Re: MACH4 Mcode testing
Post by: BR549 on May 26, 2014, 10:45:09 AM
Using

mc.mcCntlGcodeExecuteWait(inst, "G65 P9020 A10 B1.125");

Should help with large Mcodes with lots of Gcode lines IF it would run the G65 or M98 as a SUB.

IS there a limit to the nesting of a sub ?? Maybe that is the problem.

 I'll test some more,(;-) TP
Title: Re: MACH4 Mcode testing
Post by: BR549 on May 26, 2014, 12:04:19 PM
Steve IF you get a chance could you test this script . HERE it will try to run the very first time your try it after staring Mach4. It stalls out in the Gcode somewhere randomly.

after the first run it will never run again untill you restart MAch4.

What happens IS on line 3 where it is to get the #var value it stalls for about 20 seconds and return the WRONG value(Looks like it is trying to find it but cannot) it returns "0" when it should return the #var value(it does it correctly the first time it runs)

I cannot tell if it is the PC ,Mach4 or me so I would appreciate a 2nd set of eyes on this one.

Thanks (;-) TP
Title: Re: MACH4 Mcode testing
Post by: smurph on May 26, 2014, 02:28:53 PM
Did you forget to post the script?  Or are you talking about the one above?
Title: Re: MACH4 Mcode testing
Post by: BR549 on May 26, 2014, 02:56:51 PM
OOPS, sorry here is the script I am trying to run it as a Mcode.

function m100()
    inst=mc.mcGetInstance()
local SNv = mc.mcCntlGetPoundVar(inst , 590)
local str = string.sub(SNv,1,6)
 wx.wxMessageBox(tostring(str))
local SN = {}
for i = 1, #str do
    SN = str:sub(i, i)
end


  for _,v in ipairs(SN) do
    if     v == "1" then
            mc.mcCntlGcodeExecuteWait(inst, "G0 X1.0");
    elseif v == "2" then
            mc.mcCntlGcodeExecuteWait(inst, "G0 X2.0");
    elseif v == "3" then
            mc.mcCntlGcodeExecuteWait(inst, "G0 X3.0");
    elseif v == "4" then
            mc.mcCntlGcodeExecuteWait(inst, "G0 X4.0");
    elseif v == "5" then
            mc.mcCntlGcodeExecuteWait(inst, "G0 X5.0");
    elseif v == "6" then
            mc.mcCntlGcodeExecuteWait(inst, "G0 X6.0");
    elseif v == "7" then
            mc.mcCntlGcodeExecute(inst, "G0 X7.0");
    elseif v == "8" then
            mc.mcCntlGcodeExecuteWait(inst, "G0 X8.0");
    elseif v == "9" then
            mc.mcCntlGcodeExecuteWait(inst, "G0 X9.0");
    elseif v == "0" then
            mc.mcCntlGcodeExecuteWait(inst, "G0 X0.0");

    end
  end


--SN = (SN +1)
mc.mcCntlSetPoundVar(inst , 590,(str +1))
 
end

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






Title: Re: MACH4 Mcode testing
Post by: BR549 on May 26, 2014, 05:08:55 PM
Steve here is another example of a SIMPLE Mcode to do a simple tap operation. It will not run from the MDI or a Gcode program call.

It will TRY to cycle the first line of code as you can SEE the TOOL CHANGE LED blink but will run the Tap cycle IF you run it from the editor. BUT same as the other example ONLY the first time you run it. After that it is a nogo until you restart Mach4.

function m111()
    inst=mc.mcGetInstance()

    mc.mcCntlGcodeExecuteWait(inst, "T111 \n M6  ");

    mc.mcCntlGcodeExecuteWait(inst, "  M3 S500 M8 \n G4P3 \n G84 Z-0.5000 R.1 G98 F10 \n M5 M9");

end

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


(;-) TP
Title: Re: MACH4 Mcode testing
Post by: smurph on May 26, 2014, 06:30:16 PM
For your first example, I don't know what you were doing with that table.  I assume that you wanted to walk the digits of the #590 var.  This is more easily accomplished by converting the #var number to a string.  This is done by the "string.sub(SNv, 1, 6);".  Then just loop through each character.

Code: [Select]
function m100()
    local inst = mc.mcGetInstance();
    local SNv = mc.mcCntlGetPoundVar(inst , 590);
    local str = string.sub(SNv, 1, 6);
    local idx = 0;
    --wx.wxMessageBox(tostring(str));
    --local SN = {}
    local SN;
    for idx = 1, #str do
        SN = str:sub(idx, idx);
        if     SN == "1" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X1.0");
        elseif SN == "2" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X2.0");
        elseif SN == "3" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X3.0");
        elseif SN == "4" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X4.0");
        elseif SN == "5" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X5.0");
        elseif SN == "6" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X6.0");
        elseif SN == "7" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X7.0");
        elseif SN == "8" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X8.0");
        elseif SN == "9" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X9.0");
        elseif SN == "0" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X0.0");
        end
    end

    mc.mcCntlSetPoundVar(inst , 590, tonumber(str) + 1);
 
end

if (mc.mcInEditor() == 1) then
    m100()
end
Title: Re: MACH4 Mcode testing
Post by: smurph on May 26, 2014, 07:18:26 PM
A better example.  m100 will not execute at all from MDI or G code file.  Because user M codes start at 101.  It will run in the editor though.  So I changed it to M101 and it works fine.

Code: [Select]
function m101()
    local inst = mc.mcGetInstance();
    mc.mcCntlSetLastError(inst, "m101");
    local SNv = mc.mcCntlGetPoundVar(inst , 590);
    local str = string.sub(SNv, 1, 6);
    local idx = 0;
    mc.mcCntlSetLastError(inst, "#590 = " .. str);
    --local SN = {}
    local SN;
    for idx = 1, #str do
        SN = str:sub(idx, idx);
        if     SN == "1" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X1.0");
        elseif SN == "2" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X2.0");
        elseif SN == "3" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X3.0");
        elseif SN == "4" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X4.0");
        elseif SN == "5" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X5.0");
        elseif SN == "6" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X6.0");
        elseif SN == "7" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X7.0");
        elseif SN == "8" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X8.0");
        elseif SN == "9" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X9.0");
        elseif SN == "0" then
                mc.mcCntlGcodeExecuteWait(inst, "G0 X0.0");
        end
    end
    mc.mcCntlSetLastError(inst, "Setting #590 = " .. tostring(SNv + 1));
    mc.mcCntlSetPoundVar(inst , 590, SNv + 1);
end

if (mc.mcInEditor() == 1) then
    m101()
end
Title: Re: MACH4 Mcode testing
Post by: BR549 on May 26, 2014, 07:38:32 PM
OK SO, M101 is the starting point of User Macros is there a upper limit of macros one can create?

The first example take the #var(6 digit serial Number) and WILL eventially engrave the full 6 digit serial number one digit at a time. After teh engraving the SN is incremented by 1 for teh next call.

The problem with it is it will ONLY run one time per session of MACH4 else it errors ou because it cannot find the #var value again it searches for something for about 20-30 seconds then ends with a 0 value for the #var then ends.
Title: Re: MACH4 Mcode testing
Post by: BR549 on May 26, 2014, 08:32:34 PM
HIYA Steve I tried your version and it tried to run 1 time and got to the 4th digit then stopped, crashed ,after about 30 seconds it cleared BUT would not run again.

No need to go further with it

Thanks for the TIME, (;-) TP
Title: Re: MACH4 Mcode testing
Post by: smurph on May 27, 2014, 01:27:10 AM
Hmm...  mine works every time.  I also have G code that uses Macro B that does a nice job of serial numbers.

Steve
Title: Re: MACH4 Mcode testing
Post by: BR549 on May 27, 2014, 12:49:21 PM
YEP I have a SUB/Macro that does Sequential SN, Engrave, Etc.

Was just playing to see what  Mach4 could do as Mcodes.

 Mcodes are simple just type in the MCODE #(M101) . Alot of users don't quite get the Subs/G65macro deal YET. BUT hopefully they will soon.

I was HOPING that Mach4 could call a SUB/Macro from inside the Mcode . THAT would make it very simple to create Mcode functions based on Sub/Macros code.

In mach3(yes I know) I had Mcodes for every little special function. Take 5/16x24 tapping. I have one that loads the tap and does the cycle where ever you are. Yes I do a LOT of one off tapping functions. That just made it easy to do on the fly.

I tried it in MACH4 BUT it will run from the editor (RUN) just fine but has NEVER ran from MACH4 MDI or Gcode call

Just have to order another LARGE truck full of rocks.

(;-) TP

Title: Re: MACH4 Mcode testing
Post by: BR549 on May 27, 2014, 05:57:34 PM
Steve Just out of curiosity and maybe to save some time (;-). IS IT possible to call a SUB/Macro (M98 or G65) from inside a Mcode ???

(;-) TP
Title: Re: MACH4 Mcode testing
Post by: BR549 on May 27, 2014, 06:30:37 PM
Ok simple step by step test, Here is the Mcode to run a SUB via M98..

The Mcode Runs AND the SUB(o5555) loads in Mach4  BUT it does not know to Cycle Start the sub to run. It just STOPS there and the Mcode ends (no error) IT does run teh last sequence of the Gocde line as it places the comment (StartMacro) in the comment line.   BUT it does not finish the next sequence in the Mcode.

Could the Mcode be fixed to RUN the SUB and then finish out the Mcode code?  If so "THAT" would be the CAT's MEOW

function m222()
    local inst = mc.mcGetInstance();
    mc.mcCntlSetLastError(inst, "m101");
  
    mc.mcCntlGcodeExecuteWait(inst, "M98 P5555 L1 \n (StartMacro) ");
      
    mc.mcCntlSetLastError(inst, "M222 Completed " );
    
end

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








Title: Re: MACH4 Mcode testing
Post by: smurph on May 27, 2014, 06:59:11 PM
I don't know Terry.  It was never a design goal to have M codes run subs.  But it is probably possible. 

The build that you have has an issue where IF the G code that is passed to mc.mcCntlExecuteGcode() or the Wait variant DOES NOT produce any movement DIRECTLY, it will basically just return.  For example, one of your previous M codes was trying to do "T111 M6" on one line.  Well...  that line produced no direct movement of any sort.  M6 could have possibly produced movement, but only as a result of another interpreter firing up.  Thus it would have been indirect.  In any case, the only line that was processed was that "T111 M6" line and the rest was ignored.  So the same thing is going to happen with "M98 P5555 L1". 

I'm working on making the mc.mcCntlExecuteGcode() calls work in a different manner where they are not waiting on movement, per say, but rather the execution of the code to be completed.  It seems all just a play on semantics, but there is a difference.  And with this, it just may be able to run subs or G65s.  i don't know yet though.

Steve
Title: Re: MACH4 Mcode testing
Post by: BR549 on May 27, 2014, 07:42:23 PM
OK that makes sense.

Thanks (;-) TP
Title: Re: MACH4 Mcode testing
Post by: poppabear on May 27, 2014, 10:16:54 PM
Terry, just so I understand (or not) what your trying to do, I have this in my m3 macro:

function m3()
    local inst = mc.mcGetInstance();
    local sigh = mc.mcSignalGetHandle(inst, mc.OSIG_SPINDLEON);
    local sigState = mc.mcSignalGetState(sigh);

    if (sigState == 0) then
        mc.mcSpindleSetDirection(inst, 1);
        --dir is:  -1=ccw, 1=cw, 0=off    
    end

    local dummy = 1;
end
 
if (mc.mcInEditor() == 1) then
   m3();
end

Then in my test a macro running from in a macro, I made a macro called: m700
here is what is in it:

function m700()
    local inst = mc.mcGetInstance();
    local rc, DebugStopVar = 0;    
    mc.mcCntlMdiExecute(inst, "m3");--call the m3 macro from within this m700 macro
    DebugStopVar = 1;
end

if (mc.mcInEditor() == 1) then
   m700();
end

Is this the kind of thing as an example, your trying to do? Run the m700 from the MDI line?

Scott
Title: Re: MACH4 Mcode testing
Post by: BR549 on May 27, 2014, 11:34:56 PM
HIYA Scott, Nothing too fancy just try to run a M98 SUB from inside a Mcode.  IF it can be done then I am in HIGH cotton. In the simple example I call the SUB in Gcode, it does LOAD the sub in mach4 and it does display the message (start Macro) SO it gets that far. Steve explained why it does not go any further. It DOES NOT display the last message (M222 Complete).

function m222()
    local inst = mc.mcGetInstance();
    mc.mcCntlSetLastError(inst, "m101");
 
    mc.mcCntlGcodeExecuteWait(inst, "M98 P5555 L1 \n (StartMacro) ");
     
    mc.mcCntlSetLastError(inst, "M222 Completed " );
   
end

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


OK in your code what does the line before and after the MDI call do ?  I will try it that way as a test using the MDI line

local rc, DebugStopVar = 0;   
    mc.mcCntlMdiExecute(inst, "m3");--call the m3 macro from within this m700 macro
    DebugStopVar = 1;
Title: Re: MACH4 Mcode testing
Post by: BR549 on May 28, 2014, 12:08:26 AM
OK the MDI did the same thing so I did some testing with GcodeExecuteWait . It should run as teh Gcode line stated BUT it did NOT.



The Message(M222) Displayed fiirst
The X started moving to X10 and at the same time the Message (M222 Completed) was displayed
The X continued to X10 then Pause for 3 sec then returned to X0

So did something get OUT of sequence ??? or not It shoudl not have dispalyed the last message UNTIL the Gcode was done correct??

With some testing earlier it did the same thing it had 6 lines of Gcode to do using GcodeExecuteWAIT and it processed it all OUT of order it ran the 2,4,6 then it ran the 5,3,1 lines.

So far I have tried 4 PCs here and none have been able to run code that Steve and Craig can run fine without problems. SO I do not know , untill something changes I'll just wait to see what happens. I am Dead in the water.   I can can run everything else but the LUA scripting side of mach4.

I am as happy as a a pig with a new slop trough full of PIZZA with the Gcode side of MACH4. Even more so when all the #VARs get brought out so I can use them. Well maybe if we get "AND, OR ,XOR " included in the conditional side(;-).

(;-) TP

(;-) TP



function m222()
    local inst = mc.mcGetInstance();
    mc.mcCntlSetLastError(inst, "m222");
   local rc, DebugStopVar = 0;  
    mc.mcCntlGcodeExecuteWait(inst, "G1 X10 F30 \n G4p5 \n G0X0");--call the m3 macro from within this m700 macro
    DebugStopVar = 1;
    --mc.mcCntlGcodeExecuteWait(inst, "G0 x10");
      
    mc.mcCntlSetLastError(inst, "M222 Completed " );
  end
if (mc.mcInEditor() == 1) then
    m222()
end




Title: Re: MACH4 Mcode testing
Post by: BR549 on May 28, 2014, 12:13:43 AM
STEVE forgot to tell you I really LIKE that popup window in the Lua editor that when you start to type in a call it gives you a list to go by.

THAT really helps when you have to deal with that CASE sensitive beast called LUA   >:D

Thanks (;-) TP
Title: Re: MACH4 Mcode testing
Post by: BR549 on May 29, 2014, 06:36:21 PM
Question for you WizBangs.

  local inst = mc.mcGetInstance();
    mc.mcCntlSetLastError(inst, "m101");

WHAT is the "inst" and what does it do in the 2nd line. WHAT IS ITS PURPOSE ???

(;-) TP
Title: Re: MACH4 Mcode testing
Post by: Ya-Nvr-No on May 29, 2014, 07:57:52 PM
try opening a second mach4 you will find that in the hobby version you can only run one at a time
Title: Re: MACH4 Mcode testing
Post by: poppabear on May 29, 2014, 09:54:17 PM
Terry, the inst is the instance handle to the running mach application, technically if you had more than one instance of Mach4 running, you could "address" which instance your talking to, i.e. if you wanted the second instance you started, you would pass:
local inst = mc.mcGetInstance(1); (zero being the 1st instance you opened, and it the assumed default if you put no parameters in).

when you see it in the calls, that is so the call "knows" which instance you want it to do its thing on....

scott
Title: Re: MACH4 Mcode testing
Post by: BR549 on May 29, 2014, 10:10:35 PM
Thanks  Scott, that clears that up(;-)

(;-) TP
Title: Re: MACH4 Mcode testing
Post by: BR549 on May 30, 2014, 03:24:50 AM
OK seeing how Mcodes and multi line Gcode does not work HERE on my PC I figure out a way to Break the 6 digit s/n into 6 individual numbers to engrave the Serial Numer via a sub routine in Gcode.

DOn't need no stinkin LUA now   :o  ;D


PS but it would be nice when LUA gets to working right HERE.

(;-) TP