Com port перезапуск

SergioSV
Дата: 24.05.2011 15:53:01
Существует некоторая программа обчитывающая приборы по средствам преобразователя RS485->COM порт. Так вот по непонятным причинам порт иногда подвисает и начинает работать только после перезапуска приложения хотя работа с портом вынесена в отдельный поток, который я в основном приложении пытался пересоздать.
  TAPIComPort = class(TThread)
  private
    Port: THandle;
    Status: Boolean;

  protected
    procedure Execute; override;
  public
    FComNo: string;
    FBaudRate: integer;
    FerrPort: Boolean;
    constructor Create;
    function Open(AComNo: string; ABaudRate: integer): Boolean;
    procedure Read(Var buf: TArrayByte; var Count: Cardinal);
    procedure Write(TRBuf: PAnsiChar; Count: integer);
    Function Close(): Boolean;
    destructor Destroy;
  end;


// если завис
  port.Terminate;
  FreeAndNil(port); // на всякий случай
  Sleep(100);
  port := TAPIComPort.Create;
  if port.Open(cComNom, cBuadRate) then
  begin
  ....
Так вот смоделировать ситуацию при которой порт не открылся бы заново у меня не получается (т.е. даже при отключении преобразователя и пропадании порта из системы всё корректно отрабатывает и при его появлении все процессы востанавливаются автоматически)
На производстве же
port.Open(cComNom, cBuadRate)
отрабатывать отказывается. И всё начинает работать после полного перезапуска модуля.


function TAPIComPort.Open(AComNo: string; ABaudRate: integer): Boolean;
Var
  DCB: TDCB; // структура, содержащая настройки порта
  CommTimeouts: TCommTimeouts;
