Hello Guest it is October 10, 2026, 01:09:51 PM

Recent Posts

Pages: « 1 2 3 4 5 6 7 8 9 10 »
71
General Mach Discussion / Re: Diy CNC router build
« Last post by coeddie11 on September 15, 2026, 10:16:21 PM »
Since the error is a consistent 2 mm per run and occurs with the cutter lifted, I’d first check your steps-per-unit calibration and whether Mach3 is actually commanding the expected distance, then verify the DM542 microstep settings match the software before chasing lost steps.
72
MachPro General Discussion / Re: MachPro upgrade questions
« Last post by joeaverage on September 15, 2026, 03:11:38 PM »
Hi Paul,
thanks for your extensive reply.

I get a general sense as to how MachPro handles signals, but my programming skills are only fair and my understanding of your terminology is poor.
I do rather believe however that MachPro and Mach4 have a similarity.

In Mach4, for which I am familiar each screen set has a ScreenLoad script, and in that script there is a Lua table called SigLib{...........}. Given that the ScreenLoad script
is part of the screen set, and most operators choose to use say wx4.set or wx6.set as a basis for their own personalised copy, and thus survive Mach build updates.

This is the SigLib table in my current Mach4 installation:
Code: [Select]
---------------------------------------------------------------
-- Signal Library
---------------------------------------------------------------
SigLib = {
[mc.OSIG_MACHINE_ENABLED] = function (state)
    machEnabled = state;
    ButtonEnable()
end,

[mc.ISIG_INPUT0] = function (state)
   
end,

[mc.ISIG_INPUT1] = function (state) -- this is an example for a condition in the signal table.
   -- if (state == 1) then   
--        CycleStart()
--    --else
--        --mc.mcCntlFeedHold (0)
--    end

end,

[mc.OSIG_JOG_CONT] = function (state)
    if( state == 1) then
       scr.SetProperty('labJogMode', 'Label', 'Continuous');
       scr.SetProperty('txtJogInc', 'Bg Color', '#C0C0C0');--Light Grey
       scr.SetProperty('txtJogInc', 'Fg Color', '#808080');--Dark Grey
    end
end,

[mc.OSIG_JOG_INC] = function (state)
    if( state == 1) then
        scr.SetProperty('labJogMode', 'Label', 'Incremental');
        scr.SetProperty('txtJogInc', 'Bg Color', '#FFFFFF');--White   
        scr.SetProperty('txtJogInc', 'Fg Color', '#000000');--Black
   end
end,

[mc.OSIG_JOG_MPG] = function (state)
    if( state == 1) then
        scr.SetProperty('labJogMode', 'Label', '');
        scr.SetProperty('txtJogInc', 'Bg Color', '#C0C0C0');--Light Grey
        scr.SetProperty('txtJogInc', 'Fg Color', '#808080');--Dark Grey
        --add the bits to grey jog buttons becasue buttons can't be MPGs
    end
end,
[mc.ISIG_INPUT20] = function(state) --X servo alarm port1 pin10
if(state==1)then
mc.mcCntlEStop(inst)
local handle=mc.mcRegGetHandle(inst,"iRegs0/XAlarm")
mc.mcRegSetValue(handle,1)
else
local handle=mc.mcRegGetHandle(inst,"iRegs0/XAlarm")
mc.mcRegSetValue(handle,0)
end
end,
[mc.ISIG_INPUT21] = function(state) --Y servo alarm port1 pin11
if(state==1)then
mc.mcCntlEStop(inst)
local handle=mc.mcRegGetHandle(inst,"iRegs0/YAlarm")
mc.mcRegSetValue(handle,1)
else
local handle=mc.mcRegGetHandle(inst,"iRegs0/YAlarm")
mc.mcRegSetValue(handle,0)
end
end,
[mc.ISIG_INPUT22] = function(state) --Z servo alarm port1 pin12
if(state==1)then
mc.mcCntlEStop(inst)
local handle=mc.mcRegGetHandle(inst,"iRegs0/ZAlarm")
mc.mcRegSetValue(handle,1)
else
local handle=mc.mcRegGetHandle(inst,"iRegs0/ZAlarm")
mc.mcRegSetValue(handle,0)
end
end,
[mc.ISIG_INPUT23] = function(state) --A servo alarm port1 pin13
if(state==1)then
mc.mcCntlEStop(inst)
local handle=mc.mcRegGetHandle(inst,"iRegs0/AAlarm")
mc.mcRegSetValue(handle,1)
else
local handle=mc.mcRegGetHandle(inst,"iRegs0/AAlarm")
mc.mcRegSetValue(handle,0)
end
end,
[mc.ISIG_INPUT24] = function(state) --B servo alarm port1 pin15
if(state==1)then
mc.mcCntlEStop(inst)
local handle=mc.mcRegGetHandle(inst,"iRegs0/BAlarm")
mc.mcRegSetValue(handle,1)
else
local handle=mc.mcRegGetHandle(inst,"iRegs0/BAlarm")
mc.mcRegSetValue(handle,0)
end
end,
[mc.ISIG_INPUT29] = function(state) --C servo alarm port2 pin2
if(state==1)then
mc.mcCntlEStop(inst)
local handle=mc.mcRegGetHandle(inst,"iRegs0/CAlarm")
mc.mcRegSetValue(handle,1)
else
local handle=mc.mcRegGetHandle(inst,"iRegs0/CAlarm")
mc.mcRegSetValue(handle,0)
end
end,

[mc.ISIG_INPUT25] = function(state) --AXIS1 port3 pin6
if(state==1)then
local handle=mc.mcRegGetHandle(inst,"iRegs0/AXIS1")
mc.mcRegSetValue(handle,0)
else
local handle=mc.mcRegGetHandle(inst,"iRegs0/AXIS1")
mc.mcRegSetValue(handle,1)
end
ChangeJogAxis()
end,
[mc.ISIG_INPUT26] = function(state) --AXIS2 port3 pin7
if(state==1)then
local handle=mc.mcRegGetHandle(inst,"iRegs0/AXIS2")
mc.mcRegSetValue(handle,0)
else
local handle=mc.mcRegGetHandle(inst,"iRegs0/AXIS2")
mc.mcRegSetValue(handle,1)
end
ChangeJogAxis()
end,
[mc.ISIG_INPUT27] = function(state) --AXIS3  port3 pin8
if(state==1)then
local handle=mc.mcRegGetHandle(inst,"iRegs0/AXIS3")
mc.mcRegSetValue(handle,0)
else
local handle=mc.mcRegGetHandle(inst,"iRegs0/AXIS3")
mc.mcRegSetValue(handle,1)
end
ChangeJogAxis()
end,

[mc.ISIG_INPUT28] = function(state) --FEEDHOLD port3 pin9
mc.mcCntlFeedHold(inst)
end,
[mc.ISIG_INPUT30] = function(state) --AXIS3  port3 pin8
if(state==1)then
local handle=mc.mcRegGetHandle(inst,"iRegs0/Velocity1")
mc.mcRegSetValue(handle,1)
else
local handle=mc.mcRegGetHandle(inst,"iRegs0/Velocity1")
mc.mcRegSetValue(handle,0)
end
ChangeJogAxis()
end,
[mc.ISIG_INPUT31] = function(state) --AXIS3  port3 pin8
if(state==1)then
local handle=mc.mcRegGetHandle(inst,"iRegs0/Velocity2")
mc.mcRegSetValue(handle,0)
else
local handle=mc.mcRegGetHandle(inst,"iRegs0/Velocity2")
mc.mcRegSetValue(handle,1)
end
ChangeJogAxis()
end,
[mc.ISIG_INPUT1]=function(state)

if(state==1)then

local handle=mc.mcRegGetHandle(inst,"iRegs0/Trial")
local LEDState=mc.mcRegGetValue(inst,handle)
wx.wxMessageBox("LED State=="..tostring(LEDState))
if(LEDState==1)then
wx.wxMessageBox("here"..tostring(LEDState))
local handle=mc.mcRegGetHandle(inst,"iRegs0/Trial")
mc.mcRegSetValue(handle,0)
else
local handle=mc.mcRegGetHandle(inst,"iRegs0/Trial")
mc.mcRegSetValue(handle,1)
end
end
end,

}

