PDA

Просмотр полной версии : Управление движением механизма.



alexval2006
26.09.2013, 15:27
Возникла необходимость автоматизировать механизм тележки. Был написан функциональный блок на ST вроде бы всё работает но так как наша отечественная механика 72 года и никто её ни менять ни приводить в нормальный вид не хочет приходится крутится самому. В общем когда механизм отправляется на выбранный адрес (датчик) и достигая его останавливается иногда этот датчик проскакивает хоть тормоза и стоят. В результате датчик выключается и положение механизма становится = 0. Механизм не знает куда ему ехать при следующем запуске. Возникла идея записывать все сработавшие датчики в массив и последний сработавший считать текущим положением и точкой отправления.
Может кто подскажет как это правильно сделать а то больно жуткие схемы приходят в голову.

текущий проект прилагается.



(* О визуализации.
Квадратики от 1 до 6 датчики положения тележки нажимая их имитируем срабатывание.
Квадратики А и В аварийные датчики конечных положений нажимая их имитируем аварию.
Пуск стоп сброс аварии кнопки управления.
Также есть цифровой индикатор положения показывает битовый номер.
Для примера битовый номер датчиков выглядит так:
датчик №1=1, датчик №2=2, датчик №3=4, датчик №4=8, датчик №5=16, датчик №6=32.
цифровой панели задачи адреса указываем адрес в виде битового значения 1,2,4,8,16,32 и тп.
нажмем кнопку старт механизм начинает движение в сторону выбранного датчика.
Для имитации после запуска выключаем датчик на котором тележка стоит в текущий момент
и нажимаем тот датчик на который отправляли тележку.
*)

Sergey666
26.09.2013, 18:31
Может поставить "дублирующие" датчики или сделать механически так , чтобы датчик был в сработавшем положении (фиг его знает какие там датчики) в некотором безопасном диапазоне .

alexval2006
26.09.2013, 20:50
Датчики индуктивные лишние ставить накладно будет их и так по 25 штук стоит на каждую ленту на датчик наезжает лыжа из метала сделать её длиннее нельзя будет не доезжать до нужного места

2345lug
26.09.2013, 21:00
А зачем массив? Последнее направление и последний сработавший концевик, кажется, проще записывать?

petera
27.09.2013, 01:48
Возникла необходимость автоматизировать механизм тележки. Был написан функциональный блок на ST вроде бы всё работает но так как наша отечественная механика 72 года и никто её ни менять ни приводить в нормальный вид не хочет приходится крутится самому. В общем когда механизм отправляется на выбранный адрес (датчик) и достигая его останавливается иногда этот датчик проскакивает хоть тормоза и стоят. В результате датчик выключается и положение механизма становится = 0. Механизм не знает куда ему ехать при следующем запуске. Возникла идея записывать все сработавшие датчики в массив и последний сработавший считать текущим положением и точкой отправления.
Может кто подскажет как это правильно сделать а то больно жуткие схемы приходят в голову.
Что-то у меня совсем просто получилось. Ни каких массивов и больно жутких схем.
10263
Даже с учетом того, что для выключения движения здесь использовал "параноидальные" условия достижения заданного положения тележки, пологая возможность неисправности датчика, когда тележка может доехать до следующего.
И визуализация.
10264
Пример конечно упрощенный, показал только идею. То, что использую только 8 датчиков не проблема, можно аналогично сделать и для большего количества.

ЗЫ. ФБ PACK для адреса не является принципиально необходимым. По задумке он служит только для того, чтобы после начала движения тележки (после нажатия кнопки ПУСК) нельзя было изменить адрес до момента остановки тележки.

UPD
Вложение можно скачать здесь [B] https://drive.google.com/open?id=0B1ENDtxOet_iWDcxX2dIekNibDg

alexval2006
27.09.2013, 09:26
Большое спасибо за помощь как раз то что нужно. Свежий взгляд на проблему творит чудеса я слишком усложнял простое решение :)
Ещё вопросик как в элементе PACK увеличить количество входов.

petera
27.09.2013, 12:11
Большое спасибо за помощь как раз то что нужно. Свежий взгляд на проблему творит чудеса я слишком усложнял простое решение :)
Ещё вопросик как в элементе PACK увеличить количество входов.
На счет этого утверждения

Свежий взгляд на проблему творит чудеса я слишком усложнял простое решение+100%
А по существу вопроса
1. Решение "в лоб"

