3.2 Описание языка программирования

Управляющая программа разработана на языке программирования высокого уровня Delphi 7 и предназначена для работы в операционных системах Windows 98, Windows 2000 и Windows XP.

Delphi — это среда быстрой разработки, в которой в качестве языка программирования используется язык Delphi. Язык Delphi — строго типизированный объектно-ориентированный язык, в основе которого лежит Object Pascal.

При написании программы использовались следующие типа данных: integer, real, string, boolean.

Язык Delphi поддерживает семь целых типов данных: shortint, smailint, Longint, Int64, Byte, word и Longword, описание которых приведено в таблице 4.

Object Pascal поддерживает и наиболее универсальный целый тип - Integer, который Эквивалентен Longint.

Таблица 4 – Целые типа данных

Тип

Диапазон

Формат

Shortint

-128-127

8 битов

Smallint

-32 768 - 32 767

16 битов

Longint

-2 147 483 648 - 2 147 483 647

32 бита

Int64

-263- 263 - 1

64 бита

Byte

0-255

8 битов, беззнаковый

Word

0-65 535

16 битов,

Longword

0 - 4 294 967 295

32 бита, беззнаковый

Язык Delphi поддерживает шесть вещественных типов: Reai48, single, Double, Extended. Типы различаются между собой диапазо-ном допустимых значений, количеством значащих цифр и количеством байтов, необходимых для хранения данных в памяти компьютера (таблица 5).

Таблица 5 – Вещественные типа данных

Тип

Диапазон

Real48

2.9x 10-39-1.7x1038

Single

1.5 x 10-45-3.4х 1038

Double

5.0x10-324 -1.7x10308

Extended

3.6x10-4951 -1.1 х104932

Язык Delphi поддерживает и наиболее универсальный вещественный тип - Real, который эквивалентен Double.

Язык Delphi поддерживает три строковых типа: shortstring, Longstring

- WideString:

- тип shortstring представляет собой статически размещаемые в памяти компьютера строки длиной от 0 до 255 символов;

- тип Longstring представляет собой динамически размещаемые в памяти строки, длина которых ограничена только объемом свободной памяти;

- тип WideString представляет собой динамически размещаемые в памяти строки, длина которых ограничена только объемом свободной памяти. Каждый символ строки типа WideString является Unicode-символом.

В языке Delphi для обозначения строкового типа допускается использование идентификатора string. Тип string эквивалентен типу shortstring.

Логическая величина может принимать одно из двух значений True (истина) или False (ложь). В языке Delphi логические величины относят к типу Boolean.

3.3 Описания управляющей программы

Для корректной работы программы необходимо задать диапазон изменения плотности рабочей жидкости ρ и необходимый расход Q . По умолчанию ρ присваиваются значения от 850 до 870. При установки неверных диапазонов программа будет предупреждать об ошибке.

Далее следует выбрать com-порт, к которому подключен внешний модуль ЦАП/АЦП и установить скорость порта.

Программа автоматической коррекции может работать в трех основных режимах:

- единичный расчет;

- запись результатов в файл;

- запись результатов в com-порт.

Рисунок 15 – Предупреждение о неверном указании диапазона исходных данных

Режим единичного расчета позволяет в ручную ввести значение плотности и получить посчитанную величину управляющего напряжения U. Для наглядности исходные и полученные данные отображаются на графике.

Рисунок 16– Программа автоматической коррекции в режиме единичного расчета

В режиме записи результатов в файл происходит опрос com-порта и расчет управляющего воздействия. В поле «Периодичность опроса» задается частота опроса com-порта. Полученные данные в лог-файл. По умолчанию файл создается в корневом каталоге диска C с именем result.txt. Данные имеют табличную форму и могут в дальнейшем использоваться для статистических исследований.

Рисунок 17 – Лог-файл

Режим записи результатов в com-порт аналогичен режиму записи результатов в файл за исключением того, что программа полученные данные записывает в com-порт. В данном режиме так же можно установить периодичность опроса.

В режимах записи результата в файл и в com-порт для наглядности строиться временная диаграмма, на которой показывается текущая плотность и соответствующее ей напряжение.

Рисунок 18 – Программа автоматической коррекции в режиме записи результата в файл

Рисунок 18 – Временная диаграмма

