Hello Guest it is October 20, 2019, 10:42:06 AM

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - smurph

181
Yeah, I don't know why people use the message box.  There is NOTHING more aggravating.  You can paint yourself into a corner quickly if you move some code from say like a macro script to the PLC script!  mc.mcCntlSetLastError() is a much better choice.  Or mc.CntlLog() and watch the diagnostic log window. 

Also, in the new builds, I have put in:

number: rc = mc.mcCntlMacroAlarm(number: inst, number: error, string: message)
number: rc = mc.mcCntlMacroStop(number: inst, number: error, string: message)

Using mc.mcCntlMacroAlarm() basically does the same thing that writing a number to #3000 does in G code.

#3000 = 16 (Error 16 condition)

is the same as

mc.mcCntlMacroAlarm(inst, 16, 'Error 16 condition')

This will cause "Error 16 condition" in the status history, stop the cycle (not E-Stop), and raise the OSIG_ALARM signal.  The alarm can only be canceled by hitting reset.  OSIG_ALARM can be used to drive a yellow beacon light or similar that is commonly found on production CNC machines. 

Using mc.mcCntlMacroStop() basically does the same thing that writing a number to #3006 does in G code.

#3006 = 12 (Error 12 condition)

is the same as

mc.mcCntlMacroStop(inst, 12, 'Error 12 condition')

This will cause "Error 16 condition" in the status history and stop the cycle (not E-Stop) without raising the OSIG_ALARM signal.  It does not need to be canceled by a reset.  Basically, it is the same as hitting the cycle stop button. 

These functions are good for M code scripts because they will stop the machine if they are used for error conditions.  The rest of the script may process, but the control will not advance to the next line of G code.  But typically one would return from the script right after calling one of these functions.  Of course, in order to use these functions, you have to write scripts that check for error conditions in the first place, right?  :)  If you are going to write scripts, it doesn't really matter if it is for a hobby machine or an industrial production machine, do it right.  People sometimes say "it is just a hobby machine", etc...  And I call BS!!!!  Doing things the right way will save you time and money in the future.

Steve

182
The scripting manual shows where to go to edit all of the scripts.  It is in the screen editor.  Screen Load script, PLC script, Singal script, screen unload script, timer scripts, etc...  Even the control event scripts.  They are all in the screen editor.  The latest release (3804) on the website has all of these documents in the Docs folder of the installation directory. 

"Mach4 Screen Editor V1.0.pdf" and "Scripting Manual.pdf" are of particular interest. 

The scripts will be in the property/event grid (events button).  Go to the top element of the tree (the screen object) and then click on the events button in the grid. 

Steve

183
For that, you will most definitely have to use the screen API.

string: value, number: rc = scr.GetProperty(string: ctrlName, string: propertyName)

number: rc = scr.SetProperty(string: ctrlName, string: propertyName, string: value)

The control name is the name you have given the screen element in the Name property.  It is case sensitive. 
The property name is the name of the property as spelled in the property grid.  Value, for example. Or Top, Left, Width, Height, etc...

The value of the property is always a string.  Use tonumber() to convert a string to a number in LUA.  Conversely, use tostring() to convert a number to a string.  Some properties are lists, which have values associated with the string description in the list.  In this case, you will get the value instead of the string description.

If you open up the screen editor and look at the properties of a regular button, you will see a property called "Bg Color".  This is the property you will want to set with scr.SetProperty().  The property is editable in the screen editor with a color picker control.  But it is actually stored as a string.  A call to scr.GetProperty("myButton", "Bg Color") will reveal the stored value.  If the returned sting is blank/empty, then the default color based on the current Windows theme will be used.  Otherwise, it will return a value in HTML RGB format like "#RRGGBB"  #FF0000 is pure red, #00FF00 is pure green, #0000FF is pure blue.  Any color can be represented with this syntax. 

An easy way to get the value for the color you want is to open the screen editor, set a button's "Bg Color" to the color you want, and then use scr.GetProperty("myButton", "Bg Color") to get the value.  Record it, and then maybe change the color and get more values.  Otherwise, there are probably lots of color picker tools out there that are capable of doing this too. 

Once you have your color values, then you can set the button color based on the current jog increment in the PLC script.
Code: [Select]
if (incr == .001) then
    rc = scr.SetProperty("myButton", "Bg Color", "#FF0000") -- set button color to red if incr == .001
