Автосмена инструмента

Настройка автоматической смены инструмента

  1. Автосмена инструмента выполняется на макросах.
  2. Ниже представлены макросы для линейной и карусельной смены инструмента.
  3. Макросы необходимо добавить через меню Сервис -> Настройки -> Макросы. 
  4. Минимальная версия, на которой поддерживаются макросы из данной статьи: релиз 4.3.

Библиотека переменных - все настройки необходимо выполнять только в этом макросе. Название макроса обязательно должно быть: ATC_VLIB - по такому имени эта библиотека подключается к остальным макросам. Макрос нужно сделать скрытым.

Библиотека функций - в этом макросе реализованы все функции . Название макроса обязательно должно быть: ATC_FLIB - по такому имени эта библиотека подключается к остальным макросам. Макрос нужно сделать скрытым.

Макрос смены инструмента - в этом макросе реализована непосредственно смена инструмента. Макрос нужно сделать скрытым. Макрос нужно назначить на макровызов для команды M0?6 через меню Сервис -> Настройки -> Макровызовы. Макрос будет автоматически вызываться только при работе управляющей программы, когда в ней встречается команда M6Tx, где Tx - следующий номер инструмента.

Макрос построения таблицы инструментов - в этом макросе реализован алгоритм построения таблицы инструментов. После создания таблицы автосмена будет выполняться без измерения только что установленного инструмента - компенсация длины будет выполняться автоматически по таблице. Макрос нужно сделать видимым - запускать его по кнопке на панели МАКРОСЫ. Чтобы активировать режим автоматической компенсации длины инструмента (G43), необходимо в контроллер отправить команду $457=1 (через консоль).

Макрос выполняет измерение инструмента и заносит его длину (фактически значение машинной координаты точки касания фрезы калибратора) в память контроллера. После запуска макроса он просит ввести номер инструмента для измерения - чтобы измерить все инструменты в цикле, введите 0.

Макрос сброса инструмента - в этом макросе реализован автоматический сброс текущего установленного инструмента в соответствующую позицию в магазине. Макрос нужно сделать видимым - запускать его по кнопке на панели МАКРОСЫ.

Макросы линейной смены инструмента

Библиотека переменных

Нажмите, чтобы показать код макроса
{
    /* ****** Перед началом использования обязательно сконфигурить все параметры ниже под Ваш станок *****
    Макрос работает на версии визуализатора 4.3 и выше.
    Макрос необходимо назвать ATC_VLIB - именно по этому имени он подключается в макросах автосмены инструмента.
    Макрос нужно сделать скрытым.
    */
    
    // Размер магазина инструментов
    var TOOLS_NUMBER = 8
    
    // Параметр BASKET_LOCATION отвечает за расположение магазина инструментов.
    // Значение 1 - магазин закреплен на столе (самый частый вариант)
    // Значение 2 - магазин закреплен на портале и находится под ним.
    var BASKET_LOCATION = 1
    
    // Параметр HOLDERS_ORIENTATION_AXIS используется только, если магазин закреплен под порталом (BASKET_LOCATION = 2)
    // и определяет, вдоль какой оси расположены держатели в магазине. Обычно это ось X (сам портал при этом движется вдоль оси Y).
    var HOLDERS_ORIENTATION_AXIS = "X"
    
    // Массив координат X позиций инструментов в магазине
    var HOLDERS_X_POS = [10, 20, 30, 40, 50, 60, 70, 80]
    
    // Массив координат Y позиций инструментов в магазине
    var HOLDERS_Y_POS = [200, 200, 200, 200, 200, 200, 200, 200]
    
    // Массив координат Z позиций инструментов в магазине
    var HOLDERS_Z_POS = [-10, -10, -10, -10, -10, -10, -10, -10]
    
    // Расстояние для захода в позицию магазина с инструментом для его сброса, а также расстояние выхода из магазина с только что установленным инструментом.
    // Например, если шпинедль с установленным инструментом заходит в магазин по оси Y в положительном направлении, то необходимо параметру 
    // MOVE_WITH_TOOL_OFFSET_Y присвоить отрицательно значение, остальным 0.
    var MOVE_WITH_TOOL_OFFSET_X = 0
    var MOVE_WITH_TOOL_OFFSET_Y = -100
    var MOVE_WITH_TOOL_OFFSET_Z = 0

    // Расстояние ухода с позиции в магазине без инструмента (для снятия), а также захода в позицию магазина без инструмента (для его захвата).
    // Например, если шпиндель без инструмента заходит в магазин по оси Z в отрицательном направлении (сверху вниз), то необходимо параметру 
    // MOVE_WITHOUT_TOOL_OFFSET_Z присвоить положительно значение, остальным 0.
    var MOVE_WITHOUT_TOOL_OFFSET_X = 0
    var MOVE_WITHOUT_TOOL_OFFSET_Y = 0
    var MOVE_WITHOUT_TOOL_OFFSET_Z = 50
    
    // Безопасная высота - все перемещения желательно выполнять на безопасной высоте, по умолчанию это машинный 0 по Z
    var SAFE_Z_POS = 0
    
    // Быстрая скорость перемещения по Z
    var FAST_RATE_Z = 2000
    
    // Медленная скорость перемещения по Z
    var SLOW_RATE_Z = 500
    
    // Быстрая скорость перемещения по X,Y
    var FAST_RATE_XY = 5000
    
    // Медленная скорость перемещения по X,Y
    var SLOW_RATE_XY = 500

    // Таймаут на остановку шпинделя
    var SPINDLE_STOP_TIMEOUT = 1
    
    // !!! Ниже обязательно нужно настроить машинные коориднаты позиции, где стоит шайба !!!
    // Шпиндель будет автоматически презжать в эту позицию для измерения длины инструмента
    var PROBE_X_MPOS = 375
    var PROBE_Y_MPOS = 2982
    var PROBE_Z_MPOS = -70
    
    var FAST_RATE_PROBE = 200
    var SLOW_RATE_PROBE = 10
    
    // Ниже сервисные переменные для активации тех или иных действий в процедуре смены инструмента
    // Продувка инструмента. 0 - продувки нет.
    var NEED_BLOW_TOOL = 1
    
    // Требуется ли проверка датчиков захвата/освобождения инструмента
    var NEED_CHECK_TOOL_SENSORS = 1
    
    // Требуется ли выполнять подъем/опускание щетки отдельной командой
    var NEED_BRUSH_CONTROL = 1
    
    // Требуется ли управлять открытием/закрытием магазина инструментов
    var NEED_TOOL_BASKET_CONTROL = 0
    
    // Ниже список входов контроллера, к которым подключены датчики. Например, 8 ознаечает подключение ко входу IN8 (переопределенный HOLD).
    // Если сигнал не используется, присвойте ему значение -1
    // Сигнал поднятой щетки
    var BRUSH_UP_INPUT_ID = 9
    // Сигнал опущенной щетки
    var BRUSH_DOWN_INPUT_ID = -1
    // Сигнал наличия инструмента в патроне
    var TOOL_CAUGHT_INPUT_ID = 7
    // Сигнал отсутствия инструмента в патроне
    var TOOL_RELEASED_INPUT_ID = 8
    // Сигнал открытия магазина инструментов
    var BASKET_ON_INPUT_ID = -1
    // Сигнал закрытия магазина инструментов
    var BASKET_OFF_INPUT_ID = -1

    // Ниже список задействованных релейных выходов. Например, значение 5 означает, используется выход OUT5.
    // Номер выхода управления захватом/освобождения инструмента
    var TOOL_CTRL_PORTNO = 5
    // Номер выхода управления щеткой
    var BRUSH_CTRL_PORTNO = 6
    // Номер выхода продувки инструмента
    var TOOL_BLOW_PORTNO = 7
    // Номер выхода управления магазином
    var BASKET_CTRL_PORTNO = 4
    
    // Ниже параметры задают, по какому действию релейного выхода осуществляется активация периферии
    // Если TOOL_RELEASE_IF_RLY_ON == 1, то освобождение инструмента осуществляется активацией (M64) управляющего им выхода. Если 0 - деактивацией (M65)
    var TOOL_RELEASE_IF_RLY_ON = 1
    // Если BRUSH_UP_IF_RLY_ON == 1, то подъем щетки осуществляется активацией (M64) управляющего ей выхода. Если 0 - деактивацией (M65)
    var BRUSH_UP_IF_RLY_ON = 1
    // Если BASKET_OPEN_IF_RLY_ON == 1, то открытие магазина осуществляется активацией (M64) управляющего им выхода. Если 0 - деактивацией (M65)
    var BASKET_OPEN_IF_RLY_ON = 1
    // Если BLOW_TOOL_IF_RLY_ON == 1, то продув патрона осуществляется активацией (M64) управляющего выхода. Если 0 - деактивацией (M65)
    var BLOW_TOOL_IF_RLY_ON = 1
}

Библиотека функций

