Skip to content

crossrw/fbd-runtime

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GitHub top language GitHub code size in bytes Codacy Badge GitHub

FBD-runtime

fbd logo

Библиотека предназначена для выполнения программ на языке FBD (Язык функциональных диаграмм) для ПЛК (Программируемых Логических Контроллеров).

Подробнее о языке FBD можно прочитать на сайте Wikipedia.

FBD - один из языков программирования описанных в международном стандарте IEC 61131-3. Данная реализация не полностью совместима с указанным стандартом, однако большинство его требований реализовано.

Редактор и симулятор выполнения программ FBD вы можете скачать по ссылке.

На YoTube создан плейлист, посвященный контроллеру САТ-500, использующем бибилиотеку.

Библиотека использована при разработке универсального контроллера САТ-500, подробная информация о контроллере на доступна на сайте www.sat500.ru.

Оглавление

Введение

Язык функциональных диаграмм создан для описания функционирования одного или нескольких (соединенных через информационную сеть) логических контроллеров. Язык описывает входящие в состав схемы элементы и соединяющие их цепи.

Возможности

  • Нет зависимости от аппаратуры, возможность применения на любой платформе где есть компилятор языка C
  • Алгоритм оптимизирован для встроенных контроллеров: PIC, AVR, ARM и т.п. Вычисление не использует рекурсию, стек данных используется очень экономно
  • Поддержка архитектур Big-Endian и Litle-Endian
  • Экономное использование RAM: схема из 400 элементов использует только около 1 kb ОЗУ
  • Широкий диапазон поддерживаемых элементов: логические, арифметические, сравнение, таймеры, триггеры, регулятор. Набор элементов может быть легко расширен
  • Сохранение промежуточных результатов в NVRAM (для триггеров, таймеров, точек регулирования и т.п.)
  • Поддержка работы по сети (Ethernet, ModBus или подобное)
  • Базовая поддержка интерфейса с оператором (HMI)

Основные понятия

Контроллер

ПЛК – программируемый логический контроллер, представляют собой микропроцессорное устройство, предназначенное для сбора, преобразования, обработки, хранения информации и выработки команд управления, имеющий конечное количество входов и выходов, подключенных к ним датчиков, ключей, исполнительных механизмов к объекту управления, и предназначенный для работы в режимах реального времени с ограниченным вмешательством человека. Наиболее часто ПЛК используются для автоматизации технологических процессов.

Типовая структура ПЛК показана на рисунке:

fbd struct

Обычно ПЛК предусматривает выполнение следующих функций:

  • Выполнение управляющей программы реализующей алгоритм управления
  • Подключение входных сигналов (input pins) внешних датчиков (температура, давление, дискретные входы, напряжение и т.п.)
  • Подключение выходных сигналов (output pins) для управления внешним оборудованием (дискретные выходы, сигналы тока или напряжения)
  • Подключение к информационной сети (network), объединяющей несколько ПЛК и обеспечивающей их совместное функционирование
  • Содержит средства реализации интерфейса с человеком (HMI) с помощью индикатора, дисплея, клавиатуры и т.п.

Рабочий цикл ПЛК включает 4 фазы:

  1. Чтения значений входных сигналов
  2. Выполнение программы обработки
  3. Установку значений выходных сигналов
  4. Вспомогательные операции (обмен данными по информационной сети, реализация HMI и т.п.).

Схема

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

Элемент

Элемент схемы это минимальный функциональный блок, выполняющий определенную операцию (логическую, арифметическую, задержку и т.п.) или обеспечивающий подключение схемы к входным или выходным цепям программируемого контроллера.

  • Каждый элемент должен иметь уникальное в рамках схемы идентифицирующее его имя.
  • Элемент может иметь некоторое количество входов (а может и не иметь) и один или ни одного выхода. Количество входов и выходов зависит от типа элемента. На графическом изображении элементов входы всегда расположены слева, а выходы справа от элемента. Каждый вход элемента должен быть подключен к цепи, которая соединяет его с выходом другого элемента. Выход элемента может быть подключен к одному или нескольким входам других элементов (в том числе и его собственным входам). Выход элемента может быть никуда не подключен, в этом случае элемент не имеет смысла.
  • Элементы, которые не имеют выхода обычно используются для обозначения аппаратных выходов программируемого контроллера, выходных сетевых переменных или точек отображения.
  • Элементы, которые не имеют входа обычно используются для обозначения аппаратных входов программируемого контроллера, входных сетевых переменных или точек регулирования.
  • Элемент может иметь (а может и не иметь: это зависит от типа элемента) параметры, влияющие на его функционирование. Параметры имеют фиксированное значение и задаются при разработке схемы.

Цепь

Цепь это логическая связь между входами и выходами элементов предназначенная для передачи состояния (значения) сигнала. Каждая цепь должна быть подключена строго к одному выходу и одному или нескольким входам элементов схемы. Состояние цепи к которой не подключен ни один выход элемента является неопределенным. Цепь, которая не подключена ни к одному входу элемента, является не используемой и ее состояние не вычисляется. Аналогично элементам, цепи имеют уникальные в рамках схемы имена. Цепи служат для передачи значений сигналов между элементами схемы. На графическом изображении схемы цепи изображаются в виде линий, которые соединяют входы и выходы элементов.

Сигнал

Сигнал представляет собой целое число со знаком. В зависимости от параметров, указанных при сборке библиотеки, сигнал может занимать 1, 2 или 4 байта. Сигналы можно использовать для логических операций. При этом значение сигнала равное 0 интерпретируется как логический "0" (False), а значение сигнала не равное 0 - как логическая "1" (True). Для входов некоторых элементов важно не само значение сигнала, а факт его нарастания (передний фронт). Такие входы на графическом изображении элемента обозначены наклонной чертой. Факт наличия переднего фронта фиксируется при любом изменении сигнала в большую сторону (Si > Si-1). Элементы, выполняющие логические функции, формируют значение сигнала "1" для логической "1" и значение сигнала "0" для логического "0".

Точки регулирования и контроля

Точка регулирования является составной частью организации интерфейса контроллера с оператором (HMI). При помощи точек регулирования оператор может установить значения параметров, используемых при работе схемы.

Точка контроля является составной частью организации интерфейса контроллера с оператором (HMI). При помощи точек контроля оператор может просматривать значения сигналов в различных цепях схемы.

Сетевая переменная

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

Пример схемы

Пример простой схемы показан на рисунке:

fbd demo

Ограничения

Используемый алгоритм расчета содержит определенные ограничения:

  • Элемент не может иметь более одного выхода
  • Поддерживается только один тип данных (tSignal). Это относится ко всем входам и выходам всех элементов, значениям сигналов цепей, констант. Размерность типа данных определяется при компиляции проекта. Обычно используется тип целое число со знаком.

Производительность

Один цикл вычисления схемы производится в ходе выполнения функции fbdDoStep(). В ходе одного цикла производится расчет значений всех элементов схемы и установка значений всех сетевых переменных и выходных контактов. Время расчета зависит от множества факторов, в первую очередь от количества и типов используемых элементов в схеме. Результаты тестирования времени выполнения небольшой схемы из 10 элементов показаны в таблице:

CPU@FreqКомпиляторДлительность циклаРасчет одного элемента (среднее)
PIC18@9.83x4MHzxc8 v1.21~5ms~500µs
Si8051@48MHzKeil C51~2.5ms~250µs
ARM920T@180MHzgcc v4.1.2~61µs~6.1µs
STMF437@168MHzKeil~31µs~3.1µs
i7-3770K@3.5GHzgcc v4.4.1~279ns~27.9ns

Описания элементов

Входы/Выходы/Константы/Переменные

Вход

Элемент имеет один выходной контакт. Входов у элемента нет. Элемент является источником значения сигнала для других подключенных к нему элементов. В зависимости от настроек, элемент может выполнять четыре разные функции:

Связь с входным контактом контроллера

inpin

В этом случае у элемента имеется один параметр: номер контакта контроллера. Выходное значение сигнала элемента зависит от номера контакта и особенностей аппаратной реализации контроллера. Обычно используется для получения значений подключенных дискретных входов, датчиков температуры, давления, АЦП и т.п. Активное состояние дискретного входа (замкнут, подано напряжение) должно соответствовать значению сигнала "1".

