PDA

Просмотр полной версии : Modubs через Ethernet; Входы МДВВ



Flomaster
11.11.2007, 18:26
Приветствую всех!
Снова появилась пара вопросов. На этот раз они касаются связи 2-х и более контроллеров по сети Ethernet, а также чтения дискретных входов на модуле МДВВ.
1. Есть 2 контроллера ПЛК-150. Контроллеры соединены через свитч. Контроллер №1 имеет адрес 10.0.0.10, контроллер №2 - адрес 10.0.6.12. Также с свитчу подключается ноутбук с CoDeSys.
К контроллеру №1 по интерфейсу RS-485 с использованием протокола Modbus подключены несколько устройств, работой которых он, собственно, и управляет.
Контроллер №2 должен считывать некоторые данные с контроллера №1 (для выполнения последующих операций), а также передавать некоторые значения контроллеру №1. Наиболее удачный вариант для этого, по моему мнению - это использование сетевых переменных. Т.е. часть переменных изменяет первый контроллер, а читае их второй. Другую часть изменяет второй контроллер, а читает первый.
Данные решили передавать по протоколу Modbus. Вроде бы всё верно настраивал, по документации. Список сетевых переменных одинаковый. Но ситуация получается такая.Если в онлайне смотреть переменные первого контроллера, пронициализированы должным образом только его переменные. У второго контроллера ситуация аналогичная. А по идее в списке любого контроллера должно быть, так сказать, объединение проинициализированных переменных обоих контроллеров.
Может быть нет связи между контроллерами? как ее проверить?
Контроллер №2 является Modbus Master, режим работы - TCP. У него создан Universal Modbus device, у которого указан IP-адрес контроллера №1. У контроллера №1 создан Modbus Slave c режимом работы по TCP.

2. К контроллера подключен модуль МДВВ по RS-485 Modbus. В конфигураторе ПЛК добавлен модуль OWEN_MDVV. Связь устанавливается. Возник вопрос по считыванию значений на входах модуля. Понятно, что он хранится в регистре Bit Mask for input.Если текущее значение этого регистра перевести в двоичку, то получим статус входов (с 12 до 1). А есть ли какой-нибудь реализованный смеханизм, чтобы без лишних вычислений узнать, скажем, состояние входа №4?

Flomaster
12.11.2007, 11:09
Ворос 2, думаю, можно снять. В библиотеке Util.lib нашел нужную мне функцию.

Филоненко Владислав
12.11.2007, 11:36
1. Проекты обоих контроллеров в студию
2. Самый простой способ - наложить маску и сравнить с нулем.

Flomaster
12.11.2007, 13:50
Вот пример проектов.
224

Филоненко Владислав
12.11.2007, 15:18
гм... Как бы сказать-то.
1. Или Вы используете сетевые переменные или ModBus TCP.
2. Если ModBus TCP - то вставьте хотя-бы по одной переменной в мастер и slave.
3. Если же сетевые переменные - то на контроллере №1 надо создать список переменных, к-е будут передаваться, а на №2 - читаться те же.
Прилагаю пример.

Flomaster
12.11.2007, 16:34
Блин, а я почему-то вбил себе в голову, что для работы с сетевыми переменными у контроллеров должна быть настроена связь по одному из протоколов...
Завтра попробую использовать просто список переменных.

Flomaster
12.11.2007, 17:53
У меня еще пара вопросов.
1. Можно ли каким-либо образом в программе, написанной на языке ST, задать бесконечный цикл типа
WHILE (TRUE) DO
(*здесь ведется опрос входов и выполняются какие-либо действия*)
END_WHILE.
При попытку запустить такую программу на контроллере, вылетает ошибка о бесконечном цикле.

2. Есть функциональный блок, который хочу использовать в различных участках своей программы. Блок написан на SFC. Основная программа тоже. Как вызвать блок - в общем-то понятно. Но куда должен указывть переход в конце выполнения ФБ?

Nekit
12.11.2007, 18:15
По вопросу 1: такие поползновения обычно бывают у людей переходящих с С на ST. В ПЛК такой цикл невозможен да и не нужен. Программа сама по себе работает по схеме: опрос входов-"какие-либо действия"-запись выходов, т.е. цикл реализован как бы поумолчанию.

Филоненко Владислав
12.11.2007, 18:27
У меня еще пара вопросов.
1. Можно ли каким-либо образом в программе, написанной на языке ST, задать бесконечный цикл типа
WHILE (TRUE) DO
(*здесь ведется опрос входов и выполняются какие-либо действия*)
END_WHILE.
При попытку запустить такую программу на контроллере, вылетает ошибка о бесконечном цикле.

2. Есть функциональный блок, который хочу использовать в различных участках своей программы. Блок написан на SFC. Основная программа тоже. Как вызвать блок - в общем-то понятно. Но куда должен указывть переход в конце выполнения ФБ?


