Serial communication(MODBUS relay board) with PlanetCNC TNG – Part 3

In this part, we will use and configure Expr.txt file so that we will be able to control relay board via serial communication using Modbus protocol. Expression array and serial functions described in first two parts will be used in order to achieve this.

 

Modbus supports communication to and from multiple devices connected to the same wire of serial communication line.

In this tutorial we will use MODBUS RTU frame format.

Modbus “frame” consists of an Application Data Unit (ADU), which encapsulates a Protocol Data Unit (PDU):

ADU = Address + PDU + Error check

PDU = Function code + Data

If we put the table above in context, with TNG we will send suitable ADU frame to our slave device(relay board) in order that we will successfully control it.

By using array and serial expression functions, we will manipulate data in such way, that each byte will be at correct value and position of transmitted data.

We will use boards user manual for reference regarding the suitable data.

For more about the Modbus protocol you can read on its official site:
https://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf

 

Hardware used

As mentioned earlier, we will use Modbus RTU frame format, which by definition uses RS-485 electrical interface – differential signalling over twisted pair wire.

Relay board uses RS-485 communication interface and by that we need to make sure that differential line is terminated using termination resistor. In our case this is done by placing a jumper in proper position(on board). If multiple boards are used in daisy chain fashion, only last board needs to terminate the differential line. By doing this we prevent signal reflection and therefore data corruption.
This board will be our Modbus slave device.

As a master device, we will use PlanetCNC TNG software, which will send and receive data trough a PC’s COM port. My PC does not have COM port, let alone a RS-485 interface. This is why I will use USB to RS-485 converter. Such device is classified as a USB CDC(communication device class) device and emulates COM port of my computer.

Under Device Manager we can check COM ports ID as “COM11”:

RS-485 converter and relay board are connected using twisted pair wire.

 

Identifying relay board

Since this board uses Modbus protocol on top of serial communication(UART), we need to obtain  board’s serial communication parameters.

Namely, we need boards address ID and baudrate value.  Address ID is in domain of Modbus and it is an important piece of information, since it defines which slave device will respond to our transmitted data. In most cases, Modbus devices use DIP switches for address ID configuration or have some other means for configuring. This relay board does not use DIP switches and we will need to identify the device with different approach.

For start, we need some information about COM port that we intend to use. Specifically,  COM ports name, which is important parameter of the serial_open() command..

Type into the MDI:

=serial_list()

Output window will print the returned information:

COM ports name is “COM11”.

Using serial_open() command, we can check if this port is ready for transmission of data. We will use the most common serial port parameter setting: 9600–8-N-1 (9600 bits per second, eight (8) data bits, no (N) parity bit, and one (1) stop bit)

=serial_open("COM11",9600,8,0,1,0)
;baudrate at 9600
;8 data bits
;1 stop bits
;none parity
;no flowcontrol

Output window will print the returned information. Remember, this function’s return value gives 0, when port is successfully opened.

Great, now that this is settled, we can close it and we can prepare the data which will be sent to the relay board in order that we obtain board’s address ID.

 

Request message and response message data for reading address ID of relay board(as per user manual):

Request message HEX: 0x00 0x03 0x00 0x00 0x00 0x01 0x85 0xDB 
  First byte [0x00] is slave device address ID. But since we have no way of knowing it(board does not use DIP switches), we can use reserved value of "00".
    This means that all devices(or only one) on the bus will receive and acknowledge this data and give suitable response. 
 
  Second byte [0x03] is function code
    Function code in Modbus is a specific code used in a Modbus PDU to tell the Modbus slave device what type of memory (i.e. holding registers, input coils, etc)
    to access and what action to perform on that memory (i.e. reading or writing). This PDU uses function code 3, which is used for reading holding registers.
    Holding registers are the most universal 16-bit register, may be read or written, and may be used for a variety of things including inputs, outputs, configuration data, or any requirement for "holding" data.
  
  Bytes 3 to 6 [0x00 0x00 0x00 0x01] are starting register address and the number of registers we want to read. 
  
  Last two bytes [0x85 0xDB] are CRC 16-bit calculated value. CRC 16-bit value is first calculated and then appended to the end position of array.

Response message HEX: Expected return data should be 0x00, 0x03, 0x02, 0x00, 0x01, 0x44, 0x44. 
5th byte of the return data is boards address ID -> HEX: 0x01 ; DEC: 1