elseif (incr == .01) then
    rc = scr.SetProperty("myButton", "Bg Color", "#00FF00") -- set button color to green if incr == .01
elseif (incr == .1) then
    rc = scr.SetProperty("myButton", "Bg Color", "#0000FF") -- set button color to blue if incr == .1
end

Steve

184
Allan is 100% correct on this.  And he also tested empirically.  Good job!  

A G31 move will either skip, or not.  Meaning probe strike, or not.  If the probe strikes a surface, the G code variables are filled with the strike position.  If the probe does NOT touch a surface, the G code variables will contain the end point of the move.  Normally, this is the ONLY way to know if the probe has touched a surface in G code is by comparing the G code variable positions to the end point of the move.  If different, the probe struck a surface.  

Since Mach is not running on a real time OS, it can't possibly capture the strike position accurately.  So this job is delegated to the motion controller, which is a real-time device.  So if the values in those G code variables are not correct, then I would suspect an issue with the motion controller or its' plugin.  

If there is a hang waiting on a set still, then the motion control plugin is not working correctly.  Again, since Mach is not running on a real-time OS, and Mach doesn't know the outcome of the G31 move, it will ask the motion controller/plugin to tell it when the move is complete.  It could have reached the endpoint of the move or stopped somewhere in between.  Mach just doesn't know.  So Mach will wait indefinitely for a response back from the motion controller. If no response is given, hang.  

Fanuc only specifies the variables #5061-#5066, which should be the position with all current offsets applied.  Mach also gives you #5071-#5076, which should be the machine position.  All of these positions are in native machine units.  Meaning if you setup the machine for inch, then inches is what you will see in those variables, even if you are probing in G21.  

On an inch machine:
G90 G21
G00 X0
G31 X10 F1000 (probe does not strike)

At the end of the move #5071 == .393701 (inch value for 10mm)

Steve

185
Thanks for the input Steve,

Just curious, why is anything under 16 GB bad for windows 10? 

When it comes to regenerating my toolpath, I've gotten in this cycle start habit of Regen --> Cycle Start.  Just to be safe.

Because a stock Windows 10 installation on a new machine (Dell, etc...) idles at 12GB.  They put all of that bloatware on there.  Plus all of the MS telemetry stuff.  If you are persistent enough to remove all of the crap, then 8GB might be ok.  All it takes is a quick look to the task manager to see how well the machine will perform.  Virt mem vs. Physical mem.  If your virt mem is higher, expect the machine to be sluggish.   My machine is idling at 21GB as we speak!  Now, it is a development machine.  But let's face it, that is the amount of memory my machine REQUIRES to operate like I want it to.  All that is running is Visual Studio, email, web browser, file manager, Skype, and Mach.  The big ones are Skype and the web browser.  Next is the Visual Studio.

Steve

186
Mach4 General Discussion / Re: IMTS 2018
« on: May 24, 2018, 04:57:13 PM »
I don't know what our plans are for IMTS this year.  When I find out, I'll let everyone know. 

I like going and meeting the people I converse with on this board.  I missed it last time around because it fell on my 10th wedding anniversary.  :(

Steve

187
It is not a 32 vs. 64 bit thing.  It is a processor/memory thing.  Mach 4 does things differently than Mach 3 did on the file loads.  The capabilities of the interpreter are far more advanced and requires a LOT more switch code.  Thus it does take more processor power to generate the tool path.  The newer builds will be an improvement in this regard, as I optimized it as much as I could.  

With the latest build, on my desktop machine, I can process 1000 lines of G code per second or 1 G code line per millisecond.  Now, my Atom board WILL NOT do this.  :)

The files are memory mapped.  This enables files that are far larger than the 32 bit address space.  However, if your machine is swapping memory to disk, well...  it is GOING TO BE SLOW.  I agree that 8GB of RAM is not sufficient for a Windows 10 machine.  Anything less than 16GB is uncivilized.  

If you change an offset, you MUST regenerate the tool path.  We don't auto regenerate because you may need to change several offsets and would then have to wait on each offset to regenerate the tool path.  

Steve

188
The stock jogging will follow G20/G21.  Also, the increments are defined in the General setup tab.  Define them in the order and content that you want. 

