CNC machine semaphore application, using expressions (Expr.txt) – Part 3

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

Diagram of 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.

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

 

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 initialisation 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 flowchart is below:

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 flowchart is below:

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.