Hello Guest it is October 28, 2020, 04:53:19 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

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

Steve

342
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

343
Yes, you use the screen API.  It is not documented other than you will get the function signatures in the ZeroBrane editor.  The two staples are:

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.

Keep in mid that it is ALWAYS better to use the underlying data that backs the screen element instead of the screen element itself, if possible.  For instance, if there is a slider on the screen named "myFROslider" that sets the feed rate override, use mc.mcCntlGetFRO() instead of scr.GetProperty('myFROslider', 'Value").  This is part of the reason that this stuff is not documented.  Because people will use it and not use the main Mach API proper.  I JUST ran into this when support gave me a supposed "BUG" the other day.  It wasn't a bug.  The slider is imprecise because it is pixel based.  If the slider has a range of 0 to 250, but the slider is displayed in less than 250 pixels, well...  there are going to be gaps in the range when using the slider.  Meaning you can start sliding it up from zero and get counts like 1, 2, 3, 5, 6, 7, 9.  So it wasn't a bug at all!!!!  It is why the FRO slider in fresh on my mind.  Yeah, I went down that rabbit hole. 

The other reason is I just don't like writing documentation.  LOL

99% of the time, these scr.* functions are not needed.  If you find yourself needing them all of the time, take a step back and think about how it could be done some other way.  Most of the time, the ONLY time you may absolutely need them is for a screen specific function.  Like the figuring out what tab is current to make the Start Cycle button process MDI commands instead of running a file.  

Steve

344
Mach4 General Discussion / Re: Simple one line MDI required
« on: May 20, 2018, 02:32:01 PM »
What is wrong with Mach4's "Run From Here"?  It works fine for me.  Let me explain what it does.

1.  The first thing it does is do a dry run to and including the line before the selected restart line.  Why?  To get the interpreter state correct.  So if cutter comp was in effect, it would start at the correct offset.  Or any offset, for that matter. 
2.  The dry run is for the interpreter state only, not necessarily the machine state.  If you turned the spindle off, you had better have turned it back on.  Why?  Because you turned it off.  You are master and commander of the machine tool.  And there might not be a line in the G code to tell the control to restart the spindle.  Otherwise, you will drag the cutter through the part and you WILL break something.  At this point, you really can't blame it on the machine control.  :)
3.  Execution will start at the beginning point of the desired line.  If the machine is not already at those coordinates, it will do a feed move to get there.  This includes Z.  This may seem contradictory to the statement above.  But is it?  The last line of the dry run set the starting point of the line.  If the machine is not there, you basically have told the machine to get there. 

Mach doesn't "automatically" restart spindles and such because it has no way of knowing the reason for the run from here.  It could be used to restart a program.  Or it could be used to start a program at a certain place.  You, the operator, know this and it is your responsibility to make sure the machine is in a state to accomplish this.

It is all about understanding what goes on in automatic vs. manual mode.  There is nothing magical about Run From Here.  It will do the same things every time.

Steve

345
The screen script is a screen resource.  Meaning it is part of the screen set.  You edit the screen to edit the script.  It has nothing to do with a machine profile other than the profile determine WHAT screen is use with it.  Fore example, multiple profile could use the same screen set.  Or each profile could use a different set. 

As Craig mentioned, the larger ScreenScript.lua is generated from smaller script snippets in the screen.  So you can't edit the ScreenScript.lua file directly.  See section 5 of "Mach4 Screen Editor V1.0.pdf" in the docs folder.

Usually, if one wants to make a function available for the screen elements, the function is put in the screen load script.  This allows for any button to call that function from their respective event scripts, etc..  So you will see the CycleStart() function in the screen load script. 

Now, do you NEED to put the code into the screen load script?  It depends.  If the code is something that is repetitive and common, then adding it as a function in the screen load script becomes desirable.  But if the button code is very specific to a certain button, then just use the button event script to do the whole job.  A LOT of times, doing all of the the code in the button event script is more clear to the intent.  Readability is important a year from now if you decide to change something and have pretty much forgotten what you are doing now.  :)  It really depends on what is most comfortable/effective for you. 

Steve

346
Striplar,

One thing to do is check the return code from any and all API calls.  These return codes will do a lot of work for you in diagnosing why something doesn't work.  Anything other than zero (mc.MERROR_NOERROR) is an error.

Allan's code is getting the return codes in the variable rc.  That is a step in the right direction, but it is still not actually checking the return code. 

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

rc = mc.mcJogIncStart(inst, axis, dist)
if (rc ~= mc.MERROR_NOERROR) then
    -- Error condition!  Maybe use SetLastErrror
    mc.mcCntlSetLastError(inst, "jog Start Failed")
    -- And return immediately so that things don't go all pear shaped.
    return;
end
...

It is a lot more coding, but I can promise you that it will pay off.  Things won't sneak up and bite you.  And it covers all of the bases, so to speak.  If you get into the habit of checking the return codes, it just becomes at some point.  It is especially important on API calls that are to perform an action.  Because you want to handle the case if the action didn't or couldn't happen. 

Steve

347
Mach4 General Discussion / Re: Lua Stats
« on: May 19, 2018, 09:04:21 PM »
Craig,

Well...  Configure may indeed be working properly.  The library looks like it have several bindings, LUA only being one of them.  If configure can't find the LUA headers and libraries, it may build just the other bindings, etc...  That is what I was thinking.  Cmake is a good concept but I don't think it can ever be implemented perfectly.  Too many pieces to the puzzle a lot of times. 

That plplotluac.i file is what we call an interface definition file.  The C code is generated from that .i file.  Normally, it is processed by LUA itself.  So you may need Lua.exe in the path.  And there may be a place in the configure portion to tell it where that is.  So maybe a REAL LUA installation is needed.

Steve

348
Mach4 General Discussion / Re: Simple one line MDI required
« on: May 19, 2018, 03:08:40 AM »
Ctrl-Enter will execute the MDI.

Steve

349
Mach4 General Discussion / Re: Lua Stats
« on: May 19, 2018, 02:41:55 AM »
Well...  typically the configure process will show you what all is needed.  You may have to check the advanced checkbox in the cmake GUI to see everything.  The module documentation may also shed some light on what is needed. 

I would not modify CmakeCache.txt, as it is generated.  And usually, to modify a make file, you do it through the cmake interface.  You CAN change them, but be aware that the next time you either configure or generate, those changes will be overwritten. 

Anyway, since that checkbox goes away, I suspect it is looking for the LUA 5.2 headers and libraries.  You may have to point cmake to these directories if it doesn't automatically find them in the configure process.  Usually, one will "configure" and resolve all dependencies and repeat as necessary.  Then "generate" the make files.  If the configure process fails for some reason, it will show up in the log.  And possibly highlight the areas in the config list with red.

Steve

350
Mach4 General Discussion / Re: Lua Stats
« on: May 12, 2018, 03:39:17 AM »
Look at the Makefile and look for the target "all"

the format is:

target:dependencies

A target may include other targets as dependencies.  Layer upon layer, etc...

Also, search the build directory and all child directories for *.dll.

Sometimes the modules will have more than a DLL file and have quite complex directory structures.  In that case, look for an installation directory path in the Makefile.  INSTALLDIR or something of the like.  You can directly edit the Makefile if needed.  Create a directory and point the installation directory variable to that path.  Then "make install".  All of the build files will be copied to the directory you created with the correct directory structure.  To use them in Mach, you would copy all of those files to the Modules directory of Mach, preserving the directory structure. 

Steve