Hello Guest it is April 19, 2024, 03:14:12 PM

Author Topic: mcCntlGetGcodeFileName ...Crashes M4  (Read 3955 times)

0 Members and 1 Guest are viewing this topic.

mcCntlGetGcodeFileName ...Crashes M4
« on: December 13, 2016, 04:46:22 AM »
Hi All,
I'm writing a script that involves file handling and despite my infancy with LUA getting some good results.

This piece of code doesn't work as I expected:

 local code,rc= mc.mcCntlGetGcodeFileName(inst) ;
    if rc ~=0 then;
        wx.wxMessageBox("G code file not loaded");
        error=1;
        return error;
    end;

When this  macro is called either by a running Gcode file or MDI with a file loaded but not running it works well. I had hoped to use the macro as a file processing
utility even when a Gcode file is not loaded. My intention was to use the error trap and at some later stage add a navigation panel to select the file to process.

The problem is that the macro fails immediately on the ...mc.mcCntlGet...function and so never gets to the error trap which I had hoped to use.

Any ideas on how to detect whether a file is loaded or not?

Craig
'I enjoy sex at 73.....I live at 71 so its not too far to walk.'

Offline DazTheGas

*
  •  778 778
  • DazTheGas
    • View Profile
Re: mcCntlGetGcodeFileName ...Crashes M4
« Reply #1 on: December 13, 2016, 05:21:43 AM »
Your not in a function so where are you returning the error too??

DazTheGas
New For 2022 - Instagram: dazthegas

Offline DazTheGas

*
  •  778 778
  • DazTheGas
    • View Profile
Re: mcCntlGetGcodeFileName ...Crashes M4
« Reply #2 on: December 13, 2016, 05:32:29 AM »
Something like this should work

Code: [Select]
local inst = mc.mcGetInstance()

local GCode = mc.mcCntlGetGcodeFileName(inst)

if GCode == "" then
    wx.wxMessageBox("No Code Loaded")
else
    wx.wxMessageBox(GCode.." GCode Loaded")
end

DazTheGas
New For 2022 - Instagram: dazthegas
Re: mcCntlGetGcodeFileName ...Crashes M4
« Reply #3 on: December 13, 2016, 12:54:41 PM »
Hi DTG,
thanks for that, the piece of code is in a function so it returns to the macro main body code.

Craig
'I enjoy sex at 73.....I live at 71 so its not too far to walk.'
Re: mcCntlGetGcodeFileName ...Crashes M4
« Reply #4 on: December 14, 2016, 02:37:52 AM »
Hi DTG,
unfortunately that little code alteration didn't work either. The macro entry and two of the internal function are:

Code: [Select]
function M41()
inst = mc.mcGetInstance();
mc.mcCntlProbeFileClose( inst );-- Close Mach4 ProbeFile
--
-- FUNCTION OpenRPF
-- arguments: inst
-- return data,numdata,pathRPF,error
--
function OpenRPF(inst);
    local error=0;
    local hreg=mc.mcRegGetHandle(inst,"iRegs0/ALfile");
    if hreg==0 or hreg==nil then;
        wx.wxMessageBox("register ALfile not found...Abort");
        error=1;
        return error;
    end;
    local pathRPF=mc.mcRegGetValueString(hreg);
    if pathRPF=="" then;
        wx.wxMessageBox("Filepath not found...Abort");
        error=1;
        return error;
    end;
    local handRPF=assert(io.open(pathRPF,"r"));
    if handRPF==nil then;
        wx.wxMessageBox("File not opened...Abort");
        error=1;
        return error;
    end;
    local data=handRPF:read("*all");
    if data=="" then;
        wx.wxMessageBox("No Data...Abort");
        error=1;
        return error;
    end;
    local i,j,numdata;
    numdata=0;
    i=1;
    j=1;
    while i do;
        i=string.find(data,"\n",j+1);
        if i==nil then break end;
        j=i;
        numdata=numdata+1;
    end;
    return data,numdata,pathRPF,error;
end;
--
-- FUNCTION OpenGcode
-- arguments: inst
-- return: code,error
--
function OpenGcode(inst)
    local error=0
    local code,rc= mc.mcCntlGetGcodeFileName(inst) ;
    if rc ~=0 then;
        wx.wxMessageBox("G code file not loaded");
        error=1;
        return error;
    end;
    local hcode=assert(io.open(code,"r"));
    if hcode==0 or hcode==nil then;
        wx.wxMessageBox("G code file could not be opened");
        error=1;
        return error;
    end;
    code=hcode:read("*all");
    if code=="" then;
        wx.wxMessageBox("G code file empty");
        error=1
        return error;
    end;
    hcode:close();
    return code,error;
end;

As you can see I've tried to detect and report any errors.

