Это оборудование хорошо работает с поставляемым ПО, но нам надо автоматизировать процесс обработки данных исходя из наших интересов. Решили реализовывать ПО на Delphi. Для начала сделал простую форму с четырьмя кнопками и простой системой отображения снятых данных.
Вот что получилось:
Код: Выделить всё
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Buttons, COMPORT, StdCtrls, ComCtrls;
type
TForm1 = class(TForm)
ButtonThreadOpen: TButton; (*кнопка для запуска потока обращения к RS232 *)
ButtonThreadStop: TButton; (*здесь пытаемся отображазить считанные с RS232 данные*)
ButtonClearLabel: TButton;(*кнопка для очищения метки,чтобы не мешала *)
ButtonCOM232: TButton;
ListBox1: TListBox; (*кнопка для инициализации порта*)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure ButtonThreadOpenClick(Sender: TObject);
procedure ButtonThreadStopClick(Sender: TObject);
procedure ButtonClearLabelClick(Sender: TObject);
procedure ButtonCOM232Click(Sender: TObject);
private
public
end;
TMy = class(TThread) (*класс для потока, в котором мы обращаемся к порту*)
protected
published
constructor create;
procedure Execute;override;(* здесь мы и обращаемся *)
procedure writemes;(*здесь пишем результат обращения в Label1 из Mess*)
public
Mess:string;(*перевоначально результат обращения записывается сюда*)
end;
var
Form1: TForm1;
Port1:TCOMPort;
My:TMy;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var i:integer;
begin (* при создании формы создаём класс Хотел так сделать *)
(*но если оборудование отключено, то программа не запускается *)
// Port1:=TComPort.create; (* для работы с портом *)
// Port1.LoadFromFile(False);(* из файла инициализации*)
(* ничего не грузим *)
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Port1.destroy; (*при прекращении работы программы *)
(* удаляем класс, отвечающий за работу порта *)
end;
procedure TForm1.ButtonThreadOpenClick(Sender: TObject);
begin (*по нажатию этой кнопки запускаем поток для считывания данных с RS232*)
My:=TMy.create;
end;
procedure TForm1.ButtonThreadStopClick(Sender: TObject);
begin (*при нажатии на эту кнопку прекращаем работу потока *)
My.Terminate;(*прекращаем обращаться к порту, иными словами*)
end;
procedure TForm1.ButtonClearLabelClick(Sender: TObject);
var k:integer;
begin (*если считывание происходит с ошибками, а так оно и происходит*)
ListBox1.Items.Clear;
end;
procedure TForm1.ButtonCOM232Click(Sender: TObject);
var i:integer;
begin (*класс инициирован, теперь надо *)
Port1:=TComPort.create; (* для работы с портом *)
Port1.LoadFromFile(False);(* из файла инициализации*)
(* ничего не грузим *)
i:=Port1.SetPort; (* установить режим RS232 *)
end;
constructor TMy.create;
begin
inherited Create(True); // вызываем родительский класс
FreeOnTerminate := True; // при завершении потока освобождаем память
Self.Priority := tpHighest;// приоритет наивысший (данные всё-таки)
resume; // запускаем поток
end;
procedure TMy.writemes;
begin (* вызывается строго из Synchronize(writemes) *)
Form1.ListBox1.Items.Add(Mess)
end;
procedure TMy.Execute;
var count1:DWord; (*количестов записанный/считанных байт*)
fact:byte; (*здесь будут отображаться ошибка считывания порта*)
s:string;(*используем для буфера считывания на всякий случай*)
i:integer;
Wr:array[0..100] of byte; (*сюда/отсюда читаем/пишем*)
begin
while not terminated do (*если поток не завершён то*)
begin
count1:=3; (* 0 посылаем в порт три байта инициализации (пытался и не посылать)*)
Wr[0]:=35; Wr[1]:=115; Wr[2]:=13; fact:=Port1.WriteBuf(Wr,count1);
count1:=4; (* 1 запрашиваем координаты ЛИРы с адресом 1*)
Wr[0]:=35; Wr[1]:=01; Wr[2]:=111; Wr[3]:=13;
fact:=Port1.WriteBuf(Wr,count1); (* запрашиваем *)
sleep(150); (* 2 ждём немного 50-100 мс*)
Count1:=100; (*считываем 100 байт (сколько укажем при инициализации)*)
fact:=Port1.ReadBuf(Wr,Count1); (* 3 собственно читаем *)
s:='';(*ну и разбираем то, что у нас получилось*)
for i:=0 to Count1 do s:=s+chr(Wr[i]);
if fact=0 then Mess:=s;
if fact=1 then Mess:='в буфере нет данных'; (*это и получается*)
if fact=2 then Mess:='порт закрыт';
if fact=3 then Mess:='ошибка при чтении';
Synchronize(writemes); (*заполняем Label1 отсюда*)
sleep(700); (*ждём секунду*)
end;
end;
end.
Например, если датчики начинали отсчёт с >-1, то после "работы" и принятия стержнями исходного состояния получаем >-11
Это значит, что получаемые в программе другие цифры тоже "битые".
Но поставляемое ПО всё отображает правильно! Значит, где-то в моей программе имеется ошибка.
Не могли бы подсказать, где? Простенькую программу и результат её работы добавил во вложения.