1. бесконечный цикл уже реализован, все инструкции в PLC_PRG выполняются с начала в конец. Доп. бесконечные циклы нельзя создавать, сработает Watchdog.
2. Просто return, контроллер сам разберется откуда вызвали экземпляр ФБ и передаст управление на сл. строку после вызова.

Flomaster
13.11.2007, 04:04
Если в ФБ, написанном на SFC, конечный переход указываю как RETURN, компилятор выдает ошибку 4356 "Jump without valid Step Name: 'RETURN' ". Как быть?

Игорь Петров
13.11.2007, 13:01
:eek: ФБ на SFC никогда не заканчивается в принципе. Если он прошагал по всем шагам, то должен вернуться на начальный шаг. В конце должен быть переход на начальный шаг. Он ставится по умолчанию при создании нового ФБ.

Когда вызывается ФБ на SFC, то это совершенно не означает что он пройдет по всем шагам и отдаст управление. Он выполнит только шаги, которые имеют маркер активности и сразу отдаст управление вызывающему POU. При этом он проверит условия переходов. Если некий переход разрешен, то маркер(ы) активности перейдет на соотв-й шаг, который будет работать при след вызове. Положение маркеров запоминается между вызовами.

Т.е. SFC это машина состояний. Работает по тактам = вызовам. Она постоянно стоит в некотором состоянии и переходит из одного состояния в другое по условиям переходов. Но выполнение никогда не заканчивается, как собственно и вся программа ПЛК. Это же не вычислительный алгоритм: высчитал результат – закончил, выключился из розетки :)

Flomaster
13.11.2007, 17:38
:eek: ФБ на SFC никогда не заканчивается в принципе. Если он прошагал по всем шагам, то должен вернуться на начальный шаг. В конце должен быть переход на начальный шаг. Он ставится по умолчанию при создании нового ФБ.

Когда вызывается ФБ на SFC, то это совершенно не означает что он пройдет по всем шагам и отдаст управление. Он выполнит только шаги, которые имеют маркер активности и сразу отдаст управление вызывающему POU. При этом он проверит условия переходов. Если некий переход разрешен, то маркер(ы) активности перейдет на соотв-й шаг, который будет работать при след вызове. Положение маркеров запоминается между вызовами.

Т.е. SFC это машина состояний. Работает по тактам = вызовам. Она постоянно стоит в некотором состоянии и переходит из одного состояния в другое по условиям переходов. Но выполнение никогда не заканчивается, как собственно и вся программа ПЛК. Это же не вычислительный алгоритм: высчитал результат – закончил, выключился из розетки :)

То, что начальный шаг ставится по умолчанию - это понятно. По поводу RETURN уже залез в документацию и понял, что c SFC такой фокус не прокатит.

Вернусь к вопросу о сетевых переменных. Сегодня попробовал сделать так, как в выложенном мне примере. Вначале ничего не получалось - переменные показывали только свое состояние применительно к каждому контроллеру. Потом неожиданно контроллер №2 увидел значения переменных, которые задал контроллер №1, т.е. собственно этого я и хотел добиться. Но потом пришлось поправить программку одного из контроллеров, и после этого переменные снова не хотят корректно отображаться. Может быть есть какая-то последовательность запуска контроллеров?

И еще заметил пару особенностей, которые появились после добавления в проект сетевых переменных:
1. При попытке записать пограмму в контроллер нередко передача данных "подвисает", после чего теряется связь с контроллером и он перегружается. Лечится нажатием кнопки "Сброс" и последующим удержанием кнопки "Работа". Об этой проблеме читал на этом форуме, и хотелось бы узнать, как скоро она решится.
2. Почему-то не получается в работающей на контрллере программы задать точку останова для отладки. Если щалкаю мышкой на строке кода, контроллер уходит в перезагрузку.

Филоненко Владислав
13.11.2007, 18:00
Эти 2 баги были нами обнаружены недавно и поправлены в новой версии прошивки. Связаны они с сетевыми переменными. Сами сетевые переменные полностью работоспособны, но при отладке, остановке и online change программы с сетевыми переменными возможна перезагрузка.
Для исправления перепрошейтесь прошивкой 2.02.6 или старше.

А вы правильно выставили маски подсети для контроллеров (сеть класса A всё-таки). Маска должна быть 255.255.0.0 или 255.0.0.0. Или переместите оба контроллера в одну подсеть класса С, тогда маска будет 255.255.255.0

Flomaster
13.11.2007, 18:22
Эти 2 баги были нами обнаружены недавно и поправлены в новой версии прошивки. Связаны они с сетевыми переменными. Сами сетевые переменные полностью работоспособны, но при отладке, остановке и online change программы с сетевыми переменными возможна перезагрузка.
Для исправления перепрошейтесь прошивкой 2.02.6 или старше.

А вы правильно выставили маски подсети для контроллеров (сеть класса A всё-таки). Маска должна быть 255.255.0.0 или 255.0.0.0. Или переместите оба контроллера в одну подсеть класса С, тогда маска будет 255.255.255.0

