Цитата Сообщение от Вольд Посмотреть сообщение
Зачем было нужно делать общий минус для дискретных входов ?
Дело в том, что станок был разработан немцами более 20 лет назад, весь монтаж датчиков, релюшек и т.д. был продуман еще в то время, вся логика продумана на общем минусе, я тогда в школе еще учился, посему мне пришлось приспосабливаться к уже имеющемуся шкафу автоматики.

Цитата Сообщение от Владимир Ситников Посмотреть сообщение
Вообще говоря, должно хватать такого (и разнообразные программные сбросы по 50000 я бы выключал. Зачем они?):
Код:
prevEncoderValue : WORD; (* например, в глобальных *)
encoderValue : WORD; (* это в plc configuration *)

value : DINT; (* тут будет абсолютное положение энкодера *)

value := value + WORD_TO_INT(encoderValue-prevEncoderValue);
prevEncoderValue := encoderValue;
Т.е. все эти "abs", ">40000" и т.п. это всё не нужно.
Для вычисления абсолютного положения энкодера достаточно двух строк.
Сбросы по 50000 делал - мог и максимум взять, 65000, просто 50000 для удобства, для себя, а нужно для того, чтобы не потерять данных с счетчика энкодера. В ходе работ выяснилось, что даже при медленных режимах движения шпинделя за время одного цикла управляющей программы счетчик энкодера меняется на 15 и более значений. Движение шпинделя может быть от приводов, и так же от ручной подачи, т.е. оператор станка крутит штурвалы рукой и теперь нет понятия в программе, куда будет вращаться энкодер, в отличии от программного управления серводвигателями, где я явно знаю направление движения, относительно к которому привязал бы логику - или плюсовать или минусовать. Получается, если мы находимся на границе программного обнуления счетчика при 65000 (если максимальное, у меня 50000) и в это время оператор крутанул штурвал, при следующем цикле счет будет (примерно) или 25 - если вперед, или 64980 - обратка. Разница предыдущего значения счетчика и действующего будет или ABS(65000-25) = 64975 или ABS(65000-64980) = 20. Если просто это значение прибавлять или отнимать от счетчика, то будет неправильно. Потому для себя заморочился, что если разница более 40000, то нужно с полученного значения отнимать максимальное значение счетчика. И у меня общий счетчик DINT, для того чтобы соблюдался нуль и держались при необходимости и минусовые значения. 7985 им/мм * 9000 мм(максимальный ход по оси) = +-71865000, в пределы DINT входим.
Тяжеловато объяснил...
В краце, для себя такой алгоритм разработал, он работает и не привязывается к командам управления серводвигателей, а просто следит за данными с энкодеров.

value := value + WORD_TO_INT(encoderValue-prevEncoderValue); - не совсем ясно как работает выделенное.
prevEncoderValue := encoderValue;

Вижу что разницу прибавляем к общему счетчику, а если была ситуация, что обнуление энкодера при достижении 65000 произошло именно в тот момент, когда оператор в ручную ловит микроны, и в этот момент он раз 10 штурвалом крутил почуточку в разные стороны, и получаем значения то 64980, то 20, и и это все отнимается и складывается... и счет ушел