FUNCTION PACK_W : WORD
VAR_INPUT
B0: BOOL;
B1: BOOL;
B2: BOOL;
B3: BOOL;
B4: BOOL;
B5: BOOL;
B6: BOOL;
B7: BOOL;
B8: BOOL;
B9: BOOL;
B10: BOOL;
B11: BOOL;
B12: BOOL;
B13: BOOL;
B14: BOOL;
B15: BOOL;
END_VAR
VAR
END_VAR
(*Тело функции*)
PACK_W.0:=B0;
PACK_W.1:=B1;
PACK_W.2:=B2;
PACK_W.3:=B3;
PACK_W.4:=B4;
PACK_W.5:=B5;
PACK_W.6:=B6;
PACK_W.7:=B7;
PACK_W.8:=B8;
PACK_W.9:=B9;
PACK_W.10:=B10;
PACK_W.11:=B11;
PACK_W.12:=B12;
PACK_W.13:=B13;
PACK_W.14:=B14;
PACK_W.15:=B15;

2. По мотивам библиотеки OSCAT

FUNCTION PACK_W2 : WORD
VAR_INPUT
B0: BOOL;
B1: BOOL;
B2: BOOL;
B3: BOOL;
B4: BOOL;
B5: BOOL;
B6: BOOL;
B7: BOOL;
B8: BOOL;
B9: BOOL;
B10: BOOL;
B11: BOOL;
B12: BOOL;
B13: BOOL;
B14: BOOL;
B15: BOOL;
END_VAR
VAR
BYTE_0: BYTE;
BYTE_1: BYTE;
END_VAR
(*Тело функции*)
BYTE_0:=SHL(SHL(SHL(SHL(SHL(SHL(SHL(BOOL_TO_BYTE(B 7),1) OR BOOL_TO_BYTE(B6),1) OR BOOL_TO_BYTE(B5),1) OR BOOL_TO_BYTE(B4),1)
OR BOOL_TO_BYTE(B3),1) OR BOOL_TO_BYTE(B2),1) OR BOOL_TO_BYTE(B1),1) OR BOOL_TO_BYTE(B0);
BYTE_1:=SHL(SHL(SHL(SHL(SHL(SHL(SHL(BOOL_TO_BYTE(B 15),1) OR BOOL_TO_BYTE(B14),1) OR BOOL_TO_BYTE(B13),1) OR BOOL_TO_BYTE(B12),1)
OR BOOL_TO_BYTE(B11),1) OR BOOL_TO_BYTE(B10),1) OR BOOL_TO_BYTE(B9),1) OR BOOL_TO_BYTE(B8);
PACK_W2:=SHL(BYTE_TO_WORD(BYTE_1),8) OR BYTE_TO_WORD(BYTE_0);
10266

petera
27.09.2013, 12:49
Увеличиваем количество датчиков до 32

FUNCTION PACK_DW : DWORD
VAR_INPUT
B0: BOOL;
B1: BOOL;
B2: BOOL;
B3: BOOL;
B4: BOOL;
B5: BOOL;
B6: BOOL;
B7: BOOL;
B8: BOOL;
B9: BOOL;
B10: BOOL;
B11: BOOL;
B12: BOOL;
B13: BOOL;
B14: BOOL;
B15: BOOL;
B16: BOOL;
B17: BOOL;
B18: BOOL;
B19: BOOL;
B20: BOOL;
B21: BOOL;
B22: BOOL;
B23: BOOL;
B24: BOOL;
B25: BOOL;
B26: BOOL;
B27: BOOL;
B28: BOOL;
B29: BOOL;
B30: BOOL;
B31: BOOL;
END_VAR
VAR
W1: WORD;
W0: WORD;
BYTE_0: BYTE;
BYTE_1: BYTE;
BYTE_2: BYTE;
BYTE_3: BYTE;
END_VAR
(*Тело функции*)
BYTE_0:=SHL(SHL(SHL(SHL(SHL(SHL(SHL(BOOL_TO_BYTE(B 7),1) OR BOOL_TO_BYTE(B6),1) OR BOOL_TO_BYTE(B5),1) OR BOOL_TO_BYTE(B4),1)
OR BOOL_TO_BYTE(B3),1) OR BOOL_TO_BYTE(B2),1) OR BOOL_TO_BYTE(B1),1) OR BOOL_TO_BYTE(B0);
BYTE_1:=SHL(SHL(SHL(SHL(SHL(SHL(SHL(BOOL_TO_BYTE(B 15),1) OR BOOL_TO_BYTE(B14),1) OR BOOL_TO_BYTE(B13),1) OR BOOL_TO_BYTE(B12),1)
OR BOOL_TO_BYTE(B11),1) OR BOOL_TO_BYTE(B10),1) OR BOOL_TO_BYTE(B9),1) OR BOOL_TO_BYTE(B8);
W0:=SHL(BYTE_TO_WORD(BYTE_1),8) OR BYTE_TO_WORD(BYTE_0);