Whole code for reading board’s address ID:

=.payload = array_new()
array_setdata(.payload, 0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01)
serial_open("COM11", 9600, 8, 0, 1, 0)
.crc = array_crc16(.payload, 0, -1)
array_setdata16(.payload, -1, .crc)
serial_writearray("COM11", .payload)
array_clear(.payload)
serial_readarray("COM11", .payload, 150)
serial_close("COM11")
.rc = array_getdata(.payload, 4)
print('Address ID:', .rc)
array_delete(.payload)
Description of used functions: 
=.payload = array_new()  -> new array with handle .payload is created
array_setdata(.payload, 0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01) -> we set data to .payload array
serial_open("COM11", 9600, 8, 0, 1, 0) -> opens COM port and sets parameters
.crc = array_crc16(.payload, 0, -1) -> calculates CRC 16-bit value of .payload array data
array_setdata16(.payload, -1, .crc) -> we append 16-bit CRC data at the end position of .payload array
serial_writearray("COM11", .payload) -> sends .payload array data via COM11 port
array_clear(.payload) -> we clear .payload array data
serial_readarray("COM11", .payload, 150) -> we read the response data from relay board and set it to .payload array
serial_close("COM11") -> closes COM11 port
.rc = array_getdata(.payload, 4) -> we set the 5th byte (zero type numbering is used) of received data into .rc variable
print('Address ID:', .rc) -> prints .rc value
array_delete(.payload) -> deletes .payload array handle

 

Relay On/Off control

Now that we know board address ID, and since this is a relay board, lets control one of the relays on/off.
Request message and response message data for relay No. 1 ON(as per user manual):

Request message HEX: 0x01 0x05 0x00 0x00 0xFF 0x00 CRC-byte CRC-byte 
  First byte [0x01] is slave device address ID. As we know, address ID of relay board is 1.

  Second byte [0x05] is function code. Function code in Modbus is a specific code used in a Modbus PDU to tell the Modbus slave device what type of memory (i.e. holding registers, input coils, etc) to access
    and what action to perform on that memory (i.e. reading or writing). This PDU uses function code 5, which is used to write a single output to either ON or OFF in a remote device.
 
  Bytes 3 to 6 [0x00 0x00 0xFF 0x00] are coil address(first relay at 0...) and the constant value for ON 0xFF 0x00, and a constant value for OFF 0x00 0x00. 
 
  Last two bytes are CRC 16-bit calculated value. These two bytes are not set together with first six bytes. CRC 16-bit value is first calculated and then appended to the end position of array.

Whole code for turning relay 1 ON:

=.payload = array_new()
array_setdata(.payload, 0, 0x01, 0x05, 0x00, 0x00, 0xFF, 0x00)
serial_open("COM11", 9600, 8, 0, 1, 0)
.crc = array_crc16(.payload, 0, -1)
array_setdata16(.payload, -1, .crc)
serial_writearray("COM11", .payload)
array_clear(.payload)
serial_readarray("COM11", .payload, 150)
serial_close("COM11")
.rc = array_getdata(.payload, 4)
array_printdata(.payload)
print('Address ID:', .rc)
array_delete(.payload)

Whole code for turning relay 1 OFF:

=.payload = array_new()
array_setdata(.payload, 0, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00) 
serial_open("COM11", 9600, 8, 0, 1, 0) 
.crc = array_crc16(.payload, 0, -1) 
array_setdata16(.payload, -1, .crc) 
serial_writearray("COM11", .payload) 
array_clear(.payload) 
serial_readarray("COM11", .payload, 150) 
serial_close("COM11") 
.rc = array_getdata(.payload, 4) 
array_printdata(.payload) print('Address ID:', .rc) 
array_delete(.payload)

 

Implementing Modbus communication within TNG software

Executing these commands from MDI is nice for testing, but not really practical in real application. Best way to implement MODBUS communication within the TNG would be to write an expression function which would inhibit all necessary code for master modbus <-> slave communication.

To read more about Expr file and its properties, you can follow link below:
CNC machine semaphore application using Expressions (Expr.txt)

 

 

Create new expr file and name it e.g. Expr_MB_relay.txt. We can include two expression functions in this file, one for relay ON and other for relay OFF.
Lets name them #RelayControl_ON and #RelayControl_OFF.  Include the corresponding code for each function.

