Страница 1 из 3 123 ПоследняяПоследняя
Показано с 1 по 10 из 25

Тема: Проблема с кодом на ST. Цикл выполняется с ошибкой.

  1. #1

    По умолчанию Проблема с кодом на ST. Цикл выполняется с ошибкой.

    Коллеги, выручайте.
    Вот объявление переменных:
    PROGRAM PLC_PRG
    VAR
    Inic: BOOL;
    v2: INT;
    v3: INT;
    sw: BOOL;
    END_VAR
    VAR RETAIN
    v1: INT := 20;
    END_VAR
    Вот сама программа (проект прилагаю):
    IF NOT Inic THEN
    v2 := v1;
    v3 := v1;
    END_IF

    IF (v2 <> v1) AND sw THEN
    v1 := v2;
    v3 := v2;
    ELSIF (v3 <> v1) AND NOT sw THEN
    v1 := v3;
    v2 := v3;
    END_IF

    sw := NOT sw;
    Inic := TRUE;
    Конец программы

    Мне нужно, чтобы при запуске значение из памяти v1, присвоилось к v2 и v3.
    Далее v1 по замыслу работает как буфер и хранение последнего значения.
    Потом я меняю значение v2 или v3 и всё прекрасно синхронизируется (v1=v2=v3).
    Потом я пробую менять вторую переменную v3 или v2. Тут и начинается проблема. v1 присваивает поочерёдно разные значения v2 и v3.
    PS: sw добавил от отчаянья. Что с ним, что без - одно и тоже.
    Вложения Вложения
    • Тип файла: pro Test3.pro (10.5 Кб, Просмотров: 5)

  2. #2

    По умолчанию

    Вот этот кусок лучше переписать по другому:
    IF Inic = FALSE THEN
    v2 := v1;
    v3 := v1;
    Inic := TRUE;
    END_IF
    То есть сразу ставим флаг инициализации в коде инициализации, а не где-то там в конце программы.

    Дальше я бы переписал чуток по другому:
    а) Хранил бы предыдущие значения для v2 и v3, обновляя их в самом конце программы:
    v2Prev := v2;
    v3Prev := v3;

    б) Тебе же значения надо обновлять при изменении v2 или v3.
    Значит я бы так и писал отдельно для каждой ветки:
    IF (v2Prev <> v2) AND (можно вписать какие-то условия на валидность v2, если надо - мало ли, она не может ещё и меньше "-1" быть) THEN
    v1 := v2;
    END_IF

    и так далее. Я могу ошибаться и тупить. Если неверно понял - прошу прощения.
    Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живёте. © Steve McConnell
    Мой рабочий блог со статьями про щиты и автоматику ОВЕН - Cs-Cs.Net | Почта: Info@Cs-Cs.Net

  3. #3
    Пользователь Аватар для capzap
    Регистрация
    25.02.2011
    Адрес
    Киров
    Сообщений
    10,224

    По умолчанию

    Цитата Сообщение от hardkp Посмотреть сообщение
    Коллеги, выручайте.
    Мне нужно, чтобы при запуске значение из памяти v1, присвоилось к v2 и v3.
    Далее v1 по замыслу работает как буфер и хранение последнего значения.
    Потом я меняю значение v2 или v3 и всё прекрасно синхронизируется (v1=v2=v3).
    Потом я пробую менять вторую переменную v3 или v2. Тут и начинается проблема. v1 присваивает поочерёдно разные значения v2 и v3.
    не должно быть проблем
    Вложения Вложения
    • Тип файла: pro sets.pro (33.1 Кб, Просмотров: 14)
    Bad programmers worry about the code. Good programmers worry about data structures and their relationships

    среди успешных людей я не встречала нытиков
    Барбара Коркоран

  4. #4

    По умолчанию

    Спасибо за пример.
    Запустил проверяю. Когда работает DEMO значения записываются и всё пашет синхронно.
    Если я меняю значение v2 кликнув по ней и записав новое значение, то запись происходит и всё успешно синхронизируется.
    Затем я меняю значение v3 и тут проблема снова появляется, v1 присваивает новое значение v3, а потом прежнее значение v2 и так по кругу.
    Я уже думаю, что это просто способ отладки такой корявый.

    Объясню подробнее зачем мне это, может это вообще не так решается.
    Есть v1, она в RETAIN с начальным значением. Её я храню в контроллере и выгружаю в v2 и в v3 при запуске.
    v2 добавлена в порт rs232 и общается с панелью СП307.
    v3 добавлена в Ethernet и работает со СКАДОЙ.
    Нужно чтобы изменения на панели, загружались в СКАДУ и наоборот.

    В примере проекта я объявлял переменные локально в программе.
    На реальном проекте я v2 и v3 добавляю в конфигураторе добавляя Modbus slave под RS232 и ещё один Modbus slave Ethernet.
    Тип подэлемента 2 byte.

  5. #5
    Пользователь
    Регистрация
    31.01.2019
    Адрес
    РФ/РБ
    Сообщений
    917

    По умолчанию

    Я не понимаю, зачем тут v3.
    Она всегда будет равна v2, при изменении v1.

    Если вам нужен контроль однократного изменения v1, то это одно.
    Если нужен контроль двухкратного изменения v1, то это другое.

  6. #6
    Пользователь
    Регистрация
    31.01.2019
    Адрес
    РФ/РБ
    Сообщений
    917

    По умолчанию

    Цитата Сообщение от hardkp Посмотреть сообщение
    Объясню подробнее зачем мне это, может это вообще не так решается.
    Есть v1, она в RETAIN с начальным значением. Её я храню в контроллере и выгружаю в v2 и в v3 при запуске.
    v2 добавлена в порт rs232 и общается с панелью СП307.
    v3 добавлена в Ethernet и работает со СКАДОЙ.
    Нужно чтобы изменения на панели, загружались в СКАДУ и наоборот.
    У вас есть контроллер, который управляется панелью и скадой. Так?
    Если прав, тут надо разделить "задания" и "состояния".
    Например
    btnPalel: BOOL; // кнопка на панели
    btnSCADA: BOOL; // кнопка в скаде

    outRelay:= btnPanel OR btnSCADA;

    В панели записываете переменную btnPanel, читаете переменную outRelay.
    в SCADA записываете переменную btnSCADA, читаете переменную outRelay.

  7. #7

    По умолчанию

    Цитата Сообщение от keysansa Посмотреть сообщение
    Например
    btnPalel: BOOL; // кнопка на панели
    btnSCADA: BOOL; // кнопка в скаде

    outRelay:= btnPanel OR btnSCADA;

    В панели записываете переменную btnPanel, читаете переменную outRelay.
    в SCADA записываете переменную btnSCADA, читаете переменную outRelay.
    Так я смогу включать из панели или скады.
    А если эта как в моём примере уставка температуры, как быть?

    А даже если эта кнопка, мне нужно чтобы я включил переключатель на панели, а выключил в скаде, но подойдя к скаде я хочу видеть переключатель включенным и выключать именно этот переключатель. Т.е. выключив в скаде, выключиться переключатель должен и на панели.

  8. #8
    Пользователь
    Регистрация
    31.01.2019
    Адрес
    РФ/РБ
    Сообщений
    917

    По умолчанию

    Цитата Сообщение от hardkp Посмотреть сообщение
    Так я смогу включать из панели или скады.
    А если эта как в моём примере уставка температуры, как быть?
    Прошу прощения, не сразу вник в вашу проблему.

    В вашем случае, принято использовать технологию, разработанную около века назад.
    Используется бит, который в True означает, что значение можно изменять, в False - что изменение запрещено.
    1. По старту контроллера, через некоторое время взводится бит, для защиты значения v1 от изменений по загрузке.
    2. Далее, при v1<>v2, этот бит сбрасывается при операции v1=v2, на то же (или другое) время.
    4. При v1<>v3 - ждем, установленного бита. И снова его сбрасываем, при выполнении v1=v3. Восстанавливаем через временной промежуток.

    Это применяется, если PERSISTENT переменные хранятся в контроллере, а не в панели/SCADA.
    Хотя я лично, придерживаюсь логики хранения PERSISTENT в панели/SCADA, но согласен, это не всегда эффективно.
    Последний раз редактировалось keysansa; 09.04.2022 в 13:39.

  9. #9

    По умолчанию

    hardkp Хммм! Вот знаешь ЧТО?! Надо тогда задачу ставить понятнее! А не "там три переменных, надо хранить последнее значение и менять если другие меняются"
    Тогда ты вообще неверно делаешь прям в корне!

    У меня стояла задача такая:
    * Есть устройство, на котором есть местное управление (термостат) кнопками (вкл-выкл, уставка температуры)
    * Есть сенсорный ПЛК (читай - панель оператора), на котором тоже нужно этим же устройством управлять и отображаеть с него данные
    * Связь сделана по Modbus

    То есть, как должно работать:
    а) Включили термостат или поменяли уставку - на СПК поменялись значения
    б) С СПК поменяли уставку или включили-выключили - это ушло в термостат

    Я делал так же, как и ты: сравнивал значения. Получалась лажа и фигня: что-то работало первым, а что-то не работало вообще.
    Задача была решена через автомат состояний (State Machine) с тремя состояниями:
    * Equal - оба значения равны
    * ChangeUI - изменено с СПК
    * ChangeHW - изменено с устройства

    В каждом из ChangeXX программа находится (и не регагирует на другие изменения) пока не кончится таймаут (на случай отвала связи) или пока не выполнится операция записи новых данных в устройство и чтения их оттуда так, чтобы они совпали.

    Если описать простыми словами, то получался такой алгоритм:
    * Поменяли температуру с СПК? =>
    * Заходим в ChangeUI =>
    * Отправляем новые данные по Modbus в устройство и запускаем таймер выдержки таймаута =>
    * Ждём, пока запись закончится =>
    * Читаем данные из устройства =>
    * Сравниваем =>
    * Если равны ИЛИ если насчитали таймаут =>
    * Выходим из состояния ChangeUI

    Вот тогда у меня всё работало без сбоев и не было такого конфликта, когда одновременно кто-то начал менять на UI и на устройстве - и шла бесконечная перезапись значений из-за того, что они якобы поменялись.
    Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живёте. © Steve McConnell
    Мой рабочий блог со статьями про щиты и автоматику ОВЕН - Cs-Cs.Net | Почта: Info@Cs-Cs.Net

  10. #10

    По умолчанию

    Скажу как есть. Я программист не опытный. ST только начал использовать. Я по логике сделал всё задуманное, но работает оно не так как надо.
    Пользователь capzap написал пример, который более оптимально написан, но делает тоже самое. capzap дописал DEMO, в которой часть кода имитирует те перезаписи v2 и v3, которые предполагается делать.
    Когда v2 и v3 перезаписываются программно всё работает, перезапись происходит, всё синхронизируется.
    Когда я запускаю отладку. В поле справа наблюдаю значения переменных.
    Я кликаю на переменную, ввожу значение, потом F7, чтобы переменная его приняла. Запись происходит, всё синхронизируется, но переменная приобретает красный цвет.
    Пробую записать вторую переменную, она тоже краснеет, а потом та самая проблема из-за котрой я начал эту тему.

    Люди опытные подскажите, это в отладке проблема или в коде?
    В железе выполняться будет нормально или как в отладке?

Страница 1 из 3 123 ПоследняяПоследняя

Похожие темы

  1. Ответов: 0
    Последнее сообщение: 21.01.2021, 22:08
  2. Панель СП310 - загрузка проекта с исходным кодом
    от _Алексей_ в разделе Панели оператора (HMI)
    Ответов: 1
    Последнее сообщение: 23.08.2018, 07:19
  3. Экспорт проекта с ошибкой
    от Poo в разделе Master SCADA 3
    Ответов: 9
    Последнее сообщение: 27.07.2018, 15:44
  4. Не выполняется PLC_PRG
    от S#716_0P в разделе ПЛК1хх
    Ответов: 7
    Последнее сообщение: 08.09.2017, 13:35
  5. Не выполняется установка Codesys V3
    от Дмитрий Артюховский в разделе СПК2хх
    Ответов: 11
    Последнее сообщение: 26.06.2013, 01:27

Метки этой темы

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •