Hello Guest it is March 28, 2024, 12:46:40 PM

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

921
Mach4 General Discussion / Re: need a little bit of help
« on: June 02, 2015, 04:55:24 PM »
You are correct!!!  It is prudent to check the API functions for error codes.  In examples, I don't write that stuff in, as it becomes time consuming.  But it is NEEDED for production scripts to ensure that when things go wrong, it gets handled properly.  In the API docs, most of the examples are in C.  Some of the functions have LUA examples.  But the C examples use the error codes and can be used to deduce what they would be in LUA. 

Here is a snippet of a manual tool change M6 macro.
Code: [Select]
    -- M6start stuff here....

    --Here, we process an EVT_MACRO_HOLD and enter the macro hold state.  We can jog there!
    mc.mcCntlSetLastError(inst, "Press Cycle Start to finish the tool change.");
    wx.wxMilliSleep(100); -- wait a few so that the GUI can retrieve the message before the machine changes state.
    --  A sleep is not generally a good idea to use.  But in this case, it is harmless as the wait is minimal. 
    local rc = mc.mcCntlToolChangeManual(inst); 
    -- execution resumes from here when the user presses Cycle Start or Cycle Stop or some sort of E-stop or disabling of the machine.

    -- but in the mean time the user can Jog, toogle switches, stand on your head, or do anything else he likes!

    -- We check the rc of mc.mcCntlToolChangeManual() because the user might have aborted
    -- the tool change by pressing Cycle Stop.
    if (rc == mc.MERROR_NOERROR) then
        -- the user has not aborted, finish the tool change.  M6end stuff.
        ...
    end

Steve

922
Mach4 General Discussion / Re: need a little bit of help
« on: June 02, 2015, 03:11:32 PM »
Terry, I think you are missing the point.  G code is NOT a programming language in the classical sense.  It is a command language.  It has no logic statements without the macro B stuff.  No way to control the flow at all sans the simple sub routine mechanism at all.  For example, what is the G code to test that machine movement has been completed?  What in G code notifies the operator of the machine that the G code is complete?  I mean standard G code.  Not a scripted macro.  M00?  M01?  What action/event is taken by the G code if "G00 X0Y0" is executed and then completed?  Nothing.  The machine executed the code and then just sits there like a bump on a log waiting for the operator to do something else.

Macro B is not another language.  It is an extension of the G code command set.  It executes in the same context as the regular G code.  Therefore it is an apples and oranges comparison.

Waiting on an event in a PLC with a loop is controlling program flow.  It is a LESS efficient way of doing so!  Ladder with VB is an extension just like Macro B is an extension to G code.  It operates in the same "program" context.  It is the same interpreter on the same device.  So how would you take TWO PLCs and make them work with each other?  That is a better example.  You will HAVE to use flow control mechanisms to prevent a race condition in one or the other PLC.  Because you are now executing code in two different environments/devices/contexts.  Is it a kludge?  Certainly not.

With that HUGE thing said, there is no possible way to integrate G code and LUA to the extent you are talking about.  Simply because G code can't really "communicate" with anything to that extent.  Unless we also interpret LUA along side of G code with the same interpreter, then having what you describe is simply not possible.  And then users would have to sprinkle LUA in with their G code just like you had to sprinkle VB in with your ladder logic.  Terry...  you have to distinguish what is a dream and what is reality.

In my example code above, it uses a semaphore like var to control the execution.  Please explain to me how that will not work on different machines?  Or for that matter, how would C/C++ mutexes and semaphores not work the same on different PCs?  If that were the case, EVERY windows program would have to be custom made for EACH PC.  That is not the case.  I don't want to argue, but what you are saying is simply not the case and I feel it a disservice to the rest of the community to let such a notion stand.

There is nothing wrong.  There is no design flaw.  It is working as intended to make the system as flexible as it can be.  It is the way it is for very good reasons.  The sooner you accept that and just move on, the happier you will be.  :)

Steve

923
Mach4 General Discussion / Re: need a little bit of help
« on: June 02, 2015, 03:43:35 AM »
The use of semaphores is a glutch fix that may or may NOT work across different machines/Pc's  Same with Mach3. Each PC can have different timing aspects to threads and what triggers a race condition. That has been proven many times in Mach3 I dought if controls are not in place to prevent it it will also occur in Mach4.

