Необходимо программно считывать показания аппаратных часов реального времени.SysLibRTC не работает.При использовании SysLibTime
корректное время появляется один раз, после чего часы "стоят"(меняются только микросекунды).Как быть?
Serhy
Вид для печати
Необходимо программно считывать показания аппаратных часов реального времени.SysLibRTC не работает.При использовании SysLibTime
корректное время появляется один раз, после чего часы "стоят"(меняются только микросекунды).Как быть?
Serhy
Обратите внимание что переменная SystemTime имеет тип VAR_IN_OUT и обращаться к ней нужно через указатели.
"...Обратите внимание, что переменные вход-выход (VAR_IN_OUT) передаются в экземпляр функцио-
нального блока через указатели. Поэтому таким переменным нельзя присваивать константы при вызове...".
Должно все работать.
Для корректной работы SysLibTime, если вы хотите считать данные, то надо обнулить структуру, передаваемую ФБ, иначе будет происходить запись! Это описано в документации.
пример простейший можно? что-то в доке написано как-то..... да и пример из доки у меня не заработал.
Пожалуйста:
FUNCTION_BLOCK DateAndTimeStr
...
VAR_OUTPUT
DateStr: STRING;
...
END_VAR
VAR
CTimeEX: CurTimeEx;
SystemTime: SysTime64;
TimeDate: SystemTimeDate;
StrTemp1: STRING;
StrTemp0: STRING;
END_VAR
(* получение системного времени *)
LD 0
ST TimeDate.Milliseconds
ST TimeDate.Second
ST TimeDate.Minute
ST TimeDate.Hour
ST TimeDate.Day
ST TimeDate.DayOfWeek
ST TimeDate.Month
ST TimeDate.Year
ST SystemTime.ulLow
ST SystemTime.ulHigh
CAL CTimeEX(SystemTime:=SystemTime, TimeDate:=TimeDate)
(* подготовка строки "дата" в формате DD Month YYYY (16) *)
LD TimeDate.Year
INT_TO_STRING
ST StrTemp1
LD DateFormat
(* вывод названия месяца *)
LD TimeDate.Month
SUB 1
MUX ' января ', ' февр. ', ' марта ', ' апреля ', ' мая ', ' июня ', ' июля ', ' авг. ', ' сент. ', ' окт. ', ' ноября ', ' дек. '
CONCAT StrTemp1
ST StrTemp1
LD TimeDate.Day
INT_TO_STRING
INSERT '0', 0
RIGHT 2
CONCAT StrTemp1
ST DateStr
ну и т.д. для времени.
Удачи.
В примере выше время конвертируется в строку.
А как перевести полученные INT-овые дату и время в формат DATE_AND_TIME (в секундах)?
Время-то таким образом переводить можно. А вот как перевести дату? Нет чёткого алгоритма, на сколько умножать, например, месяцы. Потому что в месяце может быть разное количество дней.
Или, может быть, кто-то подскажет другой способ получения текущих даты/времени в секундах от 01/01/1970.
яндекс поможет, существуюет стандартный алгоритм
Вопрос. процедура CurTimeEx в режиме эмуляции не работает?
нет. только на живом плк
это как бы... засада. могу ли я надеяться, что если выложу код, знающие люди просмотрят его правильность? а то все отдали заказчику, а нужно переделать...
и еще, есть ли способ в режиме эмуляции получить время из ос?
спасибо. завтра еще вопросы созреют ))
А вот у меня уже созрел вопросец:
Функциональный блок CurTime как и CurTimeEX выдаёт переменную SystemTime типа SysTime64, которая содержит в двух двойных словах системное время в микросекундах(при этом нижний регистр ulLow вмещает в себя около 80минут). Работа с 64 разрядными данными в КоДеСисе ,видимо, не предусмотрено (есть какой то LWORD, но никакие операции преобразования с ним не работают), поэтому чтобы перевести SystemTime скажем в минуты мне приходится делать так:
Отсюда вопрос: может существует более изящный метод работы с этими данными?Код:VAR
fb_time:CurTime;
t_time:SysTime64;
dw_time:DWORD;
rrr:REAL;
END_VAR
fb_time(SystemTime:=t_time);
rrr:=16#100000000;
dw_time:=t_time.ulHigh*REAL_TO_DWORD(rrr/60000000) + t_time.ulLow/60000000;(*конвертируем в минуты*)
есть еще время в мс.
и вообще, какова задача? нузны ли там наносекунды?
Да нет, не нужны, просто интересно - если функция есть - значит её нужно както использовать)))
Кстати ещё вопрос: есть ли разница по скорости работы функции RTC из стандартной библиотеки и функциями из библиотеки SysLibTime?
в настоящее время функция Rtc исключена из стандарта мэк, так как есть определенные проблемы в ходе выполнения функции(к примеру остановка при отключении питания плк). аппаратными часами пользоваться гораздо надежнее. аппаратные часы идут не зависимо от от цикла плк.
вы только обращаетесь к определенному регистру и считываете его значение и затем делаете в программе необходимые вам преобразования.
подробно данный вопрос описан в книге и. в. петрова "программируемые контроллеры"
спасибо за совет, интересная книжица...
наконец то я хоть гдето увидел хорошее методическое пособие по Sfc языку...
Вообще суть в том чтобы не парится при расчётах времени(перевод дат со временем - во время),
а иметь конкретное время, скажем в минутах, от начала работы ПЛК, благо в два двойных слова (64 bit) в миллисекундах влезает более пятисот тысяч лет, что вполне достаточно для любых задач)))
В библиотеке SysLibTime.lib можно получить время в мили и микросекундах с момента запуска ПЛК
Да ладно, в документации говорится что в CurTimeEx.Milliseconds находятся миллисекунды текущей секунды, но никак не миллисекунды от начала работы...
Мне такая точность не нужна. Поэтому я и привёл способ перевода времени от начала работы (SysTime64) из микросекунд в минуты... Спрашивал есть ли более удачные решения И удивлялся - почему в кодесисе не работают 64х битные переменные....
А вы мне второй раз про миллисекунды рассказываете, да мне хоть наносекунды, разберитесь в сути вопроса прежде чем отвечать!!!
Мне нужно непрерывное значение времени в минутах, будь оно от начала работы или от рождества христого - не принципиально...
если вам надо время с включения - используйте миллисекунды/микросекунды, если время в минутах с какой-то даты - только часы реального времени. это радикально разные понятия.
а 64 битные переменные не работают. наверное процессор 32-битный?
но что мешает вам обработать 64битное число как 2 32 битных? переполнилось младшее - +1 к старшему.
дело в том что с двумя 32х битными данными трудновато работать, рутинные операции (логические, арехметические) требуют отдельных процедур...
к сожалению кодесис не поддерживает перегрузку операторов как в с++, а методы фб не могут принимать аргументов(зачем их вообще реализовали?), поэтому я в моей процедуре и перевожу 64 бита в 32 с округлением времени до минут(8171 год влезает)))...
Какие трудные операции? Функцию ADD64, принимающую 3 аргумента Pointer to 64bita, 32 бита операнд , 32 бита операнд трудно сделать? И остальные?