Страница 2 из 3

Re: Ladder

Добавлено: 06 янв 2015, 15:31
Loituma
А как реализовать в программе удар? Представили себе пресс координатный, мы подтащили заготовку к месту и какой командой сделать удар?

G0 x100 y100
????????? --- команда удара
G0 x200 y200
????????? --- команда удара.

Понимаю, что можно как то реализовать, но как?

Re: Ladder

Добавлено: 06 янв 2015, 15:33
PKM
Например через М-коды

То есть скажем М111 будет устанавливать в 1 (и потом сбрасывать в 0) некий пин, который даст команду бабахнуть :)

Re: Ladder

Добавлено: 06 янв 2015, 20:13
Loituma
Гениальное просто, но как на это среагирует программа?
То есть: что бы матрице пуансону отработать требуется пол секунды минимум, как на это отреагируют оси? Они будут дожидаться пока будет выполнено или все таки придется делать кнопку "продолжить программу"
Тогда, программа принимает вид:

G0 x100 y100
m101 - установка пина на удар
m0
m102 - выключение пина
G0 x200 y200
m101 - установка пина на удар
m0
m102 - выключение пина

или сделать через ладдер, что то вроде:
Безымянный2.png
Безымянный2.png (5 КБ) 1930 просмотров
то есть логика: от кода m111 в ладдере устанавливается некое реле (на рис Y10) в 1 и таймер t1 встает на питание, и по переднему фронту сбрасывает реле Y10 в 0

чеж ладдер та такой кривой (((( вот бы в плк, я бы полдня бы и закончил ))))

Re: Ladder

Добавлено: 06 янв 2015, 20:19
PKM
Можно сделать и в одной команде, мне кажется... установить пин и ждать, пока исполнительный механизм отработает и выдаст сигнал завершения. Но не уверен, как именно это сделать.
В крайнем случае после М111 добавить M66

Re: Ladder

Добавлено: 06 янв 2015, 20:29
Loituma
эххх, ну ладно я это обойду кустарным методом и напишу методичку к написанию программы... Или напишу интерпретатор который формирует команды по координатам.

Есть другая проблема, которая мне кажется более ужасной:
Алгоритм работы станка:
Включили, захомили X, Захомили Y, а вот с Z то крутая проблема: перед тем как его захомить, нужно совершить ряд действий в автоматическом режиме, а именно отвести фиксаторы... РКМ, ты же делал смену инструмента, там же перед тем как выставить нулевой инструмент, надо как минимум фиксатор убрать или нет?

Re: Ladder

Добавлено: 06 янв 2015, 20:40
PKM
У меня ничего не нужно убирать.
А что за фиксаторы? Может просто убирать их при включении станка?

Re: Ladder

Добавлено: 06 янв 2015, 20:46
Loituma
да вот фиг его знает, скорее не выйдет. ну допустим станок выключен, то как хомится? Выставлять фиксаторы при старте программы? опасно.... че то хрен его знает... Единственный выход который я пока вижу - это только делать физическую кнопку home z, ее запустить через внешний PLC и пока все условия не будут выполнены, он не даст сигнал на месу...

Re: Ladder

Добавлено: 06 янв 2015, 20:50
PKM
Можно все внутренней логикой HAL или classicladder сделать не хуже PLC.

Так что там за фиксаторы, они убираются автоматически? Какой алгоритм процесса?

Re: Ladder

Добавлено: 06 янв 2015, 21:12
Loituma
обычные штыри с двух сторон на пневмотяге...
логика такова: при нажатии хоум алл ну или хоум z хал должен подтянуть катушку которая управляет пневмораспределителем и проверить по датчикам, что выполненно. после этого захомить з и вставить штыри обратно и проверить что вставленны

Re: Ladder

Добавлено: 06 янв 2015, 21:17
PKM
Интересно, надо подумать. Наверное проще вручную кнопку ткнуть перед хомлением. А проверки сделать обязательно, да...

Re: Ladder