Константа

const

В этом случае у элемента имеется один параметр: значение константы. Выходное значение сигнала элемента всегда соответствует значению параметра (константе).

Точка регулирования

sp

Точка регулирования необходима для реализации возможности корректировки значений настроек, используемых при вычислении схемы. В отличие от константы, значение выходного сигнала элемента может быть изменено эксплуатирующим персоналом (или наладчиком) контроллера. Изменение значения точки регулирование может быть организовано через средства человеко-машинного интерфейса (HMI) контроллера (клавиатуру, индикатор и т.п.). Точка регулирования имеет 4 параметра: значение по умолчанию, минимальное значение, максимальное значение, текстовая строка с описанием.

Входная сетевая переменная

invar

Библиотека предусматривает возможность подключения контроллера в информационную сеть, которая объединяет несколько однотипных или разнородных контроллеров. Такая сеть может быть построена с использованием интерфейсов Ethernet, RS-485, CAN и т.п. Значение выходного сигнала соответствует значению, полученному от другого контроллера по информационной сети. У элемента есть два параметра: номер сетевой переменной и значение переменной "по умолчанию". Последние полученные по сети значения переменных сохраняются в NVRAM и доступны в дальнейшем при возникшей неисправности сети, в том числе после выключения и включения контроллера. Значение сетевой переменной "по умолчанию" используется после загрузки новой программы в контроллер до получения нового значения переменной из сети.

Выход

Элемент имеет один входной контакт. Выходов у элемента нет. В зависимости от настроек, элемент может выполнять две разные функции:

Связь с выходным контактом контроллера

outpin

У элемента имеется один параметр: номер выходного контакта контроллера. Интерпретация входного значения зависит от особенностей аппаратной реализации на конкретном контроллере. Обычно используется для управления дискретными и аналоговыми выходами контроллера.

Выходная сетевая переменная

outvar

У элемента имеется один параметр: номер выходной сетевой переменной. Значение поданного на вход элемента сигнала передается по информационной сети и доступно на других контроллерах через элемент "Входная сетевая переменная". Не рекомендуется иметь в рамках одной схемы элементы "Входная сетевая переменная" и "Выходная сетевая переменная" с одинаковыми номерами.

Логические функции

Инверсия (NOT)

not

Элемент выполняет функцию логической инверсии "NOT". Элемент имеет один вход и один выход. Таблица истинности:

ВходВыходной сигнал
Логический "0"1
Логическая "1"0

Логическое "И" (AND)

and

Элемент выполняет логическую функцию "И" ("AND"). Элемент имеет два входа и один выход. Элемент имеет настройку инвертирования выходного сигнала. Таблица истинности:

Вход 1Вход 2ВыходИнвертированный выход
Логический "0"Любое значение01
Any valueЛогический "0"01
Логическая "1"Логическая "1"10

Логическое "ИЛИ" (OR)

or

Элемент выполняет логическую функцию "ИЛИ" ("OR"). Элемент имеет два входа и один выход. Элемент имеет настройку инвертирования выходного сигнала. Таблица истинности:

Вход 1Вход 2ВыходИнвертированный выход
Логический "0"Логический "0"01
Логическая "1"Любое значение10
Любое значениеЛогическая "1"10

Логическое "Исключающее ИЛИ" (XOR)

xor

Элемент выполняет логическую функцию "Исключающее ИЛИ" ("XOR"). Элемент имеет два входа и один выход. Элемент имеет настройку инвертирования выходного сигнала. Таблица истинности:

Вход 1Вход 2ВыходИнвертированный выход
Логический "0"Логический "0"01
Логический "0"Логическая "1"10
Логическая "1"Логический "0"10
Логическая "1"Логическая "1"01

Триггеры

RS - триггер

rs

RS - триггер имеет два входа (R-Reset и S-Set) и один выход (Q).

RS - триггер, сохраняет своё предыдущее состояние при неактивном состоянии обоих входов (сигнал логического "0") и изменяет своё состояние при подаче на один из его входов сигнала логической "1". Пока на входы R и S подан сигнал логический "0", выход Q находится в неизменном состоянии. Если на вход S (Set) подать сигнал логическая "1", то сигнал на выходе Q принимает значение "1". Если на вход R (Reset) подать сигнал логическая "1", то сигнал на выходе Q принимает значение "0". При переводе сигнала на входе S или R в состояние логического "0", сигнал на выходе Q сохраняет своё предыдущее значение. При подаче на оба входа S и R сигнала логическая "1" состояние выхода Q не определено. Элемент имеет настройку инвертирования выходного сигнала.

Таблица истинности:

SRQnextДействие
00QХранение
010Сброс
101Установка
11?Не разрешено

Каждый раз, когда триггер изменяет своё состояние, новое значение сохраняется в энергонезависимой памяти NVRAM (путём вызова функции FBDsetProc(1, index, *value)). При инициализации схемы, ранее сохранённые значения триггера восстанавливаются (путём вызова функции FBDgetProc(1, index)).

D - триггер

d

D - триггер имеет два входа (D-Data и C-Clock) и один выход (Q).

D - триггер при положительном перепаде (нарастании) сигнала на входе C запоминает состояние входа D и выдаёт его на выход Q. При отсутствии положительного перепада на входе C, состояние выхода Q сохраняется постоянным.

Таблица истинности:

DCQnextДействие
Любое значениеНарастаниеDЗапоминание
Любое значениеНет нарастанияСохранённое значение DХранение

В отличие от традиционных D - триггеров значения сигнала на входе D и выходе Q может принимать любое значение (не только "0" и "1").

Каждый раз, когда триггер изменяет своё состояние, новое значение сохраняется в энергонезависимой памяти NVRAM (путём вызова функции FBDsetProc(1, index, *value)). При инициализации схемы, ранее сохранённые значения триггера восстанавливаются (путём вызова функции FBDgetProc(1, index)).

Счётчик

cnt

Элемент имеет три входа и один выход. Если на вход R (Reset) подан сигнал логической "1", то сигнал на выходе Q принимает значение "0" (сброс счётчика). Если на вход R подан сигнал логического "0", то значение сигнала на выходе Q увеличивается на 1 при положительном перепаде на входе "+" или уменьшается на 1 при положительном перепаде на входе "-". При отсутствии положительного перепада на входах "+" и "-" значение сигнала на выходе Q не изменяется.

Таблица истинности:

+-RQnextДействие
Любое значениеЛюбое значение10Сброс
НарастаниеНет нарастания0Q+1Увеличение на 1
Нет нарастанияНарастание0Q-1Уменьшение на 1
Нет нарастанияНет нарастания0QНет изменений
НарастаниеНарастание0QНет изменений

Каждый раз, когда счётчик изменяет своё состояние, новое значение сохраняется в энергонезависимой памяти NVRAM (путём вызова функции FBDsetProc(1, index, *value)). При инициализации схемы, ранее сохранённые значения счётчика восстанавливаются (путём вызова функции FBDgetProc(1, index)).

Арифметические функции

Сложение

add

Элемент имеет два входа и один выход. Значение выходного сигнала вычисляется, как арифметическая сумма значений сигналов на входах.

Вычитание

sub

Элемент имеет два входа и один выход. Значение выходного сигнала вычисляется, как арифметическая разность сигнала на первом (уменьшаемое) и на втором (вычитаемое) входах.

Умножение

mul

Элемент имеет два входа и один выход. Значение выходного сигнала вычисляется, как арифметическое произведение сигналов на первом и втором входах.

Деление

div

Элемент имеет два входа и один выход. Значение выходного сигнала вычисляется, как арифметическое деление значения сигнала на первом входе (делимое) на значение сигнала на втором входе (делитель).

Особые случаи:

Вход 1Вход 2Выход
001
Любое положительное значение0MAX_SIGNAL
Любое отрицательное значение0MIN_SIGNAL

О том, что делить на 0 нельзя я знаю. :-)

Абсолютное значение

abs

Элемент имеет один вход и один выход. Значение выходного сигнала есть абсолютное значение сигнала на входе.