This macro, M41 and its partner M40 are intended to be used with Autoleveller, a crafty software utility that generates a Gcode job to probe a circuit
board blank and then apply Z corrections to the PCB-Gcode file to ensure near perfect  accuracy of cut depth when 'etching' circuit boards. I've used it
with M3 and PP and have found it so useful I can't do without it. There are quite a number of M3 users and over time more will migrate to M4 and these
macros may come in use.

As it stands if the M40 and M41 macros are called from the Gcode probe job it works well. I had hoped that if a user tried to run M41 as a stand alone
file processing job that would also be possible. I would need to add navigation windows to get the two files but not insurmountable. Given that there may in
time be a number of people using these macros I've tried to make them as flexible and yet robust as possible. In particular if a file open/read/write op
is going to fail try to detect/report and shut gracefully rather than leaving a user in suspense not knowing if it failed or why.

I may be accused of 'trying to run before I can walk'. All of the other error traps seem to work but for the one trying to get the filename/path of the loaded
probe job in the situation where the job is not loaded or accidently been closed before M41 gets a chance to run.

Must be said that I'm a complete newb with LUA. There was a couple of days there when I was SHOUTING EXTEREMLY LOUDLY the most unprintable
profanities I could imagine. I'm surprised you didn't hear it, after all you're only 14000 naut miles away and I was LOUD!  Have slowly come to some understanding
of syntax. When I think back it was no worse than when I started with VB and is still better than I am with C/C++.

I was of the opinion that Artsoft had made a mistake with LUA. Having suffered the 'hump' I'm beginning to see how powerful and flexible LUA is with such a remarkably
simple instruction set and libraries. I feel that I've just scratched the surface of the flexibility that can be achieved with such a simple language. Same sort of argument
about RISC processors. The upshot is I wont be going back to VB.

I have a couple more bits to write, one extracts the mesh points from a Gcode probe job in one 'dialect' of Autoleveller, and another, a user definable/editable tolerance
applied in the search/replace applied to the numerical values. The tolerance I intend to save in iRegs0 and so can be kept between sessions. If it goes well and live tests
goes as well as my debugging should be able to post in a few more days.

Craig
'I enjoy sex at 73.....I live at 71 so its not too far to walk.'

Offline DazTheGas

*
  •  778 778
  • DazTheGas
    • View Profile
Re: mcCntlGetGcodeFileName ...Crashes M4
« Reply #5 on: December 14, 2016, 06:00:35 AM »
Firstly take a look at your m code function M41, it is normal practice for all m codes to be declared in lower case as lua is case sensitive and it sets the norm,

After declaring your m function you have also tried to declare "function OpenRPF(inst)" inside of it, all functions must be declared on top level, if you open up the m code in the editor you will see the error of "'end' expected (to close 'function' at line 1) " but saying that I cant see the function being called from anywhere in the script so perhaps just delete that line so the m code becomes the function. There is also a function called "function OpenGcode(inst)" thats not called in anyway and lots of "return error" thats not being returned to anything?

consider an approach something like this

Code: [Select]
hreg, rc = mc.mcRegGetHandle(inst,"iRegs0/ALfile")
if rc ~= 0 then
    wx.wxMessageBox("register ALfile not found...Abort") -- could add the returned rc code here too
    return -- nothing to return just quit (this is only quitting the m code you might need to Stop the gcode??)
else
    --everything was fine so lets get value from Reg
    local pathRPF = mc.mcRegGetValueString(hreg)
    if pathRPF == "" then
        wx.wxMessageBox("register ALfile empty...Abort")
        return
    end
end

-- so now you if you get here do something with the reg value.


Cant test any further than that as dont know whats contained in "mc.mcRegGetHandle(inst,"iRegs0/ALfile")" I can only assume its a file path?

DazTheGas
New For 2022 - Instagram: dazthegas
Re: mcCntlGetGcodeFileName ...Crashes M4
« Reply #6 on: December 14, 2016, 07:18:12 AM »
Hi DTG,
I have in fact five or six functions, behaving in the manner of subroutines. After all the functions have been declared then the body of the M41 macro occurs. The
body code it probably only 20-30 lines which really only schedules each function and looks to the error flag to see whether the function called has behaved.

The first function to be called is OpenRPF as listed above. As you rightly surmise the filename/path is stored in iRegs0/ALfile. OpenRPF checks that the register
exists and messages an error if not, then checks to see if the filepath is empty and messages an error if it is, and so on. Each of these errors, in absence of any
recovery code, returns to the main body code, the error flag tested and then it returns presumably to the Gcode calling program.

My intention when going about it this way was to keep the various string manipulation parts separate and reduce confusion, mine particularly.

I found tonight that if I run the macro from the editor the mcCntlGeteGcodeFilname function works OK, that is it returns a null result if there's no file loaded , my simple
test works , messages the error, returns to M41 and it returns to the editor. If I MDI M41 that's when mcCntlGeteGcodeFilname stops it dead without the test
being performed.

I may be getting too fancy for my own good, it works as a macro but not so well as a stand alone process.

Craig
'I enjoy sex at 73.....I live at 71 so its not too far to walk.'