begin
  FComNo := AComNo;
  FBaudRate := ABaudRate;
  Port := CreateFile(PWideChar('\\.\COM' + AComNo), // открываем первый порт
    GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if (Port = INVALID_HANDLE_VALUE) // если порт не окрылся
  then
  begin
    result := False; // то выводим сообщение об ошибке
    Exit;
  end
  else
    result := True; // Если порт открылся, то пишем что открылся
  Windows.SetupComm(Port, 1024, 1024);
  Status := not result;
  GetCommState(Port, DCB);
  // что бы не заполнять всю структуру самим, сначал считываем ее, потом поменяем нужные поля
  DCB.BaudRate := ABaudRate; // скорость обмена
  DCB.Parity := NoParity; // нет контроля четности
  DCB.ByteSize := 8; // байт из восьми бит
  DCB.StopBits := ONESTOPBIT; // один стоповый бит
  SetCommState(Port, DCB);
  // записываем измененную структуру, для открытого порта

  GetCommTimeouts(Port, CommTimeouts);

  CommTimeouts.ReadTotalTimeoutConstant := 50;
  CommTimeouts.ReadIntervalTimeout := 50;
  CommTimeouts.ReadTotalTimeoutMultiplier := 1;
  CommTimeouts.WriteTotalTimeoutMultiplier := 0;
  CommTimeouts.WriteTotalTimeoutConstant := 10;
  // операции записи не используется.
  SetCommTimeouts(Port, CommTimeouts); // записываем измененную структуру
  FerrPort := not result;
end;

Может у кого есть соображения по поводу, желательно без перезапуска приложения самого из себя?
Мимопроходящий
Дата: 24.05.2011 15:58:42

Hello, SergioSV!
You wrote on 24 мая 2011 г. 12:53:01:

SergioSV
> Может у кого есть соображения по поводу, желательно
без перезапуска приложения самого из себя?

используй нормальные компоненты.
AsyncFree, или AsyncPro.
они запускают собственный служебный поток.
и ничего мудрить не нужно.

а разбирать твой код - лень.

--
With best regards, Мимопроходящий.

Posted via ActualForum NNTP Server 1.4

SergioSV
Дата: 24.05.2011 16:03:06
Мимопроходящий,

Пользовался я AsyncPro они просто выдавали сообщение что то вроде error purge port! и валили модуль наглухо. Даже из диспетчера задач не снимешь.
Мимопроходящий
Дата: 24.05.2011 16:05:47

Hello, SergioSV!
You wrote on 24 мая 2011 г. 13:03:06:

SergioSV
> Пользовался я AsyncPro они просто выдавали сообщение
что то вроде error purge port! и валили модуль наглухо.
Даже из диспетчера задач не снимешь.
не должно такого быть.
скорее всего, железяка битая.

--
With best regards, Мимопроходящий.

Posted via ActualForum NNTP Server 1.4

SergioSV
Дата: 24.05.2011 16:12:06
Мимопроходящий,
Железяки дешёвые, но рабочие. Меняли тасовали местами, на линиях RS485 много помех они как то и валят (только вот понять как я не могу). В общей сложности таких модулей (программ чтения(одинаковых)) работает штук 16. Одни работают по месяцу и ничего, некоторые же и 2х-5и часов не выдерживают и виснут. Компы с чистыми операционками все обновления и т.п. доступ ограничен.
defecator
Дата: 24.05.2011 16:15:28
Если переходник RS485-COM-USB сделан на базе чипа FTDI, то такая ситуация лечится переустановкой драйвера, в том числе на свежую версию с сайта разработчика.
Если на чипах CP1201/CP1204 - то лечится полным удалением дров (вместе с файлами) и переустановкой.

В старых версиях дров VCP от FTDI была бага, когда софтовое закрытие порта реально его не закрывала, и последующее открытие уже порт не открывала, так как считала, что порт открыт.

Сделай примитивную программу:
1. Открыть порт
2. Погонять данные
3. Закрыть порт

И так несколько раз. Если в какой-то момент порт не откроется, то вставить задержку на закрытие.
defecator
Дата: 24.05.2011 16:16:24
SergioSV
Мимопроходящий,
Железяки дешёвые, но рабочие. Меняли тасовали местами, на линиях RS485 много помех они как то и валят (только вот понять как я не могу). В общей сложности таких модулей (программ чтения(одинаковых)) работает штук 16. Одни работают по месяцу и ничего, некоторые же и 2х-5и часов не выдерживают и виснут. Компы с чистыми операционками все обновления и т.п. доступ ограничен.


А гальваническая развязка присутствует ? Если не присутствует - пробуй сделать нормальное заземление
defecator
Дата: 24.05.2011 16:16:59
defecator
SergioSV
Мимопроходящий,
Железяки дешёвые, но рабочие. Меняли тасовали местами, на линиях RS485 много помех они как то и валят (только вот понять как я не могу). В общей сложности таких модулей (программ чтения(одинаковых)) работает штук 16. Одни работают по месяцу и ничего, некоторые же и 2х-5и часов не выдерживают и виснут. Компы с чистыми операционками все обновления и т.п. доступ ограничен.


А гальваническая развязка присутствует ? Если не присутствует - пробуй сделать нормальное заземление


Ну и, конечно, проверить, чтобы были шунтирующие резисторы на концах линии (100 ом, кажись)
Мимопроходящий
Дата: 24.05.2011 16:20:11

Hello, defecator!
You wrote on 24 мая 2011 г. 13:16:24:

defecator
> А гальваническая развязка присутствует ? Если не
присутствует - пробуй сделать нормальное заземление

не факт что заземление поможет.
мы использовали оптронную развязку-переходник 485<-->232.

--
With best regards, Мимопроходящий.

Posted via ActualForum NNTP Server 1.4

SergioSV
Дата: 24.05.2011 16:21:49
defecator,

Всё есть и земля и сопротивления. Вот только качество кабеля х.. и прокладка по таким местам где проводов в том числе и высоковольтных необъятные жгуты. А за драйвера спасибо ща разберу посмотрю что за чипы попробую.