Вопросы новичка |
Здравствуйте, гость ( Вход | Регистрация )
Вопросы новичка |
7.10.2020 - 15:12
Сообщение
#1
|
|
Читатель Группа: Пользователи Сообщений: 11 Регистрация: 6.10.2020 Пользователь №: 11316 |
Только начал изучать ПЛК, у меня FX3G GXwork2 полностью в ST тк раньше сидел только в урезанном СИ микроконтроллеров. Вопросы которые я не смог понять/найти за эту неделю:
- как вызвать программный блок из основной программы, например на рисунке из POU_01 вызвать inte и вернуться; - как перемещаться в одной программе по меткам (Goto); - задать время повторения программы (цикл контроллера); - управлять быстрыми выходами (выдать пачку импульсов за время меньшее чем цикл контроллера). Задача минимум управлять 5-ю осями с серваками step/dir, линейная интерполяция по 2-м из них с точностью 0.1мм, без доп модулей это вполне возможно. Сообщение отредактировал Waldislaw - 7.10.2020 - 16:11
Прикрепленные файлы
|
|
|
14.09.2021 - 09:04
Сообщение
#2
|
|
Читатель Группа: Пользователи Сообщений: 7 Регистрация: 14.09.2021 Пользователь №: 11444 |
Впервые встретился с ПЛК FX1N.
К ПЛК подключена панель оператора OP320 Делаю первые шаги в освоении этого чуда. Написал простейшую программу. После перепрошивки, при включении ПЛК регистрам сразу назначаются указанные в условиях значения. Такое ощущение, что на первом цикле условия не проверяются и выполняются все инструкции. Думал что это связано с панелью оператора. Нет. Отключаю ее и получаю тот же результат. При этом в дальнейшем, код работает верно. Т.е. если в процессе работы регистры обнулить то условия работают верно. Код IF M8002=1 THEN M0 := 0; M3 := 0; END_IF; IF M0 THEN D132 := 1; END_IF; IF M3 THEN D168 := 100; END_IF; Подскажите пожалуйста, в какую сторону копать? зы. На панели оператора 2 кнопки связаны с маркерами M0, M3. Тип "Revers". |
|
|
14.09.2021 - 21:45
Сообщение
#3
|
|
Гигант мысли Группа: Пользователи Сообщений: 377 Регистрация: 30.12.2004 Пользователь №: 108 |
После перепрошивки, при включении ПЛК регистрам сразу назначаются указанные в условиях значения. Такое ощущение, что на первом цикле условия не проверяются и выполняются все инструкции. Думал что это связано с панелью оператора. Нет. Отключаю ее и получаю тот же результат. При этом в дальнейшем, код работает верно. Т.е. если в процессе работы регистры обнулить то условия работают верно. Похоже, Вы просто не учитываете, что программа непрерывно выполняется циклически, а наблюдаете Вы результат не первого прохода, а последнего законченного. В первом проходе (скане) все указанное происходит, но результат мониторится лишь один скан (миллисекунды). Его не увидеть глазом, но при желании можно зафиксировать в конце первого скана во вспомогательных регистрах. Сообщение отредактировал Sergei Troizky - 14.09.2021 - 21:53 -------------------- Делать надо сразу хорошо. Плохо само получится.
|
|
|
14.09.2021 - 22:41
Сообщение
#4
|
|
Читатель Группа: Пользователи Сообщений: 7 Регистрация: 14.09.2021 Пользователь №: 11444 |
Похоже, Вы просто не учитываете, что программа непрерывно выполняется циклически, а наблюдаете Вы результат не первого прохода, а последнего законченного. В первом проходе (скане) все указанное происходит, но результат мониторится лишь один скан (миллисекунды). Его не увидеть глазом, но при желании можно зафиксировать в конце первого скана во вспомогательных регистрах. Сергей, я имею некоторый опыт программирования МК в среде RTOS и совсем немного в программировании ПЛК в среде Codesys (ST). Эти моменты я прекрасно понимаю. Следующий код работает верно. В том числе все IF, CASE ... Больше времени ушло на исследование работы функций DDRVA/DDRVI (управление ШД) Управление с панели оператора OP320 (тоже китайской сборки) Захотел добавить еще одну функцию, которая должна сделать некоторый перерасчет значений, но вызывать ее по требованию т.е. в ручную. Для этого на кнопку панели поключил M0. Код простейший IF M0 THEN .... пересчет; END_IF; Но пересчет выполняется при каждом старте, не зависимо от того какое условие. Даже если M0 := 0; перед условием поставить. Подозреваю, что при старте что-то может нужно еще инициализировать. Пробовал задержку по таймеру выставить перед выполнением кода - не помогло. Просто какая-то магия. Код (****************************************************************************
*************** Входы/Выходы X0 - Сигнал датчику нуля оси Z Y0 - STEP. Выход на драйвер ШД Y4 - DIR. Выход на драйвер ШД Регистры M0 Bit Запускает/останавливает движение по заданным координатам M1 Bit Ручное движение вверх M2 Bit Ручное движение вниз M3 Bit Режим скорости ручного перемещения (0 - медленно S1, 1 - быстро S) M5 Bit Поимк нулевой точки D9 DWORD Уставка Z в импульсах D128 INT Высота стола (0.1 мм) D132 INT Высота заготовки (0.1 мм) D136 INT Количество импульсов на 1 мм перемещения по оси Z D140 INT Скорость движения по оси Z (мм/сек). Автоматический режим D142 INT Скорость движения по оси Z (мм/сек). Ручное управление D144 INT Текущая координата Axis Z (0.1 мм) D148 INT Текущая высота от заготовки до линзы Work Z (0.1 мм) D152 INT Текущий номер линзы Lens (1..4) D156 INT Фокусное расстояние линзы F1 (0.1 мм) D160 INT Фокусное расстояние линзы F2 (0.1 мм) D164 INT Фокусное расстояние линзы F3 (0.1 мм) D168 INT Фокусное расстояние линзы F4 (0.1 мм) D172 INT MaxZ. Максимальное значение Z D176 INT Фокусное расстояние выбранной линзы D8140 DWORD Текущее значение координаты Z в импульсах M8029 Bit Сигнал завершения позиционирования (в одном цикле) M8147 Bit 1 - происходит перемещение (Занято), 0 - ожидание команды ******************************************************************************** ************) IF M8002 = 1 THEN (* Выполняется однократно при старте программы *) M0 := FALSE; M1 := FALSE; M2 := FALSE; M4 := FALSE; END_IF; (* Вычисляем чатсоту импульсов *) dK := INT_TO_DINT(D136); (* K *) HiSpeed := INT_TO_DINT(D140); (* Hi Speed *) HiFreq := (dK * HiSpeed) / 10; LoSpeed := INT_TO_DINT(D142); (* Lo Speed *) LoFreq := (dK * LoSpeed) / 10; CASE D152 OF 1: (* Линза 1 *) D176 := D156; FLeanse := INT_TO_DINT(D156); 2: (* Линза 2 *) D176 := D160; FLeanse := INT_TO_DINT(D160); 3: (* Линза 3 *) D176 := D164; FLeanse := INT_TO_DINT(D164); 4: (* Линза 4 *) D176 := D168; FLeanse := INT_TO_DINT(D168); ELSE D176 := 0; FLeanse := 0; END_CASE; (* Вычисляем заданную координату Z в импульсах *) TableH := INT_TO_DINT(D128); (* Высота стола *) Mesure := INT_TO_DINT(D132); (* Высота заготовки *) MaxZ := INT_TO_DINT(D172 ); (* MaxZ смещение*) DestZ := MaxZ - (TableH + Mesure + FLeanse); (* Значение Z в 0,1 мм с учетом смещения MaxZ*) DestPulsZ := DestZ * (dK/10); (* Вычисляем количество импульсов для смещения *) DMOV( TRUE, DestPulsZ , D9); (* Вычисляем текущую координату Z в 0,1 мм*) DMOV( TRUE, D8140 , HardZ); AxisZ := MaxZ - (HardZ * 10) / dK; D144 := DINT_TO_INT(AxisZ); (* Вычисляем текущее расстояние от заготовки до линзы Z1 в 0,1 мм*) WorkZ := AxisZ - (TableH + Mesure); D148 := DINT_TO_INT(WorkZ); (* Soft Limit max *) IF AxisZ > MaxZ THEN M0 :=FALSE; M1 := FALSE; END_IF; (* Soft Limit min *) IF (AxisZ <= (TableH + Mesure)) THEN M0 := FALSE; M2 := FALSE; END_IF; (* По сигналам ручного управления отключить автоматическое M0 *) IF M1 OR M2 THEN M0 := FALSE; M5 := FALSE; END_IF; DDRVA( M0 , DestPulsZ, HiFreq, Y0 , Y4); (* Переключение скорости перемещения в ручном режиме *) IF M3 THEN HandSpeed := HiFreq; ELSE HandSpeed := LoFreq; END_IF; DDRVI( M1 , -80000 , HandSpeed , Y0 , Y4 ); DDRVI( M2 , 80000 , HandSpeed , Y0 , Y4 ); Y7 := M8147; (* Поиск референтной точки/ мащинный 0 по датчику *) DZRN( M5 , HiFreq, MaxZ * dK, X0 , Y0 ); (* Сброс M0 по оканчании позиционирования *) IF M8029 THEN M0 := FALSE; M5 := FALSE; END_IF; |
|
|
Текстовая версия | Сейчас: 29.04.2024 - 00:33 |