The code of Expr_MB_relay.txt file would look like this:

#RelayControl_ON
.payload = array_new();
array_setdata(.payload, 0, 0x01, 0x05, 0x00, 0x00, 0xFF, 0x00);
serial_open("COM11", 9600, 8, 0, 1, 0); 
.crc = array_crc16(.payload, 0, -1); 
array_setdata16(.payload, -1, .crc); 
serial_writearray("COM11", .payload); 
array_clear(.payload); 
serial_readarray("COM11", .payload, 150); 
serial_close("COM11"); 
.rc = array_getdata(.payload, 4); 
array_printdata(.payload);
print('Address ID:', .rc); 
array_delete(.payload);

#RelayControl_OFF
.payload = array_new();
array_setdata(.payload, 0, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00); 
serial_open("COM11", 9600, 8, 0, 1, 0); 
.crc = array_crc16(.payload, 0, -1); 
array_setdata16(.payload, -1, .crc); 
array_writearray("COM11", .payload); 
array_clear(.payload); 
serial_readarray("COM11", .payload, 150); 
serial_close("COM11"); 
.rc = array_getdata(.payload, 4); 
array_printdata(.payload)
print('Address ID:', .rc); 
array_delete(.payload);

 

You can run expression functions either from .NC file, script file, button file, M code file, expression file etc..

Now, if you would like to execute these two functions within a .NC program or gcode script file, you can use (expr, ) comment function:

%
.
.
.
G00 X0 Y20
G01 Z5
(expr,exec("#RelayControl_ON"))
G01 Z-1
G00 Z5
(expr,exec("#RelayControl_OFF"))
.
.
.
%

 

While both examples of Modbus functions described above would work, it would not be a good example of how such communication should be handled.

For each request data sent, we also need to read the response data. Response is an automated process from slave device, and we can use the response data in order that we can verify that request procedure has been acknowledged, processed and correctly executed. In next part we will describe how to correctly write more reliable expression code for Modbus communication.

 

Continued at part 4:
https://planet-cnc.com/serial-communication-with-planetcnc-tng-part-4/

 

 

 

 

 

 

PlanetCNC wireless handwheel button customization

User can customize handwheel button functionality. This can be done by configuring the Handwheel.txt file.

User manual for wireless handwheel is available here: Wireless handwheel user manual

 

First, create a blank Handwheel.txt file and place it in your TNG profile root folder. You can create such file with any text editor. How to configure this file will be described further in this document.

 

Button HEX values:

Each button of the handwheel keypad is represented by its default HEX value. These values could also be in a decimal form, but HEX gives better and more intuitive
description. Each button can be represented with two types of HEX values, Lower HEX (SHIFT button is not active) and Upper HEX values (SHIFT button is active).

 

Best to describe it is by using illustrated view:

Lower HEX button values (SHIFT button not active):

 

While holding SHIFT button, each buttons is now represented with the Upper HEX value:

Now that we know LOWER and UPPER values of each button, we can easily assign new
alternative functions of the handwheel buttons.

 

 

BASIC Handwheel.txt file configuration:

Earlier chapter can be better described with the actual command lines of the configuration
file.

Below are a default* program functions that will be executed when corresponding
button will be activated:

cmd: "Machine.Emergency_Stop" "" num=0x0001
cmd: "Machine.Start" "" num=0x0002
cmd: "Machine.Pause" "" num=0x0003
cmd: "Machine.Work_Position.Offset.To_Zero" "" num=0x0004
cmd: "Machine.Work_Position.Axis_To_Zero.XY" "" num=0x0005
cmd: "Machine.Work_Position.Axis_To_Zero.Z" "" num=0x0006
cmd: "Machine.Flood" "" num=0x0007
cmd: "Machine.Work_Position.Measure_Height" "" num=0x0008
cmd: "Machine.Tool_Offset.Measure_Length" "" num=0x0009
cmd: "Machine.Move.Axis_To_Zero.XY" "" num=0x000a
cmd: "Machine.Spindle" "" num=0x000b

*(Note that this is a default behaviour of handwheel buttons. No configuration file or
configuration of it is needed to obtain it… )

 

Lines below will execute Homing procedure, Machine Stop and Mist ON/OFF actions.
Becuse upper HEX values are used, this indicates that SHIFT button needs to be pressed:

Homing procedure:
cmd: "Machine.Home" "" num=0x0a00

+

Machine Stop:
cmd: "Machine.Stop" "" num=0x0300

+

Mist On/Off:
cmd: "Machine.Mist" "" num=0x0700

+

So if user wishes to add an alternative functionality to a button, all it needs to be done is to add a line which would execute desired program function.

Upper HEX value of button should be used.

 

Example:
We would like to execute Surface Measure procedure when we press the Start button in combination with SHIFT button.
Since we will assign an alternative button functionality we need to obtain the Upper HEX button value.

Earlier chapter with the layout illustration gives this information → 0x0200

Cmd line is usually the menu path of the program function. In this case this would be:
Machine/Measure/Surface

Note that path menu levels are represented with “.” and spaces in the program function name with “_” character.

Command line that would help us achieve this is: cmd: “Machine.Measure.Surface” “” num=0x0200

If we would like to turn ON/OFF Output 1 with the same button instead, we would write: cmd: “Machine.Outputs.Output_1” “” num=0x0200

 

ADVANCED Handwheel.txt file configuration:

Since there are not enough buttons for every possible function of tool that TNG offers, macros can be created. Macros are able to execute program functions, expression
functions, parameter manipulation etc. They can be navigated and used trough the Custom menu.

How to create a macro:
Just as we added command lines for button alternative functions to Handwheel.txt file, in the same way we add dedicated lines to create macros.
We will demonstrate three examples of macro use. Macro for program function, program function with parameter manipulation and expression function.

 

Macro command line for program function File Open:

cmd: "File.Open_..." "Open file" num=0x10001

cmd: “File.Open_…”
Like before, command line is the path of the program function, File/Open

“Open file”
Macro will be displayed under this name in the custom menu.

num=0x10001
This num value serves as a macro ID as also as a menu sequence number. First value 1 identifies this as a macro line, and last value 1 is its sequence number.

 

Macro command line for expression function with parameter manipulation:

cmd: "Machine.Output_PWM" "PWM" num=0x10002 param=0|10|0|100 val="[0;expr:_hw_mpg_custom]"

cmd: “Machine.Output_PWM”
Like before, command line is the path of the program function, Machine/Output_PWM

“PWM”
Macro bill be displayed under this name in the custom menu.

num=0x10002
This num value serves as a macro ID as also as a menu sequence number.First value 1 identifies this as a macro line, and last value 2 is its sequence number.

param=0|10|0|100
These are definition values of PWM signal that will be changed trough this macro. So, when the PWM signal will be modified, if will consider these definitions:

0[initial value] | 10[increment value] | 0[min value] | 100[max value]

val=”[0;expr:_hw_mpg_custom]”
0 is a number of output pin that will generate the PWM signal. Zero based numbering is used (1st pin has number zero, 2nd pin has number one etc…)
Macro uses parameter _hw_mpg_custom for PWM signal value modification.

 

Macro command line for expression function:
This macro executes expression function located in the Expr.txt file.

expr: "exec('#Message')" "Message" num=0x10003