Битовые операции

Побитовое логическое "И"

band

Побитовое «И» — это бинарная операция, действие которой эквивалентно применению логического «И» к каждой паре битов, которые стоят на одинаковых позициях в двоичных представлениях значений входных сигналов. Другими словами, если оба соответствующих бита значений входных сигналов равны 1, результирующий двоичный разряд равен 1; если же хотя бы один бит из пары равен 0, результирующий двоичный разряд равен 0.

Побитовое логическое "ИЛИ"

bor

Побитовое «ИЛИ» — это бинарная операция, действие которой эквивалентно применению логического «ИЛИ» к каждой паре битов, которые стоят на одинаковых позициях в двоичных представлениях значений входных сигналов. Другими словами, если оба соответствующих бита значений входных сигналов равны 0, двоичный разряд результата равен 0; если же хотя бы один бит из пары равен 1, двоичный разряд результата равен 1.

Побитовое логическое "Исключающее ИЛИ"

bxor

Исключающее« ИЛИ» (сложение по модулю 2) — это бинарная операция, результат действия которой равен 1, если число складываемых единичных битов нечётно и равен 0, если чётно. Другими словами, если оба соответствующих бита значений входных сигналов равны между собой, двоичный разряд результата равен 0; в противном случае, двоичный разряд результата равен 1.

Функции регулирования

Регулятор

pid

Элемент имеет четыре входа и один выход. Входы:

  • U - текущее значение контролируемого процесса (обратная связь)
  • REF - значение, которое должно быть достигнуто в процессе регулирования (уставка)
  • DT - время реакции регулятора (мс)
  • P - коэффициент пропорциональности

Выход Q - сигнал влияния на регулируемый процесс.

В отличие от множества других подобных реализаций, данный элемент не использует традиционный алгоритм PID регулирования. Вместо этого применен алгоритм Эйлера-Лагранжа, обеспечивающий простоту настройки, высокую скорость сходимости и отсутствие склонности к возникновению колебаний. Данный алгоритм широко используется при стыковке космических аппаратов. Подробности можно узнать из специальной литературы, на сайте проекта Wikipedia имеется статья, которая поясняет некоторые моменты алгоритма.

Подробности реализации можно увидеть в исходном коде и примерах.

Интегратор

sum

Элемент используется для интегрирования (суммирования) во времени значения входного сигнала. Элемент часто используется совместно с описанным выше регулятором. Элемент имеет три входа и один выход. Входы:

  • X - интегрируемый сигнал
  • DT - время интегрирования (мс)
  • Lim - ограничение значения выходного сигнала

Выход Q - значение величины интеграла (суммы).

Каждый интервал времени DT значение входного сигнала X складывается с текущим накопленным значением. Если новое значение больше значения Lim или меньше значения -Lim, то результат ограничивается значением Lim или -Lim. Сигнал на выходе Q принимает значение результата.

Таймеры

Таймер TON

ton

TON - это таймер с задержкой включения. Элемент может быть использован в генераторах периодических сигналов и счетчиках времени. Элемент имеет два входа и один выход:

  • D - запуск таймера
  • T - величина задержки (мс)
  • Q - выходной логический сигнал

Если на входе D присутствует сигнал логического "0", то на выходе Q всегда сигнал "0". Если на вход D подать сигнал логической "1", то на выходе Q появится сигнал "1" через промежуток времени, соответствующий сигналу на входе T. Элемент имеет настройку, инвертирующую значение выходного сигнала.

Таблица истинности:

DУсловиеВыходИнвертированный выход
Логический "0"Любое01
Логическая "1"Время T не истекло01
Логическая "1"Время T истекло10

Временная диаграмма таймера TON:

dton

Таймер TP

tp

Элемент имеет два входа и выход:

  • D - запуск таймера
  • T - время задержки (мс)
  • Q - выход

Положительный фронт сигнала на входе D запускает таймер и устанавливает на выходе Q значение сигнала "1". По истечении времени T значение выходного сигнала принимает значение "0". Элемент имеет настройку, инвертирующую значение выходного сигнала.

Временная диаграмма таймера TP:

dtp

Генератор

