|
Конкурс статей Borland |
|
|
Сообщество ITware |
|
|
|
|
Контакты |
|
Редакция:
Web-мастер:
|
|
Методика разработки программного обеспечения в среде Delphi для систем промышленной автоматизации |
04 августа 2003 21:12 kulikovckiy |
количество баллов: 44 |
Содержание
Введение
1. Основные этапы проектирования приложения для систем промышленной автоматизации
2. Разработка ключевых классов
3. Методы тестирования приложения и разработки алгоритма выдачи команд на объект управления
4. Создание потока опроса параметров
5. Выбор приоритета потока и класса приоритета приложения
6. Разработка главного окна приложения и других окон
7. Разработка процедур инициализации приложения
8. Разработка процедур доступа к базам данных
9. Разработка процедур отображения информации
10. Выводы
Литература
Введение Назад
Приложения для систем промышленной автоматизации - это прежде всего приложения, которые должны работать в режиме реального времени, непрерывно опрашивать состояние объекта управления и выдавать управляющие воздействия на объект управления.
Это, в свою очередь, перед разработчиком приложения ставит специфичные задачи:
- обеспечение стабильной частоты опроса контролируемых параметров;
- представление информации о состоянии всего объекта управления и отдельных узлов вплоть до датчика;
- в наладочном режиме оператор должен иметь возможность подать команду на каждый исполнительный механизм объекта управления;
- информация о работе объекта управления должна сохраняться в архивах и по запросам оператора должна быть представлена в виде таблиц и графиков.
В связи с тем, что приложение работает в режиме реального времени при постоянном изменении состояния объекта управления, оно имеет свои особенности отладки.
Условно объекты промышленной автоматизации можно разделить на две группы - объекты, требующие работы системы управления в режиме "жесткого" реального времени, и объекты, требующие - "не жесткого" реального времени. Приложения систем управления, работающие в режиме "жесткого" реального времени, выполняются в специальных операционных системах реального времени типа QNX, RTOS-32 и других (обзор операционных систем реального времени в [7]).
Многие объекты управления работают в режиме "не жесткого" реального времени, и для них можно применить операционные системы линии Windows NT.
У разработчика приложения для автоматизированной системы управления (АСУ), работающей в режиме "не жесткого" реального времени, возникают вопросы - можно ли разработать в среде Delphi эффективные, надежно работающие приложения, и, если возможно, то какая должна быть структура приложения, в какой последовательности строить приложение, какие компоненты применить для представления информации и выдачи команд на объект управления, какие методы отладки и тестирования применить. Публикации, отвечающие на поставленные выше вопросы, встречаются очень редко.
В данной статье кратко описана последовательность разработки в среде Delphi приложения для АСУ, приведены некоторые наиболее интересные, по мнению автора, рекомендации и советы по решению тех или иных задач, возникающих в процессе создания программного обеспечения для систем промышленной автоматизации.
1. Основные этапы проектирования приложения для систем промышленной автоматизации Назад
Проанализировав стадии разработки программного обеспечения для систем промышленной автоматизации, можно выделить следующие основные этапы разработки приложения:
- создание каркаса приложения с одним окном;
- определение количества потоков;
- разработка классов;
- разработка окон и процедур тестирования;
- разработка алгоритма выдачи команд на объект управления;
- создание дополнительных потоков;
- детальная разработка главного окна приложения и дополнительных окон;
- разработка процедур инициализации приложения;
- разработка процедур доступа к базам данных;
- разработка процедур отображения информации.
Конечно, это деление на этапы условно, и для различных объектов управления и задач могут быть отличия.
Рассмотрим более детально последовательность разработки приложения.
Разработку приложения начинаем обычным образом. Создаем новый проект в Delphi с одним главным окном. Интерфейс главного окна на данном этапе можно детально не проектировать, а главное окно дополнить компонентами окон редактирования и компонентами кнопок, которые необходимы для тестирования приложения в процессе его разработки.
Далее определяемся с количеством потоков в приложении. Вариант однопоточного или многопоточного приложения определяет структуру создаваемых классов и приложения в целом, поэтому, с количеством потоков в приложении, необходимо определиться на начальном этапе.
В однопоточном варианте приложения частота опроса параметров в значительной мере будет зависеть от скорости отображения информации, и времени выполнения запросов к базам данных, так как опрос диагностируемых параметров, запросы к базам данных и отображение информации осуществляется в одном потоке. Поэтому, для обеспечения стабильной частоты опроса диагностируемых параметров и своевременной выдачи команд на объект управления, необходимо проектировать приложение минимум с двумя потоками.
В главном потоке осуществляется обработка сообщений Windows и запросов оператора. Во втором потоке (назовем его потоком опроса параметров) осуществляется непрерывный опрос параметров объекта управления, обработка полученной информации и выдача, при необходимости, управляющих воздействий на объект управления.
Для структурирования приложения и обеспечения c минимальными затратами дальнейшего его сопровождения при разработке применяем технологию объектно-ориентированного программирования. Проводим детальный анализ объекта управления на предмет выявления классов.
Классы, которые необходимо разработать, могут быть специфичные, применительно к данному объекту управления и более общие, которые можно использовать в большинстве приложений для систем промышленной автоматизации. Рассмотрим более детально процесс создания общих классов (назовем их ключевыми классами).
2. Разработка ключевых классов Назад
Ключевым объектом на оформление в виде класса является объект - диагностируемый параметр. Диагностируемые параметры присутствуют в каждой системе автоматического управления, поэтому разработку класса диагностируемого параметра необходимо провести особенно тщательно.
В общем случае диагностируемый параметр может быть дискретным или аналоговым. Далее, например, классификацию аналогового параметра можно продолжить. Аналоговым параметром может быть информация с датчиков вибрации, температуры, давления, которые отличаются методами вторичной обработки.
Все типы диагностируемых параметров имеют общие характеристики:
- обозначение параметра;
- описание параметра;
- адрес модуля ввода-вывода;
- номер канала модуля ввода-вывода;
- размещение датчика или исполнительного механизма.
Каждый тип диагностируемого параметра имеет специфичные свойства.
Например, аналоговый параметр имеет свойства, присущие только аналоговому параметру:
- масштабные коэффициенты;
- единицы измерений;
- максимальный и минимальный порог допустимых значений и пр.
Наличие различных типов диагностируемых параметров требует разработки иерархии классов диагностируемых параметров. Схематически иерархию классов диагностируемых параметров можно представить следующим образом (см. рисунок 1).
Рисунок 1 - Иерархия классов диагностируемых параметров
Базовый класс диагностируемого параметра с некоторыми упрощениями можно представить, например, следующим образом:
TParamClass = class
private
FNomer:word; // Номер параметра
FObSx:string; // Обозначение параметра на схеме FTDatch:string; // Тип датчика
FAdres:string; // Адрес модуля
FNKanal:integer; // Номер канала
FNaznach:string; // Назначение параметра
FRazmesh:string; // Размещение датчика
public
property Nomer:word read FNomer write FNomer;
property ObSx:string read FObSx write FObSx;
property TDatch:string read FTDatch write FTDatch;
property Adres:string read FAdres write FAdres;
property TModul:string read FTModul write FTModul;
property NKanal:integer read FNKanal write FNKanal;
property Naznach:string read FNaznach write FNaznach;
property FRazmesh:string read Frazmesh write Frazmesh;
end;
Для использования базового класса диагностируемого параметра в нескольких приложениях код базового класса расположим в отдельном модуле и добавим в проект. Файл модуля сохраним в отдельном каталоге.
Тогда, производный от базового класса диагностируемого параметра, класс аналогового параметра будет содержать характерные для аналогового параметра свойства и методы:
TAnalogParam = class(TParamClass)
private
FF:double; // Физическая величина
FA:double; // Коеффициент А при вычислении физической величины
FB:double; // Коеффициент В при вычислении физической величины
FIzm:TIzm; // Измеренное значение параметра
FFIFO:TFIFO; // Список измеренных значений, хранящихся в памяти
FEdIzm:string; // Единицы измерений
FCS:TRTLCriticalSection;
function GetF: double; // Процедура расчета физической величины параметра
public
property A:double read FA write FA;
property B:double read FB write FB;
property F:double read GetF;
property Izm:TIzm read FIzm write FIzm;
property FIFO:TFIFO read FFIFO write FFIFO;
property EdIzm:string read FEdIzm write FEdIzm;
constructor Create;
destructor Destroy; override;
procedure CalcF;
procedure EnterCrSect;
procedure LeaveCrSect;
end;
Как правило, в автоматизированных системах управления измеренные значения диагностируемых параметров должны храниться в оперативной памяти компьютера за определенный промежуток времени и постоянно обновляться. А при аварийной ситуации на объекте управления или по команде оператора, измеренные значения должны быть сохранены в файле с записью в файл дополнительной информации (количество зарегистрированных значений, период регистрации, дата и время записи и т.д.). Для решения поставленной задачи класс аналогового параметра содержит свойство FIFO типа TFIFO, где TFIFO - класс со всеми необходимыми свойствами и методами для обеспечения поставленных выше задач. Приведем упрощенное объявление класса TFIFO.
TFIFO = class
private
FArr:TArr; // Открытый массив TArr=array of TIzm;
FCount: word; // Емкость буфера
// Промежуток времени мкс, через который идет заполнение буфера
FPeriod: word;
FInd: word; // Текущая позиция
public
property Period: word read FPeriod write FPeriod;
property Count:word read FCouListIzm write FCouListIzm;
procedure Push(I:Tizm); // Процедура заполнения буфера;
procedure Get(I:Tizm); // Процедура извлечения данных из буфера;
// Процедура сохранения измеренных параметров из буфера в файл
// s-полный путь и имя файла
procedure SaveFIFO (S:string;T:TDateTime);
// Процедура чтения параметров из файла в буфер
// s-полный путь и имя файла
procedure LoadFIFO(S:string);
end;
Для каждого объекта аналогового параметра может потребоваться различная емкость и период заполнения буфера, поэтому в конструкторе класса TFIFO устанавливаем длину массива FАrr вызовом процедуры:
SetLength (FArr, Fcount)
Реализация методов класса TFIFO в общем тривиальна и ее приводить не будем.
В общем случае частота опроса аналоговых параметров может быть не стабильной, поэтому с каждым зарегистрированным значением должно храниться и время регистрации.
Это реализовано при помощи класса Tizm, содержащего поля со значением времени регистрации и зарегистрированное значение.
Обращения к методам и свойствам объектов типа TAnalogParam могут идти из главного потока и из потока опроса параметров. Например, для отображения аналогового параметра в графическом виде, в главном потоке вызываются некоторые методы и свойства (текущее значение, емкость буфера измеренных значений и т. д.) объекта аналогового параметра. В это же время до завершения процедуры отображения аналогового параметра, возможна модификация этих данных в потоке измерения, что может вызвать не корректную работу приложения.
Для исключения подобной ситуации необходима синхронизация потоков. Поскольку потоки находятся в пределах одного процесса, то логично ввести синхронизацию потоков с использованием критических секций, наиболее быстрый метод синхронизации [6].
Чтобы снизить время простоя потоков в связи с синхронизацией, необходимо применить не единичный объект критической секции, а для каждого объекта диагностируемого параметра свой объект критической секции.
Для реализации механизма синхронизации потоков при помощи критических секций в класс аналогового параметра введены поле FCS типа TRTLCriticalSection и методы EnterCrSect, LeaveCrSect.
Перед использованием критическую секцию необходимо инициализировать вызовом процедуры Win32 API InitializeCriticalSection(), а по завершении работы, удалить вызовом процедуры Win32 API DeleteCriticalSection(FCS). Лучшим местом для инициализации и удаления критической секции является конструктор и деструктор класса аналогового параметра.
constructor TAnalogParam.Create;
begin
// Код для создания включаемых объектов
// Например, буфер измеренных значений FIFO
InitializeCriticalSection(FCS); // Процедура Win32 API
end;
А в деструкторе удалим критическую секцию.
destructor TAnalogParam.destroy;
begin
DeleteCriticalSection(FCS); // Процедура Win32 API
// Код для разрушения включаемых объектов.
// Например, буфер измеренных значений FIFO
end;
Для удобства заключения участков кода в критические секции, в класс аналогового параметра введены два метода EnterCrSect, LeaveCrSect. Реализация методов класса TAnalogParam EnterCrSect, LeaveCrSect содержат по одной строке кода:
procedure TAnalogParam.EnterCrSect;
begin
EnterCriticalSection(FCS); // Процедура Win32 API
end;
procedure TAnalogParam.LeaveCrSect;
begin
LeaveCriticalSection(FCS); // Процедура Win32 API
end;
Участки кода, содержащие данные, которые могут быть модифицированы или использованы в другом потоке, заключаем в критические секции.
Например, в главном потоке приложения для представления параметра Pakt (активная мощность) в графическом виде, использованы данные, которые могут быть модифицированы в потоке опроса параметров (значение параметра, текущая позиция в буфере зарегистрированных значений и т. д.). Поэтому участок кода главного потока, использующий эти данные, заключен в критическую секцию.
Вот как это реализовано:
// Главный поток приложения
Pakt. EnterCrSect;
// Код использующий данные, которые могу быть
// модифицированы в потоке опроса параметров
Pakt. LeaveCrSect;
Участки кода методов класса аналогового параметра, модифицирующие свойства (физическая величина, текущая позиция в буфере зарегистрированных значений и т. д.) в потоке опроса параметров также заключаем в критические секции.
// Поток опроса параметров
procedure TAnalogParam.CalcF;
begin
EnterCrSect; //Метод класса
FF:=(fizm.I-b)*a;
LeaveCrSect; //Метод класса
end;
За один цикл опроса параметров в приложении может быть несколько обращений к значению физической величины конкретного аналогового параметра, поэтому для исключения многократного вызова метода CalcF в класс TanalogParam, введено поле FF, а метод CalcF вызывается один раз для каждого объекта аналогового параметра после цикла опроса.
Значения диагностируемых параметров в общем случае компьютер получает при помощи плат цифрового ввода-вывода, аналогово-цифровых преобразователей (АЦП), установленных в слоты шины ISA или PCI компьютера, или внешних устройств, которые ведут обмен данными с компьютером посредством различных интерфейсов (RS-232, RS-485, CAN, Ethernet и. т. д.).
Поэтому, следующим в списке ключевых объектов на выделение в отдельный класс, будет объект устройства ввода-вывода данных. Для различных типов устройств ввода-вывода данных (аналого-цифровые преобразователи, цифро-аналоговые преобразователи, цифровой ввод-вывод), создадим базовый класс - устройство ввода-вывода данных и производные классы для каждого типа устройства. В базовый класс включаем общие свойства для всех типов устройств и абстрактную процедуру опроса параметров.
TMod=class
private
FAdres:string; // Адрес модуля
FModul:string; // Тип модуля
FPort:integer; // Номер порта
FBaudRate:integer; // Скорость двоичной передачи
FChecksum:boolean; // Контрольная сумма Enable=True, Disable=False
fRazmesh:string; // Размещение модуля
FInd:TKan; // Массив индексов параметров
function GetInd(ind,mode: integer): integer;
procedure SetInd(ind,mode: integer; const Value: integer);
public
constructor Create;
property Adres:string read FAdres write FAdres;
property Modul:string read FModul write FModul;
property Port:integer read FPort write FPort;
property BaudRate:integer read FBaudRate write FBaudRate;
property Checksum:boolean read FChecksum write FChecksum;
property Razmesh:string read FRazmesh write FRazmesh;
property Ind[ind,Mode:integer]:integer read GetInd write setInd;
// Абстрактная процедура ввода - вывода данных
procedure IO; virtual; abstract;
end;
Назначение свойств и методов данного класса приведено в комментариях. Метод ввода-вывода IO сделан виртуальным и абстрактным.
Реализацию метода IO (ввода-вывода) выполняем в производных классах для конкретных типов модулей.
Класс объекта конкретного устройства (например, модуль АЦП) можно представить следующим образом:
TModAIn=class(Tmod)
public
procedure IO ; override;
end;
Как правило, устройства ввода-вывода поставляются с DLL библиотеками, которые включают высокоуровневые функции ввода-вывода данных.
Реализация процедуры ввода-вывода IO для внешнего модуля АЦП будет содержать вызов процедуры ввода-вывода из DLL, входящей в комплект поставки модуля.
procedure TModAIn. IO;
var
j:integer;
P: TPort;
begin
j:=port;
P:= ArrPort[j-1];
// Проверим соответствие параметров последовательного порта //требуемым параетрам модуля
if P.BaudRate <> BaudRate then
begin
P.closeCom;
P.BaudRate:=BaudRate;
P.OpenCom;
end;
// Если последовательный порт не проинициализирован
if not P.Open then
begin
P.BaudRate:=BaudRate;
P.OpenCom;
end;
//Вводим данные для опроса модуля
gw7000[0] :=j-1 ; // COM Port
gw7000[1] := StrToInt('$' + Adres); // Module Address
gw7000[2] := StrToInt('$' + Modul); // Module ID
if checksum then gw7000[3] := 1
else gw7000[3] := 0;
// Вызов процедуры ввода - вывода из DLL (входит в комплект поставки модуля).
wRet := AnalogIn8(@gw7000[0], @gf7000[0], gszSend, gszReceive);
If wRet <> 0 then
begin
//Код сообщения об ошибке опроса модуля
end;
// Процедура поиска аналоговых параметров принадлежащих
// этому модулю и присвоения новых значений параметрам
end;
В системах управления с внешними устройствами ввода-вывода, производящими обмен данными через последовательные порты, для обеспечения заданной частоты опроса параметров, может потребоваться опрос внешних модулей с нескольких последовательных портов параллельно.
Для таких систем разработаем еще один класс TPort, который содержит характеристики режима работы последовательного порта (скорость двоичной передачи, открыт/закрыт порт и другие) и методы (процедуры) инициализации и закрытия последовательного порта.
TPort=class
private
FNomer:integer; // Номер порта
FOpen:boolean;
FIzmConf:boolean; // Если менялась конфигурация то True
FBaudRate:integer;
public
property Nomer:integer read FNomer write FNomer;
property Open:boolean read FOpen write FOpen;
property IzmConf:boolean read FIzmConf write FIzmConf;
property BaudRate:integer read FBaudRate write FBaudRate;
procedure OpenCom; // Инициализация и открытие порта
procedure CloseCom; // Закрытие порта
end;
Для упрощения использования объекты последовательных портов помещаем в массив.
Созданные ключевые классы, которые можно с некоторой доработкой применить в большинстве программ для систем автоматизации, по возможности располагаем в отдельных модулях, добавляем в проект и сохраняем в отдельный каталог.
Далее разрабатываем специфичные классы, присущие конкретному объекту промышленной автоматизации. Разработка специфичных классов, по мнению автора, особого интереса не представляет. В эти классы включаем, ранее разработанные ключевые классы в качестве полей и свойств.
После реализации классов, или в процессе их разработки, необходимо протестировать методы классов. Особенно классы, методы которых содержат вызовы процедур обращения к аппаратной части. Это такие классы, как класс последовательного порта, классы устройств ввода-вывода, класс аналогового параметра.
3. Методы тестирования приложения и разработки алгоритма выдачи команд на объект управления Назад
Для тестирования целесообразно дополнить проект отдельным окном тестирования, которое содержит компоненты управления и отображения, обеспечивающие создание тестируемых объектов их инициализацию и взаимодействие. В начале процесса тестирования окно тестирования может быть очень упрощенным с несколькими кнопками (кнопка для создания определенного объекта, кнопка вызова методов объекта и кнопка разрушения объекта, и несколько окон редактирования). После успешного тестирования классов типа устройство ввода-вывода, порт, аналоговый параметр необходимо доработать окна тестирования до уровня, обеспечивающего прямые обращения к устройствам ввода-вывода. И эти окна оставить в окончательной версии проекта для поиска неисправности аппаратуры объекта управления.
Приведем пример такого окна тестирования для модуля ввода дискретных данных.
Когда та часть приложения, которая работает непосредственно с аппаратной частью, протестирована, можно вызовы процедур обращения к аппаратной части заменить вызовами процедур, которые имитируют величины контролируемых параметров. Эти процедуры (назовем процедуры-имитаторы) желательно разместить в отдельном модуле с названием UImit.
Создание процедур-имитаторов очень важный момент. Продуманные процедуры-имитаторы, позволят разработку остальной части приложения совместить с тестированием, не привлекая для этого датчиковую и преобразующую аппаратуру объекта управления.
Для отладки приложения АСУ со сложным алгоритмом управления и большим количеством параметров, возможно, потребуется применение следующей технологии отладки:
- создание математической модели объекта управления, размещаемой в отдельном приложении;
- организация обмена данными между приложением АСУ и приложением математической модели объекта управления с использованием СОМ-технологии (приложение математической модели - сервер автоматизации);
- отладка обмена данными между приложением АСУ и приложением математической модели объекта управления;
- перенос приложения математической модели объекта управления на другой компьютер;
- осуществление обмена данными между приложениями с использованием технологии DCOM;
- имитация различных нештатных ситуаций объекта управления, путем изменения параметров математической модели;
- отладка алгоритма путем анализа реакции приложения АСУ на симитированные нештатные ситуации.
Схематически это можно представить следующим образом (см. рисунок 3).
Создание математической модели объекта управления потребует не столь значительных затрат времени, так как для приложения математической модели объекта управления можно заимствовать модули с ранее разработанными классами для приложения АСУ.
Такая технология позволяет достаточно полно отлаживать приложения для объектов промышленной автоматизации без самого объекта управления.
Теоретические выкладки по технологиям COM и DCOM и процесс создания серверов и клиентов автоматизации детально описаны в [3].
Рисунок 3 - Структурная схема обмена данными между приложением АСУ и приложением математической модели
Алгоритм выдачи команд, как реакцию на изменения параметров и состояний объекта управления, лучше не описывать строками кода типа
If (q.L and w.L) then kom1.Y; ,
а разработать методы хранения алгоритма в базе данных, чтения алгоритма из базы данных и выполнения в приложении.
В общем, упрощенно алгоритм выдачи команд на объект управления можно представить следующим образом - для включения или выключения какого либо устройства необходим определенный набор включенных датчиков, определенный набор отключенных датчиков, а также определенный набор логических состояний объекта управления (например, шток пневмоцилиндра был в рабочем положении). Через требуемый промежуток времени после выдачи команд необходимо проверить срабатывание определенных датчиков, и если условие не выполнено, выполнить требуемые действия - аварийные сообщения, перевод АСУ в наладочный режим управления и т. д. И так повторяем для каждого устройства объекта управления.
Технология реализации, хранения алгоритма выдачи команд в базе данных, и реализации в приложении может быть следующей:
1. Создаем базу данных описания алгоритма выдачи команд, в которой:
- каждая запись в базе данных описания алгоритма - это определенный набор условий для подачи команд на включение или выключение какого либо устройства;
- каждое отдельное поле базы данных содержит определенный набор параметров, связанных по требуемому условию. Например, набор положительных параметров, объединенных по условию логического "и" (все включены) или объединенных по условию "или" (хотя бы один включен). Также в базе данных есть поля, содержащие списки подаваемых положительных и отрицательных команд.
2. Разрабатываем набор процедур и классов для выполнения следующих действий:
- чтение из базы данных алгоритма в оперативную память;
- после цикла опроса параметров проверка каждого набора условий для включения отдельных устройств;
- если какой- то набор условий выполняется - выдача команд для включения определенного устройства.
Например, окно ввода алгоритма в базу данных можно представить следующим образом:
1 - окно типа TDBEdit для ввода и редактирования описания набора логических условий;
2 - окно типа TDBEdit для ввода и редактирования положительных параметров, объединенных логическим "и";
3 - окно типа TDBEdit для ввода и редактирования выдаваемых положительных команд;
4 - компонент DBCtrlGrid для представления списка условий для включения отдельных устройств.
Такая технология имеет ряд преимуществ:
- можно корректировать алгоритм без перекомпиляции приложения, проводя только повторную инициализацию приложения;
- незначительную корректировку алгоритма может проводить не программист (технолог, наладчик КИП). В процессе отладки приложения в режиме реального времени необходимо выяснять причины неправильной подачи команд на включение определенных устройств, и здесь может оказать неоценимую помощь появление подсказок (Hint) для окон типа ТDBEdit (рисунок 4, поз.2, 3), содержащую:
- обозначение параметра;
- описание параметра;
- значение параметра.
Это можно выполнить следующим образом:
- на окно ввода алгоритма помещаем компонент Timer;
- интервал таймера устанавливаем 1 сек;
- таймер делаем доступным при активации окна ввода алгоритма;
- в обработчик таймера помещаем процедуру, присваивающую свойству Hint соответствующего DBEdit текст, который содержит обозначение, назначение и значение параметра.
procedure TFormLogika.TimerHintTimer(Sender: TObject);
var
s:string;
begin
// s- Текст окна редактирования определенного поля БД
// HintListDI(s) функция формирования текста подсказки
s:=EditListIliDa.Text;
EditListIliDa.Hint:=HintListDI(s);
// Код формирования подсказок для следующих окон
end;
HintListDI - следующая функция.
function HintListDI(s:string):string;
var
sl,ss:string;
ListP:TList;
dl,j:integer;
j1,cou:integer;
pd:TDParam;
Label
lab;
begin
sl:='';
dl:=length(s);
ListP:=TList.Create;
for j:=1 to dl do
begin
if s[j]='#' then goto lab;
if s[j]=',' then
begin
cou:=listParamD.Count-1;
for j1:=0 to cou do
begin
if (TDParam(ListParamD.ITEMS[j1]).ObSx=sl) then
begin
pd:=TDParam(ListParamD.ITEMS[j1]);
ListP.Add(pd);
end;
end;
sl:='';
end else sl:=sl+s[j];
end;
lab:
result:='';
cou:=ListP.Count-1;
if cou >= 0 then
for j:=0 to cou do
begin
pd:=TDParam(ListP.ITEMS[j]);
if pd.l then ss:=' = Вкл. ' else ss:=' = Откл. ';
result:=result+pd.ObSx+ss+' '+pd.Naznach+#13;
end;
end;
4. Создание потока опроса параметров Назад
Задача создания потока в Delphi в общем тривиальна и никаких сложностей не представляет. Для создания потока опроса проще использовать стандартный инструментарий создания потоков в Delphi с использованием класса Delphi Тhread, хорошо описанный в литературе [5]. Но некоторые сложности могут возникнуть по следующим причинам. Для непрерывного опроса параметров и выдачи управляющих воздействий на объект управления в методе Execute потока опроса необходимо сделать бесконечный цикл для опроса параметров, обработки характеристик и выдачи управляющих команд.
При этом необходимо решить следующие задачи:
- выход из непрерывного цикла опроса параметров;
- завершение потока при закрытии главного окна приложения;
- завершение опроса параметров без выхода из приложения;
- повторное создание потока опроса параметров.
Основная проблема - нельзя закрыть главное окно приложения пока не завершится поток опроса параметров.
Следующие три участка кода с детальными комментариями показывают, как решить комплекс поставленных задач.
Код создания потока опроса параметров, размещаемый в главном потоке приложения, имеет следующие строки:
if not FlagInterrog then
begin
if ThreadMain=nil then ThreadMain:=TThreadMain.Create(False);
ThreadMain.Priority:=tpHigher;
FlagInterrog:=true;
end;
Переменная FlagInterrog типа Boolean при инициализации приложения принимает значение false.
В процедуре Execute сделан непрерывный цикл опроса параметров, обработки характеристик и выдачи управляющих воздействий.
procedure TThreadMain.Execute;
var
begin
// При свойстве потока freeOnterminate:=true по завершению потока
// происходит освобождение ресурсов потока
freeOnterminate:=true;
while FlagInterrogation do
begin
// Процедуры опроса параметров
// Процедуры алгоритма управления
// Процедуры выдачи управляющих воздействий
end;
ThreadMain:=nil;
flThreadClose:=true;
end;
Процедура закрытия приложения, размещаемая в главном потоке приложения.
procedure ApplicationOnClose;
label lab;
begin
if not FlagInterrog then goto lab;
while (not flThreadClose) do
begin
// Ожидаем завершения потока опроса параметров
end;
FlagInterrog:=false;//;
lab:
//Сохраняем состояние приложения
SaveStateApplication;
end;
5. Выбор приоритета потока и класса приоритета приложения Назад
Когда ставятся жесткие требования к стабильности частоты опроса параметров, необходимо повысить приоритет потока опроса параметров. Это может вызвать некоторую задержку в отображении информации.
Вот как это можно выполнить:
ThreadMain.Priority:=tpHigher;
Когда выполняется только одно приложение, то изменение класса приоритета приложения влияния на скорость выполнения приложения не оказывает, но пользователь может открыть еще несколько приложений, что отрицательно может сказаться на скорости выполнения приложения АСУ. Для исключения подобной ситуации необходимо повысить класс приоритета приложения до High.
6. Разработка главного окна приложения и других окон Назад
Главное окно приложения должно в комплексе представлять состояние объекта управления. А по запросам оператора представлять необходимую детальную информацию. Иногда необходимо представление информации в виде графиков и одновременно отображение состояния диагностируемых узлов, агрегатов. Для экономии пространства окна можно поступить следующим образом.
На поверхность окна установить компонент Chart, поверх компонента Chart, установить компоненты Image, отображающие состояние контролируемых агрегатов. Мнемосхему всей установки можно загрузить в свойство Panel компонента Сhart. Это выполняется в следующей последовательности:
- вызвать панель редактирования свойств компонента Chart двойным щелчком;
- перейти на страницу Panel (смотри рисунок 5);
- нажать на кнопку "Browse:", вызвав диалог выбора графического файла для загрузки.
Для того чтобы фона картинок компонентов Image не было видно на графике, свойство Transparent компонента Image при помощи инспектора объектов устанавливаем в True.
Внешний вид главного окна приложения может сильно зависеть от типа объекта управления и аппаратной реализации автоматизированной системы управления. Например, если на рабочем месте оператора установлен классический персональный компьютер, то главное окно приложения целесообразно проектировать, придерживаясь стандартов Microsoft Windows. Это и расположение пунктов меню и строк состояния и. т. д.
При применении монитора с сенсорным экраном классический стиль приложения не подойдет, необходимо проектировать окна приложения с большими кнопками и возможно без строки меню. Один из вариантов следующий:
1) На главном окне располагаем компоненты Image для отображения состояния основных узлов системы.
2) В обработчики OnClik каждого компонента Image включаем строки кода для вызова окна детального отображения параметров объекта управления и перехода на страницу выбранного узла.
procedure TFormMainEkran.ImagePGSClick(Sender: TObject);
begin
// Переходим на страницу показа пневмогидросистеммы.
FormNalad.PageControl1.ActivePage:=FormNalad.TabSheetPGS;
// Показываем окно детального отображения параметров.
FormNalad.show;
end;
3) На страницах окна детального отображения параметров размещаем компоненты отображения состояния диагностируемых параметров и компоненты выдачи команд на выбранные оператором исполнительные механизмы (см. рисунок 6).
7. Разработка процедур инициализации приложения Назад
Для наладки и обслуживания объекта управления необходимо редактировать характеристики диагностируемых параметров. Например, номер канала параметра или масштабные коэффициенты. Поэтому логично разместить все характеристики диагностируемых параметров в базе данных, и тогда при инициализации, приложение открывает соответствующую базу данных и читает характеристики каждого диагностируемого параметра. Также в приложении необходимо предусмотреть доступ к базе данных параметров со стороны оператора. Например, таким образом (см. рисунок 7).
8. Разработка процедур доступа к базам данных Назад
В зависимости от объема сохраняемой информации, а также таких требований как возможность многопользовательского доступа, простота обслуживания и сопровождения создания архивных копий необходимо определиться с СУБД. Методика выбора СУБД достаточно хорошо описана в литературе, и на ней останавливаться не будем, а вот выбор метода доступа к базе представляет интерес. В данный момент наиболее целесообразно организовать доступ к базам данных через компоненты страницы ADO. Это позволит с минимальными изменениями в проекте сделать переход к другой более мощной базе данных [2].
Например, на начальном этапе разработки АСУ была применена СУБД Access, но потом в процессе развития системы потребовался многопользовательский доступ к базам данных, автоматическое создание WEB-страниц и. т. д., изменяя свойства только одного компонента TADOConnection, можно сделать переход к более мощной базе данных.
9. Разработка процедур отображения информации Назад
В большинстве систем управления требуется представление диагностируемых параметров в графическом виде.
Для этого лучше всего использовать компонент Сhart. В общем использование компонента Сhart не вызывает трудностей и достаточно полно описано в литературе [1].
Для отображения диагностируемого параметра в графическом виде в режиме реального времени, как на осциллографе, можно использовать следующий метод. Для этого применим компонент Timer со свойством Interval=200. В обработчик таймера Timer помещаем процедуру отображения выбранного диагностируемого параметра.
procedure TMainEkran.TimerMainTimer(Sender: TObject);
var
j:integer;
T:Tizm;
dat:TDateTime;
begin
VEUForm.SeriesP.Clear;
Pakt.EnterCriticalSection;
for j:=0 to Pakt .FIFO.Count-1 do
begin
T:=AP.Pakt.FIFO.get(j);
f:=T.f;
d:=T.d;
dat:=CalcDat(d);
VEUForm.SeriesP.Addxy(dat,f);
end;
Pakt.LeaveCrSect;
end;
Значения параметра Pakt модифицируются в потоке опроса параметров, а отображаются в главном потоке приложения, поэтому операторы, использующие данные, которые могут быть модифицированы, заключаем в критическую секцию при помощи методов класса TanalogParam EnterCriticalSection, LeaveCrSect.
10. Выводы Назад
Используя богатую палитру компонентов Delphi, можно с минимальными временными затратами создавать содержательный интерфейс, удовлетворяющий стандартам Microsoft, для приложений систем промышленной автоматизации.
Язык программирования Object Pasсal позволяет разработать легко сопровождаемые, эффективные и надежно функционирующие приложения для АСУ, работающие в режиме "не жесткого" реального времени в ОС Windows NT4, Windows 2000, Windows XP.
По мнению автора, имея собственные наработки и библиотеки, можно в среде Delphi так же быстро создавать качественные приложения для АСУ, как и в SCADA-системах (обзор SCADA-систем в [4]).
Литература Назад
1. Архангельский А.Я. Программирование в Delphi 6. - М.: Бином, 2001.
2. Федоров А., Елманова Н. ADO в Delphi: Пер. с англ. - СПб.: БХВ Петербург, 2002.
3. Калверт Чарльз. DELPHI 4. Энциклопедия пользователя. - Киев:Издательство "ДиаСофт", 1998.
4. Андрей Кузнецов. SCADA системы: программистом можешь ты не быть: Современные технологии автоматизации. - 1996. - © 1.
5. Ксавье Пачеко, Стив Тейксейра. Delphi 5 Руководство разработчика. - М.: Издательский дом "Вильямс", 2000.
6. Рихтер Дж. Windows для профессионалов: создание эффективных Win32-приложений с учетом специфики 64-разрядной версии Windows: Пер. с англ. - 4-е изд. - СПб:Питер;,М.:Издательско-торговый дом "Русская редакция", 2001.
7. Сергей Сорокин. Как много ОС РВ хороших: Современные технологии автоматизации. - 1997. - © 2.
|
|
|
Статьи данного автора в акции Borland:
|
Обсуждение |
9 сентября 2003 - 10:53 drweb извеняюсь... |
я просто на одном из конкурсов читал, что победитель есть, но его никто не оглашал. Поэтому и спрашивал. Но так как конкурс продлили, то вопрос снимается.... ;) |
6 сентября 2003 - 07:18 kulikovckiy Ответ drweb |
Я не член жюри на ITWARE и не имею ни какого поняитя когда будут подведены результаты конкурса. По поводу того, что в моей статье 6 рисунков, и как я их загрузил. Я просто позвонил в редакцию и попросил Олега Соболева вставить рисунки из, отправленной по электронке, статьи. За это спасибо Олегу Соболеву. Рисунки вставили через 3 дня. Но статья не отформатирована (можно подумать читая статью, что у меня нет понятия об отступах в коде), некоторые рисунки очень маленького размера. Всем кто хоче прочесть статью в оригинале, пишите, вышлю. |
5 сентября 2003 - 10:09 drweb уже известно имя победителя? |
сабж. |
5 сентября 2003 - 09:07 daddy |
Мне понравилось. Некоторые положения воспринял как откровения. Но хорошие статьи всегда оказываются слишком короткими! Очень хотелось бы глянуть на пример проекта. |
4 сентября 2003 - 15:15 admkb5 |
Очень интересная статья, узнал для себя много нового и полезного. Особенно понравились рекомендации по структуре классов и использованию потоков и баз данных. |
3 сентября 2003 - 13:34 _shox_ |
давно занимаюсь проблемами АСУ ТП, могу сказать, очень интересная статья, даже распечатал ее, что бывает в редких случаях. |
3 сентября 2003 - 10:04 yumoroz |
Весьма полезная статья. Наряду с полезностью для разработчиков АСУ она также может представлять интерес для преподавателей занимающихся подготовкой студентов в данной области. |
30 августа 2003 - 07:34 aeff А как понимать вот это? |
Как подметил Rollback, особенностью конкурса на itware есть то, что в статье позволено размещать только одну картинку и то в конце статьи, а я вижу 2 статьи, к которым это не относится. У нас, есть черные и белые люди? Предлагаю исключить из конкурса статьи, у которых больше одного рисунка. ИМХО это будет справедливо. |
30 августа 2003 - 01:34 sales ok |
Очень интересная статья. Особенно много полезной информации по структуре классов, синхронизации потоков. Интересно посмотреть как это реализовано на С++. |
28 августа 2003 - 10:40 elk142 |
Прочитал с интересом. Мой голос за Вас. Прошу информацию о конкретном применении. С наилучшими пожеланиями. Сергей Лось |
27 августа 2003 - 21:56 kulikovckiy Ответ Valera_t |
Уважаемый Валерий! Спасибо за то, что нашли время высказать свое мнение. По поводу Вашей категоричной и однозначной критики языков графического программирования я не согласен. Не все задачи можно решить эффективно при помощи С++ или Delphi. Например, при проведениии уникальных эксперементов со сложной математической обработкой результатов измерений вероятно лучше применить среду графического программирования LabVIEW, разработки фирмы National Instruments (www.natinst.com/labview), которая включает более сотни различных математических функций для обработки сигналов (спектральный анализ, фильтрацию и т. д.), различные виды графического представления информации и многое другое. |
22 августа 2003 - 17:40 analog |
Прозрачное видение задачи и свободное владение инструментарием ведет к прозрачному и хорошо структурированному изложению. Даже для специалиста, непосредственно и интенсивно не занимающегося программированием, статья может оказаться весьма интересной и полезной с точки зрения дальнейшей систематизации некоторых понятий и моментов в обширной теме автоматического управления и мониторинга. |
22 августа 2003 - 13:28 valera_t |
Очень приятно прочитать, что стремятся писать программы используя Delphi или C++. По своему опыту создание программ с помощью различных языков диаграмм - красиво, но большие программы стают такими запутанными, и приличные комментарии вставить негде. Причем заставляли в них писать, именно заставляли и выбора не оставляли люди которые далеки от программирования - мой заведующий кафедрой. Побольше таких статей - может он прочитает и передумает. Очень понравилась часть, связанная с отладкой ПО. Писать программы должны те кто их умеет писать, а учить создавать что ни будь с помощью диаграмм или им подобным - неблагодарное дело. |
21 августа 2003 - 14:45 mao |
Статья интересная. Я думаю Borland воспользуется наработками автора для создания компонентов для АСУ ТП. Для полноты впечатления хотелось бы ознакомится с проектом или реальной системой АСУ в которой реализованы наработки. |
21 августа 2003 - 10:37 plohoy Очень актуальная статья |
Действительно, в целом ряде случаев, создание систем промышленной автоматизации связано с реализацией алгоритмов управления объектами, функционирующими в режиме "не жесткого" реального времени. В этом случае использование богатых возможностей такого продукта как Borland DELPHI не полько возможно, но и вполне оправдано. Данная статья вносит вклад в восполнение недостатка методической литературы по данной проблеме. С уважением, Игорь Плохой, Atlantis Industrial Systems. |
16 августа 2003 - 22:08 kulikovckiy Ответ Pint |
Уважаемый Сергей. спасибо за высокую оценку моей статьи. По поводу реализаций моих проектов. Они вероятно будут опубликованы в ближайших номерах журнала П-КАД, издаваемого "Холит Дейта Системс" www.holit.com.ua |
14 августа 2003 - 10:09 baranikov 260370 |
Статья имеет большую практическую ценность имнно для промышленников, поскольку описывает конкретную реализацию методов и идей в производство, успешную их апробацию на практике. Практически представлен продукт высокого качества, готовый к внедрению в автоматизированные линии на производстве. |
13 августа 2003 - 08:54 pint |
Благодарю автора за статью, восполняющую недостаток литературы по методике программирования для систем промышленной автоматизации. Считаю, что приведение примеров реализованных проектов было бы очень полезным. С уважением, Сергей. |
12 августа 2003 - 12:47 avip |
Весьма интересная статья. Будет полезна для всех, кто занимается системами промышленной автоматизации и пытается создавать собственные программные системы. Мой голос! |
7 августа 2003 - 07:32 rollback |
Спасибо за статью. Вам мой голос. Рисунков, конечно, не хватает. Но таковы особенности добавление рисунков на данном сайте - один в конце. |
6 августа 2003 - 20:14 kulikovckiy |
Уважаемый Андрей! Благодарен Вам за то, что Вы с интересом прочитали мою статью, которая не по моей воле до сих пор не отформатирована и без рисунков. Внимательно и с интересом проанализирую все Ваши замечания. Относительно ╚┘диаграмм UML ┘╩- цель статьи, показать не средства сторонних производителей для быстрой разработки классов, а саму структуру классов, какие типы Object Pasсal применить в качестве полей класса и т. д.. |
5 августа 2003 - 19:23 macroflex слуяайно нажал кнопку "Добавить сообщение" |
... Интересно было бы посмотреть на пример проекта в диграммах вариантов использования, моделей классов и диаграмм состояний. Я вижу в персональной карточке, что автор знаком с C++, то в этом случае рекомендовал бы обратить внимание на Rational Rose как средство проектирования и генерации классов. Уж больно красиво IMHO подобные задачи туда ложаться. :) С наилучшми пожеланиями, Андрей Семак. |
5 августа 2003 - 19:17 macroflex Неплохо |
Хотел бы акцентировать внимание автора статьи на литературу по UML и утилиту ModelMaker компании ModelMakerTools (http://www.modelmakertools.com). Статья могла бы быть более интересной, если бы автор рассмотрел процесс проектирования своих автоматов с помощью диаграмм UML и проецирования методов в код Delphi с помощью ModelMaker. Интересно было бы посмотреть на пример проекта в диграммах вариантов использования и моделей |
|
|
|