Hello Guest it is November 05, 2025, 07:43:39 AM

Author Topic: Mach4 Signal Tower LUA script  (Read 1317 times)

0 Members and 1 Guest are viewing this topic.

Mach4 Signal Tower LUA script
« on: October 20, 2025, 08:25:39 AM »
Hi

I have been struggling with LUA signal tower script for a while and decided to ask some help. I do not have much experience with LUA (in the context of Mach4) and I´m continuously trying to figure some things out.

About the script. At first I made the logic in PMC, then converted to LUA but couldn´t get it to work. The script seemed very long and complicated one. Then I was suggested to pure LUA approach which I have been working with, but so far without any promising results. I have also used AI input (Gemini, GPT 5), but it seems they are a bit suspicious about giving some appropriate results.

Can anyone suggest some decent LUA script for signal tower logic? Or some hint how to build up the correct one?

I have following setup for my lathe:
- Mach4 version 4.2.0.5036
- CSMIO/IP-S controller (plugin ver 3.501)

Machine conditions (may change):
Blinking Red - Estop condition
Static Yellow - Hold
Blinking Yellow - Tool change
Static Green - Gcode finished
Blinking Green - Gcode running

Mach4 outputs:
Output 0 - green light
Output 1 - yellow light
Output 2 - red light
Re: Mach4 Signal Tower LUA script
« Reply #1 on: October 21, 2025, 07:31:10 PM »
Hi,
do need any scripting? Aren't those lights displayed with the same logic displayed on the screen at the moment?

Would it be sufficient just to have a mach output reflect what those LEDs are doing already?

Craig
'I enjoy sex at 73.....I live at 71 so its not too far to walk.'
Re: Mach4 Signal Tower LUA script
« Reply #2 on: October 22, 2025, 01:45:51 PM »
Hi

do need any scripting? Aren't those lights displayed with the same logic displayed on the screen at the moment?

Yes and no... In terms of getting the lathe just to work no scripting is needed. Today I connected the tower to Mach4 given outputs (GCode Running - static green, Feed Hold - static yellow) and everything works perfectly.
Even a tool change output can be used. But blinking option is more difficult to implement directly, that´s why I was looking for a LUA scripting. To my knowledge I can´t take directly the blinking function from Mach4´s LEDs as outputs.
Although, for the emergency stop light (blinking red) I use LOGO! controller which programming was a child´s play.

I wish there were several step-by-step LUA programming examples for common and specific tasks in Mach4. It doesn't need to be a ready-made script, but something that can be taken as a good working example.
If someone knows, I would be very grateful. So far I haven´t found any which can be successfully implemented to build up a working customized script.

I would also be grateful if someone can and want to program some scripts in LUA, for an agreed fee. Through TeamViewer. I have simple turret tool change (8 inputs and one output), spindle speed selection (3 mechanical gears) and some button scripts. I think I´d figure it out myself over time, but I´m running out of time and I need to get the lathe ready soon.

henri

Offline Bill_O

*
  •  607 607
Re: Mach4 Signal Tower LUA script
« Reply #3 on: October 23, 2025, 10:05:36 AM »
Henri,
I dont know if this will help but it might.
It is a basic LUA scripting for Mach4 tutorial.
https://www.machsupport.com/forum/index.php?topic=45397.msg289143#msg289143

Bill
Re: Mach4 Signal Tower LUA script
« Reply #4 on: October 30, 2025, 11:57:45 AM »
Weird setup but it works.  It requires some setup... so be prepared. 
We make our PLC handle all the flashing, but I figured out how to let Mach4 handle it all internally. 
This example will make the Yellow Light flash when the code reaches the end and reads M30.  (Adjust as you see fit.)

This requires you to make a register:  Go to Config --> Plugins --> and make a new register called Timer.

This also uses Output 30 as an M30 output.  So you will need to create an m30 macro as well.
Here is the code for it: Create a new macro m30 (save it in Mach4Folder --> Profiles --> YOUR PROFILE --> Macros --> m30.mcs)

