Codesys 3. Очередь для ПЛК
Здравствуйте, коллеги. Сегодня мы с вами познакомимся с организацией работы при ограниченных ресурсах. Рассмотрим что такое "Очередь" как она работает, реализуем пару вариантов очередей, затронем динамическое выделение памяти в ПЛК.
Я пишу эту статью и программирую в режиме реального времени, т.е. у меня есть задача и я ее решаю. Все свои мысли и попытки(за исключением очень глупых) я записываю в эту статью так что приятного чтения.
ТЕОРИЯ
Очередь - это абстрактный тип данных, в котором доступ организуется по принципу FIFO(first in, first out) - первый пришел, первый ушел. Имеет два метода: добавить в очередь и достать из очереди. Данные которые мы достали из очереди - удаляются.
Согласно теории есть два метода реализации - массивом и односвязным списком. В большинстве ПЛК второй способ невозможен.
РЕАЛИЗАЦИЯ
Начнем с малого. Реализуем очередь для одного типа данных. Например, мы будем вырезать отверстия. По нужным координатам нужного диаметра.
Создадим необходимы DUT. В структуре у нас хранятся координаты по X,Y и диаметр отверстия.
Теперь организуем список необходимых операций, которые нам понадобятся. Всего их три: Ожидание, Добавить элемент, Достать элемент. Для такого типа операций я использую перечисление и CASE в реализации. Мне просто так удобнее. Можно с помощью флагов, триггеров, IF'ов, но я делаю так.
Теперь работаем с FB. Пытаемся уместить все в одном месте. Нам потребуется на вход:
1) Указатель на Глобальный UDT для чтения
2) Указатель на UDT куда будем писать.
(*тут я думаю как сделать команды*)
3) Команды управления
На выход у нас получается:
1) Сигнал об успешной записи в очередь
2) Сигнал об успешном чтении из очереди
3) Очередь пустая
4) Очередь полная
5) В работе
Пункты 3 и 4 можно объединить в ошибку и сделать какой-нибудь код для нее, но я не буду.
Под капотом:
1) Массив элементов( для теста 10)
2) Индекс старта
3) Индекс окончания
ЛОГИКА РАБОТЫ
Логика легка и проста. читаем из элемента под индексом iStart. Считали прибавили 1. Записываем в индекс iEnd. Записали прибавили единицу.
Дошли до конца, скинули счетчик. Пошли по кругу. Всего может быть 10 элементов. Если индексы пересекаются, то это неопределенность. Либо очередь полная, либо пустая. Так что этот вопрос продеться контролировать.
При старте реализации было обнаружено, что значения пустой и полной очереди необходимо обрабатывать внутри кода. Есть два три выхода: переносим в In_Out, переносим указателями в In, создаем в области VAR и во время WAIT копируем значения.
Я выбираю третий вариант с дублированием.
Добавил в Output переменную Error.
ИТОГ
Я опять пожалуюсь, что вставлять и сюда код очень проблематично так что ссылка на PDF документ на Яндекс.Диск с листингом.
Ну и небольшая видео демонстрация как там все происходит.Спасибо за внимание. Если что стучите в комментарии, если что-то очень личное, то на почту info@engcore.ru.



Лига КИПиА
47 постов540 подписчиков
Правила сообщества
Правила - в соответствии с общими правилами Пикабу.