Да, таймеры работают в миллисекундах, мне нужен вывод в секундах.
Получается нужно сделать что-то типа WORD + WORD:= TO_WORD (DWORD)?
Вид для печати
Для начала определитесь, какое максимальное время у вас будет?
У вас на скрине уже 37098 +509 =37607, а WORD максимум 65 535 (это максимум 18 часов, если в секундах).
Если больше, то конвертация DWORD_TO_ WORD уже не нужна. DWORD это максимум 49 дней (в мс), это тоже надо помнить.
Потом зачем скрадывать конвертированное время WORD, если проще складывать само время TIME, а конвертировать только результат.
У вас на 10 строках несколько раз конвертация туда и обратно. Не мудрено, что всё считает криво.
Сначала надо составить алгоритм, прикинуть, хватает ли вам диапазона переменных и только потом писать программу.
Простои считаются и сохраняются по одному часу, например с 6:30 до 7:30, далее сохраняются в другой час, и так далее в течении смены, так что WORD мне достаточно.
Код ФБ:
FUNCTION_BLOCK Downtime_Chassis_line
VAR_INPUT
xRedButton: BOOL; //Красная кнопка "Авария"
END_VAR
VAR_OUTPUT
wDownTimeS1H1: WORD; //Простой в минутах I смены 1-ый час
wDownTimeS1H2: WORD; //Простой в минутах I смены 2-ой час
wDownTimeS1H3: WORD; //Простой в минутах I смены 3-ий час
wDownTimeS1H4: WORD; //Простой в минутах I смены 4-ый час
wDownTimeS1H5: WORD; //Простой в минутах I смены 5-ый час
wDownTimeS1H6: WORD; //Простой в минутах I смены 6-ой час
wDownTimeS1H7: WORD; //Простой в минутах I смены 7-ой час
wDownTimeS1H8: WORD; //Простой в минутах I смены 8-ой час
wDownTimeS2H1: WORD; //Простой в минутах II смены 1-ый час
wDownTimeS2H2: WORD; //Простой в минутах II смены 2-ой час
wDownTimeS2H3: WORD; //Простой в минутах II смены 3-ий час
wDownTimeS2H4: WORD; //Простой в минутах II смены 4-ый час
wDownTimeS2H5: WORD; //Простой в минутах II смены 5-ый час
wDownTimeS2H6: WORD; //Простой в минутах II смены 6-ой час
wDownTimeS2H7: WORD; //Простой в минутах II смены 7-ой час
wDownTimeS2H8: WORD; //Простой в минутах II смены 8-ой час
wTotalDownTimeS1: WORD; //Всего простоев за I смену
wTotalDownTimeS2: WORD; //Всего простоев за II смену
END_VAR
VAR
tonDowntime: TON; //Таймер времени простоя
tDowntime: TIME; //Время работы таймера простоя в секундах
dwDowntime: DWORD;
wDowntime: WORD;
END_VAR
//Присвоение значения селектору количества часов в I смене
IF ((TargetVars.stRTC.sGetFormatTime>=TargetVars.sSta rtShift1) AND (TargetVars.stRTC.sGetFormatTime<TargetVars.sH1_H2 Shift1))
THEN TargetVars.iHourShift1:=1; //1-ый час
ELSIF ((TargetVars.stRTC.sGetFormatTime>=TargetVars.sH1_ H2Shift1) AND (TargetVars.stRTC.sGetFormatTime<TargetVars.sStart Break11))
THEN TargetVars.iHourShift1:=2; //2-ой час
ELSIF ((TargetVars.stRTC.sGetFormatTime>=TargetVars.sEnd Break11) AND (TargetVars.stRTC.sGetFormatTime<TargetVars.sH3_H4 Shift1))
THEN TargetVars.iHourShift1:=3; //3-ий час
ELSIF ((TargetVars.stRTC.sGetFormatTime>=TargetVars.sH3_ H4Shift1) AND (TargetVars.stRTC.sGetFormatTime<TargetVars.sStart Lunch1))
THEN TargetVars.iHourShift1:=4; //4-ый час
ELSIF ((TargetVars.stRTC.sGetFormatTime>=TargetVars.sEnd Lunch1) AND (TargetVars.stRTC.sGetFormatTime<TargetVars.sH5_H6 Shift1))
THEN TargetVars.iHourShift1:=5; //5-ый час
ELSIF ((TargetVars.stRTC.sGetFormatTime>=TargetVars.sH5_ H6Shift1) AND (TargetVars.stRTC.sGetFormatTime<TargetVars.sStart Break12))
THEN TargetVars.iHourShift1:=6; //6-ой час
ELSIF ((TargetVars.stRTC.sGetFormatTime>=TargetVars.sEnd Break12) AND (TargetVars.stRTC.sGetFormatTime<TargetVars.sH7_H8 Shift1))
THEN TargetVars.iHourShift1:=7; //7-ой час
ELSIF ((TargetVars.stRTC.sGetFormatTime>=TargetVars.sH7_ H8Shift1) AND (TargetVars.stRTC.sGetFormatTime<TargetVars.sEndSh ift1))
THEN TargetVars.iHourShift1:=8; //8-ой час
END_IF
//Присвоение значения селектору количества часов во II смене
IF ((TargetVars.stRTC.sGetFormatTime>=TargetVars.sSta rtShift2) AND (TargetVars.stRTC.sGetFormatTime<TargetVars.sH1_H2 Shift2))
THEN TargetVars.iHourShift2:=1; //1-ый час
ELSIF ((TargetVars.stRTC.sGetFormatTime>=TargetVars.sH1_ H2Shift2) AND (TargetVars.stRTC.sGetFormatTime<TargetVars.sStart Break21))
THEN TargetVars.iHourShift2:=2; //2-ой час
ELSIF ((TargetVars.stRTC.sGetFormatTime>=TargetVars.sEnd Break21) AND (TargetVars.stRTC.sGetFormatTime<TargetVars.sH3_H4 Shift2))
THEN TargetVars.iHourShift2:=3; //3-ий час
ELSIF ((TargetVars.stRTC.sGetFormatTime>=TargetVars.sH3_ H4Shift2) AND (TargetVars.stRTC.sGetFormatTime<TargetVars.sStart Lunch2))
THEN TargetVars.iHourShift2:=4; //4-ый час
ELSIF ((TargetVars.stRTC.sGetFormatTime>=TargetVars.sEnd Lunch2) AND (TargetVars.stRTC.sGetFormatTime<TargetVars.sH5_H6 Shift2))
THEN TargetVars.iHourShift2:=5; //5-ый час
ELSIF ((TargetVars.stRTC.sGetFormatTime>=TargetVars.sH5_ H6Shift2) AND (TargetVars.stRTC.sGetFormatTime<TargetVars.sStart Break22))
THEN TargetVars.iHourShift2:=6; //6-ой час
ELSIF ((TargetVars.stRTC.sGetFormatTime>=TargetVars.sEnd Break22) AND (TargetVars.stRTC.sGetFormatTime<TargetVars.sH7_H8 Shift2))
THEN TargetVars.iHourShift2:=7; //7-ой час
ELSIF ((TargetVars.stRTC.sGetFormatTime>=TargetVars.sH7_ H8Shift2) AND (TargetVars.stRTC.sGetFormatTime<TargetVars.sEndSh ift2))
THEN TargetVars.iHourShift2:=8; //8-ой час
END_IF
//Сброс данных о простоях I и II смены
IF TargetVars.stRTC.sGetFormatTime=TargetVars.sDataRe set OR TargetVars.stRTC.sGetFormatTime='12:08:00'
THEN wDownTimeS1H1:=0;
wDownTimeS1H2:=0;
wDownTimeS1H3:=0;
wDownTimeS1H4:=0;
wDownTimeS1H5:=0;
wDownTimeS1H6:=0;
wDownTimeS1H7:=0;
wDownTimeS1H8:=0;
wDownTimeS2H1:=0;
wDownTimeS2H2:=0;
wDownTimeS2H3:=0;
wDownTimeS2H4:=0;
wDownTimeS2H5:=0;
wDownTimeS2H6:=0;
wDownTimeS2H7:=0;
wDownTimeS2H8:=0;
END_IF
//Включение/отключение/сохранение времени Таймера времени простоя
tonDowntime (IN:=xRedButton, PT:= T#28800S); // Таймер на 8 часов
IF NOT tonDowntime.Q
THEN tDowntime:=tonDowntime.ET;
END_IF
CASE TargetVars.iHourShift1 OF
1:
dwDowntime:= TO_DWORD (tDowntime);
dwDowntime:= dwDowntime / 1000; //Перевод миллисекунд в секунды
wDowntime:= TO_WORD (dwDowntime);
wDownTimeS1H1:= wDownTimeS1H1 + wDowntime;
2:
dwDowntime:= TO_DWORD (tDowntime);
dwDowntime:= dwDowntime / 1000; //Перевод миллисекунд в секунды
wDowntime:= TO_WORD (dwDowntime);
wDownTimeS1H2:= wDownTimeS1H2 + wDowntime;
3:
dwDowntime:= TO_DWORD (tDowntime);
dwDowntime:= dwDowntime / 1000; //Перевод миллисекунд в секунды
wDowntime:= TO_WORD (dwDowntime);
wDownTimeS1H3:= wDownTimeS1H3 + wDowntime;
4:
dwDowntime:= TO_DWORD (tDowntime);
dwDowntime:= dwDowntime / 1000; //Перевод миллисекунд в секунды
wDowntime:= TO_WORD (dwDowntime);
wDownTimeS1H4:= wDownTimeS1H4 + wDowntime;
5:
dwDowntime:= TO_DWORD (tDowntime);
dwDowntime:= dwDowntime / 1000; //Перевод миллисекунд в секунды
wDowntime:= TO_WORD (dwDowntime);
wDownTimeS1H5:= wDownTimeS1H5 + wDowntime;
6:
dwDowntime:= TO_DWORD (tDowntime);
dwDowntime:= dwDowntime / 1000; //Перевод миллисекунд в секунды
wDowntime:= TO_WORD (dwDowntime);
wDownTimeS1H6:= wDownTimeS1H6 + wDowntime;
7:
dwDowntime:= TO_DWORD (tDowntime);
dwDowntime:= dwDowntime / 1000; //Перевод миллисекунд в секунды
wDowntime:= TO_WORD (dwDowntime);
wDownTimeS1H7:= wDownTimeS1H7 + wDowntime;
8:
dwDowntime:= TO_DWORD (tDowntime);
dwDowntime:= dwDowntime / 1000; //Перевод миллисекунд в секунды
wDowntime:= TO_WORD (dwDowntime);
wDownTimeS1H8:= wDownTimeS1H8 + wDowntime;
END_CASE
wTotalDownTimeS1:= wDownTimeS1H1+wDownTimeS1H2+wDownTimeS1H3+wDownTim eS1H4+wDownTimeS1H5+wDownTimeS1H6+wDownTimeS1H7+wD ownTimeS1H8;
CASE TargetVars.iHourShift2 OF
1:
dwDowntime:= TO_DWORD (tDowntime);
dwDowntime:= dwDowntime / 1000; //Перевод миллисекунд в секунды
wDowntime:= TO_WORD (dwDowntime);
wDownTimeS2H1:= wDownTimeS2H1 + wDowntime;
2:
dwDowntime:= TO_DWORD (tDowntime);
dwDowntime:= dwDowntime / 1000; //Перевод миллисекунд в секунды
wDowntime:= TO_WORD (dwDowntime);
wDownTimeS2H2:= wDownTimeS2H2 + wDowntime;
3:
dwDowntime:= TO_DWORD (tDowntime);
dwDowntime:= dwDowntime / 1000; //Перевод миллисекунд в секунды
wDowntime:= TO_WORD (dwDowntime);
wDownTimeS2H3:= wDownTimeS2H3 + wDowntime;
4:
dwDowntime:= TO_DWORD (tDowntime);
dwDowntime:= dwDowntime / 1000; //Перевод миллисекунд в секунды
wDowntime:= TO_WORD (dwDowntime);
wDownTimeS2H4:= wDownTimeS2H4 + wDowntime;
5:
dwDowntime:= TO_DWORD (tDowntime);
dwDowntime:= dwDowntime / 1000; //Перевод миллисекунд в секунды
wDowntime:= TO_WORD (dwDowntime);
wDownTimeS2H5:= wDownTimeS2H5 + wDowntime;
6:
dwDowntime:= TO_DWORD (tDowntime);
dwDowntime:= dwDowntime / 1000; //Перевод миллисекунд в секунды
wDowntime:= TO_WORD (dwDowntime);
wDownTimeS2H6:= wDownTimeS2H6 + wDowntime;
7:
dwDowntime:= TO_DWORD (tDowntime);
dwDowntime:= dwDowntime / 1000; //Перевод миллисекунд в секунды
wDowntime:= TO_WORD (dwDowntime);
wDownTimeS2H7:= wDownTimeS2H7 + wDowntime;
8:
dwDowntime:= TO_DWORD (tDowntime);
dwDowntime:= dwDowntime / 1000; //Перевод миллисекунд в секунды
wDowntime:= TO_WORD (dwDowntime);
wDownTimeS2H8:= wDownTimeS2H8 + wDowntime;
END_CASE
wTotalDownTimeS2:= wDownTimeS2H1+wDownTimeS2H2+wDownTimeS2H3+wDownTim eS2H4+wDownTimeS2H5+wDownTimeS2H6+wDownTimeS2H7+wD ownTimeS2H8;
В таблице, и соответственно в переменной wDownTimeS2Hх, вместо 509 отображается 37098 и 29851.
Значение доходит до 9999 (так как в таблице ограничено 4 знаками) и начинается отсчет сначала, и именно это значение записывается в wDownTimeS2Hх, а нужно чтобы 509.
Вложение 81545
Я ТС уже не понимаю. То ему надо суммировать, то не надо. Походу щас ожидаю вопросы по правильности работы case, типа он не те числа складывает.. Вы определитесь как элементарные функции работают.
Скрины разрисовывать время есть, а приложить исходник в виде файла проекта совесть не позволяет. Тогда уж код отдклите служебными словами кода...
По времени цикла программы...)
Ниче, и так сойдет.
PS Сейчас опять новый вопрос предвижу: какое такое время цикла... Что за 20 мс по умолчанию... Мне так не надо...
Ваш функциональный блок, кстати, не информативен без кода, его вызывающего. Триггер нужен или вне, или внутри блока.
ну тогда значения 37098 и 29851 это результат сложения старого с текущим, что не так? Где тогда должно отображаться текущее?
И главное чтоб не "выкатывать" такие "портянки" напишите функцию, например
и тогда заметно код сократится, если в каждом кейсе написать wDownTimeSXHX:= Solver(wDownTimeSXHX,tDowntime);Код:function Solver: WORD;
var_input
OLD_TIK : WORD;
tDowntime: TIME;
end_var
var_
dwDowntime: DWORD;
end_var
dwDowntime:= TO_DWORD (tDowntime);
dwDowntime:= dwDowntime / 1000; //Перевод миллисекунд в секунды
Solver := OLD_TIK + TO_WORD (dwDowntime);
end_function
А может ТС смущает:
12345:= 12345 + 123
И он хочет узнать почему отображается не:
12345:= 12222 + 123
Ну думаю это не так, и все же он спрашивает о том, о чем мы все говорим...
PS Включил ПК, щас набросаю код...
Вложение 81552
Не благодарите...
У ТС там арифметическая прогрессия была. Задолбался переменные прописывать начала-конца часов. Ну мы же не можем проект приложить, мы выше этого...
PS Но ваш алгоритм все равно будет работать неправильно, вернее моя корректировка. Т.к. если кнопка стоп будет отжата после перехода часовки, то данные наработки в предыдущем часе присвоятся следующему часу. Так что внедряйте другой механизм, тут я показал просто вашу ошибку в коде, и костыль для ее решения малой кровью...
PS2 Создайте цикл на 1000 мс, перенесите туда ваш код, и просто прибавляйте в вашем старом алгоритме не время, а 1. Это кстати так и надо делать. Таймер можно вообще убрать. Тогда и часовки будут правильными.
И никаких преобразования таймеров...Код:If not кнопка-стоп then
Case...
1: часовка1:= часовка1 + 1
2: часовка2:= часовка2 + 1
...