Добавлено: 07 янв 2015, 08:30
Loituma
Ладно, будем собирать и думать, что делать и кто виноват.

Re: Ladder

Добавлено: 12 янв 2015, 09:42
Nick
Loituma писал(а):G0 x100 y100
m101 - установка пина на удар
m0
m102 - выключение пина
А чем не понравился m64?

Код: Выделить всё

M64 P0 ; вкл удар
M66 P0 L1 Q10 ; ждем срабатывания пина готовности
M65 P0 ; выкл удар 
или

Код: Выделить всё

M64 P0 ; вкл удар
G4 P0.1 ; ждем 0.1с 
M65 P0 ; выкл удар 
M66 P0 L1 Q10 ; ждем срабатывания пина готовности
Еще к этому можно добавить проверку того, что удар прошел нормально, т.к. M66 просто ждет растущий фронт (L1) в течении 10 секунд (Q10):

Код: Выделить всё

O100 IF [#5399 EQ -1]
  (DEBUG, Неисправность при ударе!)
  M02 
O100 ENDIF 
И вообще весь удар лучше всего запихать в процедуру:
O<punch> SUB, ну и потом как обычно O<punch> CALL.

Re: Ladder

Добавлено: 12 янв 2015, 09:47
Nick
Loituma писал(а):логика такова: при нажатии хоум алл ну или хоум z хал должен подтянуть катушку которая управляет пневмораспределителем и проверить по датчикам, что выполненно. после этого захомить з и вставить штыри обратно и проверить что вставленны
Сделай на ладдере кнопку для хуминга.
Которая сначала уберет все блокираторы, а потом выставит halui.joint.N.home в 1.
halui.joint.N.home bit in
pin for homing joint N

Только надо как-то стандартные кнопки хоуминга заблокировать. :roll:
...
О, можно проверять, если axis.N.homing активен, но блокиролвка не снята - то Авост.
axis.N.homing OUT BIT
TRUE if the joint is currently homing

Re: Ladder

Добавлено: 12 янв 2015, 15:43
Loituma
Ник, считай что ты со мной матом поговорил... мне это переваривать неделю )))

Re: Ladder

Добавлено: 12 янв 2015, 17:42
Nick
Откуда начинать объяснять? :)

Что более не понятно, Gкод или хоуминг оси? :)

Re: Ladder

Добавлено: 13 янв 2015, 11:34
Loituma
ща прокачу станок, потом будем выяснять

Re: Ladder

Добавлено: 09 дек 2015, 15:21
vovafed
пока только пытаюсь разобраться в Ladder
есть револьверный магазин для инструмента на 8 ячеек
номер инструмента считывается 3 датчиками
вероятней всего в виде двоичного кода
вопрос такой как в Ladder сделать дешифратор двоичного кода в номер инструмента
станок этот http://www.cnc-club.ru/forum/viewtopic. ... 12#p234212

Re: Ladder

Добавлено: 09 дек 2015, 18:58
nkp
vovafed писал(а):вероятней всего в виде двоичного кода
там может быть и код грея , но это не так существено( прояснить конечно необходимо))
есть вроде такой компонент (надо его поближе рассмотреть)

Re: Ladder

Добавлено: 09 дек 2015, 19:13
N1X
А скорее всего будет как обычно: индексация (начало отсчета), счет и фиксация (контроль зазима)

Re: Ladder

Добавлено: 09 дек 2015, 19:29
nkp
пригодится-не пригодится,я оставлю здесь этот компонент:
carousel.comp.rar
(2.68 КБ) 209 скачиваний

Код: Выделить всё