Нажмите, чтобы показать код макроса
{    
    /*
    Макрос работает на версии визуализатора 4.3 и выше.
    Макрос необходимо назвать ATC_FLIB - именно по этому имени он подключается в макросах автосмены инструмента.
    Макрос нужно сделать скрытым.
    */
    
    // include "ATC_VLIB"
    
    var brush_up_signal = "i" + String(BRUSH_UP_INPUT_ID)
    var brush_down_signal = "i" + String(BRUSH_DOWN_INPUT_ID)
    var tool_caught_signal = "i" + String(TOOL_CAUGHT_INPUT_ID)
    var tool_released_signal = "i" + String(TOOL_RELEASED_INPUT_ID)
    var basket_on_signal = "i" + String(BASKET_ON_INPUT_ID)
    var basket_off_signal = "i" + String(BASKET_OFF_INPUT_ID)

    // Функция освобождения инструмента из патрона путем включения реле, подключенного к выходу TOOL_CTRL_PORTNO
    function release_tool() {
        var port_mask = Math.pow(2, TOOL_CTRL_PORTNO-1)
        if (TOOL_RELEASE_IF_RLY_ON == 1) {
            $.send("M64P" + String(port_mask))
        }
        else {
            $.send("M65P" + String(port_mask))
        }
        if (tool_released_signal == "i-1") {
            $.send("G4P2")
        }
    }
    
    // Функция захвата инструмента в патрон путем выключения реле, подключенного к выходу TOOL_CTRL_PORTNO
    function catch_tool() {
        var port_mask = Math.pow(2, TOOL_CTRL_PORTNO-1)
        if (TOOL_RELEASE_IF_RLY_ON == 1) {
            $.send("M65P" + String(port_mask))
        }
        else {
            $.send("M64P" + String(port_mask))
        }
        if (tool_caught_signal == "i-1") {
            $.send("G4P2")
        }
    }
    
    function get_basket_sensors_value() {
        // 0 - магазин закрыт
        // 1 - магазин открыт
        // 2 - неверное состояние, когда оба датчика имеют одинаковое состояние
        // 3 - датчики магазина не установлены, проверку делать не нужно
        if (basket_on_signal != "i-1" || basket_off_signal != "i-1") {
            var sensor_value = 0
            if (basket_on_signal != "i-1" && basket_off_signal != "i-1") {
                var sensor_value = $.inputs[basket_on_signal] && !$.inputs[basket_off_signal]
                if (sensor_value == 0) {
                    if( ($.inputs[basket_on_signal] && $.inputs[basket_off_signal]) || (!$.inputs[basket_on_signal] && !$.inputs[basket_off_signal]) ) {
                        // Неверное состояние: оба датчика либо одновременно активны, либо одновременно неактивны
                        var sensor_value = 2
                    }
                }
            }
            else if (basket_on_signal != "i-1") {
                var sensor_value = $.inputs[basket_on_signal]
            }
            else {
                var sensor_value = !$.inputs[basket_off_signal]
            }
            return sensor_value
        }
        else {
            return 3
        }
    }
    
    // Функция открытия магазина инструментов путем включения реле, подключенного к выходу BASKET_CTRL_PORTNO
    function tool_basket_on() {
        var sensor_value = get_basket_sensors_value()
        // Проверяем состояние магазина инструментов перед началом процедуры смены инструмента
        if (sensor_value == 2) {
            // Оба датчика магазина либо одновременно активны, либо одновременно неактивны
            $.message("Неверное состояние датчиков магазина инструментов: невозможно определить его состояние!")
            $.tasklist.stop()
            $.exit()
        }
        
        if(sensor_value == 0 || sensor_value == 3) {
            var port_mask = Math.pow(2, BASKET_CTRL_PORTNO-1)
            //Магазин инструментов закрыт, открываем его
            if (BASKET_OPEN_IF_RLY_ON == 1) {
                $.send("M64P" + String(port_mask))
            }
            else {
                $.send("M65P" + String(port_mask))
            }
            // Если датчик открытия инструмента не установлен, то безусловно отправляем таймаут на открытие инструмента
            if(basket_on_signal == "i-1") {
                $.send("G4P2")
            }
        }
    }
    
    // Функция закрытия магазина инструментов путем выключения реле, подключенного к выходу BASKET_CTRL_PORTNO
    function tool_basket_off() {
        var port_mask = Math.pow(2, BASKET_CTRL_PORTNO-1)
        if (BASKET_OPEN_IF_RLY_ON == 1) {
            $.send("M65P" + String(port_mask))
        }
        else {
            $.send("M64P" + String(port_mask))
        }
        // Если датчик закрытия инструмента не подключен, то безусловно отправляем таймаут на закрытие магазина.
        if(basket_off_signal == "i-1") {
            $.send("G4P3")
        }
    }
    
    function blow_tool() {
        var port_mask = Math.pow(2, BASKET_CTRL_PORTNO-1)
        
        // Пускаем воздух для продувки инструмента
        if (BLOW_TOOL_IF_RLY_ON == 1) {
            $.send("M64P" + String(port_mask))
        }
        else {
            $.send("M65P" + String(port_mask))
        }
        
        // Выдерживаем паузу для продувки
        $.send("G4P2")
        
        // Отключаем воздух
        if (BLOW_TOOL_IF_RLY_ON == 1) {
            $.send("M65P" + String(port_mask))
        }
        else {
            $.send("M64P" + String(port_mask))
        }
    }
    
    // Функция подъема щетки (включение выхода BRUSH_CTRL_PORTNO)
    function set_brush_up() {
        var port_mask = Math.pow(2, BRUSH_CTRL_PORTNO-1)
        if (BRUSH_UP_IF_RLY_ON == 1) {
            $.send("M64P" + String(port_mask))
        }
        else {
            $.send("M65P" + String(port_mask))
        }
        // Если датчик поднятой щетки не установлен, то безусловно отправляем таймаут на поднятие щетки
        if (brush_up_signal == "i-1") {
            $.send("G4P2")
        }
    }
    
    // Функция опускания щетки (выключение выхода BRUSH_CTRL_PORTNO)
    function set_brush_down() {
        var port_mask = Math.pow(2, BRUSH_CTRL_PORTNO-1)
        if (BRUSH_UP_IF_RLY_ON == 1) {
            $.send("M65P" + String(port_mask))
        }
        else {
            $.send("M64P" + String(port_mask))
        }
        // Если датчик опущенной щетки не установлен, то безусловно отпраляем таймаут на опускание щетки
        if (brush_down_signal == "i-1") {
            $.send("G4P2")
        }
    }
    
    function check_tool_basket_on() {
        // Проверяем, что магазин инструментов открыт
        // Если датчик открытого магазина не установлен, то сразу выходим из функции
        if (basket_on_signal == "i-1") {
            return
        }
        var try_count = 0
        while (try_count < 20) {
            if (get_basket_sensors_value() == 1) {
                // Магазин открылся, выходим из цикла проверки датчиков
                break;
            }
            var try_count = try_count + 1
            $.send("G4P0.1")
        }
        
        var sensor_value = get_basket_sensors_value()
        if (sensor_value == 1) {
            // Всё хорошо, магазни открыт
        }
        else if (sensor_value == 0) {
            $.message("Магазин инструментов не открылся!")
            $.tasklist.stop()
            $.exit()
        }
        else {
            $.message("Неверное состояние датчиков магазина инструментов, невозможно проверить его открытие!")
            $.tasklist.stop()
            $.exit()
        }
    }
    
    function check_tool_basket_off() {
        // Проверяем датчик закрытия магазина инструментов
        // Если датчик закрытого магазина не установлен, то сразу выходим из функции
        if (basket_off_signal == "i-1") {
            return
        }
        var try_count = 0
        while (try_count < 30) {
            if (get_basket_sensors_value() == 0) {
                // Магазин закрылся, выходим из цикла проверки датчиков
                break;
            }
            var try_count = try_count + 1
            $.send("G4P0.1")
        }
        
        var sensor_value = get_basket_sensors_value()
        if (sensor_value == 0) {
            // Всё хорошо, магазни закрыт
        }
        else if (sensor_value = 1) {
            $.message("Магазин инструментов не закрылся!")
            $.tasklist.stop()
            $.exit()
        }
        else {
            $.message("Неверное состояние датчиков магазина инструментов, невозможно проверить его закрытие!")
            $.tasklist.stop()
            $.exit()
        }
    }
    
    function tool_basket_on_if_closed() {
        var sensor_value = get_basket_sensors_value()
        if (sensor_value == 0 || sensor_value == 3) {
            // Всё хорошо, магазни закрыт, можем его открыть
            tool_basket_on()
        }
    }
    
    function tool_basket_off_if_opened() {
        var sensor_value = get_basket_sensors_value()
        if (sensor_value == 1 || sensor_value == 3) {
            // Всё хорошо, магазни открыт, можем его закрыть
            tool_basket_off()
        }
    }
    
    function get_tool_sensors_value() {
        // 0 - отсутствие инструмента
        // 1 - наличие инструмента
        // 2 - неверное состояние, когда оба датчика имеют одинаковое состояние
        if (tool_caught_signal != "i-1" || tool_released_signal != "i-1") {
            var sensor_value = 0
            if (tool_caught_signal != "i-1" && tool_released_signal != "i-1") {
                var sensor_value = $.inputs[tool_caught_signal] && !$.inputs[tool_released_signal]
                if (sensor_value == 0) {
                    if( ($.inputs[tool_caught_signal] && $.inputs[tool_released_signal]) || (!$.inputs[tool_caught_signal] && !$.inputs[tool_released_signal]) ) {
                        // Неверное состояние: оба датчика либо одновременно активны, либо одновременно неактивны
                        var sensor_value = 2
                    }
                }
            }
            else if (tool_caught_signal != "i-1") {
                var sensor_value = $.inputs[tool_caught_signal]
            }
            else {
                var sensor_value = !$.inputs[tool_released_signal]
            }
            return sensor_value
            
        }
        else {
            return 0
        }
    }
    
    // Функция для проверки, что инструмент захвачен в патрон
    function check_tool_caught() {
        $.send("G4P0.1")
        if(tool_caught_signal == "i-1") {
            return
        }
        var try_count = 0
        while (try_count < 20) {
            if (get_tool_sensors_value() == 1) {
                // Инструмент захвачен, выходим из цикла проверки датчиков
                break;
            }
            var try_count = try_count + 1
            $.send("G4P0.1")
        }
        
        var sensors_value = get_tool_sensors_value()
        if (sensors_value == 1) {
            // Всё хорошо, инструмент захвачен, датчик разжатия цанги не активен.
        }
        else if (sensors_value == 0) {
            $.message("Не получен сигнал захвата инструмента либо получен сигнала разжатия цанги!")
            $.tasklist.stop()
            $.exit()
        }
        else {
            $.message("Невозможно определить состояние цанги после захвата инструмента!")
            $.tasklist.stop()
            $.exit()
        }
    }
    
    // Функция для проверки разжатия цанги
    function check_tool_released() {
        $.send("G4P0.1")
        if(tool_released_signal == "i-1") {
            return
        }
        var try_count = 0
        while (try_count < 20) {
            if (get_tool_sensors_value() == 0) {
                // Инструмент освобожден, выходим из цикла проверки датчиков
                break;
            }
            var try_count = try_count + 1
            $.send("G4P0.1")
        }
        
        var sensor_value = get_tool_sensors_value()
        if (sensor_value == 0) {
            // Всё хорошо, цанга разжата
        }
        else if (sensor_value == 1) {
            $.message("Не получен сигнал разжатия цанги либо получен сигнал захвата инструмента!")
            $.tasklist.stop()
            $.exit()
        }
        else {
            $.message("Невозможно определить состояние цанги после освобождения инструмента!")
            $.tasklist.stop()
            $.exit()
        }
    }
    
    // Функция для проверки, что инструмент не установлен в патрон
    function check_no_tool_installed() {
        $.send("G4P0.1")
        if (get_tool_sensors_value() == 0) {
            // Всё хорошо, цанга разжата
        }
        else {
            $.message("Получен сигнал наличия инструмента в патроне после его освобождения!")
            $.tasklist.stop()
            $.exit()
        }
    }
    
    function get_brush_sensors_value() {
        // 0 - щетка внизу
        // 1 - щетка поднята
        // 2 - неверное состояние, когда оба датчика имеют одинаковое значение
        if (brush_up_signal != "i-1" || brush_down_signal != "i-1") {
            var sensor_value = 0
            if (brush_up_signal != "i-1" && brush_down_signal != "i-1") {
                var sensor_value = $.inputs[brush_up_signal] && !$.inputs[brush_down_signal]
                if (sensor_value == 0) {
                    if( ($.inputs[brush_up_signal] && $.inputs[brush_down_signal]) || (!$.inputs[brush_up_signal] && !$.inputs[brush_down_signal]) ) {
                        // Неверное состояние: оба датчика либо одновременно активны, либо одновременно неактивны
                        var sensor_value = 2
                    }
                }
            }
            else if (brush_up_signal != "i-1") {
                var sensor_value = $.inputs[brush_up_signal]
            }
            else {
                var sensor_value = !$.inputs[brush_down_signal]
            }
            return sensor_value
        }
        else {
            return 0
        }
    }
    
    // Функция для проверки, что щетка подтяна
    function check_brush_up() {
        $.send("G4P0.1")
        // Если датчик поднятия щетки не установлен, сразу выходим из функции
        if (brush_up_signal == "i-1") {
            return
        }
        var try_count = 0
        while (try_count < 20) {
            if (get_brush_sensors_value() == 1) {
                // Щетка поднялась, выходим из цикла проверки датчиков
                break;
            }
            var try_count = try_count + 1
            $.send("G4P0.1")
        }
        
        var sensor_value = get_brush_sensors_value()
        if (sensor_value == 1) {
            // Всё хорошо, щетка подтяна
        }
        else {
            $.message("Щетка не поднялась!")
            $.tasklist.stop()
            $.exit()
        }
    }
    
    // Функция для проверки, что щетка опущена
    function check_brush_down() {
        $.send("G4P0.1")
        // Если датчик опускания щетки не установлен, сразу выходим из функции
        if (brush_down_signal == "i-1") {
            return
        }
        var try_count = 0
        while (try_count < 20) {
            if (get_brush_sensors_value() == 0) {
                // Щетка опустилась, выходим из цикла проверки датчиков
                break;
            }
            var try_count = try_count + 1
            $.send("G4P0.1")
        }
        
        var sensor_value = get_brush_sensors_value()
        if (sensor_value == 0) {
            // Всё хорошо, щетка опущена
        }
        else {
            $.message("Щетка не опустилась!")
        }
    }
    
    // Функция для установки нового инструмента в шпиндель
    function install_new_tool(tool_num) {
        // Устанавливаем новый инструмент
    
        if (BASKET_LOCATION == 1) {
            // Магазин инструментов закреплен на столе
            
            // Подъезжаем к позиции отступа без инструмента
            $.send("G1G53G90X" + String(HOLDERS_X_POS[tool_num - 1] + MOVE_WITHOUT_TOOL_OFFSET_X) + "Y" + String(HOLDERS_Y_POS[tool_num - 1] + MOVE_WITHOUT_TOOL_OFFSET_Y) + "F" + String(FAST_RATE_XY))
            $.send("G1G53G90Z" + String(HOLDERS_Z_POS[tool_num - 1] + MOVE_WITHOUT_TOOL_OFFSET_Z) + "F" + String(FAST_RATE_Z))
            
            // Проверяем, что магазин инструментов открыт
            if(NEED_TOOL_BASKET_CONTROL) {
                tool_basket_on_if_closed()
                check_tool_basket_on()
            }
        
            // Продуваем патрон и опускаемся в позицию установки нового инструмента
            if(NEED_BLOW_TOOL) {
                blow_tool()
            }

            // Опускаемся в позицию захвата инструмента (без инструмента)
            $.send("G1G91X" + String(-MOVE_WITHOUT_TOOL_OFFSET_X) + "Y" + String(-MOVE_WITHOUT_TOOL_OFFSET_Y) + "F" + String(SLOW_RATE_XY))
            $.send("G1G91Z" + String(-MOVE_WITHOUT_TOOL_OFFSET_Z) + "F" + String(SLOW_RATE_Z))
        
            // Захватываем инструмент
            catch_tool()
            
            // Проверяем, что инструмент захвачен в патрон
            if(NEED_CHECK_TOOL_SENSORS) {
                check_tool_caught()
            }
            
            // Устанавливаем в системе номер инструмента
            $.send("T" + String(tool_num))
        
            // Поднимаемся на расстояние отступа с инструментом
            $.send("G1G91X" + String(MOVE_WITH_TOOL_OFFSET_X) + "Y" + String(MOVE_WITH_TOOL_OFFSET_Y) + "F" + String(SLOW_RATE_XY))
            $.send("G1G91Z" + MOVE_WITH_TOOL_OFFSET_Z + "F" + SLOW_RATE_Z)
            
            // Поднимаемся на безопасную высоту
            $.send("G90G1G53Z" + String(SAFE_Z_POS) + "F" + String(FAST_RATE_Z))
            
            $.send("G4P0.1")
            
            if(NEED_TOOL_BASKET_CONTROL) {
                tool_basket_off()
                check_tool_basket_off()
            }
        }
        else if (BASKET_LOCATION == 2) {
            // Магазин инструментов установлен под порталом
            
            // Поднимаемся на безопасную высоту
            $.send("G90G1G53Z" + String(SAFE_Z_POS) + "F" + String(FAST_RATE_Z))
            
            // Открываем магазин и проверяем, что он открылся
            if(NEED_TOOL_BASKET_CONTROL) {
                tool_basket_on_if_closed()
                check_tool_basket_on()
            }
        
            // Подъезжаем к позиции отступа без инструмента
            if (HOLDERS_ORIENTATION_AXIS == "X") {
                $.send("G1G53G90X" + String(HOLDERS_X_POS[tool_num - 1] + MOVE_WITHOUT_TOOL_OFFSET_X) + "F" + String(FAST_RATE_XY))
            }
            else if (HOLDERS_ORIENTATION_AXIS == "Y") {
                $.send("G1G53G90Y" + String(HOLDERS_Y_POS[tool_num - 1] + MOVE_WITHOUT_TOOL_OFFSET_Y) + "F" + String(FAST_RATE_XY))
            }
            $.send("G1G53G90Z" + String(HOLDERS_Z_POS[tool_num - 1] + MOVE_WITHOUT_TOOL_OFFSET_Z) + "F" + String(FAST_RATE_Z))
        
            // Продуваем патрон и опускаемся в позицию установки нового инструмента
            if(NEED_BLOW_TOOL) {
                blow_tool()
            }

            // Опускаемся в позицию захвата инструмента (без инструмента)
            $.send("G1G91X" + String(-MOVE_WITHOUT_TOOL_OFFSET_X) + "Y" + String(-MOVE_WITHOUT_TOOL_OFFSET_Y) + "F" + String(SLOW_RATE_XY))
            $.send("G1G91Z" + String(-MOVE_WITHOUT_TOOL_OFFSET_Z) + "F" + String(SLOW_RATE_Z))
        
            // Захватываем инструмент
            catch_tool()
            
            // Проверяем, что инструмент захвачен в патрон
            if(NEED_CHECK_TOOL_SENSORS) {
                check_tool_caught()
            }
            
            // Закрываем магазин инструментов, после этого инструмент остается зажатым в патроне
            if(NEED_TOOL_BASKET_CONTROL) {
                tool_basket_off()
                check_tool_basket_off()
            }
            
            // Устанавливаем в системе номер инструмента
            $.send("T" + String(tool_num))
        
            // Поднимаемся на расстояние отступа с инструментом
            $.send("G1G91X" + String(MOVE_WITH_TOOL_OFFSET_X) + "Y" + String(MOVE_WITH_TOOL_OFFSET_Y) + "F" + String(SLOW_RATE_XY))
            $.send("G1G91Z" + MOVE_WITH_TOOL_OFFSET_Z + "F" + SLOW_RATE_Z)
            
            // Поднимаемся на безопасную высоту
            $.send("G90G1G53Z" + String(SAFE_Z_POS) + "F" + String(FAST_RATE_Z))
        }
        
        $.send("G4P0.5")
    }
    
    // Функция сброса текущего инструмента в магазин
    function drop_current_tool(tool_num) {
        // Сбрасываем текущий инструмент в магазин

        // Поднимаемся на безопасную высоту
        $.send("G90G1G53Z" + String(SAFE_Z_POS) + "F" + String(FAST_RATE_Z))
        
        if (BASKET_LOCATION == 1) {
            // Магазин инструментов закреплен на столе
                        
            // Опускаемся на расстояние отступа на быстрой скорости
            $.send("G1G53G90X" + String(HOLDERS_X_POS[tool_num - 1] + MOVE_WITH_TOOL_OFFSET_X) + "Y" + String(HOLDERS_Y_POS[tool_num - 1] + MOVE_WITH_TOOL_OFFSET_Y) + "F" + String(FAST_RATE_XY))
            $.send("G1G53G90Z" + String(HOLDERS_Z_POS[tool_num - 1] + MOVE_WITH_TOOL_OFFSET_Z) + "F" + String(FAST_RATE_Z))
            
            if(NEED_TOOL_BASKET_CONTROL) {
                tool_basket_on()
                check_tool_basket_on()
            }
            
            $.send("G4P0.1")

            // На медленной скорости движемся в позицию магазина (с инструментом)
            $.send("G1G91X" + String(-MOVE_WITH_TOOL_OFFSET_X) + "Y" + String(-MOVE_WITH_TOOL_OFFSET_Y) + "F" + String(SLOW_RATE_XY))
            $.send("G1G91Z" + String(-MOVE_WITH_TOOL_OFFSET_Z) + "F" + String(SLOW_RATE_Z))
            
            // Отправляем команду сброса инструмента на пневмомеханизм
            release_tool()
            
            // Проверяем, что цанга разжата
            if(NEED_CHECK_TOOL_SENSORS) {
                check_tool_released()
            }
            
            // Поднимаемся на расстояние отступа без инструмента на медленной скорости
            $.send("G1G91X" + String(MOVE_WITHOUT_TOOL_OFFSET_X) + "Y" + String(MOVE_WITHOUT_TOOL_OFFSET_Y) + "F" + String(SLOW_RATE_XY))
            $.send("G1G91Z" + String(MOVE_WITHOUT_TOOL_OFFSET_Z) + "F" + String(SLOW_RATE_Z))
        }
        else if (BASKET_LOCATION == 2) {
            // Магазин инструментов установлен под порталом
            
            // Закрываем магазин инструментов
            if(NEED_TOOL_BASKET_CONTROL) {
                tool_basket_off_if_opened()
                check_tool_basket_off()
            }
                            
            // Перемещаемся с инструментом на позицию отступа на быстрой скорости
            if (HOLDERS_ORIENTATION_AXIS == "X") {
                $.send("G1G53G90X" + String(HOLDERS_X_POS[tool_num - 1] + MOVE_WITH_TOOL_OFFSET_X) + "F" + String(FAST_RATE_XY))
            }
            else if (HOLDERS_ORIENTATION_AXIS == "Y") {
                $.send("G1G53G90Y" + String(HOLDERS_Y_POS[tool_num - 1] + MOVE_WITH_TOOL_OFFSET_Y) + "F" + String(FAST_RATE_XY))
            }
            $.send("G1G53G90Z" + String(HOLDERS_Z_POS[tool_num - 1] + MOVE_WITH_TOOL_OFFSET_Z) + "F" + String(FAST_RATE_Z))
            
            // Открываем магазин инструментов
            if(NEED_TOOL_BASKET_CONTROL) {
                tool_basket_on()
                check_tool_basket_on()
            }
            

            // На медленной скорости движемся в позицию магазина (с инструментом)
            $.send("G1G91X" + String(-MOVE_WITH_TOOL_OFFSET_X) + "Y" + String(-MOVE_WITH_TOOL_OFFSET_Y) + "F" + String(SLOW_RATE_XY))
            $.send("G1G91Z" + String(-MOVE_WITH_TOOL_OFFSET_Z) + "F" + String(SLOW_RATE_Z))
            
            // Отправляем команду сброса инструмента на пневмомеханизм
            release_tool()
            
            // Проверяем, что цанга разжата
            if(NEED_CHECK_TOOL_SENSORS) {
                check_tool_released()
            }
            
            // Поднимаемся на расстояние отступа без инструмента на медленной скорости
            $.send("G1G91X" + String(MOVE_WITHOUT_TOOL_OFFSET_X) + "Y" + String(MOVE_WITHOUT_TOOL_OFFSET_Y) + "F" + String(SLOW_RATE_XY))
            $.send("G1G91Z" + String(MOVE_WITHOUT_TOOL_OFFSET_Z) + "F" + String(SLOW_RATE_Z))
        }
        
        // Проверяем, что в патроне нет инструмента
        if(NEED_CHECK_TOOL_SENSORS) {
            check_no_tool_installed()
        }
        
        // Т.к. в шпинделе инструмента нет, то устанавливаем в системе нулевой инструмент
        $.send("T0")
        
        // Поднимаемся на безопасную высоту
        $.send("G90G1G53Z" + String(SAFE_Z_POS) + "F" + String(FAST_RATE_Z))
        
        $.send("G4P0.5")
    }

    // Установка длины инструмента.
    function set_tool_len(tool_num, tool_len) {
        $.send("G10L1P" + String(tool_num) + "Z" + String(tool_len.toFixed(3)))
    }

    // Функция измерения машинной координаты кончика инструмента
    function tool_measure(tool_num) {
        $.send("G90G1G53Z" + String(SAFE_Z_POS) + "F" + String(FAST_RATE_Z))
        $.send("G1G53G90X" + String(PROBE_X_MPOS) + "Y" + String(PROBE_Y_MPOS) + "F" + String(FAST_RATE_XY))
        
        $.send("G1G53G90Z" + String(PROBE_Z_MPOS) + "F" + String(FAST_RATE_Z))
        
        $.send("G21G91G38.2Z-" + String($.params.maxTravelValueZ) + "F" + String(FAST_RATE_PROBE))
        $.send("G0Z1")
        $.send("G38.2Z-3F" + String(SLOW_RATE_PROBE))
        
        $.send("G4P0.1")

        set_tool_len(tool_num, $.prb.z)
        
        $.send("G4P0.1")
        
        $.send("G90G1G53Z" + String(SAFE_Z_POS) + "F" + String(FAST_RATE_Z))
    }
}