Several of the signals are generic and came fro the donor screen set, wx6.set in this case, but quite a number more are signal entries specific to my machine and I coded them.
I think you are familiar with the general idea, whenever Mach detects a signal change, of any description , from any source,  the SignalScript runs, wherein it interrogates the
SigLib table, and if it encounters an entry for that signal identity it executes the function in that table entry. My understanding is that MachPro is similar.

Where MachPro and Mach4 differ is that the SigLib table is immediately readily available to the user to add signal entries or change functionalities. Because the SigLib table is in the
ScreenLoad script it is in effect custom to the users machine.

As you can see from the code I have entries for the servo axis alarms, with each latching data into a register, and enacting an Estop. Easy.
Other signals are from my wired pendant. The SigLib entries capture those signal events and invoke functions also within the ScreenLoad script. This is a method I am very familiar with,
it is both simple and yet immensly flexible and powerful.

Why did you deem in necessary to do away with it?

Craig
73
Pendants / Re: WHB Pendant
« Last post by cd_edwards on September 15, 2026, 01:36:08 PM »
yes. WHB06 pendant. I know it's not MachPro's, but they definitely look similar enough. Anyways, allowing a checkbox or radiobutton to toggle this as a default would be amazingly appreciated. I don't know how many bits I've driven down into my spoilboard or fixtures if I forget to toggle this from the controller. There must be a way todo this in software.
74
Pendants / Re: WHB Pendant
« Last post by paul.stephens on September 15, 2026, 12:53:41 PM »
I'll report this and push to get it changed. Just want to verify for clarities sake, it is the XHCmpg plugin you're using?
75
MachPro General Discussion / Re: MachPro upgrade questions
« Last post by paul.stephens on September 15, 2026, 12:08:41 PM »
Hi,