Offline DazTheGas

*
  •  778 778
  • DazTheGas
    • View Profile
Re: mcCntlGetGcodeFileName ...Crashes M4
« Reply #7 on: December 14, 2016, 08:40:57 AM »
Perhaps post all the code or zip n PM if its sensative or even better use the package profile in the help menu then I might be able to get a better picture of what you are trying to do. I have looked at autoleveller and have a rough gist of what you are trying to do.

Correct me if I am wrong ;-)

Now autoleveller outputs a gcode file, this file has been created from a gcode that you loaded into it, it then inserts some probe routines at the begining of this gcode file then saves it.
The idea is to then load in "mach3" (as it doesnt say its compatible with 4) and it will do the probing and use the params for Z height during the gcode.

How am I doing so far??

DazTheGas
New For 2022 - Instagram: dazthegas
Re: mcCntlGetGcodeFileName ...Crashes M4
« Reply #8 on: December 14, 2016, 01:08:31 PM »
Hi DTG,
there are a couple of versions of Autoleveller but all versions apply the general idea that you outlined.

The earliest version takes your original PCB-Gcode file, OGF in the parlance, generated by the circuit board program. It decides on a  number
of probe points throughout the board. It adds some code to the file to probe the board and applies a 2d linear interpolated correction to the
Z values of your OGF which you can then run. It uses # variables in line. As M4 # variables are differently numbered a search and replace edit
is required to get the code to work.

The two later versions take the OGF and decide on a set of probe points, the mesh in the parlance. Autoleveller then produces a new Gcode job
that probes the board and save the results in  file, the RPF. With M3 macros M40 and M41 open and close the digital probe file. The macros I'm
writing are based on M400 and M401 which come with M4 as LUA examples.

M4 and ESS operate slightly differently when probing. My M3/PP machine would report the programed XY position and the Z at the point of probe contact.
M4/ESS reports XYZ measured at the point of probe contact. The subtle difference can render Autoleveller unworkable.
Ther are two reasons, first my machine and hopefully only my machine produces a small random number of extra data triplets than probe events. Thus a RPF
may have 220 lines despite there having been only 210 probe points. I'd hoped this was due to a noisy probe circuit and have tried a number of things to sort
it out but haven't found a solution yet. As it turns out the extras are duplicates. Ergo the M41 macro needs to be able to read the file, detect and delete the
extra entries. I've got working LUA code to do this using LUA standard library string functions.

The second issue is that M4/ESS reports the measured XY not the programed XY and there is a slight difference, on my machine the average error is 0.0225mm.
When Autoleveller uses the RPF to calculate the required Z corrections it can produce wild results if the actual probe points differ from the programed ones.
AL, one variant of Autoleveller accepts errors of 0.02mm without problem but AE the latest variant goes cranky to rounding error in the fourth decimal place.

So extra functionality in M41 is required. Take the Gcode probe job file, strip out the Gcode to get the anticipated XY probe points and then overwrite the measured
XY points in the RPF if within a user specified tolerance. There again I have working code to do both. The two versions use slightly different Gcode generation
techniques and getting code that accommodates both dialects is giving me a little grief at the moment.

The upshot is that what I'm trying to do is automate a data filtering operation. The code is not sensitive or private, its always been my intention to post it for
anyone to use. Once I've got the string manipulation/filtering parts to work smoothly I will post it and a couple of genuine RPFs and the Gcode probe jobs that
generated them. Might be a few days away yet.

Craig
'I enjoy sex at 73.....I live at 71 so its not too far to walk.'
Re: mcCntlGetGcodeFileName ...Crashes M4
« Reply #9 on: December 16, 2016, 10:07:53 PM »
Hi All,
have some working code. Concentrating on the two macros M40 and M41. As DTG pointed out the names are case sensitive. AL and AE call the macros
in uppercase ergo I named them uppercase.

Found best combination of reliability/simplicity to use three persistent registers:
iRegs0/"ALcode" for the file/pathname of the G-code probe job,
iRegs0/"AEdata" for the file/pathname of the raw probe file and,
iRegs0/"ALtol" for your choice of permitted tolerance.

These will need to be set up prior to use. The write to the file/path registers occurs in M40 you will note.

While there are a few error traps in the code which will hopefully give you a clue if the code fails there is little/nothing in the way of recovery yet.

Craig
Also had hoped that the macros could be used as standalone processing jobs but have had little luck yet. As it stands they work if they are called
from the AL/AE generated G-code probe job and work from the editor but less successfully if called from the MDI line.
This code is tested by hand editing probe files and am happy that it works but be warned anyone who uses it are my guinea pigs. Please let me
know if you have problems.

Need to point out also that this is my first effort at Lua coding. If there are inconsistencies/mistakes they represent my newbie status.
Have just started looking at the string pattern/capture functions and believe I could at some future date make stronger and more readable code.
'I enjoy sex at 73.....I live at 71 so its not too far to walk.'