Макрос смены инструмента

Нажмите, чтобы показать код макроса
{
    /*
    Макрос автоматической смены инструмента. Работает на версии визуализатора 4.3 и выше.
    Макрос нужно сделать невидимым - он не предназначен для запуска по кнопке. Вызывается только 
    при выполнении УП по команде M6(M06).
    Данный макрос необходимо назначить на макровызов для команды M0?6.
    Использует для своей работы настройки и функции из библиотек ATC_VLIB и ATC_FLIB.
    */
    
    
    // include "ATC_VLIB"
    // include "ATC_FLIB"
    var current_tool = $.tc
    var next_tool = $.tn

    if (next_tool < 1 || next_tool > TOOLS_NUMBER) {
        $.message("Неверный номер следующего инструмента!");
        $.exit()
    }
    
    var tool_installed = 1
}

{
    // Функция проверки всех датчиков шпинделя
    function check_tool_sensors() {
        $.send("G4P0.1")
        var sensor_value = get_tool_sensors_value()
        if ( sensor_value == 2) {
            // Оба датчика инструмента либо одновременно активны, либо одновременно неактивны
            $.message("Неверное состояние датчиков инструмента: невозможно определить состояние инструмента в шпинделе!")
            $.tasklist.stop()
            $.exit()
        }
        else if(sensor_value == 1) {
            // Инстурмент установлен в шпиндель
            tool_installed = 1
        }
        else if(sensor_value == 0) {
            // Шпиндель свободен
            tool_installed = 0
        }
        else {
            $.message("Невозможно определить состояние инструмента в шпинделе!")
            //$.send("T" + String(current_tool))
            $.tasklist.stop()
            $.exit()
        }
    }
}