The common cycle start is on 95% of the commercial controls.  There is usually a switch on the panel to direct the cycle start to run the MDI.  All the YASNACs, Fanucs, and Fidias that I have run have been like that.  In this case, the "switch" is the current tab.  But I don't use the screen for these functions at all, because of some of the same concerns.  I use a panel to run my whole machine just like I did when the control was a YASNAC.  No mouse clicky stuff.  It is a touch screen and I do use that to load files, etc..  But that is the extent of it.  Basically, the screen is there for display purposes and I run the machine with the panel.  MPG, FRO, SRO, jog buttons, cycle start/stop feed hold.  Like God meant for CNC machines to be run.  :)

Steve

189
What kind of pendant?  And what kind of motion controller are you running? 

Steve

190
I use a rotary knob on my panel to set the jog increments.  And use Mach API function mcJogSetInc().  To find the current jog increment, use mcJogGetInc().  It is by axis, so to make all of the coordinated axes have the same jog increment, you have to do it for all of them.  The GUI does this for you in its' default configuration.  But if you want something different, then you have to do the legwork that the GUI does. 

So, how would one track this?  In the PLC script.  LEDs can be driven by signals.  One could grab some output signals that are not mapped to hardware outputs and use them for the purpose of driving LEDs.  In the PLC script, use mcJogGetInc() to determine which increment is in use and drive the appropriate output signal.  Say you have 3 LEDs to represent 3 different increments of .001, .01, and .1.  At this point, you may want to put this function in the screen load script and call it from the PLC script. 

Code: [Select]
-- this is in the screen load script.
currentInc = 0 -- global var to track the current increment. 

function SetIncrementLeds()
    local inst = mc.GetInstance()
    -- track using OSIG_OUTPUT61, OSIG_OUTPUT62, and OSIG_OUTPUT63 (for .001, .001, and .1, respectively)
    local hSig61 -- signal handle
    local hSig62 -- signal handle
    local hSig63 -- signal handle
    local inc, rc = mc.mcJogGetInc(inst, mc.X_AXIS)
    if (currentInc ~= inc) then -- the increment has changed, so light up the appropriate LED
        currentInc = inc;
        hSig61, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT61)
        if (rc ~= mc.MERROR_NOERROR) then
            -- Error condition.
            mc.mcCntlSetLastError(inst, "Failed to get signal handle in SetIncrementLeds()!"
            return;
        end
        hSig62, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT62)
        if (rc ~= mc.MERROR_NOERROR) then
            -- Error condition.
            mc.mcCntlSetLastError(inst, "Failed to get signal handle in SetIncrementLeds()!"
            return;
        end
        hSig63, rc = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT63)
        if (rc ~= mc.MERROR_NOERROR) then
            -- Error condition.
            mc.mcCntlSetLastError(inst, "Failed to get signal handle in SetIncrementLeds()!"
            return;
        end
        -- No errors at this point, set all output signals to off.
        mc.mcSignalSetState(hSig61, 0) -- check the return code for production code!  This is an example. 
        mc.mcSignalSetState(hSig62, 0)
        mc.mcSignalSetState(hSig63, 0)
        if (inc == .001) then
            mc.mcSignalSetState(hSig61, 1) -- .001 is current, turn on its' output signal. 
        elseif (inc == .01) then
            mc.mcSignalSetState(hSig62, 1) -- .01 is current, turn on its' output signal. 
        elseif (inc == .1) then
            mc.mcSignalSetState(hSig63, 1) -- .1 is current, turn on its' output signal. 
        end
    end
end

function SetIncrement(incr)
    for axis=0,5,1 do
        mc.mcJogSetInc(inst, axis, incr) -- probably want to check the rc as well... 
    end
end

Put a line in the PLC script to update the LEDs
Code: [Select]
SetIncrementLeds() -- call the function that is in the screen load script

Then map output signals 61 to 63 to some LEDs.

Then put something like the following in some button up event scripts

Code: [Select]
SetIncrement(.001) -- Call the SetIncrement() function in the screen load script.  .01 and .1 in other buttons.

That is all done without scr.Get/SetProperty().  AND it has the added benefit of working along side a panel knob.  But also do realize that you also have the PMC to do all of this stuff in ladder logic as well.  Both of these should be considered preferable to using the screen API stuff.   

Steve