BYTE_2:=SHL(SHL(SHL(SHL(SHL(SHL(SHL(BOOL_TO_BYTE(B 23),1) OR BOOL_TO_BYTE(B22),1) OR BOOL_TO_BYTE(B21),1) OR BOOL_TO_BYTE(B20),1)
OR BOOL_TO_BYTE(B19),1) OR BOOL_TO_BYTE(B18),1) OR BOOL_TO_BYTE(B17),1) OR BOOL_TO_BYTE(B16);
BYTE_3:=SHL(SHL(SHL(SHL(SHL(SHL(SHL(BOOL_TO_BYTE(B 31),1) OR BOOL_TO_BYTE(B30),1) OR BOOL_TO_BYTE(B29),1) OR BOOL_TO_BYTE(B28),1)
OR BOOL_TO_BYTE(B27),1) OR BOOL_TO_BYTE(B26),1) OR BOOL_TO_BYTE(B25),1) OR BOOL_TO_BYTE(B24);
W1:=SHL(BYTE_TO_WORD(BYTE_3),8) OR BYTE_TO_WORD(BYTE_2);

PACK_DW:=SHL(WORD_TO_DWORD(W1),16) OR WORD_TO_DWORD(W0);
10268

alexval2006
27.09.2013, 15:11
Спасибо хорошая функция получилась пригодится не только в этом проекте. Вот теперь напильником под шлифую немного под себя и будет самое то :)

alex55
27.09.2013, 16:37
:)Это что за тележка ни с элеватора случайно?

alexval2006
29.09.2013, 19:22
с него родимого

alexval2006
07.10.2013, 11:20
Ну вот и доде6лал под себя выкладываю то что получилось может кто то еще что то улучшит :)

petera
07.10.2013, 13:34
У меня есть замечания и улучшения.
1. Нужно добавить еще одно условие сброса триггера RS1
10384
Первоначально у меня было только это условие. И все работает нормально, но затем добавил два "параноидальных" условия "<=" и ">=" для случая если тележка продолжит движение при не исправном датчике заданного адреса.
При добавлении этих двух условий про условие "=" забыл.
2. У элемента PACK для адреса в моем проекте http://www.owen.ru/forum/showthread.php?t=15844&p=119997&viewfull=1#post119997 использовался вход EN с инверсией. Назначение входа EN для элемента PACK_DW понятно из картинки
10385
Если оставить EN без инверсии, то с дополнительным условием по п.1 программа работать не будет.
Еще не плохо было бы контролировать количество "1" в переменной POLOGENIE. Если оно будет больше одного, то имеет место неисправность какого-то датчика.

alexval2006
07.10.2013, 15:27
Готовых библиотечных функций для этого
Еще не плохо было бы контролировать количество "1" в переменной POLOGENIE. Если оно будет больше одного, то есть неисправность какого-то датчика. не припомню что то.
можно на ST написать нечто громоздкое но работать будет.
Например
IN: DWORD;
ALARM: BOOL;

IF (IN.0=FALSE AND IN.1=TRUE AND IN.2=TRUE) THEN
ALARM:=TRUE;
ELSIF
(IN.0=TRUE AND IN.1=FALSE AND IN.2=TRUE) THEN
ALARM:=TRUE;
ELSIF
(IN.0=TRUE AND IN.1=TRUE AND IN.2=FALSE) THEN
ALARM:=TRUE;
END_IF


Только надо учесть что у нас 32 входа нужно будет расписать 32 варианта с описанием состояний 32х входов

Валенок
07.10.2013, 16:28
Проверка наличия всех положенных датчиков по пути (проскок) ?
А проверка "едем-едем - ничего не меняется" ?
Или кладем на такую мелочь ?

petera
07.10.2013, 16:40
Проверка наличия всех положенных датчиков по пути (проскок) ?
А проверка "едем-едем - ничего не меняется" ?
Или кладем на такую мелочь ?
Класть на такую "мелочь" нельзя.
На счет "едем-едем - ничего не меняется" вроде в программе есть таймер и аларм соответствующий.

Валенок
07.10.2013, 16:44
Код от alexva2006 посмотреть немогу. Есть таймер - ок. В Вашем - невидел.
Проверка проскоков есть там ? (Типа поехали из 2 в 8. Отвалился 4й)

petera
07.10.2013, 16:49
Готовых библиотечных функций для этого не припомню что то.
можно на ST написать нечто громоздкое но работать будет.
Например
IN: DWORD;
ALARM: BOOL;