G4P0.1

G1G90G53Z{SAFE_Z_POS}F{FAST_RATE_Z}
M5
G4P{SPINDLE_STOP_TIMEOUT}

{
    // Проверяем датчики шпинделя, чтобы определить, установлен ли перед началом процедур инструмент
    if(NEED_CHECK_TOOL_SENSORS) {
        check_tool_sensors()
    }
    else {
        if(current_tool == 0) {
            tool_installed = 0
        }
    }
    
    if(tool_installed) {
        if (current_tool < 1 || current_tool > TOOLS_NUMBER) {
            $.message("Неверный номер текущего установленного инструмента: " + current_tool);
            $.tasklist.stop()
            $.exit()
        }
        
        if (next_tool == current_tool) {
            //$.message("Новый инструмент совпадает с текущим, смена не требуется!")
            if(NEED_BRUSH_CONTROL) {
                set_brush_down()
                check_brush_down()
            }
            $.exit() 
        }
    }
    
    // Запоминаем текущие рабочие координаты, из которых запускаем процедуру смены инструменты, чтобы в конце процедуры вернуться в эту же позицию
    if (tool_installed) {
        var startX = $.wc.x
        var startY = $.wc.y
        //var startZ = $.wc.z
    }
    else {
        var startX = 0
        var startY = 0
        //var startZ = $.wc.z
    }
    
    // Запоминаем текущие обороты шпинделя и скорость подачи
    var gcodeSpindleSpeed = $.gc.s
    var gcodeFeedRate = $.gc.f
    
    // Поднимаем щетку
    if(NEED_BRUSH_CONTROL) {
        set_brush_up()
        check_brush_up()
    }    
}

G4P0.1

{
    // Для безопасности перед началом процедуры закрываем магазин и проверяем, что он закрыт
    if(NEED_TOOL_BASKET_CONTROL) {
        tool_basket_off()
        check_tool_basket_off()
    }
}

G4P0.1

{
    if (tool_installed) {
        // Сбрасываем текущий инструмент в магазин при условии, что в патрон инструмент сейчас установлен 
        drop_current_tool(current_tool)
    }
}

G4P0.1

{
    // Устанавливаем новый инструмент
    install_new_tool(next_tool)
    
    $.send("G4P0.1")
    
    //Закрываем магазин инструментов
    if (NEED_TOOL_BASKET_CONTROL) {
        tool_basket_off()
        $.send("G4P0.1")
        //Проверяем, что магазин закрылся
        check_tool_basket_off()
    }
}

G4P0.1

{
    $.send("G1G90X" + String(startX.toFixed(3)) + "Y" + String(startY.toFixed(3)) + "F" + String(FAST_RATE_XY))
    $.send("G4P0.1")
    if(NEED_BRUSH_CONTROL) {
        set_brush_down()
        check_brush_down()
    }
    
}

Макрос построения таблицы инструментов

Нажмите, чтобы показать код макроса
{
    /*
    Макрос создания таблицы инструментов. Работает на версии визуализатора 4.3 и выше.
    Данный макрос вызывается по кнопке на панели Макросы.
    Использует для своей работы настройки и функции из библиотек ATC_VLIB и ATC_FLIB.
    */
    
    
    // include "ATC_VLIB"
    // include "ATC_FLIB"
    
    var current_tool = 1
    var installed_tool_id = -1
    var last_tool = TOOLS_NUMBER
}

{
    // Функция проверки всех датчиков шпинделя
    function check_tool_sensors() {
        $.send("G4P0.1")
        var sensor_value = get_tool_sensors_value()
        if ( sensor_value == 2) {
            // Оба датчика инструмента либо одновременно активны, либо одновременно неактивны
            $.message("Неверное состояние датчиков инструмента: невозможно определить состояние инструмента в шпинделе!")
            //$.tasklist.stop()
            $.exit()
        }
        else if(sensor_value == 1) {
            // Инстурмент установлен в шпиндель
            tool_installed = 1
            installed_tool_id = $.tc
            if (installed_tool_id == 0) {
                installed_tool_id = -1
            }
        }
        else if(sensor_value == 0) {
            // Шпиндель свободен
            tool_installed = 0
        }
        else {
            $.message("Невозможно определить состояние инструмента в шпинделе!")
            //$.send("T" + String(current_tool))
            //$.tasklist.stop()
            $.exit()
        }
    }
}

{
    var p = $.input("Введите номер инструмента для измерения (0 - все инструменты)", ["Номер инструмента (от 0 до " + String(TOOLS_NUMBER) + ")"], [0])
    
    if(!p.length) {
        $.exit()
    }
    
    var tools_to_measure = parseInt(p[0])
    
    if(tools_to_measure < 0 || tools_to_measure > TOOLS_NUMBER)  {
        $.message("Неверный номер инструмента!")
        $.exit()
    }
    
    if(tools_to_measure == 0) {
        var current_tool = 1
        var last_tool = TOOLS_NUMBER
    }
    else {
        var current_tool = tools_to_measure
        var last_tool = tools_to_measure
    }
    
}

{
    $.send("G4P0.1")
    
    // Поднимаем щетку
    if(NEED_BRUSH_CONTROL) {
        set_brush_up()
        check_brush_up()
    }
    
    // Проверяем датчики шпинделя, чтобы определить, установлен ли перед началом процедуры инструмент
    if(NEED_CHECK_TOOL_SENSORS) {
        check_tool_sensors()
    }
    else {
        var installed_tool_id = $.tc
        if (installed_tool_id == 0) {
            var installed_tool_id = -1
        }
    }
}

{
    // Для безопасности перед началом процедуры закрываем магазин и проверяем, что он закрыт
    if(NEED_TOOL_BASKET_CONTROL) {
        tool_basket_off()
        check_tool_basket_off()
    }
        
    if (installed_tool_id == current_tool && (installed_tool_id == tools_to_measure || tools_to_measure == 0)) {
        // Мы выбрали измерение инструмента, который уже установлен в патрон. Просто запускаем для него процедуру измерения и оставляем в патроне по завершении
        
        tool_measure(current_tool)    

        $.send("G4P0.1")
        
        $.send("G90G1G53Z" + SAFE_Z_POS + "F" + FAST_RATE_Z)
        
        //Выходим из макроса, если на измерении только один инструмент должен быть. Если был введён 0 и изначально в патроне 1й инструмент, то после измерения его скидываем, и переходим на 2-й.
        if(tools_to_measure > 0) {
            $.exit()
        }
        else {
            drop_current_tool(installed_tool_id)
            $.send("G4P0.1")
            var current_tool = current_tool + 1
        }
    }
    else if(installed_tool_id != -1) {
        // Установлен инструмент, который не нужно измерять сразу -  сбрасываем его в магазин перед началом работы
        drop_current_tool(installed_tool_id)
        
        $.send("G4P0.1")
    }
}