It should be the Programers job to make SURE that the 2 code systems are integrated to prevent it from occurring UNLESS you want it to run out of sync.  Syncronous ,Asyncronous I believe is the term.

I have used many systems that simply are designed to NOT allow an out of sync race condition to ocur UNLESS you requested it to do so.

WHY put the load on the OPs to prevent a race condition (You working for the machine (;-( ) When it should be the controllers job to prevent it in the first place. ( The machine working for you (;-) ).

Just a thought, (;-) TP

Terry...  come on now.  This is a bit of a stretch, don't you think?  What PLC on the planet does not use semaphore like/type logic to control program flow?  It is not a glutch, kludge, or workaround.  It is the correct way to handle the logic. 

And you are right, it is the programmer's job to make sure that the program works.  When you are programming a script, you just became that programmer!  We give you a plethora of tools to work with too.  You have the ability to make the controller do as you wish.  If you do the job right, the machine will work for you from that point on.  But there is NO WAY that we can guess what the script programmer's intentions for the script are and protect him from himself.  I guess we could if we constrained the script environment to only operating in a certain way.  But we just threw flexibility out the window!

Yeah, there is a learning curve.  No doubt.  It will not be everyone's cup of tea.  But some people don't build or convert their machines either.  Some buy them ready to run.  It is the thing I struggle with all of the time.  I squeak when I walk so I tend to not want to pay much for anything that I even remotely think I could handle!  But I don't have a lot of time to learn new things either.  Catch 22!  I usually err on the side of cheapness and end up finding/making the time to learn so that I can do it myself.  :)

Steve

924
Mach4 General Discussion / Re: need a little bit of help
« on: June 02, 2015, 02:37:16 AM »
The "better" way to do this stuff is to use the PLC script in conjunction with a button script.  Make a global var in the Load script to work with.  Something like "myAction".  The button script simply sets myAction to something that the PLC script knows how to handle. 

load script:
Code: [Select]
-- make some global vars.
myAction = -1;  -- holds our action code.
myActionExecuting = 0;  -- is our action executing?  This is like a semaphore.

Button script:
Code: [Select]
if (myAction == -1) then
    myAction = 1; -- set to x20 and y30 offset from spindle.
end

PLC script:
Code: [Select]
if (myAction == 1) then
    mc.mcCntlGcodeExecute(inst, "G91 G00 X20Y30");  -- set to x20 and y30 offset from spindle.
    myActionExecuting = 1; -- mark that we are executing.
    -- The state of the machine will now NOT be idle.  It will be executing the G code.
    -- The PLC script runs top down, so the test below will not see the machine in the
    --  idle state until the code above has been completed.
end

...

mcState = mc.mcCntlGetState(inst);
if (mcState == mc.MC_STATE_IDLE and myActionExecuting == 1 and myAction == 1) then
    --This part is so it will Zero axis`s after movement.
    mc.mcAxisSetPos(inst, 0, 0.000); --zero x axis
    mc.mcAxisSetPos(inst, 1, 0.000); --zero y axis 
    myActionExecuting = 0;  -- no longer excuting myAction
    myAction = -1; -- reset myAction to let another button do something.
end

If you think about it, this is how one would program any PLC where the PLC would be watching an input or register to control program flow.  Just think of a button as sort of way to update a PLC register.

Steve

925
Mach4 General Discussion / Re: Mach4 Executing Gcode from LUA
« on: May 29, 2015, 02:06:41 AM »
I was speaking of GUI events.  Button presses, menu selection, etc...  Windows has an event loop.  The application updates it's controls with the very same event loop.  Signal events are external.

The MDI and GcodeExec functions load the G code into the interpreters and run it.  The movement happens at the motion controller and the motion controller updates the core with it's positions.  These positions are immediately sent to the Mach 4 screen.  If there were no long running button event, the screen would update within milliseconds.  There is no mystery location.  Each DRO has a list of what it is to control/display.  The values can be accessed with the scr.* LUA functions if you are wanting to track them.  I have never had a need to though.

I have no idea why a signal script would pass info to a screen load script.  The load script is loaded upon initial display of the screen.  Functions in the load script can be called if they are included in the load script.  But make no mistake, the load script is only actually run once.  It sounds like you need to use the PLC/signal scripts to me.  That is what should be used to process and input event.

One thing I have noticed is that there are a lot of fancy code snippets floating around for the LUA scripts.  And that is all great and wonderful.  But sometimes simple brute force code is best and in the end, more readable.  I'm not a LUA expert by any means, so I tend to keep it simple.

Signal script.  In the example, Input #1 is tied to a stop button on the panel.  If the machine is running, this will stop it just like hitting the stop button on the screen.  Input #2 is tied to a Start button.
Code: [Select]
    local inst = mc.mcGetInstance();
   
    if (sig == mc.ISIG_INPUT1) then
        if (state == 1) then
            mc.mcCntlCycleStop(inst);
        end
    end
    if (sig == mc.ISIG_INPUT2) then
        if (state == 1) then
            mc.mcCntlCycleStart(inst);
        end
    end

It is not elegant or fancy.  But it is damned effective. 

It is important to note that the signal script only gets called when a signal is changed.  So holding down the stop button will not continually call mcCntlCycleStop().  The signal changes state from low to high once when you press the button (the signal script is then called with state set to 1) and then from high to low when you let off the button (and the signal script is called again with state set to 0).

I didn't write the scripting manual.  So I really can answer that!  I'm sure it is a work in progress. 

Steve

926
Mach4 General Discussion / Re: G31.1, G31.2, G31.3 working?
« on: May 29, 2015, 01:09:47 AM »
Support for the extended probe commands is motion plugin dependent.  I'm not sure who supports them yet.

Steve.


927
Mach4 General Discussion / Re: Mach4 Executing Gcode from LUA
« on: May 29, 2015, 12:55:45 AM »
This isn't a bug. 

mc.mcCntlGcodeExecuteWait() should not be used in a button script if you want the screen to refresh.  When you press a button, the button event is run.  If that button event takes 15 seconds total time, the screen will not refresh for that time.  mc.mcCntlGcodeExecuteWait() does what it implies.  It waits for the given code to be executed.  Meanwhile your button event has not returned and the GUI is frozen.  It is more suited for M code scripts.

mc.mcCntlGcodeExecute() is good for button scripts.  It executes the given G code in a unit of work.  It drops the code off to the interpreter and does <B>NOT</B> wait.  However, It is not meant to be called block by block.  Two consecutive calls to mc.mcCntlGcodeExecute() will act like mc.mcCntlGcodeExecuteWait() because the second call can't be submitted until the first one is done.  If multiple lines/blocks are needed, then they should be concatenated into one single line separated with \n (newline) characters.

local inst = mc.mcGetInstance()
mc.mcCntlGcodeExecute(inst, "G0 X10 Y10\nG0 X5 Y5\n")

Is proper for your last example and your DRO will update.

928
Mach4 General Discussion / Re: MACH4 - Modbus
« on: March 24, 2015, 10:46:42 PM »
We use the WINAPI EnumPorts() function to get the ports.  This API call is part of the printing subsystem.  Check to see if that is disabled/not installed on your machine.  It might be something like "print spooling" or the like.  If it is XP embedded, print support may not even be installed. 

You are the first to see this that I know of.  So I would be very interested in what Windows version you are running. 

Steve

929
Mach4 General Discussion / Re: Mach4 Screw Error Mapping
« on: March 24, 2015, 01:08:11 AM »
Screw error mapping will work for the rack.  But it as yet untested.  So I would not say it is ready for prime time.

Steve

930
Mach4 General Discussion / Re: Mach 4 Feature Request
« on: March 11, 2015, 08:38:49 PM »
The one that comes with Mach 4 is the demo version.  Demo is not a good word, as it is fully functional as it is and does not time out or anything.  Unlicensed would be a better word.  The licensed version would have more features (not all of which I can remember at this time so please do not state that I'm being vague.)  We don't have a demo version that enables the Pro features for a limited time or some such.  Not yet.  Because we simply haven't finished it yet.

When it is done, I think Todd may be able to do a time limited license or something.

Steve