component carousel """Orient a toolchanger carousel using various encoding schemes

.B loadrt toolchange pockets=\\fIN\\fR[,\\fIN\\fR]
.B encoding=\\fIssss\\fR[,\\fIsss\\fR]\\fB
.B num_sense=\\fIN\\fR[,\\fIN\\fR]
.B bidirectional=\\fIN\\fR[,\\fIN]

.RS 4
.TP
\\fBpockets\\fR The number of pockets in each toolchanger.
Use up to 8 numbers separated by commas to create multiple carousel components.
.TP
\\fBencoding\\fR The position encoding.
gray, binary, index or single. Default = 'gray'
.TP
\\fBnum_sense\\fR The number of position sense pins.
Default = 4.
.TP
\\fBdir\\fR Set to 1 for unidirectional or  2 for bidirectional operation.
Default = bidirectional
.RE""";

description """This component is intended to help operate various types of
carousel-type toolchangers. 
The component can be configured to operate with binary or gray-coded position 
feedback, with an individual sensor for each tool position or with a sensor at each
tool position and a separate index.

At the moment it is best-suited to Geneva-mechanism type systems where the
motor is either on or off.
Both unidirectional and bidirectional systems are supported. 

The number of carousel component instances created depends on the number of
entries in the 'pockets' modparam. For example

.B loadrt carousel pockets=10,10,8

Would create 3 carousel instances with 10, 10 and 8 pockets. The other 
parameters are optional. If absent then defaults will be used. Any missing
entry will assume the previous value.

When the enable pin is set to true the component will immediately set the 
"active" pin to true and then (for a bidirectional instance) calculate the
shortest path to the requested pocket number. The appropriate motor direction
output pin will then be set.

The component will monitor the carousel position and, when the correct position
is reached, set the motor-control pins to 0, set "active" to 0 and set "ready"
to 1.

In index mode the behaviour is slightly different the first time that the "enable"
pin is set; the carousel will rotate forwards when first enabled until 
both the index and pulse inputs are true. If there is no pulse line at the
index position then a HAL "or2" function can be used to allow the index sensor
to toggle both inputs. Setting "enable" low does not halt the homing move, so if
homing on first tool change is not needed then the enable pin can be toggled by
an axis homing pin or a script. 
""";