{
    while (current_tool <= last_tool) {

        // Устанавливаем первый инструмент
        install_new_tool(current_tool)

        $.send("G4P0.1")

        tool_measure(current_tool)    

        $.send("G4P0.1")

        $.send("G90G1G53Z" + SAFE_Z_POS + "F" + FAST_RATE_Z)
        
        if (tools_to_measure > 0 && tools_to_measure == current_tool) {
            // Если в начале процедуры мы выбрали только один инструмент, то после измерения его и оставляем в патроне. Выход из цикла.
            break
        }

        $.send("G4P0.1")

        // Сбрасываем текущий инструмент в магазин    
        drop_current_tool(current_tool)

        $.send("G4P0.1")

        var current_tool = current_tool + 1
        
    }
}

G4P0.1

{
    if (tools_to_measure == 0) {
        // Если измеряли все инструменты, то в конце процедуры устанавливаем первый инструмент
        install_new_tool(1)
    }
    else {
        if(NEED_TOOL_BASKET_CONTROL) {
            tool_basket_off_if_opened()
            check_tool_basket_off()
        }
    }
    
}

Макрос сброса инструмента

Нажмите, чтобы показать код макроса
{
    /*
    Макрос для сброса текущего инструмента в патрон. Работает на версии визуализатора 4.3 и выше.
    Данный макрос вызывается по кнопке на панели Макросы.
    Использует для своей работы настройки и функции из библиотек ATC_VLIB и ATC_FLIB.
    */
    
    
    // include "ATC_VLIB"
    // include "ATC_FLIB"

    var current_tool = $.tc
    var tool_installed = 1
}

{    
    // Функция проверки всех датчиков шпинделя
    function check_tool_sensors() {
        $.send("G4P0.1")
        var sensor_value = get_tool_sensors_value()
        if ( sensor_value == 2) {
            // Оба датчика инструмента либо одновременно активны, либо одновременно неактивны
            $.message("Неверное состояние датчиков инструмента: невозможно определить состояние инструмента в шпинделе!")
            $.exit()
        }
        else if(sensor_value == 1) {
            // Инстурмент установлен в шпиндель
            tool_installed = 1
        }
        else if(sensor_value == 0) {
            // Шпиндель свободен
            tool_installed = 0
        }
        else {
            $.message("Невозможно определить состояние инструмента в шпинделе!")
            $.exit()
        }
    }
}

G4P0.1

{
    // Проверяем датчики шпинделя, чтобы определить, установлен ли перед началом процедур инструмент
    if(NEED_CHECK_TOOL_SENSORS) {
        check_tool_sensors()
    }
    else {
        if(current_tool == 0) {
            tool_installed = 0
        }
    }
    
    if(tool_installed) {
        if (current_tool < 1 || current_tool > TOOLS_NUMBER) {
            $.message("Неверный номер текущего установленного инструмента: " + current_tool);
            $.exit()
        }
    }
    else {
        $.message("Инструмент не устанавлен!")
        $.exit()
    }
    
    // Поднимаемся на безопасную высоту
    $.send("G90G1G53Z" + String(SAFE_Z_POS) + "F" + String(FAST_RATE_Z))
    
    // Поднимаем щетку
    if(NEED_BRUSH_CONTROL) {
        set_brush_up()
        check_brush_up()
    }    
}

G4P0.1

{
    // Для безопасности перед началом процедуры закрываем магазин и проверяем, что он закрыт
    if(NEED_TOOL_BASKET_CONTROL) {
        tool_basket_off()
        check_tool_basket_off()
    }

    // Сбрасываем текущий инструмент в магазин при условии, что в патрон инструмент сейчас установлен 
    drop_current_tool(current_tool)
    
    $.send("G4P0.1")
    
    if(NEED_TOOL_BASKET_CONTROL) {
        tool_basket_off()
        check_tool_basket_off()
    }
}

G4P0.1

Макросы карусельной смены инструмента

Библиотека переменных

Нажмите, чтобы показать код макроса
{
    /* ****** Перед началом использования обязательно сконфигурить все параметры ниже под Ваш станок *****
    Макрос работает на версии визуализатора 4.3 и выше.
    Макрос необходимо назвать ATC_VLIB - именно по этому имени он подключается в макросах автосмены инструмента.
    Макрос нужно сделать скрытым.
    */
    
    // Размер магазина инструментов
    var TOOLS_NUMBER = 8
    
    // Машинная координата X позиции смены инструмента - обязательно нужно настроить своё значение
    var ATC_X_MPOS = 0
    
    // Машинная координата Y позиции смены инструмента - обязательно нужно настроить своё значение
    var ATC_Y_MPOS = 0
    
    // Машинная координата Z позиции смены инструмента - обязательно нужно настроить своё значение
    var ATC_Z_MPOS = -80
    
    // Ось, к которой подключена карусель
    var ROTARY_AXIS = "A"
    
    // Массив координат поворотной оси позиций инструментов в магазине
    var HOLDERS_ROTARY_POS = [20, 40, 60, 80, 100, 120, 140, 160]
    
    // Расстояние для захода в позицию магазина с инструментом для его сброса, а также расстояние выхода из магазина с только что установленным инструментом
    var MOVE_WITH_TOOL_OFFSET_X = -100
    var MOVE_WITH_TOOL_OFFSET_Y = 0
    var MOVE_WITH_TOOL_OFFSET_Z = 0

    // Расстояние ухода с позиции в магазине без инструмента (для снятия), а также захода в позицию магазина без инструмента (для его захвата)
    var MOVE_WITHOUT_TOOL_OFFSET_X = 0
    var MOVE_WITHOUT_TOOL_OFFSET_Y = 0
    var MOVE_WITHOUT_TOOL_OFFSET_Z = 70
    
    // Безопасная высота - все перемещения желательно выполнять на безопасной высоте, по умолчанию это машинный 0 по Z
    var SAFE_Z_POS = 0
    
    // Быстрая скорость перемещения по Z
    var FAST_RATE_Z = 2000
    
    // Медленная скорость перемещения по Z
    var SLOW_RATE_Z = 500
    
    // Быстрая скорость перемещения по X,Y
    var FAST_RATE_XY = 5000
    
    // Медленная скорость перемещения по X,Y
    var SLOW_RATE_XY = 500

    // Таймаут на остановку шпинделя
    var SPINDLE_STOP_TIMEOUT = 1
    
    // !!! Ниже обязательно нужно настроить машинные коориднаты позиции, где стоит шайба !!!
    // Шпиндель будет автоматически приезжать в эту позицию для измерения длины инструмента
    var PROBE_X_MPOS = 375
    var PROBE_Y_MPOS = 2982
    var PROBE_Z_MPOS = -70
    
    // Скорость быстрого поиска шайбы (первый этап зондирования)
    var FAST_RATE_PROBE = 200
    // Калибровочная подача поиска шайбы (второй этап зондирования)
    var SLOW_RATE_PROBE = 10
    
    // Ниже сервисные переменные для активации тех или иных действий в процедуре смены инструмента
    // Продувка инструмента. 0 - продувки нет.
    var NEED_BLOW_TOOL = 1
    
    // Требуется ли проверка датчиков захвата/освобождения инструмента
    var NEED_CHECK_TOOL_SENSORS = 1
    
    // Требуется ли выполнять подъем/опускание щетки отдельной командой
    var NEED_BRUSH_CONTROL = 0
    
    // Требуется ли управлять открытием/закрытием магазина инструментов
    var NEED_TOOL_BASKET_CONTROL = 0
    
    // Ниже список входов контроллера, к которым подключены датчики. Например, 8 ознаечает подключение ко входу IN8 (переопределенный HOLD).
    // Если сигнал не используется, присвойте ему значение -1
    // Сигнал поднятой щетки
    var BRUSH_UP_INPUT_ID = -1
    // Сигнал опущенной щетки
    var BRUSH_DOWN_INPUT_ID = -1
    // Сигнал наличия инструмента в патроне
    var TOOL_CAUGHT_INPUT_ID = 7
    // Сигнал отсутствия инструмента в патроне
    var TOOL_RELEASED_INPUT_ID = 8
    // Сигнал открытия магазина инструментов
    var BASKET_ON_INPUT_ID = -1
    // Сигнал закрытия магазина инструментов
    var BASKET_OFF_INPUT_ID = -1

    // Ниже список задействованных релейных выходов. Например, значение 5 означает, используется выход OUT5.
    // Номер выхода управления захватом/освобождения инструмента
    var TOOL_CTRL_PORTNO = 5
    // Номер выхода управления щеткой
    var BRUSH_CTRL_PORTNO = 6
    // Номер выхода продувки инструмента
    var TOOL_BLOW_PORTNO = 7
    // Номер выхода управления магазином
    var BASKET_CTRL_PORTNO = 4
    
    // Ниже параметры задают, по какому действию релейного выхода осуществляется активация периферии
    // Если TOOL_RELEASE_IF_RLY_ON == 1, то освобождение инструмента осуществляется активацией (M64) управляющего им выхода. Если 0 - деактивацией (M65)
    var TOOL_RELEASE_IF_RLY_ON = 1
    // Если BRUSH_UP_IF_RLY_ON == 1, то подъем щетки осуществляется активацией (M64) управляющего ей выхода. Если 0 - деактивацией (M65)
    var BRUSH_UP_IF_RLY_ON = 1
    // Если BASKET_OPEN_IF_RLY_ON == 1, то открытие магазина осуществляется активацией (M64) управляющего им выхода. Если 0 - деактивацией (M65)
    var BASKET_OPEN_IF_RLY_ON = 1
    // Если BLOW_TOOL_IF_RLY_ON == 1, то продув патрона осуществляется активацией (M64) управляющего выхода. Если 0 - деактивацией (M65)
    var BLOW_TOOL_IF_RLY_ON = 1
}

Библиотека функций

Нажмите, чтобы показать код макроса
{    
    /*
    Макрос работает на версии визуализатора 4.3 и выше.
    Макрос необходимо назвать ATC_FLIB - именно по этому имени он подключается в макросах автосмены инструмента.
    Макрос нужно сделать скрытым.
    */
    
    // include "ATC_VLIB"
    
    var brush_up_signal = "i" + String(BRUSH_UP_INPUT_ID)
    var brush_down_signal = "i" + String(BRUSH_DOWN_INPUT_ID)
    var tool_caught_signal = "i" + String(TOOL_CAUGHT_INPUT_ID)
    var tool_released_signal = "i" + String(TOOL_RELEASED_INPUT_ID)
    var basket_on_signal = "i" + String(BASKET_ON_INPUT_ID)
    var basket_off_signal = "i" + String(BASKET_OFF_INPUT_ID)

    // Функция освобождения инструмента из патрона путем включения реле, подключенного к выходу TOOL_CTRL_PORTNO
    function release_tool() {
        var port_mask = Math.pow(2, TOOL_CTRL_PORTNO-1)
        if (TOOL_RELEASE_IF_RLY_ON == 1) {
            $.send("M64P" + String(port_mask))
        }
        else {
            $.send("M65P" + String(port_mask))
        }
        if (tool_released_signal == "i-1") {
            $.send("G4P2")
        }
    }
    
    // Функция захвата инструмента в патрон путем выключения реле, подключенного к выходу TOOL_CTRL_PORTNO
    function catch_tool() {
        var port_mask = Math.pow(2, TOOL_CTRL_PORTNO-1)
        if (TOOL_RELEASE_IF_RLY_ON == 1) {
            $.send("M65P" + String(port_mask))
        }
        else {
            $.send("M64P" + String(port_mask))
        }
        if (tool_caught_signal == "i-1") {
            $.send("G4P2")
        }
    }
    
    function get_basket_sensors_value() {
        // 0 - магазин закрыт
        // 1 - магазин открыт
        // 2 - неверное состояние, когда оба датчика имеют одинаковое состояние
        // 3 - датчики магазина не установлены, проверку делать не нужно
        if (basket_on_signal != "i-1" || basket_off_signal != "i-1") {
            var sensor_value = 0
            if (basket_on_signal != "i-1" && basket_off_signal != "i-1") {
                var sensor_value = $.inputs[basket_on_signal] && !$.inputs[basket_off_signal]
                if (sensor_value == 0) {
                    if( ($.inputs[basket_on_signal] && $.inputs[basket_off_signal]) || (!$.inputs[basket_on_signal] && !$.inputs[basket_off_signal]) ) {
                        // Неверное состояние: оба датчика либо одновременно активны, либо одновременно неактивны
                        var sensor_value = 2
                    }
                }
            }
            else if (basket_on_signal != "i-1") {
                var sensor_value = $.inputs[basket_on_signal]
            }
            else {
                var sensor_value = !$.inputs[basket_off_signal]
            }
            return sensor_value
        }
        else {
            return 3
        }
    }
    
    // Функция открытия магазина инструментов путем включения реле, подключенного к выходу BASKET_CTRL_PORTNO
    function tool_basket_on() {
        var sensor_value = get_basket_sensors_value()
        // Проверяем состояние магазина инструментов перед началом процедуры смены инструмента
        if (sensor_value == 2) {
            // Оба датчика магазина либо одновременно активны, либо одновременно неактивны
            $.message("Неверное состояние датчиков магазина инструментов: невозможно определить его состояние!")
            $.tasklist.stop()
            $.exit()
        }
        
        if(sensor_value == 0 || sensor_value == 3) {
            var port_mask = Math.pow(2, BASKET_CTRL_PORTNO-1)
            //Магазин инструментов закрыт, открываем его
            if (BASKET_OPEN_IF_RLY_ON == 1) {
                $.send("M64P" + String(port_mask))
            }
            else {
                $.send("M65P" + String(port_mask))
            }
            // Если датчик открытия инструмента не установлен, то безусловно отправляем таймаут на открытие инструмента
            if(basket_on_signal == "i-1") {
                $.send("G4P2")
            }
        }
    }
    
    // Функция закрытия магазина инструментов путем выключения реле, подключенного к выходу BASKET_CTRL_PORTNO
    function tool_basket_off() {
        var port_mask = Math.pow(2, BASKET_CTRL_PORTNO-1)
        if (BASKET_OPEN_IF_RLY_ON == 1) {
            $.send("M65P" + String(port_mask))
        }
        else {
            $.send("M64P" + String(port_mask))
        }
        // Если датчик закрытия инструмента не подключен, то безусловно отправляем таймаут на закрытие магазина.
        if(basket_off_signal == "i-1") {
            $.send("G4P3")
        }
    }
    
    function blow_tool() {
        var port_mask = Math.pow(2, BASKET_CTRL_PORTNO-1)
        
        // Пускаем воздух для продувки инструмента
        if (BLOW_TOOL_IF_RLY_ON == 1) {
            $.send("M64P" + String(port_mask))
        }
        else {
            $.send("M65P" + String(port_mask))
        }
        
        // Выдерживаем паузу для продувки
        $.send("G4P2")
        
        // Отключаем воздух
        if (BLOW_TOOL_IF_RLY_ON == 1) {
            $.send("M65P" + String(port_mask))
        }
        else {
            $.send("M64P" + String(port_mask))
        }
    }
    
    // Функция подъема щетки (включение выхода BRUSH_CTRL_PORTNO)
    function set_brush_up() {
        var port_mask = Math.pow(2, BRUSH_CTRL_PORTNO-1)
        if (BRUSH_UP_IF_RLY_ON == 1) {
            $.send("M64P" + String(port_mask))
        }
        else {
            $.send("M65P" + String(port_mask))
        }
        // Если датчик поднятой щетки не установлен, то безусловно отправляем таймаут на поднятие щетки
        if (brush_up_signal == "i-1") {
            $.send("G4P2")
        }
    }
    
    // Функция опускания щетки (выключение выхода BRUSH_CTRL_PORTNO)
    function set_brush_down() {
        var port_mask = Math.pow(2, BRUSH_CTRL_PORTNO-1)
        if (BRUSH_UP_IF_RLY_ON == 1) {
            $.send("M65P" + String(port_mask))
        }
        else {
            $.send("M64P" + String(port_mask))
        }
        // Если датчик опущенной щетки не установлен, то безусловно отпраляем таймаут на опускание щетки
        if (brush_down_signal == "i-1") {
            $.send("G4P2")
        }
    }
    
    function check_tool_basket_on() {
        // Проверяем, что магазин инструментов открыт
        // Если датчик открытого магазина не установлен, то сразу выходим из функции
        if (basket_on_signal == "i-1") {
            return
        }
        var try_count = 0
        while (try_count < 20) {
            if (get_basket_sensors_value() == 1) {
                // Магазин открылся, выходим из цикла проверки датчиков
                break;
            }
            var try_count = try_count + 1
            $.send("G4P0.1")
        }
        
        var sensor_value = get_basket_sensors_value()
        if (sensor_value == 1) {
            // Всё хорошо, магазни открыт
        }
        else if (sensor_value == 0) {
            $.message("Магазин инструментов не открылся!")
            $.tasklist.stop()
            $.exit()
        }
        else {
            $.message("Неверное состояние датчиков магазина инструментов, невозможно проверить его открытие!")
            $.tasklist.stop()
            $.exit()
        }
    }
    
    function check_tool_basket_off() {
        // Проверяем датчик закрытия магазина инструментов
        // Если датчик закрытого магазина не установлен, то сразу выходим из функции
        if (basket_off_signal == "i-1") {
            return
        }
        var try_count = 0
        while (try_count < 30) {
            if (get_basket_sensors_value() == 0) {
                // Магазин закрылся, выходим из цикла проверки датчиков
                break;
            }
            var try_count = try_count + 1
            $.send("G4P0.1")
        }
        
        var sensor_value = get_basket_sensors_value()
        if (sensor_value == 0) {
            // Всё хорошо, магазни закрыт
        }
        else if (sensor_value = 1) {
            $.message("Магазин инструментов не закрылся!")
            $.tasklist.stop()
            $.exit()
        }
        else {
            $.message("Неверное состояние датчиков магазина инструментов, невозможно проверить его закрытие!")
            $.tasklist.stop()
            $.exit()
        }
    }
    
    function tool_basket_on_if_closed() {
        var sensor_value = get_basket_sensors_value()
        if (sensor_value == 0 || sensor_value == 3) {
            // Всё хорошо, магазни закрыт, можем его открыть
            tool_basket_on()
        }
    }
    
    function tool_basket_off_if_opened() {
        var sensor_value = get_basket_sensors_value()
        if (sensor_value == 1 || sensor_value == 3) {
            // Всё хорошо, магазни открыт, можем его закрыть
            tool_basket_off()
        }
    }
    
    function get_tool_sensors_value() {
        // 0 - отсутствие инструмента
        // 1 - наличие инструмента
        // 2 - неверное состояние, когда оба датчика имеют одинаковое состояние
        if (tool_caught_signal != "i-1" || tool_released_signal != "i-1") {
            var sensor_value = 0
            if (tool_caught_signal != "i-1" && tool_released_signal != "i-1") {
                var sensor_value = $.inputs[tool_caught_signal] && !$.inputs[tool_released_signal]
                if (sensor_value == 0) {
                    if( ($.inputs[tool_caught_signal] && $.inputs[tool_released_signal]) || (!$.inputs[tool_caught_signal] && !$.inputs[tool_released_signal]) ) {
                        // Неверное состояние: оба датчика либо одновременно активны, либо одновременно неактивны
                        var sensor_value = 2
                    }
                }
            }
            else if (tool_caught_signal != "i-1") {
                var sensor_value = $.inputs[tool_caught_signal]
            }
            else {
                var sensor_value = !$.inputs[tool_released_signal]
            }
            return sensor_value
            
        }
        else {
            return 0
        }
    }
    
    // Функция для проверки, что инструмент захвачен в патрон
    function check_tool_caught() {
        $.send("G4P0.1")
        if(tool_caught_signal == "i-1") {
            return
        }
        var try_count = 0
        while (try_count < 20) {
            if (get_tool_sensors_value() == 1) {
                // Инструмент захвачен, выходим из цикла проверки датчиков
                break;
            }
            var try_count = try_count + 1
            $.send("G4P0.1")
        }
        
        var sensors_value = get_tool_sensors_value()
        if (sensors_value == 1) {
            // Всё хорошо, инструмент захвачен, датчик разжатия цанги не активен.
        }
        else if (sensors_value == 0) {
            $.message("Не получен сигнал захвата инструмента либо получен сигнала разжатия цанги!")
            $.tasklist.stop()
            $.exit()
        }
        else {
            $.message("Невозможно определить состояние цанги после захвата инструмента!")
            $.tasklist.stop()
            $.exit()
        }
    }
    
    // Функция для проверки разжатия цанги
    function check_tool_released() {
        $.send("G4P0.1")
        if(tool_released_signal == "i-1") {
            return
        }
        var try_count = 0
        while (try_count < 20) {
            if (get_tool_sensors_value() == 0) {
                // Инструмент освобожден, выходим из цикла проверки датчиков
                break;
            }
            var try_count = try_count + 1
            $.send("G4P0.1")
        }
        
        var sensor_value = get_tool_sensors_value()
        if (sensor_value == 0) {
            // Всё хорошо, цанга разжата
        }
        else if (sensor_value == 1) {
            $.message("Не получен сигнал разжатия цанги либо получен сигнал захвата инструмента!")
            $.tasklist.stop()
            $.exit()
        }
        else {
            $.message("Невозможно определить состояние цанги после освобождения инструмента!")
            $.tasklist.stop()
            $.exit()
        }
    }
    
    // Функция для проверки, что инструмент не установлен в патрон
    function check_no_tool_installed() {
        $.send("G4P0.1")
        if (get_tool_sensors_value() == 0) {
            // Всё хорошо, цанга разжата
        }
        else {
            $.message("Получен сигнал наличия инструмента в патроне после его освобождения!")
            $.tasklist.stop()
            $.exit()
        }
    }
    
    function get_brush_sensors_value() {
        // 0 - щетка внизу
        // 1 - щетка поднята
        // 2 - неверное состояние, когда оба датчика имеют одинаковое значение
        if (brush_up_signal != "i-1" || brush_down_signal != "i-1") {
            var sensor_value = 0
            if (brush_up_signal != "i-1" && brush_down_signal != "i-1") {
                var sensor_value = $.inputs[brush_up_signal] && !$.inputs[brush_down_signal]
                if (sensor_value == 0) {
                    if( ($.inputs[brush_up_signal] && $.inputs[brush_down_signal]) || (!$.inputs[brush_up_signal] && !$.inputs[brush_down_signal]) ) {
                        // Неверное состояние: оба датчика либо одновременно активны, либо одновременно неактивны
                        var sensor_value = 2
                    }
                }
            }
            else if (brush_up_signal != "i-1") {
                var sensor_value = $.inputs[brush_up_signal]
            }
            else {
                var sensor_value = !$.inputs[brush_down_signal]
            }
            return sensor_value
        }
        else {
            return 0
        }
    }
    
    // Функция для проверки, что щетка подтяна
    function check_brush_up() {
        $.send("G4P0.1")
        // Если датчик поднятия щетки не установлен, сразу выходим из функции
        if (brush_up_signal == "i-1") {
            return
        }
        var try_count = 0
        while (try_count < 20) {
            if (get_brush_sensors_value() == 1) {
                // Щетка поднялась, выходим из цикла проверки датчиков
                break;
            }
            var try_count = try_count + 1
            $.send("G4P0.1")
        }
        
        var sensor_value = get_brush_sensors_value()
        if (sensor_value == 1) {
            // Всё хорошо, щетка подтяна
        }
        else {
            $.message("Щетка не поднялась!")
            $.tasklist.stop()
            $.exit()
        }
    }
    
    // Функция для проверки, что щетка опущена
    function check_brush_down() {
        $.send("G4P0.1")
        // Если датчик опускания щетки не установлен, сразу выходим из функции
        if (brush_down_signal == "i-1") {
            return
        }
        var try_count = 0
        while (try_count < 20) {
            if (get_brush_sensors_value() == 0) {
                // Щетка опустилась, выходим из цикла проверки датчиков
                break;
            }
            var try_count = try_count + 1
            $.send("G4P0.1")
        }
        
        var sensor_value = get_brush_sensors_value()
        if (sensor_value == 0) {
            // Всё хорошо, щетка опущена
        }
        else {
            $.message("Щетка не опустилась!")
        }
    }
    
    // Функция для установки нового инструмента в шпиндель
    function install_new_tool(tool_num) {
        // Устанавливаем новый инструмент
        
        // Подъезжаем к позиции отступа без инструмента
        $.send("G1G53G90X" + String(ATC_X_MPOS + MOVE_WITHOUT_TOOL_OFFSET_X) + "Y" + String(ATC_Y_MPOS + MOVE_WITHOUT_TOOL_OFFSET_Y) + "F" + String(FAST_RATE_XY))
        
        $.send("G4P0.1")
        
        // Проверяем, что магазин инструментов открыт
        if(NEED_TOOL_BASKET_CONTROL) {
            tool_basket_on_if_closed()
            check_tool_basket_on()
        }
        
        $.send("G4P0.1")
        
        // Поворачиваем магазин на нужный угол
        $.send("G90G0G53" + ROTARY_AXIS + String(HOLDERS_ROTARY_POS[tool_num - 1]))
        
        $.send("G4P0.1")
        
        $.send("G1G53G90Z" + String(ATC_Z_MPOS + MOVE_WITHOUT_TOOL_OFFSET_Z) + "F" + String(FAST_RATE_Z))
    
        // Продуваем патрон и опускаемся в позицию установки нового инструмента
        if(NEED_BLOW_TOOL) {
            blow_tool()
        }

        // Опускаемся в позицию захвата инструмента (без инструмента)
        $.send("G1G91X" + String(-MOVE_WITHOUT_TOOL_OFFSET_X) + "Y" + String(-MOVE_WITHOUT_TOOL_OFFSET_Y) + "F" + String(SLOW_RATE_XY))
        $.send("G1G91Z" + String(-MOVE_WITHOUT_TOOL_OFFSET_Z) + "F" + String(SLOW_RATE_Z))
    
        // Захватываем инструмент
        catch_tool()
        
        // Проверяем, что инструмент захвачен в патрон
        if(NEED_CHECK_TOOL_SENSORS) {
            check_tool_caught()
        }
        
        // Устанавливаем в системе номер инструмента
        $.send("T" + String(tool_num))
    
        // Поднимаемся на расстояние отступа с инструментом
        $.send("G1G91X" + String(MOVE_WITH_TOOL_OFFSET_X) + "Y" + String(MOVE_WITH_TOOL_OFFSET_Y) + "F" + String(SLOW_RATE_XY))
        $.send("G1G91Z" + MOVE_WITH_TOOL_OFFSET_Z + "F" + SLOW_RATE_Z)
        
        // Поднимаемся на безопасную высоту
        $.send("G90G1G53Z" + String(SAFE_Z_POS) + "F" + String(FAST_RATE_Z))
        
        // Поворачиваем магазин на 0й угол
        $.send("G90G0G53A0")
        
        if(NEED_TOOL_BASKET_CONTROL) {
            tool_basket_off()
            check_tool_basket_off()
        }
        
        $.send("G4P0.1")
    }
    
    // Функция сброса текущего инструмента в магазин
    function drop_current_tool(tool_num) {
        // Сбрасываем текущий инструмент в магазин

        // Поднимаемся на безопасную высоту
        $.send("G90G1G53Z" + String(SAFE_Z_POS) + "F" + String(FAST_RATE_Z))
        
        $.send("G4P0.1")
                        
        // Опускаемся на расстояние отступа на быстрой скорости
        $.send("G1G53G90X" + String(ATC_X_MPOS + MOVE_WITH_TOOL_OFFSET_X) + "Y" + String(ATC_Y_MPOS + MOVE_WITH_TOOL_OFFSET_Y) + "F" + String(FAST_RATE_XY))
        
        $.send("G4P0.1")
        
        if(NEED_TOOL_BASKET_CONTROL) {
            tool_basket_on()
            check_tool_basket_on()
        }
        
        $.send("G4P0.1")
        
        // Поворачиваем магазин на нужный угол
        $.send("G90G0G53" + ROTARY_AXIS + String(HOLDERS_ROTARY_POS[tool_num - 1]))
        
        $.send("G4P0.1")
        
        $.send("G1G53G90Z" + String(ATC_Z_MPOS + MOVE_WITH_TOOL_OFFSET_Z) + "F" + String(FAST_RATE_Z))
        

        // На медленной скорости движемся в позицию магазина (с инструментом)
        $.send("G1G91X" + String(-MOVE_WITH_TOOL_OFFSET_X) + "Y" + String(-MOVE_WITH_TOOL_OFFSET_Y) + "F" + String(SLOW_RATE_XY))
        $.send("G1G91Z" + String(-MOVE_WITH_TOOL_OFFSET_Z) + "F" + String(SLOW_RATE_Z))
        
        // Отправляем команду сброса инструмента на пневмомеханизм
        release_tool()
        
        // Проверяем, что цанга разжата
        if(NEED_CHECK_TOOL_SENSORS) {
            check_tool_released()
        }
        
        // Поднимаемся на расстояние отступа без инструмента на медленной скорости
        $.send("G1G91X" + String(MOVE_WITHOUT_TOOL_OFFSET_X) + "Y" + String(MOVE_WITHOUT_TOOL_OFFSET_Y) + "F" + String(SLOW_RATE_XY))
        $.send("G1G91Z" + String(MOVE_WITHOUT_TOOL_OFFSET_Z) + "F" + String(SLOW_RATE_Z))
        
        // Проверяем, что в патроне нет инструмента
        if(NEED_CHECK_TOOL_SENSORS) {
            check_no_tool_installed()
        }
        
        // Т.к. в шпинделе инструмента нет, то устанавливаем в системе нулевой инструмент
        $.send("T0")
        
        // Поднимаемся на безопасную высоту
        $.send("G90G1G53Z" + String(SAFE_Z_POS) + "F" + String(FAST_RATE_Z))
        
        $.send("G4P0.1")
    }

    // Установка длины инструмента.
    function set_tool_len(tool_num, tool_len) {
        $.send("G10L1P" + String(tool_num) + "Z" + String(tool_len.toFixed(3)))
    }

    // Функция измерения машинной координаты кончика инструмента
    function tool_measure(tool_num) {
        $.send("G90G1G53Z" + String(SAFE_Z_POS) + "F" + String(FAST_RATE_Z))
        $.send("G1G53G90X" + String(PROBE_X_MPOS) + "Y" + String(PROBE_Y_MPOS) + "F" + String(FAST_RATE_XY))
        
        $.send("G1G53G90Z" + String(PROBE_Z_MPOS) + "F" + String(FAST_RATE_Z))
        
        $.send("G21G91G38.2Z-" + String($.params.maxTravelValueZ) + "F" + String(FAST_RATE_PROBE))
        $.send("G0Z1")
        $.send("G38.2Z-3F" + String(SLOW_RATE_PROBE))
        
        $.send("G4P0.1")

        set_tool_len(tool_num, $.prb.z)
        
        $.send("G4P0.1")
        
        $.send("G90G1G53Z" + String(SAFE_Z_POS) + "F" + String(FAST_RATE_Z))
    }
}

