Hello Guest it is September 21, 2019, 04:52:45 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

251
Mach4 General Discussion / Re: Can you use Inputs with Macro B Programming.
« on: November 21, 2017, 01:58:39 PM »
Should work the same then.  There really is no different in the GUI between Hobby and Industrial other than industrial features are turned on in the Demo mode. 

252
Mach4 General Discussion / Re: Can you use Inputs with Macro B Programming.
« on: November 21, 2017, 01:12:47 PM »
Same build number for both Hobby and Industrial? 

253
Mach4 General Discussion / Re: mc.mcCntlGcodeExecuteWait problems
« on: November 21, 2017, 01:10:08 PM »
I explain why the GUI occurs on this post:  http://www.machsupport.com/forum/index.php/topic,36013.msg246649.html#msg246649

What you have told the control to do is execute "G91 G31 Z-5 F1000" and wait until it is done.  And that is exactly what it is doing.  :) 

mc.mcCntlGcodeExecuteWait() really shouldn't be used in a button script.  Most of the time, what you want is the plain old mc.mcCntlGcodeExecute() call with multiple lines passed to it.  If you find yourself REALLY actually needing to wait on a task, it is better to start the task with a buttons script and "wait" on it to finish in the PLC script.  This involves using what is called (in the programming world) a state machine.  Typically it is implemented with a global variable that is defined in the screen load script.  Call it "Zprobe" or something and set it to zero

Add this to the screen load script:
Code: [Select]
Zprobe = 0 -- the initial state of the state machine. 0 == not running.

The button script would contain just a small bit of code to start the action:

Code: [Select]
if (Zprobe == 0) then -- Only start the task is it isn't already running.
  Zprobe = 1 -- 1 == start the Z probe.
end

In the PLC scrip, you "watch" Zprobe and act on it accordingly:

Code: [Select]
controlState = mc.mcCntlGetState(inst) -- what state is the control in?

if ((Zprobe == 1) and (controlState == mc.MC_STATE_IDLE)) then
  mc.mcCntlGcodeExecute(inst, "G91 G31 Z-5 F1000") -- start the Z probe.  Notice that we don't use the Wait version of this function
  --Wait on the machine to NOT be idle.  This won't take long at all.  But we need to make sure that the control has entered the running state.
  while (controlState == mc.MC_STATE_IDLE) do
    controlState = mc.mcCntlGetState(inst)
  end
  Zprobe = 2 -- change the state. 2 == Z probe running.
elseif ((Zprobe == 2) and (controlState == mc.MC_STATE_IDLE)) then
  -- the task is done.  Record the Z probe pos, if needed, and retract the spindle to
  local zMachineProbePos = mc.mcAxisGetProbePos(inst, mc.Z_AXIS, 1);  -- Do something with it?  I dunno...  :)
  mc.mcCntlGcodeExecute(inst, "G53 G00 Z0") -- Raise Z to machine pos Z0.  Notice that we don't use the Wait version of this function either.
  --Wait on the machine to NOT be idle.  This won't take long at all.  But we need to make sure that the control has entered the running state.
  while (controlState == mc.MC_STATE_IDLE) do
    controlState = mc.mcCntlGetState(inst)
  end
  Zprobe = 3 -- change the state. 3 == Z retracting.
elseif ((Zprobe == 2) and (controlState == mc.MC_STATE_IDLE)) then
  -- everything is done.  Simply change the state of your state machine.
  Zprobe = 0 -- change the state. 0 == not running.
end

In this example, all the button does is set a variable.  That is extremely fast and will not "lock" the GUI.  Then, the PLC script watches that variable every time it is run and also does things that don't take a long time to do.  The tasks are simply "handed off" to the interpreter.

The reason why the GUI locks up on long running tasks is because of the way the Windows Operating System handles the application's event loop.  In the C/C++ programming world, we usually get around this by using multiple threads of execution.  And the button press event would "launch a thread" to handle the event.  But LUA is not multi-threaded, so we just can't do it.  LUA has something like threads, called coroutines, which can be used.  But coroutines are not preemptive.  It is more of a cooperative model and thus harder to use.  To me, implementing a state machine in the PLC script is the far easier and more logical/understandable method. 

Steve

254
Mach4 General Discussion / Re: m3 gets special treatment?
« on: November 21, 2017, 12:17:24 PM »
The voltage would be from the device that drives the spindle, most likely a plugin.  All Mach does is drive a number (whatever S or screen controls say).  The RPM of the spindle is what Mach is concerned with.  It really doesn't care how that is driven.  Could be a voltage, or air pressure, or hydraulic, etc... 

In the case of a motor driven spindle, there may (or may not) be some gear ratio involved.  This is defined on the spindles tab in the configurations dialog.  Hence we have the notion of the commanded spindle RPM and the notion of the motor RPM that is required to produce the commanded spindle RPM.  Ultimately, the motor RPM is what is needed to be controlled.  Devices that control spindles (typically from a plugin) have access to all of this information and can use it as it needs to.  Typically, it is a pretty simple calculation.