expr: “exec(‘#Message’)”
Since exec is an expression function, we need to use expr command at the beginning of the macro line. exec command will execute the #Message function located in our Expr.txt file.

In this case, #Message function looks like this:
#Message
exec(msg(‘Handwheel function trigger’));

“Message”

Macro bill be displayed under this name in the custom menu.

num=0x10003
This num value serves as a macro ID as also as a menu sequence number. First value 1 identifies this as a macro line, and last value 3 is a sequence number

 

Accessing and using the Custom menu
Custom menu can be accessed using axis switch knob set at C position:

 

 

At first, display will show current jogging mode info. If the handwheel encoder is rotated custom menu will be displayed.

As per our configuration, three macros will be available for selection. Using a handwheel encoder, user can navigate trough the menu items:

To execute the Open File or Message macro, macro should be selected in the menu and confirmed with Cycle button:

 

To execute PWM macro, we select it in the menu and by simultaneously using a Shift button and an encoder wheel we can change the PWM duty cycle value:

To actually set PWM on the output pin, we just need to confirm it with the Cycle button:

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

In the last part of this tutorial series, we will connect the ExtInOut board with our controller and test the functionality of our Expr.txt file, finally!

Before we continue, I would recommend that you go trough the user manual of ExtInOut board for more info about the hardware requirements and connections.

ExtInOut board user manual

 

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 behavior. 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 downloaded below:

Expr.txt

 

Commentary is added for better explanation and understanding.

 

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.

 

Short demonstration video:

Gantry square procedure with PlanetCNC

Many machines use two lead/ball screws or rack and pinion rods per machine axis. In most cases, the Y axis.
Rods can be driven with one motor or two. One motor usually drives both rods using a timing belt, which also helps with
synchronization.

But you can also drive each rod with its separate motor. At PlanetCNC we use the terms Master and Slave motor.
PlanetCNC TNG software takes care of master and slave motor synchronization internally.

Nevertheless, between the two motors, there might be some discrepancy in a sense of gantry squareness. This can be due motor failure, lost steps, mechanical problems etc..

Since CNC machines are meant to ease the pain of accuracy and repeatability of machining process, we as users always strive
for squareness of our CNC machine.

In order to achieve this with dual motor setup, PlanetCNC TNG sw offers Gantry Square feature.

What gantry square feature does,  it “decouples” the master and slave axis motors from their common axis (e.g. Y), and assigns them new axis letters U and V, for the purpose of gantry square procedure. This needs to be done so that system is able to detect limit switches of each motor, as also to separately control each motor in order to  align gantry.

 

Before you proceed, we recommend that your machine steps per unit and limit switch configuration is set correctly:
Steps per unit tutorial
Limit switch tutorial

1. Setting the motors of Master and Slave axis

Under File/Settings/Motors we set additional (slave) motor of desired axis. In our case, axis output 4 will be used.

 

2. Settings Limit switches

Configuration of limit switch inputs for master and slave motor. We need to set limit switch inputs under motor U and V.

Motor U will have the same input number as motor Y, while motor V will have input number 4.

 

 

3. Gantry square parameters

Here we set the parameters of gantry square procedure.


Speed: 

Speed value at which gantry square procedure will be performed.

 

Axis:

Machine axis that will be squared. In our case Y.

 

Direction: 

Direction of squaring axis motion. It should be the same direction as set for limit switches for U and V.

 

Move U:

Value of measured misalignment of master axis. This is the distance for which master motor will retract.

 

Move V:

Value of measured misalignment of master axis. This is the distance for which slave motor will retract.

 

4. Using the gantry square procedure

Gantry square procedure will consist of two takes.

For first take we will use Move UV values set to zero. So, if any misalignment of limit switches (gantry) exists (and it probably does), we will measure it trough a test. In second take we will use these measured values as Move UV values, and therefore square our gantry.

 

We start the procedure under : Machine/Measure/Gantry square

Machine will move in direction set under Direction. Once the first limit switch is activated, corresponding motor will stop, second motor will continue to move its side of the gantry until the second limit switch is activated. After activation, second motor also stops.

After first take, mill or engrave a square and measure the discrepancy of the angle. One user recommended the use the 3-4-5 Triangle approach. Trough measurement or calculation, we can obtain the Move UV correctional values and use it with second take.

 

Image below demonstrates (exaggerated) situation of limit switch misalignment.

-Normal line represents gantry misalignment due to limit switch

-The doted line represents squared gantry.

 

Short demonstration video:

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. 

 

 

 

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

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 behaviour 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.

Both will be described in detail in Part 3 of this tutorial.

 

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

 

 

 

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

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

We want:

  • to use a semaphore with 5 lights.
  • Each light with different colour 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.

 

 

In part 2 we will describe our state machine and Expr.txt file

Plasma CNC and THC (torch height control) with PlanetCNC

Plasma CNC cutting machine is one of the most commonly used types of CNC machine.
It’s used mostly for cutting Steel, aluminium and other conductive materials.

Like any other type of CNC machine, plasma machine has it own specifics. Machine should be properly designed for such type of machining, considering slag, steel dust, high temperatures, moisture, grease etc..

Plasma cutter is a great source of electromagnetic interference. So special care should be taken into account when designing and wiring machine electronics.
Be sure to use shielded cables for motors, limit switches. External power supply for motion controller is very recommended. Plasma cutters itself sometimes do not satisfy standards of electromagnetic compatibility (EMC), so make sure that your plasma cutter is within EMC regulations.

Heat emitted from plasma could deform workpiece material, usually metal sheet. In such case plasma cutter would not cut at constant height which could result as a faulty workpiece or could damage plasma cutter in the process. This is usually solved with THC device. THC stands for Torch Height Control.

For your plasma CNC application you can use PlanetCNC motion control system together with PlanetCNC torch height controller.

Torch height controller consists of torch height controller and torch height sensor device.

Torch height sensor device measures arc voltage. Bigger the distance between the plasma torch and material higher the voltage and vice versa. So based on the measured voltage value we can maintain constant height of plasma torch above the material.

Torch height sensor device is connected with torch height controller via optic cable. Torch height controller then sends control signals (Up, Down, Arc OK) to motion controller which then dynamically compensates Z axis and thus maintains constant cutting height.

 

Features and specifications:

Torch height sensor device:
• Plasma arc voltage measurement up to 350 V
• Additional input for divided plasma voltage (1:50) up to 10 V
• Plasma voltage present signalization
• Full optical output isolation; transmitter and receiver connected over an optical fiber
cable
• Main AC power supply (110 VAC-230 VAC/50-60 Hz)

Torch height controller:
• Output signals: Arc Ok, Up and Down (normally-open solid-state relay outputs)
• Programmable reference and hysteresis voltage, delay time and anti-dive limit voltage
• Current plasma voltage presentation on LED display
• LED signalization of arc present, up and down signals
• Full optical input isolation; transmitter and receiver connected over an optical cable
• Test mode operation
• Wide power supply voltage range (6 – 36 V)

 
Torch height controller terminal description:

 
Torch height sensor terminal description:

 
 

Connection diagrams

High voltage source from plasma cutter:

 
 

Divided voltage output source from plasma cutter:

 

 

Torch height controller connection with PlanetCNC controller inputs:

Please note that Down, Up, Arc OK signals can be connected to any input of PlanetCNC controller since inputs function can be configured later in PlanetCNC TNG settings.

 

Controller input configuration in PlanetCNC TNG software

User can configure controller inputs for THC under File/Settings/THC.

Axis:
User selects machine axis from drop down menu. Selected axis will be height compensated.

Dec Pin:
Dec input pin number, located at INPUT header of controller. Select input pin number from drop down menu.
When this input pin is active, machine will move/compensate in negative direction.
Down signal from torch height controller is connected to this input.

Inc Pin:
Inc input pin number, located at INPUT header of controller. Select input pin number from drop down menu.
When this input pin is active, machine will move/compensate in positive direction.
Up signal from torch height controller is connected to this input.

OK Pin:
OK input pin number, located at INPUT header of controller. Select input pin number from drop down menu.
If set, software waits until this input is active and only then begins with program execution.
Arc OK signal from torch height controller is connected to this input.

Range Min/Max:
Low and high limit compensation travel.

Speed:
Speed of compensation moves. Units are mm/s or inch/s.

When torch height controller will activate its output, corresponding digital input of controller should activate.
You can observe status of controller inputs via IO tab of PlanetCNC TNG state panel.

 

THC related g-codes

THC compensation can be enabled or disabled, as also additional gcode parameters can be used so that machine behaviour will suit your plasma cutting requirements for better cutting results.

M54 – Enable/Disable THC
Usage: M54 P <Q> <R> – P = zero for Off, otherwise On
– Q = speed limit
– R = constant speed
If speed limit is set then THC will not move Z axis if machine speed is below set speed.
If constant speed is enabled then THC will not move Z axis if machine is accelerating or decelerating.

Example:
M54 P1 Q1000 R1 – enable THC for constant speeds (no acceleration) above 1000.

Using ExtOut board with PlanetCNC controller

PlanetCNC controllers offer digital outputs for external equipment control. Digital outputs of controller are usually used with output board for spindle control.

To expand number of outputs, you can use ExtOut board with 8 relays. This board comes useful when you need to control many external devices such as vacuum pumps, various actuators, selenoid pneumatic valves (ATC).

Please note:
-ExtOut board can be used only with Mk3 controller

-ExtOut board is connected with Mk3 controller trough ExtIn board.

-ExtOut board requires external power supply, 12VDC , min. 200mA

 

Ext Out board:

ExtIn board:

 

 

ExtIn and ExtOut board are connected via 5wire cable(included with ExtOut board):

 

ExtIn board is then connected with controllers I/O EXT header via 10pin ribbon cable:

 

 

 

 

Using jogging keyboard with PlanetCNC controllers

With Mk3 and Mk3/4 controller you can use external jogging keyboard:

 

Jogging keyboard is connected to controllers JOG header via 16pin ribbon cable.

MK3 JOG header:

 

Mk3/4 JOG header:

 

Jogging keyboard connection with Mk3 controller:

 

Jogging keyboard connection with Mk3/4 controller:

 

Please read tutorial on how to configure jogging keyboard in PlanetCNC TNG software:

 

Replacing Chinese JP-382C board with genuine PlanetCNC MK3DRV controller

1. Take your control box and remove all screws of the top cover:

Now remove top cover of control box:

2. Locate JP-382C board and disconnect connectors of cable sets for X, Y and Z axis motor outputs, power supply and E-Stop switch. They should not be hard to find:

3. Remove JP-382C board from enclosure by unscrewing two screws at the bottom side of control box and two screws at the back panel:

4. Throw JP-382C board into the trash bin:

5. Take MK3DRV controller and 3D printed pillars:

3D printed parts are available here: PlanetCNC Mk3DRV pillars and back panel

6. Attach and screw them to Mk3DRV controller:

7. At the back panel place controller into existing cutout hole and screw it:

Screw in also pillars at the bottom side of control box:

8. Take cable sets for x,y,z motors that we previously disconnected from JP-382C board:

And cut off the connectors:

Each motor cable set should have 4 wires, 2 wires of one colour and other 2 in different colour.
Each colour represents separate phase of stepper motor.

9. Connect motor cable wires for X,Y and Z axis to Mk3DRV motor output terminals MOTOR 1(X), MOTOR 2(Y) and MOTOR 3 (Z). Motor phase 1 wires (yellow wires) are connected to terminals 1A and 1B, motor phase 2(red wires) is connected to terminals 2A and 2B.

10. Locate power supply cable and cut off its connector.
Connect power supply cable wires to Mk3DRV power supply terminal 24V. Red wire should be connected to “+” terminal and black should be connected to “–“ terminal:

11. Locate E-Stop switch cable and cut off its connector.
Connect it to Mk3DRVs GND and eSTP terminals:

Now you can use your control box with PlanetCNC TNG software and your CNC machine.

PLEASE NOTE: MK3DRV can be used only with PlanetCNC TNG software version SW2017.10.30(or newer), if you will use older version for update such as SW 2017.10.20 beta you could bridge it.

Plasma CNC and floating Z axis with PlanetCNC

Sometimes we need to modify our CNC machine in order to achieve our machining goals as quickly and as efficiently as possible. CNC machines such as plasma, plotter cutters, lasers need mechanism that helps with measuring of material surface.

Good example of such modification is Floating Z axis.

The concept is pretty straight forward:  Z axis has its own movable unit which is able to move when tool encounters with material surface.

Floating Z axis on a plasma machine is a safety feature that prevents any serious damage of your plasma torch, in case of hitting any obstacles on located on machine table.

For plotters and drag knife cutters,   floating effect comes handy because it is much easier to apply pressure of the pen or  knife onto material surface (paper, carton, vinyl etc) without the frustrating trial and error procedure.

Floating Z axis can also be used for measuring material top surface. In such case, floating z axis unit uses limit switch. When Z axis moves down towards the material, activated switch signals controller that surface of material was detected and zero work position of Z axis can be set.

This procedure is similar to movable tool sensor, except that thickness value is negative. See bottom of this page for more details.

 

Example of floating Z axis:

 

Example of floating Z axis on plasma machine using limit switch:

 

Obtaining thickness value on plasma machine with floating Z axis:

Full tutorial about movable tool sensor can be found here: https://planet-cnc.com/measure-work-position-movable-sensor/

Slowly jog Z axis towards the material surface, so that the nozzle of plasma torch is just barely touching the surface of material. You can help yourself by adding a sheet of paper between torch nozzle and the surface of material. Start moving the paper and when you are not able to move paper anymore, set work position Z to Zero.

 

Now jog Z axis further more in -Z direction. When floating Z axis limit switch will activate, write down position value of Z axis. This is your thickness value.

 

You can make your own floating Z axis unit. 3D and STL files are published here:
https://www.thingiverse.com/thing:2516238