Макрос смены инструмента

Нажмите, чтобы показать код макроса
{
    /*
    Макрос автоматической смены инструмента. Работает на версии визуализатора 4.3 и выше.
    Макрос нужно сделать невидимым - он не предназначен для запуска по кнопке. Вызывается только 
    при выполнении УП по команде M6(M06).
    Данный макрос необходимо назначить на макровызов для команды M0?6.
    Использует для своей работы настройки и функции из библиотек ATC_VLIB и ATC_FLIB.
    */
    
    
    // include "ATC_VLIB"
    // include "ATC_FLIB"
    var current_tool = $.tc
    var next_tool = $.tn

    if (next_tool < 1 || next_tool > TOOLS_NUMBER) {
        $.message("Неверный номер следующего инструмента!");
        $.exit()
    }
    
    var tool_installed = 1
}

{
    // Функция проверки всех датчиков шпинделя
    function check_tool_sensors() {
        $.send("G4P0.1")
        var sensor_value = get_tool_sensors_value()
        if ( sensor_value == 2) {
            // Оба датчика инструмента либо одновременно активны, либо одновременно неактивны
            $.message("Неверное состояние датчиков инструмента: невозможно определить состояние инструмента в шпинделе!")
            $.tasklist.stop()
            $.exit()
        }
        else if(sensor_value == 1) {
            // Инстурмент установлен в шпиндель
            tool_installed = 1
        }
        else if(sensor_value == 0) {
            // Шпиндель свободен
            tool_installed = 0
        }
        else {
            $.message("Невозможно определить состояние инструмента в шпинделе!")
            //$.send("T" + String(current_tool))
            $.tasklist.stop()
            $.exit()
        }
    }
}

