Показано с 1 по 9 из 9

Тема: Управление устройствами через битовую маску

  1. #1

    По умолчанию Управление устройствами через битовую маску

    Всех приветствую.

    Проблема с управлением устройств через битовую маску. Что-то делаю не так и не пойму что.

    Есть два параметра - входной и выходной параметры SYSTEM_WORD_PARAM.

    Допустим, что на входе 16 состояний работы устройств и на выходе 16 команд управления, то есть WORD = 2 байта = 16 битов.
    По входным состояниям битов вопросов нет - я их "распаковываю" через ST.

    А вот по выходным параметрам что-то неправильно выстраиваю.
    Значит на экран добавил 16 кнопок нефиксируемых (вкл/откл). Поставил галку на "использовать входящую связь только для отображения". Привязал входной бит состояния.
    На событие нажатия этой кнопки привязал выдачу импульса на 500ms и все кнопки проходит через этот алгоритм, но при нажатии иногда вроде бы работает нормально, а иногда не работает:

    Код:
    VAR
        firstScan: BOOL := TRUE;
        systemInitialized: BOOL := FALSE;
        initCounter: INT := 0; // Счетчик для задержки инициализации
        prevState_0: BOOL := FALSE;
    .
    .
    .
        prevState_15: BOOL := FALSE;
    END_VAR
    
    VAR_TEMP
        needUpdate: BOOL;
    END_VAR
    
    // Основной алгоритм
    needUpdate := FALSE;
    tempWord.Value := inputWord.Value;
    tempWord.SourceTime := inputWord.SourceTime;
    tempWord.StatusCode := inputWord.StatusCode;
    
    // Бит 0
    IF (state_0.Value = TRUE) AND (prevState_0 = FALSE) THEN
        tempWord.Value.0 := NOT inputWord.Value.0;
        needUpdate := TRUE;
    END_IF;
    prevState_0 := state_0.Value;
    
    .
    .
    .
    
    // Бит 15
    IF (state_15.Value = TRUE) AND (prevState_15 = FALSE) THEN
        tempWord.Value.15 := NOT inputWord.Value.15;
        needUpdate := TRUE;
    END_IF;
    prevState_15 := state_15.Value;
    
    // Записываем результат только если были изменения
    IF needUpdate THEN
        outputWord.Value := tempWord.Value;
        outputWord.SourceTime := tempWord.SourceTime;
        outputWord.StatusCode := tempWord.StatusCode;
    END_IF;
    
    // Отложенная инициализация после полной загрузки системы
    IF firstScan THEN
        initCounter := initCounter + 1;
        
        // Ждем несколько циклов (например, 3) для полной инициализации
        IF initCounter >= 3 THEN
            // Проверяем, что inputWord содержит актуальные данные
            IF inputWord.Value <> 0 OR inputWord.StatusCode <> 0 THEN
                outputWord.Value := inputWord.Value;
                outputWord.SourceTime := inputWord.SourceTime;
                outputWord.StatusCode := inputWord.StatusCode;
                systemInitialized := TRUE;
                firstScan := FALSE;
            END_IF;
        END_IF;
    END_IF;
    Что я делаю не так, подскажите как правильно должна быть выстроена структура и алгоритм.

  2. #2

    По умолчанию

    Цитата Сообщение от Asbi Посмотреть сообщение
    Всех приветствую.

    Проблема с управлением устройств через битовую маску. Что-то делаю не так и не пойму что.

    Есть два параметра - входной и выходной параметры SYSTEM_WORD_PARAM.

    Допустим, что на входе 16 состояний работы устройств и на выходе 16 команд управления, то есть WORD = 2 байта = 16 битов.
    По входным состояниям битов вопросов нет - я их "распаковываю" через ST.

    А вот по выходным параметрам что-то неправильно выстраиваю.
    Значит на экран добавил 16 кнопок нефиксируемых (вкл/откл). Поставил галку на "использовать входящую связь только для отображения". Привязал входной бит состояния.
    На событие нажатия этой кнопки привязал выдачу импульса на 500ms и все кнопки проходит через этот алгоритм, но при нажатии иногда вроде бы работает нормально, а иногда не работает:

    Код:
    VAR
        firstScan: BOOL := TRUE;
        systemInitialized: BOOL := FALSE;
        initCounter: INT := 0; // Счетчик для задержки инициализации
        prevState_0: BOOL := FALSE;
    .
    .
    .
        prevState_15: BOOL := FALSE;
    END_VAR
    
    VAR_TEMP
        needUpdate: BOOL;
    END_VAR
    
    // Основной алгоритм
    needUpdate := FALSE;
    tempWord.Value := inputWord.Value;
    tempWord.SourceTime := inputWord.SourceTime;
    tempWord.StatusCode := inputWord.StatusCode;
    
    // Бит 0
    IF (state_0.Value = TRUE) AND (prevState_0 = FALSE) THEN
        tempWord.Value.0 := NOT inputWord.Value.0;
        needUpdate := TRUE;
    END_IF;
    prevState_0 := state_0.Value;
    
    .
    .
    .
    
    // Бит 15
    IF (state_15.Value = TRUE) AND (prevState_15 = FALSE) THEN
        tempWord.Value.15 := NOT inputWord.Value.15;
        needUpdate := TRUE;
    END_IF;
    prevState_15 := state_15.Value;
    
    // Записываем результат только если были изменения
    IF needUpdate THEN
        outputWord.Value := tempWord.Value;
        outputWord.SourceTime := tempWord.SourceTime;
        outputWord.StatusCode := tempWord.StatusCode;
    END_IF;
    
    // Отложенная инициализация после полной загрузки системы
    IF firstScan THEN
        initCounter := initCounter + 1;
        
        // Ждем несколько циклов (например, 3) для полной инициализации
        IF initCounter >= 3 THEN
            // Проверяем, что inputWord содержит актуальные данные
            IF inputWord.Value <> 0 OR inputWord.StatusCode <> 0 THEN
                outputWord.Value := inputWord.Value;
                outputWord.SourceTime := inputWord.SourceTime;
                outputWord.StatusCode := inputWord.StatusCode;
                systemInitialized := TRUE;
                firstScan := FALSE;
            END_IF;
        END_IF;
    END_IF;
    Что я делаю не так, подскажите как правильно должна быть выстроена структура и алгоритм.
    Не изучал подробно ваш код, но попробуйте учитывать такой момент, что по умолчанию протоколы MS настроены на запись значения только по его изменению (значения). Можно добавить в условие запись по изменению метки времени значения.

    Если у вас команды управления импульсные - зачем вам ЧИТАТЬ значение регистра с этими командами?

  3. #3

    По умолчанию

    Цитата Сообщение от 1exan Посмотреть сообщение
    Можно добавить в условие запись по изменению метки времени значения.
    Как-то раз тех поддержка тоже такое советовало, но это замедляет работу протокола. И у меня в общей сложности устройств намного больше, а 16 привел только для примера.

    Цитата Сообщение от 1exan Посмотреть сообщение
    Если у вас команды управления импульсные - зачем вам ЧИТАТЬ значение регистра с этими командами?
    Кнопки только импульсные, на самом деле в алгоритме делаю, что-то наподобие самоподхвата. А читаю регистры, потому что было такое, что при изменении какого-либо бита в остальные биты записывались False (0), поэтому я начал туда записывать актуальные значения.

  4. #4

    По умолчанию

    Цитата Сообщение от Asbi Посмотреть сообщение
    Как-то раз тех поддержка тоже такое советовало, но это замедляет работу протокола. И у меня в общей сложности устройств намного больше, а 16 привел только для примера.

    Кнопки только импульсные, на самом деле в алгоритме делаю, что-то наподобие самоподхвата. А читаю регистры, потому что было такое, что при изменении какого-либо бита в остальные биты записывались False (0), поэтому я начал туда записывать актуальные значения.
    Попробуйте так:
    Код:
        Выход.Value.0    :=    x0;
        Выход.Value.1    :=    x1;
        Выход.Value.2    :=    x2;
        Выход.Value.3    :=    x3;
        Выход.Value.4    :=    x4;
        Выход.Value.5    :=    x5;
        Выход.Value.6    :=    x6;
        Выход.Value.7    :=    x7;
        Выход.Value.8    :=    x8;
        Выход.Value.9    :=    x9;
        Выход.Value.10   :=    x10;
        Выход.Value.11   :=    x11;
        Выход.Value.12   :=    x12;
        Выход.Value.13   :=    x13;
        Выход.Value.14   :=    x14;
        Выход.Value.15   :=    x15;
     Выход.StatusCode := Вход.StatusCode;
    т.е. просто упаковать сигналы с кнопок (импульсы) и присвоить выходу статус входного слова.
    А для надёжности было бы в конце программного цикла ПЛК обнулять регистр с командами (если конечно есть такая возможность)

  5. #5

    По умолчанию

    Цитата Сообщение от 1exan Посмотреть сообщение
    т.е. просто упаковать сигналы с кнопок (импульсы)
    так это самый элементарный вариант - я с него и начал и у меня возникла проблема с тем, что я нажимаю какую либо кнопку, он отправляет на запись True в нужный бит, а все что не было нажато записывается как False и он выключал все остальные устройства.

    То есть вся проблема в том, что при запуске скады кнопки и выходное состояние должны синхронизироваться с текущим актуальным состоянием и соотвественно, при изменении какого-либо бита на выход отправляться вся актуальная битовая маска, кроме последнего измененного, разве нет?
    Последний раз редактировалось Asbi; 08.07.2025 в 09:10.

  6. #6
    Пользователь
    Регистрация
    27.11.2011
    Адрес
    Краснодар
    Сообщений
    12,991

    По умолчанию

    так вам надо не просто отправить true в бит, если вы используете слово для записи. А изменить бит в слове и уже его отправить. Чтобы значения других бит не изменились.
    То есть взять не новое слово, где все по нулям, а текущее состояние слова.

  7. #7

    По умолчанию

    Цитата Сообщение от melky Посмотреть сообщение
    так вам надо не просто отправить true в бит, если вы используете слово для записи. А изменить бит в слове и уже его отправить. Чтобы значения других бит не изменились.
    То есть взять не новое слово, где все по нулям, а текущее состояние слова.
    В моем изначальном алгоритме я именно так и делаю

    Попробую убрать все лишнее и сделать все заново
    Последний раз редактировалось Asbi; 08.07.2025 в 09:23.

  8. #8
    Пользователь
    Регистрация
    27.11.2011
    Адрес
    Краснодар
    Сообщений
    12,991

    По умолчанию

    IF (state_0.Value = TRUE) AND (prevState_0 = FALSE) THEN
    плохо понимаю ST, но ... вы проверяете, что ваш бит True и тут же какую-то булевую переменную предыдущего состояния - простой вопрос, а нахрена все это?
    Вот просто сделать функцию SetBit и пофигу что вы там хотите записать 0 или 1 и не париться ?
    Или как-то обязательно только 1 записывать в бит ?

  9. #9

    По умолчанию

    Цитата Сообщение от Asbi Посмотреть сообщение
    так это самый элементарный вариант - я с него и начал и у меня возникла проблема с тем, что я нажимаю какую либо кнопку, он отправляет на запись True в нужный бит, а все что не было нажато записывается как False и он выключал все остальные устройства.

    То есть вся проблема в том, что при запуске скады кнопки и выходное состояние должны синхронизироваться с текущим актуальным состоянием и соотвественно, при изменении какого-либо бита на выход отправляться вся актуальная битовая маска, кроме последнего измененного, разве нет?
    Цитата Сообщение от Asbi Посмотреть сообщение
    Как-то раз тех поддержка тоже такое советовало, но это замедляет работу протокола. И у меня в общей сложности устройств намного больше, а 16 привел только для примера.

    Кнопки только импульсные, на самом деле в алгоритме делаю, что-то наподобие самоподхвата. А читаю регистры, потому что было такое, что при изменении какого-либо бита в остальные биты записывались False (0), поэтому я начал туда записывать актуальные значения.
    Я из этого понял что сигналы "ТОЛЬКО ИМПУЛЬСНЫЕ".

    Если это не так - то я, например, изрядно помучившись, отказался от идеи записывать такие биты словом. Завожу отдельные битовые теги для таких целей

Похожие темы

  1. Ответов: 56
    Последнее сообщение: 12.12.2024, 08:51
  2. ПР200 управление SLAVE-устройствами.
    от Григори в разделе Программируемые реле
    Ответов: 2
    Последнее сообщение: 12.08.2022, 14:58
  3. Ответов: 18
    Последнее сообщение: 08.10.2021, 22:54
  4. Настройка ПР200, управление 3-мя устройствами через RS-485
    от Orbes в разделе Среда программирования OWEN Logic
    Ответов: 20
    Последнее сообщение: 15.05.2017, 16:45
  5. Управление ПЛК через usb
    от DrKillJoy в разделе Помощь Разработчикам
    Ответов: 17
    Последнее сообщение: 09.06.2012, 10:03

Ваши права

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