pin in  signed pocket-number "The pocket to move to when the .enable pin goes high";
pin in  bit    enable "Set this pin high to start movement. Setting it low will stop movement";
pin out bit    active "indicates that the component is active";
pin out bit    ready "This pin goes high when the carousel is in-position";
pin in  bit    sense-# [32:personality] """Carousel position feedback pins. In 'index' mode there 
will be only 2 pins. sense-0 is the index and sense-1 is the pocket sensor.""";
pin out bit    motor-fwd "Indicates the motor should run forwards (bigger numbers)";
pin out bit    motor-rev "Indicates the motor should run reverse.";
pin out signed current-position "This pin indicates the current position feedback";

param r  signed   state = 0 "Current component state";
param r  bit    homing  = 0 "Shows that homing is in progress. Only used for index mode";
param r  bit    homed = 0 "Shows that homing is complete. Only used in index mode";

option count_function;
option extra_setup;

license "GPL";
author "andy pugh";

variable int inst_sense;
variable int inst_dir;
variable int inst_pockets;
variable int inst_code;
variable int old_index = 0;

function _ nofp;

;;

int default_pockets = 8;
int default_code = 'G';
int default_dir = 2;
int default_sense = 4;

#define MAX_CHAN 8
static int pockets[MAX_CHAN] = {-1};
RTAPI_MP_ARRAY_INT(pockets, MAX_CHAN, "The number of pockets in each carousel")
static char *encoding[MAX_CHAN];
RTAPI_MP_ARRAY_STRING(encoding, MAX_CHAN, "Position feedback type")
static int dir[MAX_CHAN] = {-1};
RTAPI_MP_ARRAY_INT(dir, MAX_CHAN, 
                    "set to 2 if the carousel is bidirectional")
static int num_sense[MAX_CHAN] = {-1};
RTAPI_MP_ARRAY_INT(num_sense, MAX_CHAN, "The number of sense pins to create")


FUNCTION(_){
    int i;
    int p = 0;
    unsigned int mask;

    switch inst_code{
    case 'G': // Gray Code
        for (i = 0; i < inst_sense ; i++) {
            p += sense(i) << i;
        }
        for(mask = p >> 1 ; mask != 0 ; mask = mask >> 1){
            p ^= mask;
        }
        break;
    case 'B': // Straight Binary
        for (i = 0; i < inst_sense ; i++) {
            p += sense(i) << i;
        }
        break;
    case 'S': // individual sensors
        for (i = inst_sense - 1; sense(i) == 0 && i > 0 ; i--) {}
        p = i;
        break;
    case 'I': // index + position.
        p = current_position;
        if (homed){
            if ( !old_index && sense(1)){
                if (motor_fwd){
                    p += 1;
                    if (p > inst_pockets) p -= inst_pockets;
                }
                if (motor_rev) {
                    p -= 1;
                    if (p < 1) p += inst_pockets;
                }
            }
            old_index = sense(1);
        }
        break;
    }

    current_position = p;

    switch (state){
    case 0: // waiting at start
        if (! enable) return ;
        active = 1;
        if (inst_code == 'I' && ! homed){
            state = 10;
            break;
        }
        state = 1;
        ready = 0;
    case 1: // choose direction
        if (pocket_number < 1 || pocket_number > inst_pockets) return;
        if (inst_dir == 2){
            if (current_position < pocket_number){
                if (pocket_number - current_position > (inst_pockets / 2)) {
                    motor_fwd = 0;
                    motor_rev = 1;
                } else {
                    motor_fwd = 1;
                    motor_rev = 0;
                }
            } else {
                if (current_position - pocket_number > (inst_pockets / 2)) {
                    motor_fwd = 1;
                    motor_rev = 0;
                } else {
                    motor_fwd = 0;
                    motor_rev = 1;
                }
            }
        } else {
            motor_fwd = 1;
            motor_rev = 0;
        }
        state = 2;
    case 2: // moving
        if ((current_position != pocket_number) && enable) return;
        motor_fwd = 0;
        motor_rev = 0;
        state = 3;
        active = 0;
        if (enable) ready = 1;
    case 3: //waiting for enable to go false
        if (enable) return;
        state = 0;
        break;
    case 10: // start of homing
        homed = 0;
        homing = 1;
        motor_fwd = 1;
        motor_rev = 0;
        state = 11;
    case 11: // waiting for index & pulse
        if  ( (! old_index) && (sense(0) && sense(1)) ){ // index found
            p = 1;
            homed = 1;
            homing = 0;
            active = 0;
            state = 0;
        }
        old_index = (sense(0) && sense(1));
        break; // So that we don't see the tool1 pulse twice
    }
}

EXTRA_SETUP(){
    if (pockets[extra_arg] > 0) default_pockets = pockets[extra_arg];
    if (encoding[extra_arg] == NULL) {
        //it's already default_code
    } else if (strncmp(encoding[extra_arg], "binary", 6) == 0) {
        default_code = 'B';
    } else if (strncmp(encoding[extra_arg], "single", 6) == 0) {
        default_code = 'S';
    } else if (strncmp(encoding[extra_arg], "index", 5) == 0) {
        default_code = 'I';
    }

    if (dir[extra_arg] > 0)  default_dir = (dir[extra_arg] > 1)? 2:1;
    
    if (default_code == 'I') {
        default_sense = 2;
    } else if (num_sense[extra_arg] > 0 ) {
        default_sense = num_sense[extra_arg];
    }
    
    inst_pockets = default_pockets;
    inst_code = default_code;
    inst_dir = default_dir;
    inst_sense = default_sense;

    if (inst_code == 'S' && inst_sense < inst_pockets) inst_sense = inst_pockets;
    personality = inst_sense;

    return 0;
}

int get_count(void){
    int i;
    for (i = 0; pockets[i] != 0 && i < MAX_CHAN; i++){}
    if (i == 0) return 1 ;
    return i;
}
он работает с кодом грея,двоичным кодом, index + position ...