G4P0.1

G1G90G53Z{SAFE_Z_POS}F{FAST_RATE_Z}
M5
G4P{SPINDLE_STOP_TIMEOUT}

{
    // Проверяем датчики шпинделя, чтобы определить, установлен ли перед началом процедур инструмент
    if(NEED_CHECK_TOOL_SENSORS) {
        check_tool_sensors()
    }
    else {
        if(current_tool == 0) {
            tool_installed = 0
        }
    }
    
    if(tool_installed) {
        if (current_tool < 1 || current_tool > TOOLS_NUMBER) {
            $.message("Неверный номер текущего установленного инструмента: " + current_tool);
            $.tasklist.stop()
            $.exit()
        }
        
        if (next_tool == current_tool) {
            //$.message("Новый инструмент совпадает с текущим, смена не требуется!")
            if(NEED_BRUSH_CONTROL) {
                set_brush_down()
                check_brush_down()
            }
            $.exit() 
        }
    }
    
    // Запоминаем текущие рабочие координаты, из которых запускаем процедуру смены инструменты, чтобы в конце процедуры вернуться в эту же позицию
    if (tool_installed) {
        var startX = $.wc.x
        var startY = $.wc.y
        //var startZ = $.wc.z
    }
    else {
        var startX = 0
        var startY = 0
        //var startZ = $.wc.z
    }
    
    // Запоминаем текущие обороты шпинделя и скорость подачи
    var gcodeSpindleSpeed = $.gc.s
    var gcodeFeedRate = $.gc.f
    
    // Поднимаем щетку
    if(NEED_BRUSH_CONTROL) {
        set_brush_up()
        check_brush_up()
    }    
}

G4P0.1

{
    // Для безопасности перед началом процедуры закрываем магазин и проверяем, что он закрыт
    if(NEED_TOOL_BASKET_CONTROL) {
        tool_basket_off()
        check_tool_basket_off()
    }
}

G4P0.1

{
    if (tool_installed) {
        // Сбрасываем текущий инструмент в магазин при условии, что в патрон инструмент сейчас установлен 
        drop_current_tool(current_tool)
    }
}

G4P0.1

{
    // Устанавливаем новый инструмент
    install_new_tool(next_tool)
    
    $.send("G4P0.1")
    
    //Закрываем магазин инструментов
    if (NEED_TOOL_BASKET_CONTROL) {
        tool_basket_off()
        $.send("G4P0.1")
        //Проверяем, что магазин закрылся
        check_tool_basket_off()
    }
}

G4P0.1

{
    $.send("G1G90X" + String(startX.toFixed(3)) + "Y" + String(startY.toFixed(3)) + "F" + String(FAST_RATE_XY))
    $.send("G4P0.1")
    if(NEED_BRUSH_CONTROL) {
        set_brush_down()
        check_brush_down()
    }
    
}

Макрос построения таблицы инструментов

Нажмите, чтобы показать код макроса
{
    /*
    Макрос создания таблицы инструментов. Работает на версии визуализатора 4.3 и выше.
    Данный макрос вызывается по кнопке на панели Макросы.
    Использует для своей работы настройки и функции из библиотек ATC_VLIB и ATC_FLIB.
    */
    
    
    // include "ATC_VLIB"
    // include "ATC_FLIB"
    
    var current_tool = 1
    var installed_tool_id = -1
    var last_tool = TOOLS_NUMBER
}

{
    // Функция проверки всех датчиков шпинделя
    function check_tool_sensors() {
        $.send("G4P0.1")
        var sensor_value = get_tool_sensors_value()
        if ( sensor_value == 2) {
            // Оба датчика инструмента либо одновременно активны, либо одновременно неактивны
            $.message("Неверное состояние датчиков инструмента: невозможно определить состояние инструмента в шпинделе!")
            //$.tasklist.stop()
            $.exit()
        }
        else if(sensor_value == 1) {
            // Инстурмент установлен в шпиндель
            tool_installed = 1
            installed_tool_id = $.tc
            if (installed_tool_id == 0) {
                installed_tool_id = -1
            }
        }
        else if(sensor_value == 0) {
            // Шпиндель свободен
            tool_installed = 0
        }
        else {
            $.message("Невозможно определить состояние инструмента в шпинделе!")
            //$.send("T" + String(current_tool))
            //$.tasklist.stop()
            $.exit()
        }
    }
}

{
    var p = $.input("Введите номер инструмента для измерения (0 - все инструменты)", ["Номер инструмента (от 0 до " + String(TOOLS_NUMBER) + ")"], [0])
    
    if(!p.length) {
        $.exit()
    }
    
    var tools_to_measure = parseInt(p[0])
    
    if(tools_to_measure < 0 || tools_to_measure > TOOLS_NUMBER)  {
        $.message("Неверный номер инструмента!")
        $.exit()
    }
    
    if(tools_to_measure == 0) {
        var current_tool = 1
        var last_tool = TOOLS_NUMBER
    }
    else {
        var current_tool = tools_to_measure
        var last_tool = tools_to_measure
    }
    
}

{
    $.send("G4P0.1")
    
    // Поднимаем щетку
    if(NEED_BRUSH_CONTROL) {
        set_brush_up()
        check_brush_up()
    }
    
    // Проверяем датчики шпинделя, чтобы определить, установлен ли перед началом процедуры инструмент
    if(NEED_CHECK_TOOL_SENSORS) {
        check_tool_sensors()
    }
    else {
        var installed_tool_id = $.tc
        if (installed_tool_id == 0) {
            var installed_tool_id = -1
        }
    }
}

{
    // Для безопасности перед началом процедуры закрываем магазин и проверяем, что он закрыт
    if(NEED_TOOL_BASKET_CONTROL) {
        tool_busket_off()
        check_tool_busket_off()
    }
        
    if (installed_tool_id == current_tool && (installed_tool_id == tools_to_measure || tools_to_measure == 0)) {
        // Мы выбрали измерение инструмента, который уже установлен в патрон. Просто запускаем для него процедуру измерения и оставляем в патроне по завершении
        
        tool_measure(current_tool)    

        $.send("G4P0.1")
        
        $.send("G90G1G53Z" + SAFE_Z_POS + "F" + FAST_RATE_Z)
        
        //Выходим из макроса, если на измерении только один инструмент должен быть. Если был введён 0 и изначально в патроне 1й инструмент, то после измерения его скидываем, и переходим на 2-й.
        if(tools_to_measure > 0) {
            $.exit()
        }
        else {
            drop_current_tool(installed_tool_id)
            $.send("G4P0.1")
            var current_tool = current_tool + 1
        }
    }
    else if(installed_tool_id != -1) {
        // Установлен инструмент, который не нужно измерять сразу -  сбрасываем его в магазин перед началом работы
        drop_current_tool(installed_tool_id)
        
        $.send("G4P0.1")
    }
}


{
    while (current_tool <= last_tool) {

        // Устанавливаем первый инструмент
        install_new_tool(current_tool)

        $.send("G4P0.1")

        tool_measure(current_tool)    

        $.send("G4P0.1")

        $.send("G90G1G53Z" + SAFE_Z_POS + "F" + FAST_RATE_Z)
        
        if (tools_to_measure > 0 && tools_to_measure == current_tool) {
            // Если в начале процедуры мы выбрали только один инструмент, то после измерения его и оставляем в патроне. Выход из цикла.
            break
        }

        $.send("G4P0.1")

        // Сбрасываем текущий инструмент в магазин    
        drop_current_tool(current_tool)

        $.send("G4P0.1")

        var current_tool = current_tool + 1
        
    }
}

G4P0.1

{
    if (tools_to_measure == 0) {
        // Если измеряли все инструменты, то в конце процедуры устанавливаем первый инструмент
        install_new_tool(1)
    }
    
}

Макрос сброса инструмента

Нажмите, чтобы показать код макроса
{
    /*
    Макрос для сброса текущего инструмента в патрон. Работает на версии визуализатора 4.3 и выше.
    Данный макрос вызывается по кнопке на панели Макросы.
    Использует для своей работы настройки и функции из библиотек ATC_VLIB и ATC_FLIB.
    */
    
    
    // include "ATC_VLIB"
    // include "ATC_FLIB"

    var current_tool = $.tc
    var tool_installed = 1
}

{    
    // Функция проверки всех датчиков шпинделя
    function check_tool_sensors() {
        $.send("G4P0.1")
        var sensor_value = get_tool_sensors_value()
        if ( sensor_value == 2) {
            // Оба датчика инструмента либо одновременно активны, либо одновременно неактивны
            $.message("Неверное состояние датчиков инструмента: невозможно определить состояние инструмента в шпинделе!")
            $.exit()
        }
        else if(sensor_value == 1) {
            // Инстурмент установлен в шпиндель
            tool_installed = 1
        }
        else if(sensor_value == 0) {
            // Шпиндель свободен
            tool_installed = 0
        }
        else {
            $.message("Невозможно определить состояние инструмента в шпинделе!")
            $.exit()
        }
    }
}

G4P0.1

{
    // Проверяем датчики шпинделя, чтобы определить, установлен ли перед началом процедур инструмент
    if(NEED_CHECK_TOOL_SENSORS) {
        check_tool_sensors()
    }
    else {
        if(current_tool == 0) {
            tool_installed = 0
        }
    }
    
    if(tool_installed) {
        if (current_tool < 1 || current_tool > TOOLS_NUMBER) {
            $.message("Неверный номер текущего установленного инструмента: " + current_tool);
            $.exit()
        }
    }
    else {
        $.message("Инструмент не устанавлен!")
        $.exit()
    }
    
    // Поднимаемся на безопасную высоту
    $.send("G90G1G53Z" + String(SAFE_Z_POS) + "F" + String(FAST_RATE_Z))
    
    // Поднимаем щетку
    if(NEED_BRUSH_CONTROL) {
        set_brush_up()
        check_brush_up()
    }    
}

G4P0.1

{
    // Для безопасности перед началом процедуры закрываем магазин и проверяем, что он закрыт
    if(NEED_TOOL_BASKET_CONTROL) {
        tool_basket_off()
        check_tool_basket_off()
    }

    // Сбрасываем текущий инструмент в магазин при условии, что в патрон инструмент сейчас установлен 
    drop_current_tool(current_tool)
    
    $.send("G4P0.1")
    
    if(NEED_TOOL_BASKET_CONTROL) {
        tool_basket_off()
        check_tool_basket_off()
    }
}

G4P0.1

Предзаказ
Предзаказ успешно отправлен!
Имя *
Телефон *
Добавить в корзину
Название товара
100 ₽
1 шт.
Перейти в корзину
Обратный звонок
Запрос успешно отправлен!
Имя *
Телефон *
Заявка

Я ознакомлен и согласен с условиями оферты и политики конфиденциальности.

Заказ в один клик

Я ознакомлен и согласен с условиями оферты и политики конфиденциальности.