IF (IN.0=FALSE AND IN.1=TRUE AND IN.2=TRUE) THEN
ALARM:=TRUE;
ELSIF
(IN.0=TRUE AND IN.1=FALSE AND IN.2=TRUE) THEN
ALARM:=TRUE;
ELSIF
(IN.0=TRUE AND IN.1=TRUE AND IN.2=FALSE) THEN
ALARM:=TRUE;
END_IF


Только надо учесть что у нас 32 входа нужно будет расписать 32 варианта с описанием состояний 32х входов
Путем перебора всех не правильных комбинаций идти нельзя. Слишком большая комбинация возможных состояний.
Ровно 32 перебора будет если с помощью CASE сравнить значение только с допустимыми комбинациями.

VAR
POLOGENIE_OUT: DWORD;
ALARM: BOOL;
END_VAR
Тело программы
CASE POLOGENIE_OUT OF
2#00000000000000000000000000000000: ALARM:=FALSE;
2#10000000000000000000000000000000: ALARM:=FALSE;
2#01000000000000000000000000000000: ALARM:=FALSE;
2#00100000000000000000000000000000: ALARM:=FALSE;
2#00010000000000000000000000000000: ALARM:=FALSE;
.................................................. ...........................
2#00000000000000000000000000000001: ALARM:=FALSE;
ELSE
ALARM:=TRUE;
END_CASE

petera
07.10.2013, 16:50
Код от alexva2006 посмотреть немогу. Есть таймер - ок. В Вашем - невидел.
Проверка проскоков есть там ? (Типа поехали из 2 в 8. Отвалился 4й)
У меня был совсем простой пример, только идея.

capzap
07.10.2013, 16:56
Путем перебора всех не правильных комбинаций идти нельзя. Слишком большая комбинация возможных состояний.
Ровно 32 перебора будет если с помощью CASE сравнить значение только с допустимыми комбинациями.

VAR
POLOGENIE_OUT: DWORD;
ALARM: BOOL;
END_VAR
Тело программы
CASE POLOGENIE_OUT OF
2#00000000000000000000000000000000: ALARM:=FALSE;
2#10000000000000000000000000000000: ALARM:=FALSE;
2#01000000000000000000000000000000: ALARM:=FALSE;
2#00100000000000000000000000000000: ALARM:=FALSE;
2#00010000000000000000000000000000: ALARM:=FALSE;
.................................................. ...........................
2#00000000000000000000000000000001: ALARM:=FALSE;
ELSE
ALARM:=TRUE;
END_CASE

А как насчет такого
Alarm:=foo>bar and foo>1;
bar:=foo;

petera
07.10.2013, 17:01
Проверка проскоков есть там ? (Типа поехали из 2 в 8. Отвалился 4й)
Что отвалился 4 нет.
Но то, что отвалился 8 можно легко сделать.
У меня было специально предусмотрены два "параноидальных" условия "<=" и ">=" останова движения тележки для случая если тележка продолжит движение при не исправном датчике заданного адреса.
Легко можно добавить по фронту с выхода каждого условия "<=" и ">=" компаратор равенства адреса и текущего положения. Если не равны, то отвалился 8 или 8 и 9 или 8, 9 и 10 и т.д. Смотря на каком остановилась тележка.

ЗЫ. Ведь едем по 8 адресу, 4 датчик не важен. Вот когда нужен будет 4 тогда и определим, что он неисправен.

Валенок
07.10.2013, 17:17
Когда нужно будет - будет позно ))
С кейсом кажется жестковато. Все-таки 32 значения. Может в цикле перебрать ?

petera
07.10.2013, 17:24
Когда нужно будет - будет позно ))
С кейсом кажется жестковато. Все-таки 32 значения. Может в цикле перебрать ?

PS.
Жаль у реала мантисса 23 бита (датчиков > 23). Можно было бы:
if положение <> 0 then
alarm := expt(2, log(положение)/log(2)) <> положение;
end_if
У OSCATA есть нужная функция
10389

FUNCTION BIT_COUNT : INT
VAR_INPUT
IN : DWORD;
END_VAR
Тело функции
WHILE in > 0 DO
IF in.0 THEN Bit_Count := Bit_Count + 1; END_IF;
in := SHR(in,1);
END_WHILE;



Добавить проверку Если BIT_COUNT( POLOGENIE) >1, то аларм

alexval2006
08.10.2013, 09:48
Сколько народа вовлёк в дискуссию :) Ну я думаю это наверно уже лишнее разве что просто из спортивного интереса. Загрузил программу на плк тестирую на механизмах пока работает нормально.