tonyk, спасибо за проект, вчера сделали большое количество тестов с этим проектом и OPC-сервером. Кнопка без фиксации при работе с битами при нажатии берёт текущее значение переменной, например 000000, меняет в нём соответствующий бит (допустим второй) на 1 и отправляет OPC-серверу на присвоение 010000. При отпускании кнопки происходит обратный процесс. Скада учитывает то, что OPC-сервер может не сразу выполнить присвоение, а пользователь при этом может продолжить нажимать на другие кнопки, которые работают с другими битами той же переменной. На этот случай скада некоторое время хранит последнее значение в оперативной памяти и все присвоения получаются корректными, даже если OPC-сервер выполняет их не сразу. Разумеется, скада не может вечно работать со значением из оперативной памяти и есть лимит времени после которого это значение сбросится на то, что предлагает OPC-сервер, иначе могла бы произойти рассинхронизация значений в скаде и на OPC-сервере. Но данный OPC-сервер по каким-то причинам выполняет присвоения чрезмерно долго, в наших вчерашних тестах бывало, что присвоение проходило более чем через 5 секунд (
смена значения в контроллере может выполниться быстрее, но скада получает результат только через 5 сек.) после отправки значения со скады. Соответственно, если нажать кнопку несколько раз, или нажать несколько кнопок, то последнее присвоение выполнится через 20 секунд и более. Возможно OPC-сервер выполняет присвоения с такой задержкой из-за отсутствия связи с конечным устройством, или из-за того что он слишком старый и работает по OPC DA 2, или ещё по каким-то причинам. И здесь, конечно, никакие лимиты по времени и работа со значением из оперативной памяти не спасают, т.к. это слишком долгий интервал присвоения, если учесть, что частота опроса тега равна одной секунде. Поэтому правильным решением было бы сменить OPC-сервер на более современный, например
arOPC, Insat Modbus OPC, или даже Lectus. Второй вариант: использовать тот же OPC-сервер, но все кнопки заменить на кнопки с фиксацией с одним состоянием (со значением = 1), а сброс на 0 выполнять на контроллере. Третий вариант: объявить отдельные битовые переменные и каждой кнопке назначить свою переменную.