если переменная глобальная, она видня в любом коде проекта без объявления
если переменная глобальная, она видня в любом коде проекта без объявления
Bad programmers worry about the code. Good programmers worry about data structures and their relationships
среди успешных людей я не встречала нытиков
Барбара Коркоран
Это понятно. Какие мои действия для сохранения насчитанных данных счетчиков, у меня их 3. Насчитанные данные пишутся в регистры ПЛК (Slave) панель (Master) читает данные из этих регистров. При выключении питания ПЛК регистры сохранят свои значения так как область памяти (Slave) по умолчанию находится в энергонезависимой области, и тут же будут перезаписаны на те что выдает ФБ, если его поместить в область retain данные сохраняться? Объявить ФБ в области памяти retain, или же после включения ПЛК по первому фронту пишем в ФБ значения с регистров Slave, и считаем дальше. Как лучше поступить?
объявите переменные, которые надо, чтобы сохраняли свои значения после пропадания питания как retain, зачем весь фб объявлять как retain.
Вот как сделано у меня, управление насосами с подсчётом наработки. Также сохраняется время переключения насосов, которое задаётся с панели.
Вот мой вариант блока
1. Правда такой блок имеет ограничение и может считать только до 49 дней включая добавочные часы и дни.Код:FUNCTION_BLOCK ENGINE_HOURS VAR_INPUT START: BOOL; (*АКТИВАЦИЯ СЧЕТА МОТОЧАСОВ*) I_TH : DWORD; (*ВВОД НОВОГО ЗНАЧЕНИЯ НАРАБОТКИ В ЧАСАХ В РУЧНУЮ*) I_TD : DWORD; (*ВВОД НОВОГО ЗНАЧЕНИЯ НАРАБОТКИ В СУТКАХ В РУЧНУЮ*) ENTER: BOOL; (*АКТИВАЦИЯ ВВЕДЕННЫХ В РУЧНУЮ ЗНАЧЕНИЙ*) RESET: BOOL; (*СБРОС СЧЕТЧИКОВ ПРИНУДИТЕЛЬНО*) END_VAR VAR_OUTPUT O_TM : WORD; (*ВРЕМЯ НАРАБОТКИ В МИНУТАХ*) O_TH : WORD; (*ВРЕМЯ НАРАБОТКИ В ЧАСАХ*) O_TD : WORD; (*ВРЕМЯ НАРАБОТКИ В СУТКАХ*) END_VAR VAR tStart: TIME; (* Точка времени начала счета *) tWorking: TIME; (* Общее время работы счетчика *) tMemmory: TIME; (* Общее время наработки после отключения *) dwCalc: DWORD; (* Для расчета минут и часов *) xStartMemmory: BOOL; xResetMemmory: BOOL; END_VAR (* Если появился сигнал на входе сброса, сбрасываем счетчик *) IF RESET AND NOT xResetMemmory THEN tStart := T#0s; tMemmory := T#0s; END_IF; xResetMemmory := RESET; (* Определяем передний фронт сигнала начала измерения. и сохраняем точку времени *) IF START AND NOT xStartMemmory THEN tStart := TIME(); END_IF; (* Определяем задний фронт START, и если отключился сохраняем наработанное время в переменную *) IF NOT START AND xStartMemmory THEN tMemmory := tMemmory + (TIME() - tStart); END_IF; xStartMemmory := START; tWorking := (TIME() - tStart) + tMemmory; IF ENTER THEN tWorking := tWorking + DWORD_TO_TIME((I_TH * 3600000) + (I_TD * 86400000)); END_IF; dwCalc := TIME_TO_DWORD(tWorking) / (1000 * 60); (* dwCalc хранит общее количество минут *) O_TM := dwCalc MOD 60; (* Остаток минут *) dwCalc := dwCalc / 60; (* dwCalc хранит общее количество часов *) O_TH := dwCalc MOD 24; (* Остаток часов *) O_TD := dwCalc / 24; (* Общее количество суток *) END_FUNCTION_BLOCK
2. Блок должен определяться в энергонезависимой памяти.
3. Расчет часов и дней происходит не общий а остаток. Например 10 дней 12 часов. То есть часов ни когда не будет больше чем 23. Тоже самое касается минут.
Эдуард_Н на работе сейчас не установлен CodeSys, сделайте скрин блока, тогда может по памяти скажу.
На вскидку, есть разрешение работы, есть вход импульса, есть вход сброса, сброс отдельных счетчиков происходит по битовой маске, 15 сбросит все, 1 сбросит только первый). Есть выход чтобы делать стекирование со следующим счетчиком.
Начинал делать для подсчета наработки, но в процессе он вылился в универсальный счетчик чего угодно, хоть бутылки - ящики - контейнеры считайте.
Делался из-за того, что встроенные счетчики 16-ти битные
Вот скринВложение 40026
CU - импульс счета
Enable - разрешение работы
PV1-PV4 - уставки для каждого счетного механизма (если не ошибаюсь, дома проверю)
PVr - битовая маска сброса. 0-й бит выход 1, 1-й бит выход 2, 2-й бит выход 3, 3-й бит выход 4
reset - подаем импульс сброса, если в битовой маске 1, то выход сбросится в 0
CV1-CV4 собственно и есть выходы с сохранением, на них подаются энергонезависимые переменные, при перезапуске ПЛК старт идет с данных значений.
stek - подается на CU следующего блока если надо расширить счет
Кажется так...
При использовании для времени PV1 = 60 (секунды), PV2 = 60 (минуты), PV3 = 24 (часы), PV4 = например 4 лярда дней
Соответственно импульсы должны приходить раз в секунду.
Последний раз редактировалось melky; 23.11.2018 в 14:04.