Показано с 1 по 9 из 9

Тема: Обнуление переменной

  1. #1

    По умолчанию Обнуление переменной

    Доброго времени суток. прошу помоши в следующем деянии:

    Необходимо обнулять переменную, типа real, в 00:00 каждый день, первого числа каждого месяца так же в 00:00, и первого января каждого года в 00:00, буду премного благодарен за помощь в этом вопросе.

    PS. На WinCC SP3, проделывал такое скриптами, а вот в CDS сделать как ума не приложу.

  2. #2
    Пользователь Аватар для capzap
    Регистрация
    25.02.2011
    Адрес
    Киров
    Сообщений
    10,243

    По умолчанию

    можно вопрос в чем отличие первого января от первого числа каждого месяца, про каждый день даже спрашивать не буду

    по вопросу, добавляете библиотеку работы с временем, считывате показания с часов реального времени, сравниваете с нужными датами, по выполнению условия сбрасываете переменную
    Bad programmers worry about the code. Good programmers worry about data structures and their relationships

    среди успешных людей я не встречала нытиков
    Барбара Коркоран

  3. #3

    По умолчанию

    Ну отличия принципиального конечно нет, согласен, просто описал алгоритм, а по поводы "Сравнивать с нужными датами", это э какая простыня то получится расписанная, 12 месяцев, и черт его знает сколько лет, или я чего то не понимаю?

  4. #4
    Пользователь
    Регистрация
    27.11.2011
    Адрес
    Краснодар
    Сообщений
    10,651

    По умолчанию

    а у вас так много 1-х чисел для создания простыни ? вот просто каждый день у вас пятница, 13-ое прямо...

    00:00 И 1-ое число, вот и все сравнения.
    Ой, достаточно каждый день 00:00 часов, если еще каждый день...

  5. #5
    Пользователь Аватар для capzap
    Регистрация
    25.02.2011
    Адрес
    Киров
    Сообщений
    10,243

    По умолчанию

    так вот по этому у меня и был сперва вопрос. С ТЗ сперва разберитесь,что нужно, если каждый день в полночь обнулять, то и ловите наступление события, смены дня и состояние часов, минут, секунд равными нулю. Вы же писали что в скриптах все это проделываете легко, здесь то чего понапридумывали про портянку
    Bad programmers worry about the code. Good programmers worry about data structures and their relationships

    среди успешных людей я не встречала нытиков
    Барбара Коркоран

  6. #6

    По умолчанию

    Скрипт был прост до безобразия и настройки на выполнения скрипта задавались в настройках триггера. См вложение. Как в CDS сделать еще раз повторюсь не понимаю.ноль.jpg

  7. #7
    Пользователь
    Регистрация
    27.11.2011
    Адрес
    Краснодар
    Сообщений
    10,651

    По умолчанию

    PROGRAM get_time
    VAR CONSTANT
    nulldt: SystemTimeDate; (*нужна для обнуления*)
    END_VAR
    VAR_IN_OUT
    Sys_Time: SysTime64;
    TimeAndDate: SystemTimeDate;
    END_VAR
    VAR
    GetTime: CurTimeEx;
    END_VAR

    TimeAndDate:=nulldt;
    GetTime (SystemTime:=Sys_Time , TimeDate:=TimeAndDate);

    (*TimeAndDate.dwLowMSecs :=0;
    TimeAndDate.dwHighMsec :=0;
    TimeAndDate.Year :=0;
    TimeAndDate.Month :=0;
    TimeAndDate.Day :=0;
    TimeAndDate.Hour :=0;
    TimeAndDate.Minute :=0;
    TimeAndDate.Second :=0;
    TimeAndDate.Milliseconds :=0;
    TimeAndDate.DayOfWeek :=0;
    *)

    Вроде есть же в примерах.. Ну и вызывайте это из основной программы.
    PROGRAM PLC_PRG
    VAR
    syst: SysTime64;
    tmd: SystemTimeDate;
    END_VAR

    get_time(Sys_Time:=syst , TimeAndDate:=tmd ); (так кажется, просто у меня это на CFC)
    ну а дальше
    second := tmd.Second

    и так далее

  8. #8
    Пользователь Аватар для petera
    Регистрация
    06.05.2011
    Адрес
    Минск
    Сообщений
    3,840

    По умолчанию

    Цитата Сообщение от Алексей87 Посмотреть сообщение
    Ну отличия принципиального конечно нет, согласен, просто описал алгоритм, а по поводы "Сравнивать с нужными датами", это э какая простыня то получится расписанная, 12 месяцев, и черт его знает сколько лет, или я чего то не понимаю?
    Все довольна просто будет, если перейти к переменным DATE

    1.
    Делаем функцию, которая преобразовывает дату ПЛК(год,месяц,день) в DATE
    FUNCTION CurDATE:
    Код:
    FUNCTION CurDATE : DATE
    VAR
       CurTimeExInst: CurTimeEx;
        CurSystemTimeDate: SystemTimeDate;
        CurSysTime64: SysTime64;
        year: INT;
        second: INT;
        day: INT;
        hour: INT;
        minute: INT;
        month: INT;
        count: INT;
    END_VAR
    
    CurTimeExInst(TimeDate := CurSystemTimeDate, SystemTime := CurSysTime64);
        year :=CurSystemTimeDate.Year;
        month :=CurSystemTimeDate.Month;
        day :=CurSystemTimeDate.Day;
        hour :=CurSystemTimeDate.Hour;
        minute :=CurSystemTimeDate.Minute;
        second :=CurSystemTimeDate.Second;
    (*------------------------------------------------------------------------*)
    (*Вычислить дату с учетом високосных лет*)
    IF month > 2 THEN
        count := (month - 1) * 30;
        IF month > 7 THEN count := count + SHR(month - 3,1);
    ELSE count := count + SHR(month - 4,1); END_IF;
        (* проверить на високосный год и добавить один день если год високосный *)
        IF SHL(year,14) = 0 THEN count := count + 1; END_IF;
    ELSE
        count := (month - 1) * 31;
    END_IF;
    CurDATE:=DWORD_TO_DATE((INT_TO_DWORD(count + day - 1)
                   + SHR(INT_TO_DWORD(year) * 1461 - 2878169, 2)) * 86400);

    2.
    Берем из OSCAT, с некоторой модификацией функцию DAY_OF_MONTH
    FUNCTION DAY_OF_MONTH:
    Код:
    FUNCTION DAY_OF_MONTH : INT
    VAR_INPUT
    	IDATE : DATE;
    END_VAR
    VAR
    	leap: INT;
    	MTH_OFS: ARRAY [1..12] OF INT  := 0,31,59,90,120,151,181,212,243,273,304,334;
    	LEAP_OF_DATE: BOOL;
    END_VAR
    LEAP_OF_DATE := SHL(((DATE_TO_DWORD(idate) + 43200) / 31557600), 30) = 16#80000000;
    (* calculate the day in the year *)
    DAY_OF_MONTH := DAY_OF_YEAR(idate);
    (* leap will be set to one for a leap year *)
    leap := BOOL_TO_INT(LEAP_OF_DATE);
    (* if leap year deduct one from the days of the year *)
    DAY_OF_MONTH := DAY_OF_MONTH - leap;
    (* search if we are in month december to march ? *)
    IF DAY_OF_MONTH > MTH_OFS[9] THEN
    	IF DAY_OF_MONTH > MTH_OFS[11] THEN
    		IF DAY_OF_MONTH > mth_ofs[12] THEN
    			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[12];
    		ELSE
    			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[11];
    		END_IF;
    	ELSE
    		IF DAY_OF_MONTH > mth_ofs[10] THEN
    			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[10];
    		ELSE
    			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[9];
    		END_IF;
    	END_IF;
    ELSIF DAY_OF_MONTH > MTH_OFS[5] THEN
    	IF DAY_OF_MONTH > MTH_OFS[7] THEN
    		IF DAY_OF_MONTH > mth_ofs[8] THEN
    			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[8];
    		ELSE
    			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[7];
    		END_IF;
    	ELSE
    		IF DAY_OF_MONTH > mth_ofs[6] THEN
    			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[6];
    		ELSE
    			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[5];
    		END_IF;
    	END_IF;
    ELSIF DAY_OF_MONTH > MTH_OFS[3] THEN
    	IF DAY_OF_MONTH > MTH_OFS[4] THEN
    		DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[4];
    	ELSE
    		DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[3];
    	END_IF;
    ELSE
    	(* since now we must be in february or january we need to add leap again *)
    	DAY_OF_MONTH := DAY_OF_MONTH + leap;
    	IF DAY_OF_MONTH > MTH_OFS[2] THEN DAY_OF_MONTH := DAY_OF_MONTH - mth_ofs[2]; END_IF;
    	(* since nothing was true before, day_of_month must already be good *)
    END_IF;

    3. Для FUNCTION DAY_OF_MONTH нужна еще одна функция из OSCAT
    Скрытый текст:
    Код:
    FUNCTION DAY_OF_YEAR : INT
    VAR_INPUT
    	IDATE : DATE;
    END_VAR
    DAY_OF_YEAR := UDINT_TO_INT((DATE_TO_UDINT(idate) / UDINT#86400) MOD UDINT#1461);
    IF DAY_OF_YEAR > 729 THEN
    	IF DAY_OF_YEAR > 1095 THEN DAY_OF_YEAR := DAY_OF_YEAR - 1095; ELSE DAY_OF_YEAR := DAY_OF_YEAR - 729; END_IF;
    ELSIF DAY_OF_YEAR > 364 THEN
    	DAY_OF_YEAR := DAY_OF_YEAR - 364;
    ELSE
    	DAY_OF_YEAR := DAY_OF_YEAR + 1;
    END_IF;


    А дальше все просто, как три пальца...
    Захват-1.png
    Мой канал на ютубе
    https://www.youtube.com/c/ПетрАртюков
    Библиотека ГМ для СП300
    https://disk.yandex.com/d/gHLMhLi8x1_HBg

  9. #9

    По умолчанию

    Цитата Сообщение от petera Посмотреть сообщение
    Все довольна просто будет, если перейти к переменным DATE

    1.
    Делаем функцию, которая преобразовывает дату ПЛК(год,месяц,день) в DATE
    FUNCTION CurDATE:
    Код:
    FUNCTION CurDATE : DATE
    VAR
       CurTimeExInst: CurTimeEx;
        CurSystemTimeDate: SystemTimeDate;
        CurSysTime64: SysTime64;
        year: INT;
        second: INT;
        day: INT;
        hour: INT;
        minute: INT;
        month: INT;
        count: INT;
    END_VAR
    
    CurTimeExInst(TimeDate := CurSystemTimeDate, SystemTime := CurSysTime64);
        year :=CurSystemTimeDate.Year;
        month :=CurSystemTimeDate.Month;
        day :=CurSystemTimeDate.Day;
        hour :=CurSystemTimeDate.Hour;
        minute :=CurSystemTimeDate.Minute;
        second :=CurSystemTimeDate.Second;
    (*------------------------------------------------------------------------*)
    (*Вычислить дату с учетом високосных лет*)
    IF month > 2 THEN
        count := (month - 1) * 30;
        IF month > 7 THEN count := count + SHR(month - 3,1);
    ELSE count := count + SHR(month - 4,1); END_IF;
        (* проверить на високосный год и добавить один день если год високосный *)
        IF SHL(year,14) = 0 THEN count := count + 1; END_IF;
    ELSE
        count := (month - 1) * 31;
    END_IF;
    CurDATE:=DWORD_TO_DATE((INT_TO_DWORD(count + day - 1)
                   + SHR(INT_TO_DWORD(year) * 1461 - 2878169, 2)) * 86400);

    2.
    Берем из OSCAT, с некоторой модификацией функцию DAY_OF_MONTH
    FUNCTION DAY_OF_MONTH:
    Код:
    FUNCTION DAY_OF_MONTH : INT
    VAR_INPUT
    	IDATE : DATE;
    END_VAR
    VAR
    	leap: INT;
    	MTH_OFS: ARRAY [1..12] OF INT  := 0,31,59,90,120,151,181,212,243,273,304,334;
    	LEAP_OF_DATE: BOOL;
    END_VAR
    LEAP_OF_DATE := SHL(((DATE_TO_DWORD(idate) + 43200) / 31557600), 30) = 16#80000000;
    (* calculate the day in the year *)
    DAY_OF_MONTH := DAY_OF_YEAR(idate);
    (* leap will be set to one for a leap year *)
    leap := BOOL_TO_INT(LEAP_OF_DATE);
    (* if leap year deduct one from the days of the year *)
    DAY_OF_MONTH := DAY_OF_MONTH - leap;
    (* search if we are in month december to march ? *)
    IF DAY_OF_MONTH > MTH_OFS[9] THEN
    	IF DAY_OF_MONTH > MTH_OFS[11] THEN
    		IF DAY_OF_MONTH > mth_ofs[12] THEN
    			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[12];
    		ELSE
    			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[11];
    		END_IF;
    	ELSE
    		IF DAY_OF_MONTH > mth_ofs[10] THEN
    			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[10];
    		ELSE
    			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[9];
    		END_IF;
    	END_IF;
    ELSIF DAY_OF_MONTH > MTH_OFS[5] THEN
    	IF DAY_OF_MONTH > MTH_OFS[7] THEN
    		IF DAY_OF_MONTH > mth_ofs[8] THEN
    			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[8];
    		ELSE
    			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[7];
    		END_IF;
    	ELSE
    		IF DAY_OF_MONTH > mth_ofs[6] THEN
    			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[6];
    		ELSE
    			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[5];
    		END_IF;
    	END_IF;
    ELSIF DAY_OF_MONTH > MTH_OFS[3] THEN
    	IF DAY_OF_MONTH > MTH_OFS[4] THEN
    		DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[4];
    	ELSE
    		DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[3];
    	END_IF;
    ELSE
    	(* since now we must be in february or january we need to add leap again *)
    	DAY_OF_MONTH := DAY_OF_MONTH + leap;
    	IF DAY_OF_MONTH > MTH_OFS[2] THEN DAY_OF_MONTH := DAY_OF_MONTH - mth_ofs[2]; END_IF;
    	(* since nothing was true before, day_of_month must already be good *)
    END_IF;

    3. Для FUNCTION DAY_OF_MONTH нужна еще одна функция из OSCAT
    Скрытый текст:
    Код:
    FUNCTION DAY_OF_YEAR : INT
    VAR_INPUT
    	IDATE : DATE;
    END_VAR
    DAY_OF_YEAR := UDINT_TO_INT((DATE_TO_UDINT(idate) / UDINT#86400) MOD UDINT#1461);
    IF DAY_OF_YEAR > 729 THEN
    	IF DAY_OF_YEAR > 1095 THEN DAY_OF_YEAR := DAY_OF_YEAR - 1095; ELSE DAY_OF_YEAR := DAY_OF_YEAR - 729; END_IF;
    ELSIF DAY_OF_YEAR > 364 THEN
    	DAY_OF_YEAR := DAY_OF_YEAR - 364;
    ELSE
    	DAY_OF_YEAR := DAY_OF_YEAR + 1;
    END_IF;


    А дальше все просто, как три пальца...
    Захват-1.png
    Огромное человеческое спасибо.

Похожие темы

  1. Обнуление счетчика МВ110-16ДН
    от nestor в разделе ПЛК3хх
    Ответов: 11
    Последнее сообщение: 11.08.2018, 16:21
  2. Обнуление регистра MODBUS RTU
    от Алексей Александрович в разделе ПЛК1хх
    Ответов: 1
    Последнее сообщение: 22.10.2014, 16:18
  3. Обнуление введенных параметров
    от Viktor40 в разделе Master SCADA 3
    Ответов: 5
    Последнее сообщение: 01.12.2011, 08:19
  4. обнуление при отсутсвии питания
    от Artem в разделе ПЛК1хх
    Ответов: 1
    Последнее сообщение: 03.09.2010, 21:08

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •