Хочется использовать ОВЕН но Kinco из серии К5 тоже может подойти
Вид для печати
Имеется рабочая программа для погодного регулирования с точностью 0,5 градуса. Но когда контроллер поддерживает целое значение температуры теплоносителя, например 50 гр., то точность становится 1 гр.: от 49,5 до 50,5 гр. Если поддерживается, например 50,5 гр. о точность становится 0,5 гр.: от 50,25 до 50,75 гр.
Где нужно подкорректировать программу чтобы точность поддержания температуры была 0,5 гр.?
PROGRAM PLC_PRG
VAR
ind_temp: INT;
ton1,ton2: TON;
df: DECODE_FLOAT;
ust_temp: REAL;
temp_pod_i: INT;
first_start: BOOL := TRUE;
(*old_mode: INT;
old_pod_ust: INT;
old_ust_temp_z: INT;*)
temp_pod, ust_temp_f: REAL;
temp_nv: REAL;
delta: REAL;
ind_temp1: REAL;
END_VAR
VAR RETAIN
temp: ARRAY [0..78] OF REAL;
(*mode_r: INT;
pod_ust_r: INT;
ust_temp_r: INT;*)
NaprReg_r:REAL;
END_VAR
…………………………………………………………………………………………………………………………………… …………………………….
NaprReg := NaprReg_r;
IF first_start THEN
(* +8 +7.5 +7 +6.5 +6 *)
temp[0] := 35; temp[1] := 36; temp[2] := 36; temp[3] := 36; temp[4] := 36;
(* +5.5 +5 +4.5 +4 +3.5 *)
temp[5] := 36; temp[6] := 36; temp[7] := 36; temp[8] := 36; temp[9] := 36.5;
(* +3 +2.5 +2 +1.5 +1 *)
temp[10] := 37; temp[11] := 37.5; temp[12] := 38; temp[13] := 38.5; temp[14] := 39;
(* +0.5 0 -0.5 -1 -1.5 *)
temp[15] := 39.5; temp[16] := 40; temp[17] := 40.5; temp[18] := 41; temp[19] := 41.5;
(* -2 -2.5 -3 -3.5 -4 *)
temp[20] := 42; temp[21] := 42.5; temp[22] := 43; temp[23] := 43.5; temp[24] := 44;
(* -4.5 -5 -5.5 -6 -6.5 *)
temp[25] := 44.5; temp[26] := 45; temp[27] := 45.5; temp[28] := 46; temp[29] := 46.5;
(* -7 -7.5 -8 -8.5 -9 *)
temp[30] := 47; temp[31] := 47.5; temp[32] := 48; temp[33] := 48.5; temp[34] := 49;
(* -9.5 -10 -10.5 -11 -11.5 *)
temp[35] := 49; temp[36] := 49; temp[37] := 49.5; temp[38] := 50; temp[39] := 50;
(* -12 -12.5 -13 -13.5 -14 *)
temp[40] := 50; temp[41] := 50.5; temp[42] := 51; temp[43] := 51; temp[44] := 51;
(* -14.5 -15 -15.5 -16 -16.5 *)
temp[45] := 51.5; temp[46] := 52; temp[47] := 52.5; temp[48] := 53; temp[49] := 53.5;
(* -17 -17.5 -18 -18.5 -19 *)
temp[50] := 54; temp[51] := 54.5; temp[52] := 55; temp[53] := 55.5; temp[54] := 56;
(* -19.5 -20 -20.5 -21 -21.5 *)
temp[55] := 56.5; temp[56] := 57; temp[57] := 57.5; temp[58] := 58; temp[59] := 58.5;
(* -22 -22.5 -23 -23.5 -24 *)
temp[60] := 59; temp[61] := 59.5; temp[62] := 60; temp[63] := 60.5; temp[64] := 61;
(* -24.5 -25 -25.5 -26 -26.5 *)
temp[65] := 61.5; temp[66] := 62; temp[67] := 62.5; temp[68] := 63; temp[69] := 63.5;
(* -27 -27.5 -28 -28.5 -29 *)
temp[70] := 64; temp[71] := 64.5; temp[72] := 65; temp[73] := 65.5; temp[74] := 66;
(* -29.5 -30 -30.5 -31 *)
temp[75] := 66.5; temp[76] := 67; temp[77] := 67.5; temp[78] := 68;
IF NaprReg=0.0 THEN
NaprReg := 0.5;
END_IF;
first_start := FALSE;
END_IF;
df( VALUE:=temp_pod_d, DEF_VALUE:= temp_pod);
CASE df._ERR OF
12: temp_pod_s := 2000; (* кз *)
13: temp_pod_s := 2001; (*обрыв *)
6,7,8,9,10,11,14,15: temp_pod_s := 2002; (*ошибка контроллера *)
ELSE
temp_pod_s := REAL_TO_INT(df.OUT_VALUE*10);
temp_pod := temp_pod_d;
END_CASE;
df( VALUE:=temp_nv_d, DEF_VALUE:=temp_nv);
CASE df._ERR OF
12: temp_nv_s := 2000; (* кз *)
13: temp_nv_s := 2001; (*обрыв *)
6,7,8,9,10,11,14,15: temp_nv_s := 2002; (*ошибка контроллера *)
ELSE
temp_nv_s := REAL_TO_INT((df.OUT_VALUE+50.0)*10);
temp_nv := temp_nv_d;
END_CASE;
ind_temp1 := temp_nv;
ind_temp := 16 - REAL_TO_INT(ind_temp1*2);
IF ind_temp < 0 THEN
ind_temp := 0;
ELSIF ind_temp > 78 THEN
ind_temp := 78;
END_IF;
IF mode = 1 THEN
ust_temp := temp[ind_temp]+pod_ust;
ELSE
ust_temp := ust_temp_z;
END_IF;
temp_pod_i := REAL_TO_INT(temp_pod);
ust_temp_f := (ust_temp);
ton1.PT := t#10m; ton2.PT := t#10s;
ton1(in :=TRUE); ton2(in :=TRUE);
IF ton1.ET >t#30s THEN
IF (temp_pod_i >ust_temp) AND (temp_pod_s <2000) AND ((temp_nv_s<2000) OR (mode=0)) THEN
delta :=(temp_pod - ust_temp_f)/500;
NaprReg := NaprReg +delta;
IF NaprReg > 0.90 THEN NaprReg := 0.90; END_IF;
END_IF;
IF (temp_pod_i delta :=(ust_temp_f - temp_pod)/500 ;
NaprReg := NaprReg -delta;
IF NaprReg < 0.0 THEN NaprReg := 0.0; END_IF;
END_IF;
ton1(in :=FALSE);
END_IF;
NaprReg_r := NaprReg;
napr_s :=REAL_TO_INT( NaprReg *1000);
IF ton2.ET >t#400ms THEN
ton2(in :=FALSE);
ClearScreen(0);
SetWorkScreen(0);
ShowString(0,0,0,'Тнв=');
CASE temp_nv_s OF
2000: ShowString(0,4,0,'КЗ ');
2001: ShowString(0,4,0,'Обр ');
2002: ShowString(0,4,0,'Ош. ');
ELSE
ShowReal(0, 4, 0, '%3.1f',temp_nv);
END_CASE;
ShowString(0,9,0,'Тп=');
CASE temp_pod_s OF
2000: ShowString(0,12,0,'КЗ ');
2001: ShowString(0,12,0,'Обр ');
2002: ShowString(0,13,0,'Ош. ');
ELSE
ShowReal(0, 12, 0, '%3.1f',temp_pod);
END_CASE;
ShowString(0,0,1,'Uуп='); ShowReal(0, 4, 1, '%4.2f',NaprReg*10);
END_IF;
Добрый день!
Я столкнулся с проблемой такого характера…
Для начала обзора моего проекта вкратце опишу проблему.
Мы используем ПЛК 110.60-М и МУ 110 -16Р
У нас приходит сигналы с расходомеров жидкости их 12 шт. с выходной частотой около 100-200 Гц. на первых 12 входов в ПЛК
ПРИМЕР: Если мы наливаем 1литру жидкости это составляет (100 импульсов для ПЛК)
1000 : 100=10грам 10=1импульсу для ПЛК, нам нельзя терять не одного импульса, это точность налива.
ЭКСПЕРЕМЕНТ:
Прилагаю видео которое я заснял с экрана «Видео-1»
на видео видно что CUT (12шт.) и остальная программа просчитала импульсы не правильно, их количество импульсов не равномерно просчитали CTU не смотря на то что я подключил все 12 входов ПЛК на один расходомер (то есть все параллельно) но это ещё не всё
когда я подключил параллельно к ПЛК 110.60-М (цикл сканирования в Statistic 7мс) ещё ПКЛ 110.30-М для того чтоб посмотреть насколько ПЛК 110.60-М считает правильно то увидел что каждый из ПЛК вообще показывает разные значения «Фото-1»
Видать проект для ПЛК 110 тяжелый
Подскажите как мне выйти из этого положения
Вложение 23242 Вложение 23243 Вложение 23244 Вложение 23245 Вложение 23246 Вложение 23247
Имеется рабочая программа для погодного регулирования с точностью 0,5 градуса. Но когда контроллер поддерживает целое значение температуры теплоносителя, например 50 гр., то точность становится 1 гр.: от 49,5 до 50,5 гр. Если поддерживается, например 50,5 гр. о точность становится 0,5 гр.: от 50,25 до 50,75 гр.
Где нужно подкорректировать программу чтобы точность поддержания температуры была 0,5 гр.?
PROGRAM PLC_PRG
VAR
ind_temp: INT;
ton1,ton2: TON;
df: DECODE_FLOAT;
ust_temp: REAL;
temp_pod_i: INT;
first_start: BOOL := TRUE;
(*old_mode: INT;
old_pod_ust: INT;
old_ust_temp_z: INT;*)
temp_pod, ust_temp_f: REAL;
temp_nv: REAL;
delta: REAL;
ind_temp1: REAL;
END_VAR
VAR RETAIN
temp: ARRAY [0..78] OF REAL;
(*mode_r: INT;
pod_ust_r: INT;
ust_temp_r: INT;*)
NaprReg_r:REAL;
END_VAR
…………………………………………………………………………………………………………………………………… …………………………….
NaprReg := NaprReg_r;
IF first_start THEN
(* +8 +7.5 +7 +6.5 +6 *)
temp[0] := 35; temp[1] := 36; temp[2] := 36; temp[3] := 36; temp[4] := 36;
(* +5.5 +5 +4.5 +4 +3.5 *)
temp[5] := 36; temp[6] := 36; temp[7] := 36; temp[8] := 36; temp[9] := 36.5;
(* +3 +2.5 +2 +1.5 +1 *)
temp[10] := 37; temp[11] := 37.5; temp[12] := 38; temp[13] := 38.5; temp[14] := 39;
(* +0.5 0 -0.5 -1 -1.5 *)
temp[15] := 39.5; temp[16] := 40; temp[17] := 40.5; temp[18] := 41; temp[19] := 41.5;
(* -2 -2.5 -3 -3.5 -4 *)
temp[20] := 42; temp[21] := 42.5; temp[22] := 43; temp[23] := 43.5; temp[24] := 44;
(* -4.5 -5 -5.5 -6 -6.5 *)
temp[25] := 44.5; temp[26] := 45; temp[27] := 45.5; temp[28] := 46; temp[29] := 46.5;
(* -7 -7.5 -8 -8.5 -9 *)
temp[30] := 47; temp[31] := 47.5; temp[32] := 48; temp[33] := 48.5; temp[34] := 49;
(* -9.5 -10 -10.5 -11 -11.5 *)
temp[35] := 49; temp[36] := 49; temp[37] := 49.5; temp[38] := 50; temp[39] := 50;
(* -12 -12.5 -13 -13.5 -14 *)
temp[40] := 50; temp[41] := 50.5; temp[42] := 51; temp[43] := 51; temp[44] := 51;
(* -14.5 -15 -15.5 -16 -16.5 *)
temp[45] := 51.5; temp[46] := 52; temp[47] := 52.5; temp[48] := 53; temp[49] := 53.5;
(* -17 -17.5 -18 -18.5 -19 *)
temp[50] := 54; temp[51] := 54.5; temp[52] := 55; temp[53] := 55.5; temp[54] := 56;
(* -19.5 -20 -20.5 -21 -21.5 *)
temp[55] := 56.5; temp[56] := 57; temp[57] := 57.5; temp[58] := 58; temp[59] := 58.5;
(* -22 -22.5 -23 -23.5 -24 *)
temp[60] := 59; temp[61] := 59.5; temp[62] := 60; temp[63] := 60.5; temp[64] := 61;
(* -24.5 -25 -25.5 -26 -26.5 *)
temp[65] := 61.5; temp[66] := 62; temp[67] := 62.5; temp[68] := 63; temp[69] := 63.5;
(* -27 -27.5 -28 -28.5 -29 *)
temp[70] := 64; temp[71] := 64.5; temp[72] := 65; temp[73] := 65.5; temp[74] := 66;
(* -29.5 -30 -30.5 -31 *)
temp[75] := 66.5; temp[76] := 67; temp[77] := 67.5; temp[78] := 68;
IF NaprReg=0.0 THEN
NaprReg := 0.5;
END_IF;
first_start := FALSE;
END_IF;
df( VALUE:=temp_pod_d, DEF_VALUE:= temp_pod);
CASE df._ERR OF
12: temp_pod_s := 2000; (* кз *)
13: temp_pod_s := 2001; (*обрыв *)
6,7,8,9,10,11,14,15: temp_pod_s := 2002; (*ошибка контроллера *)
ELSE
temp_pod_s := REAL_TO_INT(df.OUT_VALUE*10);
temp_pod := temp_pod_d;
END_CASE;
df( VALUE:=temp_nv_d, DEF_VALUE:=temp_nv);
CASE df._ERR OF
12: temp_nv_s := 2000; (* кз *)
13: temp_nv_s := 2001; (*обрыв *)
6,7,8,9,10,11,14,15: temp_nv_s := 2002; (*ошибка контроллера *)
ELSE
temp_nv_s := REAL_TO_INT((df.OUT_VALUE+50.0)*10);
temp_nv := temp_nv_d;
END_CASE;
ind_temp1 := temp_nv;
ind_temp := 16 - REAL_TO_INT(ind_temp1*2);
IF ind_temp < 0 THEN
ind_temp := 0;
ELSIF ind_temp > 78 THEN
ind_temp := 78;
END_IF;
IF mode = 1 THEN
ust_temp := temp[ind_temp]+pod_ust;
ELSE
ust_temp := ust_temp_z;
END_IF;
temp_pod_i := REAL_TO_INT(temp_pod);
ust_temp_f := (ust_temp);
ton1.PT := t#10m; ton2.PT := t#10s;
ton1(in :=TRUE); ton2(in :=TRUE);
IF ton1.ET >t#30s THEN
IF (temp_pod_i >ust_temp) AND (temp_pod_s <2000) AND ((temp_nv_s<2000) OR (mode=0)) THEN
delta :=(temp_pod - ust_temp_f)/500;
NaprReg := NaprReg +delta;
IF NaprReg > 0.90 THEN NaprReg := 0.90; END_IF;
END_IF;
IF (temp_pod_i delta :=(ust_temp_f - temp_pod)/500 ;
NaprReg := NaprReg -delta;
IF NaprReg < 0.0 THEN NaprReg := 0.0; END_IF;
END_IF;
ton1(in :=FALSE);
END_IF;
NaprReg_r := NaprReg;
napr_s :=REAL_TO_INT( NaprReg *1000);
IF ton2.ET >t#400ms THEN
ton2(in :=FALSE);
ClearScreen(0);
SetWorkScreen(0);
ShowString(0,0,0,'Тнв=');
CASE temp_nv_s OF
2000: ShowString(0,4,0,'КЗ ');
2001: ShowString(0,4,0,'Обр ');
2002: ShowString(0,4,0,'Ош. ');
ELSE
ShowReal(0, 4, 0, '%3.1f',temp_nv);
END_CASE;
ShowString(0,9,0,'Тп=');
CASE temp_pod_s OF
2000: ShowString(0,12,0,'КЗ ');
2001: ShowString(0,12,0,'Обр ');
2002: ShowString(0,13,0,'Ош. ');
ELSE
ShowReal(0, 12, 0, '%3.1f',temp_pod);
END_CASE;
ShowString(0,0,1,'Uуп='); ShowReal(0, 4, 1, '%4.2f',NaprReg*10);
END_IF;
зачем дублировать свое сообщение, да еще в таком виде, просто проект вложить не проще или хотя бы код убрать под спойлер. А по существу Вам уже посоветовали. По коду могу предложить обратит внимание на преобразование real_to_in, оно округляет до ближайшего целого, возможно в этом причина
Мин вр цикла плк должно быть больше цикла сканирования в МС(у вас 1мс и 6 мс), входы 1-4 в плк 110 быстрые время фильтрации 0(попробывать 1 если импульсы от расходомеров задаются мех контактами-такое было-дребезг) как и в других (обычных входах) т.е входы должны находится в одинаковых условиях(мое мнение)..Цитата:
когда я подключил параллельно к ПЛК 110.60-М (цикл сканирования в Statistic 7мс)
Спасибо за ответ. Я не программист. Как необходимо исправить это выражение? Оно к тому же в двух местах. Там анализируются состояния термометров сопротивления: на улице и в трубопроводе, есть ли обрыв или кз. Но как я написал ранее если контроллер поддерживает целое значение температуры теплоносителя, например 50 гр., то точность становится 1 гр.: от 49,5 до 50,5 гр. Если поддерживается, например 50,5 гр. о точность становится 0,5 гр.: от 50,25 до 50,75 гр. Почему так происходит - непонятно.
Юра, почему ты думаешь, что если ты продублируешь свой вопрос во всех ветках форума, то быстрее получишь ответ. Если не отвечают, значит мало представлено информации, или вы не воспользовались предложенным вам хорошим советом применить ПИД регулятор.
У меня работает ПЛК 63 с этой программой.
Для начала убрать все промежуточные округления. Всё выглядит подозрительно: и таблица эта (кстати её можно инициализировать при объявлении), и REAL_TO_INTы, и какие-то тысячи с сотнями, и таймеры, которые никогда не достигают своего Q. Этот код напрашивается на неприятности.Цитата:
Где нужно подкорректировать программу чтобы точность поддержания температуры была 0,5 гр.?
Юрий, то что это работает - уже сами сказали в первом посте
"Имеется рабочая программа...Но когда контроллер поддерживает..."
То что 63й - видно из кода
"ShowString... ShowReal.."
То что "таймеры нужны" - так они объявлены и как-то используются.
Здесь не тупые сидят - выводы делать умеют.
Вы бы объяснили сами сначала
1.Конечную цель проекта
2.Cуть своего регулятора
3.Объяснили чем он круче пид'а. Особенно на фоне вопроса о точности
Когда контроллер поддерживает целое значение температуры теплоносителя, например 50 гр., то точность становится 1 гр.: от 49,5 до 50,5 гр. Если поддерживается, например 50,5 гр. о точность становится 0,5 гр.: от 50,25 до 50,75 гр.
Где нужно подкорректировать программу чтобы точность поддержания температуры была 0,5 гр. для целых значений температур?
Когда контроллер поддерживает целое значение температуры теплоносителя, например 50 гр., то точность становится 1 гр.: от 49,5 до 50,5 гр. Если поддерживается, например 50,5 гр. о точность становится 0,5 гр.: от 50,25 до 50,75 гр.
Где нужно подкорректировать программу чтобы точность поддержания температуры была 0,5 гр. для целых значений температур?
Видите ли Юрий, автоматчики народ ленивый, и при словах "погода, темп-ра, регулировать" они чаще всего берут с полки пид,
что бы все нормально регулировалось и не мешало пить пиво.
А у него (пид'а) вопрос с точностью вообще не стоит. Просто 0. Если конечно коэфф-ты подобрали ))
Вы ж не объяснили как оно работает, "поддерживается ..." это не принцип, а результат.
Предлагаете другим изучать странный и неизвестный алгоритм, который вряд ли когда потребуется ?
PS
Пжста, не надо одну и ту же тему в 10-ти местах.
И на разных форумах по автоматике тоже не надо, все мы - одна шайка-лейка.
У меня был Заказчик, который за 50т вынудил меня два месяца отжиматься, но хоть мало, да все таки деньги)
Вы судя по всему ищете бесплатного решения. Ошибаюсь?
Юрий, на чужих плечах в Рай Вы вряд ли уедете.
Доброго времени суток обитателям форума. Нужна помощь. Не знаю, в какую ветку мне обратиться, поэтому оставлю свой небольшой вопрос здесь. Начинаю программировать в среде Codesys V2, на языке ST, на данном этапе мне нужно создать цикл, повторяющийся около сотни раз, и содержащий в себе таймер - задержку на каждое действие, поступающее на выход. Иными словами, код имеет вид while i<100 do {(действие); Tim1(in:=true, pt:=T#3s);}.
Возникает проблема при компиляции. 1. Если счетчик произвольно инкременируется раз в цикл, все 100 циклов завершаются быстрее, чем заканчивает работу первый таймер. 2. Если счетчику присваивается значение только после завершения работы таймера (по выходному значению Q), срабатывает сторожевой таймер, сигналит, что цикл слишком длинный. Как возможно реализовать задержку во времени в цикле, какие есть еще способы? Буду рад любым советам.
Zik, попробуйте оператор CASE
сделайте их столько, сколько Вам нужно
В каждом из них сделайте нужный Вам таймер
Может быть я и неправильно написал, но сложно понять Ваш текст, если Вы не описываете её как внешнюю задачу.
В ПЛК крайне не желательно использовать Wile&For эти операторы я в ПЛК использую, когда мне нужны манипуляции с массивами и структурами. ПЛК и Windows очень отличаются, в ПЛК Вы с легкостью подвесите процессор.
В общем - действуйте еще аккуратнее)
Спасибо за советы, попробую завтра с CASE. Непривычно довольно отказываться от циклов со счетчиком, не знал, что они так плохо воспринимаются средой.
Дело не в том что они средой не так воспринимаются, а в том что время общего цикла в ПЛК условно фиксировано и если вы в него не уложились то получили собаку. Поэтому вам надо поверх того цикла организовать свой при помощи оператора CASE. В нем в первом шаге что-то делаете (действие одно-го из ваших 100 циклов, взводите таймер и переходите во втррой шаг CASE. Во втором шаге просто проверяем таймер и если он отсчитал положенное возвращаемся в первый шаг CASE.
Попробовал вставить цикл только лишь для чередования между двумя case-блоками, в одном из которых таймер, а в другом по подверждению от таймера переход обратно к первому шагу. Происходит та же ошибка, что и без использования блоков -срабатывание сторожевого таймера. Возможно ли как-то реализовать их чередование без использования циклов? Ведь после проверки значения переменной условия case, повторная проверка возможна только при повторении всего кода, выходит. Схематично программу выложил здесь. https://ideone.com/hC38bK
Case нужен, так как по логике таймер не должен заканчивать отсчет позже,чем завершается программа. Только в итоге для плк ничего не изменилось. А while тут только для чередования блоков, без цикла выполняется только один из них, как перейти после выполнения второго к первому шагу case, например?
Опишите пожалуйста задачу.
Мне кажется Вы совершаете классическую ошибку программиста верхнего уровня и не учитываете особенности работы ПЛК. В частности того, что ПЛК в принципе работает в цикле сам по себе. Цикл уже организован в ПЛК :)
Любой другой цикл существует только для проверки условия ну или для зацикливания ПЛК, что приводит к перезагрузке.
Вот я и говорю, что с точки зрения ПЛК ничего не изменилось, как был цикл WHILE так он и остался.
В ПЛК вся программа выполняется циклически без участия программиста, время цикла задается в настройках(в конфигурации). Вы не можете ее "притормозить" - сработает сторожевой таймер.
По этому вместо WHILE используйте IF с тем же условием.
В общем-то, задача - цикл испытаний, который должен повториться сто раз. В нем мотор крутится три секунды в одну сторону, три секунды ждет, потом три секунды крутится в другую. Пишу для PLC 100 R-M. Понимаю, как это реализовать несколькими способами, но натыкаюсь на сопротивление как раз таки архитектуры ПЛК. Когда я запускаю программу без цикла в режиме эмуляции CodeSYS - она выполняется один раз с начала и до конца. Отсчитывает один раз таймер, присваивает конечные значения локальным переменным, и останавливается, не мигают выходы, не присваиваются начальные значения для нового цикла. То же самое при подключении ПЛК, т.е. уже не в режиме эмуляции, код проходит один раз. Поэтому для наглядности, которая нужна работодателю, листинг должен быть зацикленным. Будет ли программа с блоками case идти на второй круг после выполнения, если не добавлять в нее циклы вручную, и главное, как это проверить? И именно на сотом ПЛК. Я в полном смятении.
Не архитектура ПЛК Вам мешает, а накопленный за годы багаж знаний и опыт. :)
ПЛК работает по другому. Напишите в проекте:
a:=a+1; И Вы увидите, что a будет постоянно инкриментироваться, пока не переполнится. Это и есть внутернний цикл ПЛК.
Программа выполняется сверху вниз, записываются результаты, считывается область входов-выходов, и программа снова выполняется сверху вниз.
Таймеры не надо отслеживать - таймеры отследятся сами при очередном проходе.
Единственно для чего Вам нужен цикл - отключить работу логики когда условия выполнятся 100 раз.
Для организации выполнения условия циклы не нужны. Я обычно использовал обыкновенный If
Проще всего Вашу задачу вообще реализовать на SFC. Три блока, три условия перехода, три таймера. При выходе из последнего блока инкриментируем количество прошедших циклов.
А как повторить таймер-то без цикла? Даже функция Tim(IN:=TRUE, PT:=T#2S); без привязки к входным и выходным параметрам, выполнится только 1 раз и программа остановится, хотя согласно логике плк должна повторяться.
Как-то так.Код:PROGRAM PLC_PRG
VAR
Aout: BOOL;
Bout: BOOL;
Start: BOOL;
Tim: TON:=(PT:=T#3S);
X: INT;
L: INT;
R_TRIG1: R_TRIG;
END_VAR
R_TRIG1(CLK:=Ain , Q=>Start );
IF Start THEN X:=1; END_IF
IF L<100 AND Ain THEN
Tim(IN:= NOT Tim.Q );
CASE X OF
1: Aout:=TRUE; X:=X+BOOL_TO_INT(Tim.Q);
2: Aout:=FALSE; X:=X+BOOL_TO_INT(Tim.Q);
3: Bout:=TRUE; X:=X+BOOL_TO_INT(Tim.Q);
4: Bout:=FALSE; X:=X+BOOL_TO_INT(Tim.Q);
5: L:=L+1; X:=1;
END_CASE
ELSE
X:=0;
L:=0;
Aout:=FALSE;
Bout:=FALSE;
Tim(IN:= FALSE );
END_IF
ЗЫ.
Таймер-то через 2с нужно перезапустить по входу IN.
Вложение 23336
У меня в примере так - Tim(IN:= NOT Tim.Q ), т.е. он сам себя перезапускает.
Да, именно так.Цитата:
это вход ПЛК, т.е. глобальная переменная
Вот за наводку благодарен, крайне полезно мне будет. Спасибо за развернутый ответ, в целом.Цитата:
У меня в примере так - Tim(IN:= NOT Tim.Q ), т.е. он сам себя перезапускает.
Уважемые форумчане, вопрос по грамотной реализации задачи:
Дано:
20 емкостей требуется в них поддерживать темературу и давление согласно графика по 10 точками из HMI
на входе данные:
датчики температуры + датчики давления
график температуры + давления от HMI на каждую емкость
время и дата старта процесса на каждую емкость
статусы емкости: емкость выключена, ручное управление, поддержание по графику
на выходе:
магнитные дискретные клапана подачи охлаждающей жижи и клапан сброса давления
условие:
Графики по 10 точкам , точность почасовая
Температура и давление уставки на каджый момент должны расчитываться по графику между двумя точками, почасово.
Формат данных:
температура -5 до +40 градусов, точность 0,1
давление 0 до 3 бара, точность 0,1 бара
Я вижу реализацию этого так:
В плк160 выступает сервером, создаем слэйв
Создаем карту регистров , допустим 2 байтных
Для каждой емкости регистры
1: статус : емкость выключена, ручное управление, поддержание по графику
2: дата-время старта процесса в часах от 0000 года
3-13: с 0 по 10 точку графика время
14-24: с 0 по 10 точку графика температуры
25-35: с 0 по 10 точку графика время
36-46: с 0 по 10 точку графика давления
47: положение клапана температуры
48: положение клапана давления
49: текущая уставка расчетная Температуры
50: текущая уставка расчетная Давления
итого 20 емкостей х 50 данных = 1 000 разных данных !!!
Это все ручками прописывать в codesys 2.3 в Конфигурации ПЛК и создавать 1000 регистров ?
Или создавать двухмерный массив в VAR_GLOBAL на 20 х 50 ячеек INT задать каждой ячейке ссылку на адрес AT %.... и уже потом работать с ним, ?
или массив для сохранности от выключения питания помещать в VAR_GLOBAL RETAIN ?
типо:
AR1: ARRAY [1..20,1..50] OF INT := AT %QD8.1.0 , AT %QD8.2.0, AT %QD8.3.0 .... и тд
В "конфигурации задач" создаю новую задачу с интервалом в 1 час, у которой добавляю вызов программы, в которой делаю перебор массива по 20 емкостям, и для тех емкостей у которых статус "поддержание по графику" , делаем расчет на текущий момент значение уставки исходя из данных в массиве.
Прописываем эту новую уставку в ячейку массива связанную с памятью, и используем этот регистр для поддержания температуры и для того чтоб мониторить в HMI
Далее в цикле программа которая по гистерезису и тек измеренному значению рулит клапанами с учетом уставки.
Ну и вроде все)))
ну и главное ПЛК160 потянет вообще такую нагрузку ?
Вот такие вопросы от новичка . Писать на ST видимо )
Спасибо заранее
Можно обойтись и 51 точкой, из которых 50 это названные параметры, а 1 - номер ёмкости. Сильно зависит от способностей вашего HMI на самом деле.Цитата:
Это все ручками прописывать в codesys 2.3 в Конфигурации ПЛК и создавать 1000 регистров ?
Так нельзя. Можно проще: объявить указатель на массив и направить его на область слейва, если не ссыкотно. AR1: POINTER TO ARRAY [1..50] OF TANK; AR1 := ADR(%...) или типа того. TANK - структура с вашими данными (так удобнее ведь).Цитата:
AR1: ARRAY [1..20,1..50] OF INT := AT %QD8.1.0 , AT %QD8.2.0, AT %QD8.3.0 .... и тд