Whenever the commanded RPM is changed (by S word or screen/control panel), the plugin will receive a message telling it that the spindle has changed.  The spindlespeed.mcs script is also called at this time.  Anyway, the commanded RPM is given to both the spindlespeed.msc script and the plugin.

As an example, say the spindle motor is controlled by an analog voltage from 0 to 10v and that there are two spindle ranges defined.  Range 1 is 0 to 2000 RPM and range 2 is 0 to 5000 RPM.  To start with, say range 1 is selected and a spindle RPM of 1000 is commanded.  The plugin would then get a spindle changed message with 1000 as the rpm parameter and do:

1. RPM 1000 is specified
2. Determine which range is selected (1)
2. Determine the maximum RPM of the selected range (2000)

In this case, an output voltage of 0v would be 0 RPM and an output of 10v would be 2000 RPM as defined by the spindle range 1.

3. Determine the linear ratio of volts to RPM (1000/2000 == .5)
4. Apply the ratio to the maximum voltage of 10 (10 * .5 == 5v)
5. Output 5v to the VFD.

Notice that step three applies a LINEAR ratio.  And that handles 99% of the VFDs out there.  But what if 5v doesn't actually run the spindle at 1000 RPM?  Well, that is when you need to provide some sort of spindle RPM feedback.  And then the plugin also needs to be able to apply that feedback.  Not all plugins will operate the same.  For instance, the Galil plugin offers two types of spindle control.  1) Spindle without feedback and 2) spindle with encoder feedback.  If using the first method, it uses that linear scaling of voltage that I described above.  Basically, you get whatever RPM 5v produced no matter what.  If using the second method with feedback, the Galil plugin will offset the voltage by whatever amount if required to achieve the desired commanded RPM. 

To summarize, and to answer your question directly, the plugin that controls the spindle "reads" RPM and range information from Mach and its' job is to make that happen. 

Steve


 

255
Mach4 General Discussion / Re: Can you use Inputs with Macro B Programming.
« on: November 21, 2017, 11:24:38 AM »
Yes, you can use a Hobby screen set with an Industrial license.  Just not the other way around. 

Steve

256
Mach4 General Discussion / Re: Can you use Inputs with Macro B Programming.
« on: November 21, 2017, 01:46:43 AM »
Well...  It is something that is more for industrial types of environments.  And it wasn't in Mach3.  So they sales dept. decided it was to be an industrial feature.  I'm not sure if it can be "added on" with another license or not.  I'll check. 

Steve

257
Mach4 General Discussion / Re: Can you use Inputs with Macro B Programming.
« on: November 20, 2017, 06:55:03 PM »
That looks like it might just do the trick.  :)

Ok, I read your dad's post.

When a script is run from a screen control or G code via mcGcodeExecute/Wait(), it will lock the GUI for the duration of the script.  Why?  Because the button click event is the action that causes the script to run.  And it needs to complete.  The application event loop only processes one event at a time.  Screen updates are also events. 

Say you are the application event loop and I am the user of the machine control.  I'm not telling you to do anything at the moment, so you are spending your time running around the screen and updating DROs and such.  But all of a sudden, I press a button that basically says "Cbyrdtopper, go do this script task".  So you go running off to do the script.  So who is updating the DROs now?  Nobody. 

So what mechanism(s) can we use to make this better? 

1) Use the PLC script.  Most buttons scripts should be short and sweet without loops or calls to code that has loops in it.  If a long running task is needed it is better to just set a variable to initiate the action in the button script.  Then a state machine (that watches that variable) can be implemented to process the task in the PLC script. 

2) Hand the action off to the interpreter.  An example of this is the MDI.  You type some G code in and hit cycle start.  The cycle start button just starts the interpreter and comes back immediately.  So the GUI is functional and screen updates happen.  But the state of the machine has changed from idle to MDIrunning.  So you can now wait on the state to transistion back to idle.  The other use of the interpreter is to let it do the complete action (via Macro B), as you are discovering. 

Otherwise, you will need to get into advance LUA programming and use coroutines.  That isn't a road that is easily traveled.  :(




258
Mach4 General Discussion / Re: Can you use Inputs with Macro B Programming.
« on: November 20, 2017, 06:07:01 PM »
Yes. 

Steve

259
Mach4 General Discussion / Re: Can you use Inputs with Macro B Programming.
« on: November 20, 2017, 05:56:42 PM »
I can't find your dad's post.  :(

There are no #vars for DROs.  However, DROs can read/write any #var you choose.  Obviously, you don't want to step on #vars that do something important, so keep that in mind.  You accomplish this by using the DRO's Parameter property.  Enter 500 for #500, etc...  The DRO would then display whatever is in #500 and when you edit it, it would change the value of #500.

You would typically use a #var if you also want to make that information available to G code.  If you don't need that, then using a register as the backing store for the DRO would be better. 

Steve

260
Mach4 General Discussion / Re: m3 gets special treatment?
« on: November 20, 2017, 05:31:40 PM »
That spindle speed script gets called whenever there is a S word in G code or when the spindle is changed via a screen or panel control.  I believe it will do what you want.  It was originally conceived to allow external spindle controls (not on the motion device) like MODBUS work well. 

Steve