I am not 100% confident in what you mean. We do have a signal library, but I don't believe this implementation was in Mach4. It was added with the CommonGUIModule inside of MachPro.

The main implementation is in CommonGUIModule:

SIG_LIBRARY_INST[_inst]: common, per-Mach-instance handlers.
MACHINE_TYPE_SIG_LIBRARY_INST[_inst]: machine-specific handlers, such as mill, plasma, grinder, or height-control behavior.
SCREEN_SIG_LIBRARY_INST[_inst]: screen-specific handlers for multi-instance screens.
SCREEN_SIG_LIBRARY: legacy/global screen handlers used by older screen versions.
Each table is keyed by a Mach signal ID. The value is a Lua callback:

Code: [Select]
SIG_LIBRARY_INST[_inst][signalId] = function(sig_state)
    -- Handle the signal transition
end

When Mach reports a signal transition, CommonSignalScript() converts the state to a Boolean and calls _CommonSignalScript(). That function dispatches the event through the layers above, then runs the generic SignalScript hooks:

CommonSignalScript
  • SignalScript callback
  • SIG_LIBRARY_INST[instance][signal]
  • MACHINE_TYPE_SIG_LIBRARY_INST[instance][signal]
  • SCREEN_SIG_LIBRARY_INST[instance][signal]
  • SCREEN_SIG_LIBRARY[signal]
  • SignalScript hooks

The common table is rebuilt by UpdateSignalLibraryArray() in CommonGUIModule. It registers handlers for:

  • Axis positive and negative limit status signals
  • Axis homed signals
  • Toolpath mouse down/up
  • Motion-inhibit interlock input
  • Machine enabled/disabled state
  • Spindle-brake output lookup
It also stores the resolved spindle-brake signal ID in SIG_LIBRARY_INST[_inst].SpindleBrakeOutput and SIGNAL_LIB_ARRAY.SpindleBrakeOutput.

