Возникла необходимость работы с COM портом (RS232).
Для работы решил использовать библиотеку Synapse. Хорошая и быстрая библиотека. Модуль synaser.
Работать с портом довольно просто.
Основной класс для работы - TBlockSerial.
Для передачи команд я использую строку AnsiString. В ответ я так же жду строку. Мне кажется
такой способ передачи наиболее удобным.
const
recvtimeout=3000; // время ожидания ответа от устройства
var
ser: TBlockSerial;
s:AnsiString;
waiting:integer;
dtStart:TDateTime;
has_timed_out:boolean;
tempbuf, output:AnsiString;
begin
ser:= TBlockSerial.Create;
ser.RaiseExcept := True;
ser.LinuxLock := False; // это требуется для Linux. Если это не установить, то не удастся открыть порт.
ser.Connect('COM1'); // открытие порта
ser.Config(9600, 8, 'N', 0, false, false); // указываем параметры передачи данных
s:='AT'+#13; // это для примера
ser.SendBuffer(@s[1],Length(s)); // отправляем буфер в порт
s:='';
{Если размер ответа известен и устройство стабильно отвечает то все просто.}
sleep(200); // делаем небольшую задержку, так как устройство не сразу отвечает
waiting:=ser.WaitingData; // сохраняем в переменную сколько символов ждут в порту считывания
SetLength(s,waiting);
ser.RecvBuffer(@s[1], waiting);
// в строке s будет результат
{ У меня устройства могут отвечать долго и понемногу. Поэтому я несколько усложнил механизм опроса.
Я жду ответа от устройства. И если ничего не будет в течении recvtimeout миллисекунд,
то будем считать что весь ответ уже получен. Этот способ подойдет, когда вы не знаете
какой ответ вам может прийти.
}
output:='';
while 1=1 do begin
// начинаем ждать ответа
dtStart := Now;
has_timed_out:=false;
while ser.WaitingData=0 do begin
if MilliSecondsBetween(dtStart, Now) > recvtimeout then begin
has_timed_out:=true;
break;
end;
sleep(200);
end;
if has_timed_out then break; // выход. в буфере ничего нет
// считываем все из буфера порта
waiting:=ser.WaitingData;
SetLength(tempbuf, waiting);
try
ser.RecvBuffer(@tempbuf[1], waiting);
except
end;
output+=tempbuf;
end;
// в строке output результат
// а теперь получим результат, когда известно размер ответа
ser.RecvBufferEx(@s[1], waiting,500);
ser.CloseSocket; // закрытие порта
FreeAndNil(ser);
А как добавить эту библиотеку к проекту
ОтветитьУдалитьСпасибо.
ОтветитьУдалитьНужно жёлтым по белому писать, а то контраст глаз режет!
ОтветитьУдалитьНу а так спасибо! Разобрался!
ОтветитьУдалить