twincattwincat-ads

How to completely reset an NC axis in TwinCAT?


How could I completely reset the NC axes in my TwinCAT project at runtime, without restarting TwinCAT itself?

In a similar vein, I can reset my PLC project by doing a 'Cold Reset'. Can the NC collection be cold-reset in the same way?

I have a set of those NC axes without actual hardware connect to them and between tests I would like them to be back at 0 and unhomed.


Solution

  • I may have found a solution, by using the ADS interface of the NC project.
    It's not easy to find, but Beckhoff has a description of the ADS indexes of NC axes: TwinCAT 3 > Technologies > ADS > ADS Basics > Specification for ADS devices > Specification of the NC

    The reset I had in mind could be realized by:

    1. Setting the actual position to 0 (write to index 0x00n0001A)
    2. Resetting the 'homed' flag (write to index 0x00n0001B)
    3. Resetting the axis (clearing errors) (write to index 0x00000001)

    Of course this will not fully reset the axis, and any changed parameters would have to be manually changed back.

    I am using pyads to write over ADS and use the following code:

    SET_POS_STRUCT_DEF = (
        ("position_type", pyads.PLCTYPE_UDINT, 1),
        ("reserved", pyads.PLCTYPE_UDINT, 1),
        ("position_value", pyads.PLCTYPE_LREAL, 1),
    )
    
    struct_val = OrderedDict([
        ("position_type", 1),  # absolute
        ("reserved", 0),
        ("position_value", 0.0),
    ])
    
    struct_bytes = pyads.bytes_from_dict(struct_val, SET_POS_STRUCT_DEF)
    struct_size = pyads.size_of_structure(SET_POS_STRUCT_DEF)
    
    
    def reset_axis(plc: Connection, axis_id: int, reset_position=True):
    
        grp_idx = 0x4200 + axis_id
    
        index_values = [
            (0x00000051, 0, pyads.PLCTYPE_BYTE),  # Enable axis
            (0x00000002, 0, pyads.PLCTYPE_BYTE),  # Stop axis
            (0x0000001A, struct_bytes, pyads.PLCTYPE_BYTE * struct_size),  # Reset pos.
            (0x0000001B, 0, pyads.PLCTYPE_UDINT),  # Clear homed flag
            (0x00000001, 0, pyads.PLCTYPE_BYTE),  # Reset axis
            (0x00000050, 0, pyads.PLCTYPE_BYTE),  # Disable axis
        ]
    
        for idx, value, plc_type in index_values:
            plc.write(grp_idx, idx, value, plc_type)
    
    
    def main():
    
        with Connection(ams_net_id="127.0.0.1.1.1", ams_net_port=501) as plc:
    
            reset_axis(plc, 1)