The rebuild entry point is CommonUpdateSignalLibraryArray() in CommonGUIModule. It:

  • Calls the active screen/module’s UpdateSignalLibraryArray(), if present.
  • Reads auxiliary-output button mappings from the profile.
  • Enables or disables the corresponding auxiliary screen buttons.
  • Runs the UpdateSignalLibrary hooks, allowing machine-specific modules to register more callbacks.
The screen-specific tables are populated separately. For example:

  • V2 screens build SCREEN_SIG_LIBRARY_INST[_inst] in CommonScreenV02.
  • Mill and plasma modules populate MACHINE_TYPE_SIG_LIBRARY_INST for tool-changer signals in MillGUIModule.lua and PlasmaGUIModule.
  • Height controllers add their own signal handlers in HeightControllers

This Lua “library” sits above the actual Mach signal subsystem. The actual signal objects are handled by the C++/Mach API layer using functions such as mcSignalGetHandle, mcSignalGetNextHandle, mcSignalGetInfo, mcSignalGetState, and mcSignalMap. The API documentation explicitly distinguishes signals from physical I/O: signals can be mapped to I/O, but the signal abstraction does not depend on a particular I/O device.


TableScopePurpose
SIG_LIBRARY_INSTPer Mach instanceCommon machine behavior
MACHINE_TYPE_SIG_LIBRARY_INST  Per Mach instanceMachine-specific behavior, such as mill, plasma, grinder, or height control
SCREEN_SIG_LIBRARY_INSTPer Mach instanceScreen-specific behavior
SCREEN_SIG_LIBRARYGlobal/legacyOlder single-instance screen handlers

Each table uses a signal ID as its key and a Lua function as its value:

Code: [Select]
SIG_LIBRARY_INST[instanceIndex][signalId] = function(signalState)
    -- React to the signal transition
end
signalState is normalized to a Boolean before dispatch.

Dispatch sequence
When Mach detects a signal transition, the following path is used:

  • CommonSignalScript()
    • _CommonSignalScript()
      • module SignalScript()
      • SIG_LIBRARY_INST[instance][signal]
      • MACHINE_TYPE_SIG_LIBRARY_INST[instance][signal]
      • SCREEN_SIG_LIBRARY_INST[instance][signal]
      • SCREEN_SIG_LIBRARY[signal]
      • SignalScript hooks

The dispatcher does not stop after the first matching table. A signal can therefore have common, machine-specific, and screen-specific behavior.

Building the common library
CommonGUIModule.UpdateSignalLibraryArray() registers the standard handlers, including:

  • Positive and negative axis-limit status signals
  • Axis-homed signals
  • Toolpath mouse events
  • Motion-inhibit interlock input
  • Machine enable and disable signals
  • Spindle-brake output lookup

The wrapper, CommonGUIModule.CommonUpdateSignalLibraryArray(), also:
  • Calls a machine module’s UpdateSignalLibraryArray(), if implemented
  • Reads auxiliary output-button assignments from the Mach profile
  • Updates auxiliary-button enabled states
  • Runs the UpdateSignalLibrary hooks

nstance indexing
The tables are indexed by the untagged instance index:
Code: [Select]
local instanceIndex = w.GetUTI(inst)
Handlers registered for one instance should remain associated with that instance. This matters in multi-instance configurations because the same signal number may have different mappings or machine behavior in different instances.

Registration example
A machine module can register a handler for an OEM-mapped signal like this:

Code: [Select]
local signalInfo = w.GetOEMParamIOSigObject(
    "TC_ToolReleaseButtonInput",
    instanceIndex
)

if signalInfo ~= nil and signalInfo["type"] == "Input Signal" then
    MACHINE_TYPE_SIG_LIBRARY_INST[instanceIndex][signalInfo["sigid"]] =
        function(signalState)
            m.ToolReleaseButtonInputChanged(signalState, 1)
        end
end

