Sidebar

Home



Knowledge Base


Guides & Tutorials

Projects

Samples

kb:tutorials:expert:use_expressions_to_command_semaphore_lights

Use Expressions to command semaphore lights

For this multi-part tutorial we will create CNC machine semaphore(signal tower lamp).

We hope that this tutorial will serve as a good example on how to set application goals and requirements as also on how to define the tools and solutions for achieving them, while using powerful tools and flexibility of PlanetCNC motion control system.

How to begin

First we need to clarify and define application requirements.

Semaphore application requirements

  • to use a semaphore with 5 lights.
  • Each light with different color will visually represent dedicated machine state.
  • Combination of two active lights is allowed. This applies when NC program is running and pause is initiated.
  • Additionally, alarm should be activated if, at the beginning or during the program execution, front door of machine enclosure is open(ed) or pressure sensor is activated. Pressure error will be able to initiate alarm state also in Idle state.
  • In case of alarm, system should prevent or stop program execution.
  • Play siren sound to notify CNC operator.
  • Alarm notification is displayed on the main screen and at the status bar.
  • Alarm state needs to be reset. Hardware Reset button will be used.
  • If alarm is not reset and system is shut down, system will notify user to reset any pre-existing alarm at the system startup.

Machine states are:

  • Estop state
  • Idle state
  • Run state
  • Pause state
  • Alarm state

State description:

Estop

Estop state indicates that estop has been activated either using a PC keyboard key, controller estop pin (e-stop button) or Error pin indicating a motor driver fault.

This state will be indicated using active RED LIGHT on the semaphore.

Idle

Idle state indicates that machine is turned ON and connected with PC. Machine in Idle state does not perform any motion.

This state will be indicated using active YELLOW LIGHT on the semaphore.

Run

Run state indicates that CNC machine is executing the NC program.

This state will be indicated using active GREEN LIGHT on the semaphore.

Pause

Pause state indicates that machine is executing NC program, however program pause has been initiated, meaning program execution is on hold.

This state will be indicated using active ORANGE LIGHT in combination with active GREEN LIGHT(Run state) on the semaphore.

Alarm

Alarm state will indicate if CNC machine enclosure doors are open, at the start of program or during the program execution. So, if doors will be opened in any other state than Run, there is no need for an alarm.

This state will be indicated using a BLUE LIGHT on the semaphore. In this state, we will also use siren sound alarm.

What hardware will we use?

So, we need to control 5 lights on the semaphore, and read one enclosure door switch. Meaning we need to occupy 5 digital outputs and 1 digital input of our MK3 controller.

But, digital input and output pins of controller are a precious commodity. It would be better to use these pins for some other purpose.

More economic approach would be the use of ExtInOut board. This board expands the number of inputs and relay outputs used with controller by 8, respectively.


-ExtInOut board relays will control the semaphore lights, while one of the inputs will be used to evaluate CNC front door switch and Alarm reset button:ExtInOut board

-PlanetCNC Mk3 motion controller and EXT interface will be used for communication with external ExtInOut board: Mk3 controller

-Semaphore lights will be simulated with normal LED’s. If a real semaphore device would be used, integration would not be much different.

Programming the application

For a clearer and effective programming, we will use a concept called State Machine. Its functionality is suitable for the type of our application.

Drawing a flowchart will help us with visualization of such state machine and better overview of state definitions and state transition conditions.

Since we need constant and responsive background evaluation of various parameters and control of relay outputs, all our code will be included in the Expr.txt file.

What is a State Machine and how it is used?

If you google State machine, this would be the average result more or less:

“A state machine is a behavior model. It consists of a finite number of states and is therefore also called finite-state machine (FSM). Based on the current state and a given input the machine performs state transitions and produces outputs.”

Sounds exactly what we need for our application doesn’t it? 5 states, which can transition one from another based on the pre-defined conditions.

Each semaphore state has its outputs and inputs. State outputs are semaphore light configurations where specific relay output will be activated. State inputs are conditions that will cause the state transitions.

What is an Expr.txt file and how it is used?

  • Expr.txt is a file which contains functions that are evaluated by PlanetCNC TNG expression evaluator.
  • it can be very practical for PLC type applications where periodical evaluation is necessary or for program events
  • Expr.txt file can contain and use vast array of expression functions, parameters and other commands supported by PlanetCNC TNG
  • Expr.txt file is located in the profile folder of TNG software
  • Profile folder can contain multiple Expr.txt files. Specific Expr file naming convention is available for better distinction. e.g.: Expr_Semaphore
  • If multiple expr files use same function, then function will be called first in first file and only then the with the next file
  • Local variables(e.g. name convention of local variables: red_light, global variables: _red_light ) have scope only within the parent Expr file.
  • Each Expr file contains functions that are marked with symbol #.
  • Each function begins with symbol # and ends with the next # symbol.
  • Each expr file can use built-in functions that are related with program events

Built-in Expr functions:

  • #OnInit → When TNG software is started/initialized, code under this function will be executed.
  • #OnShutdown → On PlanetCNC TNG software shutdown request, code under this function will be executed, then TNG will shutdown.
  • #OnStart → On NC program Start event, code under this function will be executed.
  • #OnEnd → On NC program End event, code under this function will be executed.
  • #OnStop → On NC program Stop event, code under this function will be executed.
  • #OnEStop → On Estop event, code under this function will be executed.
  • #OnJog → On Jogging event, code under this function will be executed.
  • #OnWheel → On handwheel event, code under this function will be executed.
  • #OnCmd → On MDI command event, code under this function will be executed.
  • #Loop → this loop is executed every 83ms, or the value of refresh rate set in settings, under: File/Settings/User Interface/Refresh Rate
  • #Loop5 →this loop is executed every 5s
  • #Loop15 →this loop is executed every 15s
  • #Loop60 →this loop is executed every 60s
  • #Loop300 →this loop is executed every 300s

Diagram of program

At this step of the process we pretty much defined everything needed for semaphore application and we can begin writing the program.

First we will illustrate simple program diagram(flowchart). Diagram is very helpful, because it visually illustrates the program flow(in this case state machine) which we can use as a reference when designing program structure.

Diagram for state machine of our semaphore application:

Each state is able to transition to other state, which was defined earlier in the process. All transitions are conditioned, meaning in order for transition to happen, condition needs to be fulfilled.

So we will now describe each states possible transitions as also transition conditions.


IDLE state

It can transition to:

Run state
State transition condition: Start program

Estop state
State transition condition: Estop activated

Corresponding IDLE state parameter:

We can evaluate Idle state by combining three parameters. Idle state is basically inverted run state, in a sense that no program or any other task is being executed. For this we can use run state parameter !_hw_run. In order that we are 100% sure that system is not executing any remaining commands from the buffer, we also check _hw_buffempty parameter. We also need to be sure that Estop mode is not active with !_hw_estop.

(_hw_buffempty && !_hw_run) && !_hw_estop

RUN state

It can transition to:

Idle state
State transition condition: Stop program

Pause state
State transition condition: Pause program

Estop state
State transition condition: Estop activated

Alarm state
State transition condition: Door Open

Corresponding RUN state parameter:

We can evaluate Run state by combining three parameters. Run state is basically inverted idle state, so we can use idle state parameter !_hw_idle. Since we really want to make sure that system is not in pause state and that Estop mode is not active, we also use !_hw_pause && !_hw_estop.

!_hw_idle && !_hw_pause && !_hw_estop;

PAUSE state

It can transition to:

Run state
State transition condition: Pause released

Idle state
State transition condition: Stop program

Estop state
State transition condition: Estop activated

Alarm state
State transition condition: Open door

Corresponding PAUSE parameter:

We can evaluate Pause state by combining two parameters. Pause state uses its own dedicated parameters _hw_pause , and we also need to be sure Estop mode is not active, _hw_estop.

_hw_pause && !_hw_estop

ALARM state

It can transition to:

Estop state
State transition condition: Estop activated

Idle state
State transition condition: Error reset

Corresponding ALARM parameter:

We can evaluate Alarm state by combining two parameters. Since CNC doors will activate a door switch, that is connected with our ExtInOut boards Input 1, we evaluate Input 1 with parameter _extin1|1. As before, we need to be sure that Estop mode is not active, !_hw_estop.

!_hw_estop && _extin1|1;

ESTOP state

It can transition to:

Idle state
State transition condition: Estop released

Alarm state
State transition condition: Alarm not cleared, Estop released

Corresponding ESTOP parameter: We can evaluate estop state with _hw_estop parameter.


Flowcharts

#OnInit

Below is a flowchart for #OnInit. #OnInit is a built in expression function, which is executed when TNG software is launched/initialized. It only has one iteration. It is perfect for initialization code of our semaphore.

At the beginning we define state decimal values and conditions for Alarm, Estop and Idle states. Only these three states because, when system is powered up, it can only take up states Estop(button pressed), Alarm(alarm before system shutdown was not reset) or Idle(all is OK). So, depending on the conditions met, OnInit will set the state which will be then recognized in the #Loop function.

Snippet of code for flowchart above is following:

#OnInit
state_estop = 0; 
state_idle  = 1; 
state_pause = 2; 
state_run   = 3;  
state_alarm = 4;
from_init = 0;
 
 
cleared_not = !_alarm_cleared;
if(cleared_not,exec(state=state_alarm,from_init=1,msg('INIT: Please Reset Error')));
 
estop = _hw_estop && _hw_idle; 
if(estop, state=state_estop);
 
idle  = (_hw_buffempty && !_hw_run) && !_hw_estop && _alarm_cleared; 
if(idle, state=state_idle);

#Loop

#Loop function’s role is that is constantly checks and recognizes active state of the system.

If we, for the sake of this tutorial say, that this will be #Loop’s first execution and iteration, and since we just launched the TNG system, somebody pressed the Estop button before system shutdown (many CNC machines actually recommend to activate Estop button before system shutdown). So, #OnInit recognized and set as state Estop state.

#Loop then checks for active state and executes corresponding procedure. In our case, Estop state → #StateEstop

Snippet of code for flowchart above is following:

#Loop 
;Every 83ms
if (state == state_estop, exec('#StateEStop'));
if (state == state_idle, exec('#StateIdle'));
if (state == state_run, exec('#StateRun'));
if (state == state_pause, exec('#StatePause'));
if (state == state_alarm, exec('#StateAlarm'));

#StateEstop

At the beginning we have two safety instances. First one checks if state is indeed StateEstop, second one checks if last valid state was not StateEstop. This is important since we execute the #StateEstopInit procedure only at first and initial state change.

#StateEstopInit procedure is where we actually set the new last state and activate corresponding light on the semaphore.

With _state_last = state_estop command we set new last state. _extout1|5 = 1 will activate Red light on our ExtInOut board. All other lights are in this state at 0.

Further we check for any state transition conditions being met. This will be continuously evaluated until Estop button is not released. So if Estop button is released and error has been reset, Idle state conditions are met and we execute procedure #StateEstopEnd and set new state, state_idle. And then we return back to #Loop, where Idle state is recognized and #StateIdle is executed.

Which state transitions conditions need to be checked within each state, is defined in our state machine at the beginning of this tutorial.

Snippet of code for flowchart above is following:

#StateEStop
if (state != state_estop, return(0));
if (_state_last != state_estop, exec('#StateEStopInit'));
 
;Here we check for state transition conditions
 
idle = (_hw_buffempty && !_hw_run) && !_hw_estop; 
if(idle, exec('#StateEStopEnd', state = state_idle, return()));
 
if((!_alarm_cleared && !_hw_estop), exec('#StateEStopEnd', state = state_alarm, return()));
 
#StateEStopInit
_state_last = state_estop;
print('EStop: ',estop);
_extout1|5 = 1;
_extout1|1 = 0;
_extout1|2 = 0;
_extout1|3 = 0;
 
#StateEStopEnd

#StateRun

At the beginning we have two safety instances. First one checks if state is indeed StateRun, second one checks if last valid state was not StateRun. This is important since we execute the #StateRunInit procedure only at first and initial state change.

#StateRunInit procedure is where we actually set the new last state and activate corresponding light on the semaphore.

With _state_last = state_run command we set new last state. _extout1|5 = 2 will activate Green light on our ExtInOut board. All other lights are in this state at 0.

Further we check for any state transition conditions being met. These conditions will be continuously evaluated until either Estop, Pause, Stop buttons are pressed or CNC doors are open.