Прошивку поменяю, спасибо за совет:)
А по поводу маски подсети - имеется ввиду маска подсети именно самого контроллера, которая изменяется командой SetMask в PLC-Browser? Если да, то сейчас подсеть 255.255.255.0.

Филоненко Владислав
14.11.2007, 09:21
именно контролеров. Они у вас в разных подсетях класса С, а маска блокирует нормальный обмен. Поставьте 255.255.0.0.

Flomaster
26.11.2007, 08:52
С сетевыми переменными вопрос решился путем указания подсети 255.255.0.0. Теперь всё работает.
Однако снова возник вопрос, касающийся МДВВ. На этот раз - выходов. Не удается задать значение на выходе МДВВ. Если мне нужно, скажем, замкнуть выход №1, я записываю в соответствующий регистр значение 1. При этом, значение записывается, но лампочка на выходе не загорается - т.е. выход разомкнут. Попробовал поработать с выходами командой PUTBIT - ничего не получилось. При чтении значений входов команда EXTRACT работает отлично.
Как победить?

Василий Куц
26.11.2007, 09:15
я делал следующим образом:
MASK_OUT.0:=TRUE; (*замкнуть первый выход*)
MASK_OUT.1:=False; (*разомкнуть второй*)
....
и тд
MASK_OUT - это WORD битовая маска выхода

Flomaster
26.11.2007, 09:17
Спасибо, попробую!

Flomaster
26.11.2007, 10:20
И еще вопрос. Мне нужно в нескольких участках кода использовать временную задержку порядка 1-2 секунды.
В документации есть пример программы "Светофор" , в которой реализован ФБ WAIT. Как им пользоваться в программе SFC - ясно. Если WAIT.OK=true, то возможен переход к след. блоку. А как такой ФБ использовать в программе, написанной на ST? Или может быть в CoDeSys есть реализованный таймер для осуществления задержки?

Василий Куц
26.11.2007, 11:48
TON, TOF, TP в standart.lib

Flomaster
26.11.2007, 17:13
TON, TOF, TP в standart.lib

Да, видел такие ФБ. Но что-то не понял, как ими пользоваться:confused:
Вот, например, в теле программы мне нужно подать значение TRUE на дискретный выход 1, а через 2 секунды прочитать значение на дискретном входе 1. Как это реализовать с помощью указанных ФБ?

Малышев Олег
26.11.2007, 19:50
Это просто.
.....
ex1:=set_ex1;
.......
myTON(in:=ex1,pt:=t#2s);
if myTon.q and in1 then

end_if
А вообще приезжайте на курсы.

Flomaster
27.11.2007, 02:10
Это просто.
.....
ex1:=set_ex1;
.......
myTON(in:=ex1,pt:=t#2s);
if myTon.q and in1 then

end_if
А вообще приезжайте на курсы.

Я бы с удовольствием, но далековато. Не оплатит никто поездку. А за свои ехать недешево получается.:)

По поводу приведенного примера. До этого пытался сделать аналогично, думал, что мыслю немного не правильно. Оказалось, что мыслил в верном направлении. Беда в том, что получаю не совсем то, что мне нужно. Если в небольшой программке я подал на вход блока TON значение TRUE, то программа не заходит в кусок кода

if myTon.q and in1 then

end_if

, пока не выполнит несколько циклов. Это вполне естественно. А мне интересно, чтобы выполнение программы приостановилось на эти 2 сек., т.е. на строку if myTon.q and in1 then программа перешла только по истечении 2 с, как это происходит в программе "Светофор" у блока WAIT. Может быть в этом случае мне лучше использовать пустой цикл?

Дело всё в том, что при подаче сигнала на выход, должны замкнуться эл.цепи исполнительных механизмов. А подача сигнала на соответствующий вход говорит об успешном замыкании цепей. И поэтому мне нужно выждать 1-2 секунды, не переходя к следующей строчке кода.

RV9WFJ
27.11.2007, 06:38
По поводу приведенного примера. До этого пытался сделать аналогично, думал, что мыслю немного не правильно. Оказалось, что мыслил в верном направлении. Беда в том, что получаю не совсем то, что мне нужно. Если в небольшой программке я подал на вход блока TON значение TRUE, то программа не заходит в кусок кода

if myTon.q and in1 then

end_if

, пока не выполнит несколько циклов. Это вполне естественно. А мне интересно, чтобы выполнение программы приостановилось на эти 2 сек., т.е. на строку if myTon.q and in1 then программа перешла только по истечении 2 с, как это происходит в программе "Светофор" у блока WAIT. Может быть в этом случае мне лучше использовать пустой цикл?

Дело всё в том, что при подаче сигнала на выход, должны замкнуться эл.цепи исполнительных механизмов. А подача сигнала на соответствующий вход говорит об успешном замыкании цепей. И поэтому мне нужно выждать 1-2 секунды, не переходя к следующей строчке кода.А может правильнее будет подпрограммку на SFC реализовать и следующие строчки кода поместить в шаг, условием к выполнению которого будет таймер (см. пример "Светофор") ;)