The mill and plasma implementations follow this pattern in MillGUIModule and PlasmaGUIModule.

Use Case: Tool Release Button
A useful example is a tool changer with a physical tool-release button.

Requirement
When the operator presses or releases the tool-release input:

  • The machine-specific tool-changer logic should run.
  • The handler should use the signal mapping configured for the current instance.
  • Multiple spindles or indexed tool-release inputs should be supported.

Registration
During signal-library setup, the machine module resolves the OEM parameter to its actual signal ID and registers a callback:

Code: [Select]
local signalInfo = w.GetOEMParamIOSigObject(
    "TC_ToolReleaseButtonInput",
    instanceIndex
)

if signalInfo ~= nil and signalInfo["type"] == "Input Signal" then
    MACHINE_TYPE_SIG_LIBRARY_INST[instanceIndex][signalInfo["sigid"]] =
        function(signalState)
            m.ToolReleaseButtonInputChanged(signalState, 1)
        end
end

For a second spindle, the module can resolve a parameter such as:

Code: [Select]
TC_ToolReleaseButtonInput2
and register a callback that passes spindle index 2.

Runtime behavior

When the physical input changes:

Mach updates the underlying signal.
Mach invokes CommonSignalScript.
The signal ID is used to look up the callback in MACHINE_TYPE_SIG_LIBRARY_INST.
The callback invokes:
  • Mach updates the underlying signal.
  • Mach invokes CommonSignalScript.
  • The signal ID is used to look up the callback in MACHINE_TYPE_SIG_LIBRARY_INST.
[li]The callback invokes:
[/li][/list]
Code: [Select]
[code]m.ToolReleaseButtonInputChanged(signalState, spindleIndex)[/code]
    [/li]
  • The tool-changer module performs the configured action.

This keeps the machine module independent of the physical I/O device. The module only needs to know the logical OEM parameter and the resolved Mach signal ID.

Another Use Case: Machine Enable State
The common library registers mc.OSIG_MACHINE_ENABLED for every instance. Its callback updates the cached enable state and starts the appropriate enable or disable sequence.

The handler also performs special startup protection because Mach can emit an initial disabled state while signal synchronization is taking place. That logic is in CommonGUIModule.lua.

This is a good example of behavior that belongs in SIG_LIBRARY_INST rather than a machine-specific table because every screen and machine type needs consistent machine-enable behavior.

When to use each layer:

Use SIG_LIBRARY_INST when:
  • The behavior is common to all machine types.
  • It is instance-specific.
  • It concerns limits, homing, machine enable, or core GUI behavior.

Use MACHINE_TYPE_SIG_LIBRARY_INST when:
  • The behavior belongs to a machine family.
  • The signal is related to a tool changer, plasma THC, grinder, or similar subsystem.
  • The same machine module may register different signals per instance.