Let’s say CNC doors are suddenly opened during program run (this is checked using the ExtInOut board’s input 1, _extin1|1). Alarm state condition is met and program will execute procedure #StateRunEnd and set new state, state_alarm. Program returns back to #Loop function, where Alarm state is recognized and #StateAlarm procedure is executed.

Which state transitions conditions need to be checked within each state, is defined in our state machine at the beginning of this tutorial.


Of all states, Alarm state is the most “complex”(not really) and for that more interesting, so again just a quick detailed explanation or alarm state behaviour. I might add that I added additional requirements:

  • Additional evaluation of second and third ExtInOut input (in this case, second input will simulate a pressure sensor, third will be used as a “Error reset” button)
  • “NO Pressure” error state event can be triggered in Run state as also in Idle state (while Door error state event can be triggered only during the Run state). To clarify, Alarm state transition condition can from now on be triggered either by door switch or pressure sensor.
  • While in Alarm state, dedicated light will toggle with approx 1Hz period
  • At Alarm state event, on-screen message will appear, notifying the user of error description (either “Open Door” or “NO Pressure”). Error description message will also be displayed at the status bar.
  • At alarm state event, siren sound will activate and notify the user for better alertness
  • If user will turn off the machine while Alarm state still being active, then with the next machine start-up, Alarm state will still persist with all of its properties(light toggle, program run blockage etc) and user will need to reset it (if the conditions for reset are met). At launch, status bar will notify the user of last Error description before machine was shutdown.
  • User will not be able to start a NC program until Alarm state is cleared (pressure sensor or door switch ok) or previous alarm state has not been reset

Expr.txt file can be found here: Expr.txt

Connection of controller, ExtInOut board, input switches and LED’s of semaphore

In my case, I will use a dedicated keypad for input switch simulation and LED’s for semaphore lights. Note that I did not find all suitable colors for my lights, so some of them will the same color.


So, we have three input switches/buttons, connected at:

Input 1 → Simulates open door switch

Input 2 → Error reset button

Input 3 → Simulates pressure sensor


LED’s for indication of active states will be connected to relays:

Relay 1: IDLE state

Relay 2: RUN state

Relay 3: PAUSE state

Relay 4: ALARM state

Relay 5: ESTOP state


Picture of the demo setup:


So, lets test the Expr.txt semaphore application.

I will add some screenshots that will show the behavior of the Expr. txt.

Import program:

Since no pre-existing error events are present, status bar displays “No error” text.

ExtOut output 1 is activated already at the machine startup, indicating IDLE state:


Start program: We start the program, and ExtOut output 2 is activated:


Pause Event: Pause state is activated via M00 command in NC program:

This activates also ExtOut output 3 next to already active output 2:


Error “Door Open” Event: While in Pause state, I simulate door switch activation which triggers the Door Open alarm state. Siren sound is played trough speakers, program execution is stopped and message is displayed:

ExtOut output 4 starts to toggle:

and status bar displays the error type:


Reset Error before Start program: While in alarm state, I want to start the program again, but, since the error has not been reset, I receive notification message asking me to reset the error, and the number of alarm (1- Door error, 2- Pressure error):

After using alarm reset button, status bar displays no error:

IDLE state is again reinstated:


Error “NO pressure” Event: So, I start the program again, and at one point I simulate pressure sensor, siren sound plays, program execution is stopped and software will display the “NO PRESSURE” message:

Status bar displays the error type:


Shutdown and startup of the system:

This time, I did not reset the alarm, but I just shutdown the machine.

At machine startup, I receive the “INIT: Please Reset Error” message. At this point, machine is still in Alarm state.

Status bar notifies me of the last error that was not reset:

Note that pressure error event can be activated in IDLE as also RUN state. This is because, user should be notified right at the machine startup as also in idle state that the air pressure is not present and it should be handled appropriately. Error will not be reset if pressure sensor is still activated(i.e. no pressure detected).


Estop: At any point during of any other state, if Estop is triggered, ESTOP state will be activated. Estop does not reset the alarm state, so once the estop is released, alarm state will persist.

kb/tutorials/expert/use_expressions_to_command_semaphore_lights.txt · Last modified: 2024/09/14 16:26 by andrej

Page Tools