3.4 Листинг программы

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, ExtCtrls, StdCtrls, uRS232;

type

TForm1 = class(TForm)

Label1: TLabel;

Edit2: TEdit;

Label4: TLabel;

Label5: TLabel;

Edit3: TEdit;

Edit4: TEdit;

Label6: TLabel;

GroupBox1: TGroupBox;

GroupBox2: TGroupBox;

RadioGroup1: TRadioGroup;

Edit5: TEdit;

Label7: TLabel;

Button1: TButton;

Label8: TLabel;

Edit6: TEdit;

Image1: TImage;

Label9: TLabel;

ComboBox1: TComboBox;

Label10: TLabel;

ComboBox2: TComboBox;

GroupBox3: TGroupBox;

Button2: TButton;

Label11: TLabel;

Edit7: TEdit;

Label12: TLabel;

Image2: TImage;

Timer1: TTimer;

emu: TCheckBox;

Label2: TLabel;

function proverka():boolean;

procedure graphik1;

function Napryajenie(p:real):real;

procedure Button1Click(Sender: TObject);

procedure RadioGroup1Click(Sender: TObject);

procedure Button2Click(Sender: TObject);

procedure Timer1Timer(Sender: TObject);

procedure emuClick(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

const Kqp=5;

Kuq=0.04;

var

Form1: TForm1;

x, Pred_y, Nov_y: integer;

f: textfile;

comport: trs232;

implementation

{$R *.dfm}

function TForm1.proverka():boolean;

var a: integer;

b: boolean;

begin

//Проверка введенных данных на корректность

b:=false;

try

a:=StrToInt(edit2.text);

except

on EConvertError do

begin

b:=true;

edit2.setfocus;

end;

end;

try

a:=StrToInt(edit3.text);

except

on EConvertError do

begin

b:=true;

edit3.setfocus;

end;

end;

try

a:=StrToInt(edit4.text);

except

on EConvertError do

begin

b:=true;

edit4.setfocus;

end;

end;

if b then

begin

showmessage('Ошибка в исходных данных');

end;

proverka:=b;

end;

procedure TForm1.graphik1;

var x0,y0,x,y: integer;

nap: real;

begin

//Рисование графика при единичном расчете

x0:=60;

y0:=40;

Image1.Canvas.Brush.Color:=clBtnFace;

Image1.Canvas.FillRect(rect(0,0,image1.Width,image1.Height));

image1.Canvas.Font.Size:=10;

image1.Canvas.Font.Color:=clBlack;

image1.Canvas.Font.Style:=[];

image1.Canvas.Pen.Color:=clBlack;

image1.Canvas.Pen.Style:=psSolid;

//оси

image1.Canvas.Pen.Width:=3;

image1.Canvas.MoveTo(x0,10);

image1.Canvas.LineTo(x0,image1.Height-y0);

image1.Canvas.LineTo(image1.Width-10,image1.Height-y0);

//график

image1.Canvas.Pen.Width:=1;

image1.Canvas.Pen.Style:=psDash;

image1.Canvas.MoveTo(x0,50);

image1.Canvas.LineTo(x0+40,50);

image1.Canvas.LineTo(x0+40,image1.Height-y0);

image1.Canvas.MoveTo(x0,image1.Height-y0-40);

image1.Canvas.LineTo(image1.Width-50,image1.Height-y0-40);

image1.Canvas.LineTo(image1.Width-50,image1.Height-y0);

image1.Canvas.Pen.Width:=2;

image1.Canvas.Pen.Color:=clBlue;

image1.Canvas.MoveTo(x0+40,50);

image1.Canvas.LineTo(image1.Width-50,image1.Height-y0-40);

//надписи

image1.Canvas.TextOut(x0-24,10,'U,B');

image1.Canvas.TextOut(image1.Height-10,image1.Height-15,'плотность,кг/м3');

nap:=Napryajenie(StrToInt(edit4.Text));

image1.Canvas.TextOut(x0-image1.Canvas.TextWidth(FloatToStr(nap))-5,image1.Height-y0-40-5,FloatToStr(nap));

nap:=Napryajenie(StrToInt(edit3.Text));

image1.Canvas.TextOut(x0-image1.Canvas.TextWidth(FloatToStr(nap))-5,45,FloatToStr(nap));

image1.Canvas.TextOut(x0+40-10,image1.Height-y0+5,edit3.Text);

image1.Canvas.TextOut(image1.Width-50-10,image1.Height-y0+5,edit4.Text);

//наша точка

x:=x0+40+round((image1.Width-50-x0-40)*(StrToInt(edit5.Text)-StrToInt(edit3.Text))/(StrToInt(edit4.Text)-StrToInt(edit3.Text)));

y:=50+Round((image1.Height-y0-40-50)*(StrToFloat(edit5.Text)-StrToInt(edit3.Text))/(StrToInt(edit4.Text)-StrToInt(edit3.Text)));

image1.Canvas.Pen.Color:=clRed;

image1.Canvas.Ellipse(x-3,y-3,x+3,y+3);

image1.Canvas.Pen.Width:=1;

image1.Canvas.Pen.Style:=psDot;

image1.Canvas.MoveTo(x,image1.Height-y0);

image1.Canvas.LineTo(x,y);

image1.Canvas.LineTo(x0,y);

image1.Canvas.Font.Color:=clRed;

image1.Canvas.TextOut(x-10,image1.Height-y0+5,edit5.Text);

image1.Canvas.TextOut(x0-image1.Canvas.TextWidth(edit6.Text)-5,y-5,edit6.Text);

end;

function TForm1.Napryajenie(p:real):real;

var p1, p2, Qz: integer;

begin

//Функция расчета напряжения по значению плотности

p1:=StrToInt(edit3.Text);

p2:=StrToInt(edit4.Text);

Qz:=StrToInt(edit2.Text);

if (p2<=p1) then

begin

ShowMessage('Неверно указан диапазон');

napryajenie:=0;

end

else

if (p>p2) or (p<p1) then

begin

ShowMessage('Значение не в диапазоне');

napryajenie:=0;

end

else

Napryajenie:=(Qz-p*Kqp/1000000)*Kuq;

end;

procedure TForm1.Button1Click(Sender: TObject);

var d: real;

begin

//Единичный расчет

if proverka then

begin

exit; //Если введены неверные данные, то завершаем процедуру

end;

try

d:=StrToFloat(edit5.text);

except

on EConvertError do

begin

edit5.setfocus;

exit;

end;

end;

Edit6.text:=FloatToStr(Napryajenie(StrToFloat(edit5.Text)));

if edit6.Text<>'0' then graphik1;

end;

procedure TForm1.RadioGroup1Click(Sender: TObject);

begin

//Переключение между режимами расчета

if RadioGroup1.ItemIndex=0 then

begin

GroupBox2.Visible:=true; //единичный расчет

GroupBox3.Visible:=false;

end else

if RadioGroup1.ItemIndex=1 then

begin

GroupBox2.Visible:=false; //запись результатов в файл

GroupBox3.Visible:=true;

end else

if RadioGroup1.ItemIndex=2 then

begin

GroupBox2.Visible:=false; // запись результатов в com-порт

GroupBox3.Visible:=true;

end;

end;

procedure TForm1.Button2Click(Sender: TObject);

begin

//Старт/остановка непрерывного значения

if proverka then

begin

exit;

end;

if Button2.Caption='Старт' then

begin

button2.Caption:='Стоп';

//Рисуем сетку для графика

Image2.Canvas.Brush.Color:=clBtnFace;

Image2.Canvas.FillRect(rect(0,0,image2.Width,image2.Height));

Image2.Canvas.Pen.Width:=2;

image2.Canvas.Pen.Color:=clBlack;

image2.Canvas.TextOut(5,215,edit3.Text);

image2.Canvas.TextOut(5,15,edit4.Text);

image2.Canvas.TextOut(35,0,'плотность');

image2.Canvas.TextOut(270,237,'время');

Image2.Canvas.MoveTo(27,220);

image2.Canvas.LineTo(33,220);

Image2.Canvas.MoveTo(27,20);

image2.Canvas.LineTo(33,20);

Image2.Canvas.Pen.Width:=3;

Image2.Canvas.MoveTo(30,235);

image2.Canvas.LineTo(313,235);

Image2.Canvas.MoveTo(30,0);

image2.Canvas.LineTo(30,250);

pred_y:=860; //

x:=35;

image2.Canvas.Pen.Color:=clBlue;

if RadioGroup1.ItemIndex=1 then

begin

//готовим файл для вывода результатов замера

AssignFile(f,'c:\result.txt');

if FileExists('c:\result.txt') then Append(f) else Rewrite(f);

end else

begin

//готовим com-порт для чтения данных

comport:=TRS232.Create(Form1);

case combobox1.ItemIndex of

0: comport.ComPort:=pnCom1;

1: comport.ComPort:=PnCom2;

2: comport.ComPort:=pnCom3;

3: comport.ComPort:=PnCom4;

end;

Case ComboBox2.ItemIndex of

0: comport.ComPortSpeed:=br110;

1: comport.ComPortSpeed:=br300;

2: comport.ComPortSpeed:=br600;

3: comport.ComPortSpeed:=br1200;

4: comport.ComPortSpeed:=br2400;

5: comport.ComPortSpeed:=br4800;

6: comport.ComPortSpeed:=br9600;

7: comport.ComPortSpeed:=br14400;

8: comport.ComPortSpeed:=br19200;

9: comport.ComPortSpeed:=br38400;

10: comport.ComPortSpeed:=br56000;

11: comport.ComPortSpeed:=br57600;

12: comport.ComPortSpeed:=br115200;

end;

comport.Connect;

end;

timer1.Interval:=StrToInt(edit7.Text);

timer1.Enabled:=true;

end else

begin

//Остановка замера

button2.Caption:='Старт';

timer1.Enabled:=false;

if RadioGroup1.ItemIndex=1 then

begin

CloseFile(f);

end;

end;

end;

procedure TForm1.Timer1Timer(Sender: TObject);

var s: string;

koord_y: integer;

napr: real;

begin

//При срабатывании счетчика

//Считываем показания датчика

if emu.Checked then Nov_y:=Pred_y+Round(Random(3)-1)

else

begin

if comport.ReadString(s,3) then Nov_Y:=StrToInt(s)

else

begin

ShowMessage('Не могу прочитать данные с com-порта');

timer1.Enabled:=false;

button2.OnClick(sender);

exit;

end;

end;

if nov_y>StrToInt(edit4.Text) then nov_y:=StrToInt(edit4.Text);

if nov_y<StrToInt(edit3.Text) then nov_y:=StrToInt(edit3.Text);

Image2.Canvas.Brush.Color:=clBtnFace;

Image2.Canvas.FillRect(rect(x+2,18,x+7,230));

koord_y:=20+round(200*(Pred_y-StrToInt(edit4.Text))/(StrToInt(edit3.Text)-StrToInt(edit4.Text)));

image2.Canvas.MoveTo(x,koord_y);

x:=x+5;

koord_y:=20+round(200*(nov_y-StrToInt(edit4.Text))/(StrToInt(edit3.Text)-StrToInt(edit4.Text)));

image2.Canvas.LineTo(x,koord_y);

pred_y:=nov_y;

image2.Canvas.TextOut(35,0,'плотность='+IntToStr(nov_y));

if x=310 then

begin

x:=35;

Image2.Canvas.FillRect(rect(x-1,18,x+7,230));

end;

//Считаем значение напряжения;

napr:=Napryajenie(nov_y);

image2.Canvas.TextOut(150,0,'Напряжение='+FloatToStr(napr));

//Третий этап

if RadioGroup1.ItemIndex=1 then

begin

//Пишем результаты расчета в файл

writeln(f,DateTimeToStr(Now)+' '+IntToStr(Nov_Y)+' '+FloatToStr(napr));

end else

begin

//Пишем результат расчета в com порт

if not emu.Checked then

comport.SendString(FloatToStr(Napr));

end;

end;

procedure TForm1.emuClick(Sender: TObject);

begin

//Включение режима эмуляции com-порта

comboBox1.Enabled:=not emu.Checked;

comboBox2.Enabled:=not emu.Checked;

end;

end.

4 ВОЗМОЖНОСТИ ПРАКТИЧЕСКОГО ПРИМЕНЕНИЯ

Программное обеспечение системы автоматической коррекции скорости (САК) может применяться на большом количестве станков с ЧПУ (CNC). Необходимость применения данной программы обусловлена высокими требованиями, предъявляемыми к точности изготовления деталей.

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

Соседние файлы в папке Диплом - Сергей