Use SCREEN_SIG_LIBRARY_INST[ when:
  • The callback updates controls belonging to a particular screen.
  • The screen supports multiple Mach instances.

Use SCREEN_SIG_LIBRARY when:
  • The behavior is legacy/global screen behavior.
  • The callback is intentionally not instance-specific.

Use SCREEN_SIG_LIBRARY only for legacy/global screen behavior where the callback is intentionally not instance-specific.

Relationship to the Lua Signal Library
The Lua signal library described earlier operates above this lower-level signal/I/O layer:
Physical hardware or simulated device
  • HMCIO I/O handle
  • mcSignalMap()
  • HMCSIG logical signal
  • CommonSignalScript()
  • Lua signal-library callback

For example, a tool-release button may be physically connected to an input device. The device is mapped to a logical signal. The GUI layer then registers a Lua callback keyed by that signal ID:
Code: [Select]
MACHINE_TYPE_SIG_LIBRARY_INST[instanceIndex][signalId] =
    function(signalState)
        m.ToolReleaseButtonInputChanged(signalState, spindleIndex)
    end
The callback does not need to know whether the signal came from:
  • A simulator
  • A motion controller
  • An Ethernet I/O device
  • A PCI or USB device
  • Another plugin

I hope this info dump can help solve your questions?

Something else that will be beneficial if you wish to do any custom development for MachPro:
https://support.machmotion.com/docs/current/dir_f2541a3b18981391fa76fac5599e978a.html

This is some of our code documentation. 

I would highly recommend using the wrapper modules functions instead of the core mach API's as we have built in error handling for most of these functions. You should be able to invoke the wrapper module from anywhere with "w."
76
MachPro General Discussion / Re: MachPro upgrade questions
« Last post by joeaverage on September 14, 2026, 04:07:20 PM »
Hi Paul,
I was unaware of the extensive documentation yo have generated for MachPro, and am very pleased to see it.

I have followed the suggestions regarding accessing the screen load script. I'm not completely sure what I'm doing as yet, but it is a step in the right direction.

My question is 'where is the SignalLibrary table?.

In Mach4 if I wanted for instance to monitor an input  to the machine from an operator say, I would add an entry to the SignalLibrary table, and in that entry I would
call the functionality I wanted enacted on receipt of that signal.  In my current Mach4 installation I have about twenty such signal entries.Is it possible for me to continue
with that same idea? I presume that as MachPro is built on Mach4 that the same principle applies?

Craig
77
MachPro General Discussion / Re: Screen Edit not saving.
« Last post by joeaverage on September 14, 2026, 03:49:00 PM »
Hi,
after some more experimenting I have found, as you suggested, that if the A and C axes are not enabled then the corresponding DROs disappear whether I deliberately
drag them into the viewable area or not.

The bottom line is that the Axis Position Group IS NOT EDITABLE........and that is faulty.

You've taken away one of the greatest strengths of Mach4.

Craig
78
MachPro General Discussion / Re: Screen Edit not saving.
« Last post by joeaverage on September 14, 2026, 03:01:40 PM »
Hi,
discovered another failure of the same type.

I have a button included in the ControlGroup of my current installation. It is to drill location pins in PCBs which I regularly make.

Just a few moments ago I tried to increase the size of the ControlGroup (in MachPro) to accommodate and instantiate a new button. Saved the screen and exited, but
when the screen is redrawn my screen edits are gone.

One of the greatest strengths of Mach4 was that you could place a button/LED/Control DRO etc wherever you pleased and attach whatever code you pleased to achieve the
functionality you wanted. MachPro doe not permit this. It is a fault that needs be fixed.

Craig
79
MachPro General Discussion / Re: Screen Edit not saving.
« Last post by joeaverage on September 14, 2026, 02:40:47 PM »
Hi Paul,
I'me somewhat skeptical of your explanation.

If for instance the AxisPosition panel is hard coded then why is it that I can kick the AxisTextLabel out of the viewing area, and that is saved accross future MachPro sessions.
Also I have dragged the A (U)  and C(W) DROs, the AxisLoad indicator and the DistanceToGo DRO into the viewable are and they have all been saved.
Were they hard code then they too would be overwritten, but they are not.

When however  I drag a ZeroAxis button into the viewable are it is not saved?

In Mach4, say either wx4.set and wx6.set there was a ZeroAxis button alongside each DRO. It does not seem to much to ask that I be able to replicate that functionality,
and lo.......there is the button, already instantiated, coded and ready to go just by dragging it into the viewable pane, and yet it does not stick?

Actually I very much like the idea of all the different buttons/controls/DROs/LEDs/LabelTexts all be instantiated, ready to be included in a customers screen set, all you have to do
is drag them into the viewable area, but it would appear that some will not save. That means that the screen editor is broken, you could certainly do as I wish in Mach4, but now it does not work.

Craig
80
MachPro General Discussion / Re: MachPro upgrade questions
« Last post by joeaverage on September 14, 2026, 02:27:40 PM »
Hi Paul,
thanks for your reply. I need to work through it and digest it all.
Some of them I have discovered already.

Craig
Pages: « 1 2 3 4 5 6 7 8 9 10 »