gen

Генератор может быть использован для формирования периодических сигналов различной формы. Элемент имеет два входа и выход:

  • A - амплитуда формируемого сигнала
  • T - период последовательности (мс)
  • Q - выход

Если на входе T присутствует значение сигнала меньшее или равное "0", то генератор остановлен и на его выходе Q формируется сигнал со значением "0". При положительном значении сигнала на входе T генератор формирует на выходе Q периодический сигнал с амплитудой A и периодом T. В зависимости от настройки элемента, выполненной при проектировании схемы, форма сигнала может быть следующих видов:

  • Прямоугольные импульсы (меандр со значениями сигнала "0" и "A")
  • Пилообразный сигнал (сигнал с линейно нарастающим значением и последующим сбросом в "0")
  • Импульсы треугольной формы
  • Синусоидальный сигнал

dgen

Значение сигнала на выходе Q лежит в диапазоне от "0" до "A" для генераторов меандра, пилообразных и треугольных импульсов. Для генератора синусоидального сигнала выход Q принимает значение от "-A" до "A".

Степень достоверности формы выходного сигнала генератора зависит от соотношения заданного периода сигнала и времени выполнения расчета схемы. Рекомендуется устанавливать значение периода T большим, чем время расчета одного шага схемы умноженное на коэффициент 15-20. В противном случае форма выходного сигнала генератора может значительно отличаться от требуемой.

Остальные элементы

Сравнение

cmp

Элемент имеет два входа и выход, выполняет сравнение значений сигналов на входах 1 и 2. Элемент имеет настройку, инвертирующую значение выходного сигнала. Таблица истинности:

УсловиеВыходИнвертированный выход
Input1Val > Input2Val10
Input1Val <= Input2Val01

Вычисление максимума

max

Элемент имеет два входа и выход. Выходное значение сигнала соответствует входному сигналу с максимальным значением. Таблица истинности:

УсловиеВыход
Input1Val > Input2ValInput1Val
Input1Val <= Input2ValInput2Val

Вычисление минимума

min

Элемент имеет два входа и выход. Выходное значение сигнала соответствует входному сигналу с минимальным значением. Таблица истинности:

УсловиеВыход
Input1Val > Input2ValInput2Val
Input1Val <= Input2ValInput1Val

Мультиплексор

ms

Расширяемый мультиплексор. Элемент имеет пять входов (D0-D3, A) и один выход. Значение выходного сигнала соответствует значению сигнала на выбранном входе D0-D3. Выбор выхода производится на основании значения сигнала на входе A. Таблица истинности:

AВыход Q
0D0
1D1
2D2
3D3

Ограничитель

lim

Ограничитель сигнала имеет 3 входа и один выход:

  • D - входной сигнал
  • MX - верхнее ограничение сигнала
  • MN - нижнее ограничение сигнала

Выходное значение сигнала элемента соответствует входному значению ограниченному значениями сигналов на входах MX (верхнее ограничение) и MN (нижнее ограничение).

Установка и настройка библиотеки

Установка библиотеки заключается в копировании файлов fbdrt.h и fbdrt.c в свой проект. Настройка состоит в редактировании файла fbdrt.h в соответствии со своими требованиями.

Вы можете изменить следующие определения в файле fbdrt.h:

  1. Выберите тип данных, используемый для хранения значений сигналов.
  2. Выберите тип данных используемый для индекса элементов.
  3. Если необходимо измените определения ROM_CONST и DESCR_MEM.
  4. Выберите необходимость использования оптимизации по скорости выполнения (определение SPEED_OPT).
  5. Выберите необходимость использования функций HMI (определение USE_HMI).
  6. Напишите свою реализацию функций FBDgetProc() и FBDsetProc().
  7. Если вы используете экраны HMI напишите свою реализацию функций FBDdrawXXXXXX().

От выбора типа данных для хранения сигналов зависит то, сигналы каких значений сможет обрабатывать ваша схема. Кроме того, от этого выбора зависят объем программы и объем используемой ею памяти и скорость расчета схемы. Для небольших встариваемых микроконтроллеров это может быть важным. В общем случае тип данных должен обеспечивать хранение целого числа со знаком. Если вы не уверены в выборе, то рекомендую остановиться на значении "по умолчанию": 32-х битное целое число со знаком. Выбор типа производится установкой значения определения SIGNAL_SIZE:

// размер памяти для сигнала схемы (1, 2 или 4)
#define SIGNAL_SIZE 4

Выбор типа данных для индекса элемента определяет как много элементов может быть в вашей схеме. Тип данных должен обеспечивать возможность хранения целых чисел без знака. Выбор типа производится установкой значения определения INDEX_SIZE. Рекомендуем остановить свой выбор на значении "по умолчанию" 2, в этом случае в вашей схеме может быть до 65535 элементов.

// размер пямяти для индекса элемента (1 или 2)
#define INDEX_SIZE 2

Определения ROM_CONST и DESCR_MEM используются для описания памяти в которой размещаются константы и массив описания схемы соответственно. Значения зависят от используемого вами компилятора. Для примера, при использовании компилятора xc8 (Microchip) и размещении данных в памяти FLASH необходимо использовать const:

// data in ROM/FLASH
#define ROM_CONST const
// schema description
#define DESCR_MEM const

Использование определения SPEED_OPT уменьшает время расчета схемы примерно в 6 раз(для средних и больших схем), объем необходимой памяти RAM при этом увеличивается примерно в 3 раза. Когда вы включаете определение SPEED_OPT, то в момент инициализации производится предварительный расчет некоторых таблиц с указателями, использование которых уменьшает время расчета схемы.

Определение USE_HMI необходимо в случае, когда ваш PLC содержит средства организации интрерфейса с человеком. Такими средствами могут быть например экран и кнопки. Будьте внимательны: если вы отключите HMI точки управления будут возвращать неопределенные данные! Пример:

// needed if you use HMI functions
#define USE_HMI
// speed optimization reduces the calculation time, but increases the size of memory (RAM) required
#define SPEED_OPT

Если вы установили USE_HMI, то дополнительно необходимо указать разрешение экране вашего контроллера в определениях:

#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240

Функции FBDgetProc() и FBDsetProc() служат для связи схемы с реальными входами и выходами вашего PLC.

Функция FBDgetProc() используется для чтения состояния входных сигналов (контактов) или значений, сохраненных в памяти NVRAM.

Функция FBDsetProc() используется для записии значений выходных сигналов (контактов) или для сохранения значений в память NVRAM.

Реализация этих функций зависит от специфики ваших задач. В общем случае рекомендуем придерживаться следующих правил:

  • Для дискретных входов и выходов использовать значения 0 и 1. При этом значение 0 должно соответствовать пассивному состоянию: выключен, разомкнут и т.п.
  • Для аналоговых входов и выходов значения которых представлены в инженерных единицах измерения (градусы, бары, вольты) необходимо использовать множитель, который преобразует эти значения в целые числа. Например для входа к которому подключен датчик температуры можно использовать множитель 100, который преобразует значение температуры на датчике +10.5 C в значение сигнала схемы 1050.

Не используйте прямую запись в EEPROM при каждом вызове FBDsetProc(): библиотека далает такие вызовы при каждом изменении состяния тригеров, таймеров и генератора. Частая запись в EEPROM может значительно сократить срок ее службы. Решением может быть отложенная запись или использование памяти RAM с питанием от батарейки.

tSignal FBDgetProc(char type, tSignal index)
{
    switch(type) {
    case 0:
        printf(" request InputPin(%d)\n", index);
        return 0;
    case 1:
        printf(" request NVRAM(%d)\n", index);
        return 0;
    }
}

void FBDsetProc(char type, tSignal index, tSignal *value)
{
    switch(type)
    {
    case 0:
        printf(" set OutputPin(%d) to value %d\n", index, *value);
        break;
    case 1:
        printf(" set NVRAM(%d) to value %d\n", index, *value);
        break;
    }
}

Выполнение

fbd alg

Инициализация

Инициализация схемы должна быть выполнена один раз в начале работы. Инициализация можут быть выполнена повторно для сброса состояния схемы. Для инициализации схемы необходимо выполнить вызов функции:

int fbdInit(DESCR_MEM unsigned char *descr)

descr - указатель на массив описания схемы.

Отрицательное значение результата функции означает ошибку:
-1 - неверный код элемента в описании схемы;
-2 - несовпадение размерности сигнала или элемента;
-3 - массив описания содержит схему с неподдерживаемой версией;
-4 - ошибка при проверке контрольной суммы описания схемы.

Положительное значение результата функции - требуемый объем RAM для выполнения схемы.

Если вызов инициализаии схемы выполнен без ошибок и вы имеете необходимый объем RAM, то следующим шагом необходимо выполнить вызов инициализации памяти:

void fbdSetMemory(char *buf, bool needReset)

buf - указатель на буфер памяти, размер буфера должен быть не меньше величины, которую вернул вызов функции fbdInit();
needReset - необходимость сброса содержимого EEPROM.

Параметр needReset должен быть установлен в значение TRUE после записи в контроллер новой схемы. При этом значения всех элементов с "пямятью" (точек регулирования, тригеров и генероаторов) сбрасываются в состояние "по умолчанию".

После инициализации памяти схема готова к работе.

Пошаговое выполнение

Для вычисления схемы необходимо периодически (например в главном цикле программы) выполнять функцию:

void fbdDoStep(tSignal period)

period - время, прошедшее с момента предыдущего вызова функции, при первом вызове необходимо указать значение 0.

В результате каждого вызова функции выполняется вычисление всех элементов схемы и производится установка всех выходных контактов и переменных.

Синхронизация времени

Некоторые элементы схемы используют значение времени или временных интервалов. К таким элементам относятся генератор, таймер, интегратор сигнала, регулятор. Для каждого элемента библиотека организует независимый таймер, значение которого хранится в RAM. Для хранения значения таймера используется тип tSignal.

Timer values changes by period every time the function fbdDoStep(tSignal period) is called. Time can be expressed in any units: sec, ms, µs. Unit selection depends on the time scale in which the PLC should work. In my opinion, a decent selection of milliseconds for most cases.

Network variables

Human machine interface (HMI)

The library contains basic functions support HMI. This can be used if your PLC has a display (LCD). You can make character or graphical menu with which to perform the following functions:

  • View values of schema points (Watchpoints)
  • Set the values of set points (Setpoints)

fbd menu

Watchpoints is used to display the values of the signals for operator. Setpoints are used to set the reference values, used in the operation of the circuit. Each watchpoint and setpoint has the associated text caption, that can be displayed on LCD. Moreover, for setpoints are stored maximum and minimum values of the signal that it can receive.

fbd menu2

To get the value of the watchpoint, use the function:

bool fbdHMIGetWP(tSignal index, tHMIdata *pnt);
// index - number of watchpoint (0..watch points count-1)
// pnt - pointer to data struct:
typedef struct {
    tSignal value;              // current point value
    tSignal lowlimit;           // low limit for value (only for setpoints)
    tSignal upperLimit;         // upper limit for value (only for setpoints)
    DESCR_MEM char *caption;    // pointer to text caption (asciiz)
} tHMIdata;

If the point exists, the function returns true and the data in the structure of pnt, otherwise the function returns a value false. Items lowlimit and upperlimit not used. To get the value of the setpoint, use the function:

bool fbdHMIGetSP(tSignal index, tHMIdata *pnt);
// index - number of setpoint (0..set points count-1)
// pnt - pointer to data structure

If the point exists, the function returns true and the data in the structure of pnt, otherwise the function returns a value false. Watchpoints and setpoints numbering starts with 0. To set the new setpoint value, use the function:

void fbdHMISetSP(tSignal index, tSignal value);
// index - number of setpoint (0..set points count-1)
// value - new value of setpoint

Текущий статус

Это работает. Библиотека используется в некоторых "боевых" проектах и не содержит известных автору проблем.

Дальнейшие планы:

  • оптимизация скорости выполнения
  • доработка документации
  • Modbus-Master
  • Alarms
  • журнал событий

Автор

Алексей Лутовинин -- crossrw1@gmail.com

Releases

No releases published

Packages

No packages published

Languages