function m30()
local inst = mc.mcGetInstance()
local M30Output = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT30)
local Coolant = mc.mcSignalGetHandle(inst, mc.OSIG_COOLANTON)
mc.mcSpindleSetDirection(inst, 0)
mc.mcSignalSetState(M30Output, 1)
mc.mcSignalSetState(Coolant, 0)
mc.mcCntlMdiExecute(inst, "G40")
end --m30()

if (mc.mcInEditor() == 1) then
   m30()
end

Next you will need a way to turn of the m30 output (output 30).  I handle this by pressing the Reset button or by hitting cycle start. 
Change the script on your reset button on your screen to this:  Reset()
Next in the screen load script make a new Reset Function.  Here is the code for it:  Add it anywhere after the SigLib()

---------------------------------------------------------------
--Reset Function
function Reset()
local inst = mc.mcGetInstance()
local M30Output = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT30)
local M30Flasher = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1)

mc.mcSignalSetState(M30Output, 0)
mc.mcSignalSetState(M30Flasher, 0)

mc.mcCntlReset(inst)
mc.mcSpindleSetDirection(inst, 0)
mc.mcCntlSetLastError(inst, '')
end--Reset()
---------------------------------------------------------------

Next replace your CycleStart() Function with this

---------------------------------------------------------------
-- Cycle Start() function.
---------------------------------------------------------------
function CycleStart()   
   local rc
    local tab, rc = scr.GetProperty("MainTabs", "Current Tab")
    local tabG_Mdione, rc = scr.GetProperty("nbGCodeMDI1", "Current Tab")
   local tabG_Mditwo, rc = scr.GetProperty("nbGCodeMDI2", "Current Tab")
   local state = mc.mcCntlGetState(inst)
   local M30Output = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT30)
   local M30Flasher = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1)
   
   if (state == mc.MC_STATE_MRUN_MACROH) then
      mc.mcCntlCycleStart(inst)
      mc.mcSignalSetState(M30Output, 0)
      mc.mcSignalSetState(M30Flasher, 0)
   elseif ((tonumber(tab) == 0 and tonumber(tabG_Mdione) == 1)) then 
      scr.ExecMdi('mdi1')
      mc.mcSignalSetState(M30Output, 0)
      mc.mcSignalSetState(M30Flasher, 0)
   elseif ((tonumber(tab) == 5 and tonumber(tabG_Mditwo) == 1)) then 
      scr.ExecMdi('mdi2')
      mc.mcSignalSetState(M30Output, 0)
      mc.mcSignalSetState(M30Flasher, 0)
   else
      mc.mcCntlCycleStart(inst)
      mc.mcSignalSetState(M30Output, 0)
      mc.mcSignalSetState(M30Flasher, 0)
   end
end--CycleStart()
-------------------------------------------------------

Finally, add this to the end of your PLC Script (But above the section that says "this is the last thing we do".

--Custom Scripts
--Blink when m30 is on.
local inst = mc.mcGetInstance()
local M30Output = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT30)
local FlashingLight = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT1)
local M30OutputState = mc.mcSignalGetState(M30Output)
local FlashingLightState = mc.mcSignalGetState(FlashingLight)
if M30OutputState == 1 then
    local TimerReg = mc.mcRegGetHandle(inst,"iRegs0/Timer")
    local TimerVal = mc.mcRegGetValue(TimerReg)
    mc.mcRegSetValue(TimerReg, (TimerVal + 1))
    if TimerVal >= 50 then --Adjust the number for flashing frequency
        if FlashingLightState == 0 then
          mc.mcSignalSetState(FlashingLight, 1)
       else
          mc.mcSignalSetState(FlashingLight, 0)
       end
       mc.mcRegSetValue(TimerReg, 0)
    end--Timer >= Number
end--M30Output == 1
« Last Edit: October 30, 2025, 12:04:52 PM by Cbyrdtopper »
Chad Byrd