Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
0 / 0 / 0
Регистрация: 06.02.2019
Сообщений: 57
1
Delphi 6-7

Как сбросить повисший ComPort?

24.02.2019, 17:28. Показов 2058. Ответов 16

Author24 — интернет-сервис помощи студентам
Здравствуйте дорогие Форумчане.

Возникла задача, реализовать автоопределение подключаемых COM-устройств, а так же их отключение. и Возможно переподключение в другой порт. Чтоб программа определяла тип устройства и знала что с ним делать. Есть устройство - работаем, нет устройства - ждём.
В качестве устройств выступают "ардуины".
Язык Delfi7,
Библиотека CPort.

С подключением и определением вроде проблем не должно возникнуть.
А вот с отключением проблема! Дело в том, что если в программе COM порт открыт и в этот момент физически отключить устройство, то порт повисает, и его ни открыть, ни закрыть, ни пересоздать невозможно. На всё выдаёт ошибку. И при повторном включении в тот же порт, порт уже не работает. В программе он открыт, а в системе он свободен и доступен для подключения.
Основная проблема, что порт виртуальный и при отключении устройства он уничтожается в системе, а при подключении создаётся заново.
Я предполагаю, что ситуация абсолютно тупиковая, но может кто знает хитрости какие?


Вот тестовая программка, для теста понадобится любое устройство которое создаёт виртуальный ком порт. Лучше "ардуина", любая, прошивка не важна.

Для читабильности и простоты выкинул всё лишнее, оставил только чтоб отключение проверить можно было.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, CPort, ExtCtrls;
 
type
  TForm1 = class(TForm)
    BtnOn: TButton;
    BtnOff: TButton;
    Timer1: TTimer;
    Label1: TLabel;
    ComPort1: TComPort;
    ReCreate: TButton;
    Edit1: TEdit;
    procedure BtnOnClick(Sender: TObject);
    procedure BtnOffClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure ReCreateClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
procedure TForm1.BtnOnClick(Sender: TObject);
begin
  Try
    ComPort1.Port:=Edit1.Text;
    ComPort1.Open;
  Except
    IOResult;
    beep;
  end;
end;
 
procedure TForm1.BtnOffClick(Sender: TObject);
begin
  Try
    ComPort1.Close;
  Except
    IOResult;
    Beep;
  end;
end;
 
procedure TForm1.ReCreateClick(Sender: TObject);
begin
  try
    ComPort1.Destroy;
    ComPort1:=TComPort.Create(Form1);
    ComPort1.Port:=Edit1.Text;
  Except
    IOResult;
    Beep;
  end;
end;
 
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  If ComPort1.Connected then Label1.Caption:='ON' else Label1.Caption:='OFF';
end;
 
end.
Вложения
Тип файла: rar COM_TEST.rar (180.5 Кб, 5 просмотров)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.02.2019, 17:28
Ответы с готовыми решениями:

Как передать bin фаил через ComPort
Пытаюсь написать свою програмку прошивальщик для Openbox. Но везде приводяться примеры передачи...

Comport vs Delphi
Вечер в хату! Хочу спросить в 100500-й раз)) Есть прога на Delphi, есть Arduino. Скетч Arduino...

Delphi+RS232 ComPort
Уважаемые форумчане-дельфичане! Обращаюсь к Вам за помощью, изъясняя на ходу суть проблемы: ...

WiFi как COMport
Есть ПО, которое работает с COM портами. Если в ноут сунуть блюпуп-свисток, то ПО работает...

16
пофигист широкого профиля
4735 / 3168 / 860
Регистрация: 15.07.2013
Сообщений: 18,255
25.02.2019, 02:46 2
Цитата Сообщение от klass2323 Посмотреть сообщение
Основная проблема, что порт виртуальный
Имхо пока полного решения нет.
0
0 / 0 / 0
Регистрация: 06.02.2019
Сообщений: 57
25.02.2019, 20:55  [ТС] 3
Цитата Сообщение от northener Посмотреть сообщение
Имхо пока полного решения нет.
Жаль...
Но всё равно спасибо!
0
Rius
26.02.2019, 06:35
  #4

Не по теме:

Цитата Сообщение от klass2323 Посмотреть сообщение
но может кто знает хитрости какие?
Смена языка и среды разработки. Кощунство, конечно, но поможет.

0
0 / 0 / 0
Регистрация: 06.02.2019
Сообщений: 57
26.02.2019, 20:05  [ТС] 5
Цитата Сообщение от Rius Посмотреть сообщение

Не по теме:


Смена языка и среды разработки. Кощунство, конечно, но поможет.

Смешно... Смешно...
0
Эксперт .NET
10571 / 6495 / 1506
Регистрация: 25.05.2015
Сообщений: 19,673
Записей в блоге: 14
26.02.2019, 20:08 6
Ничего смешного.
Мне такая же точно проблема встречалась и решилась легко. Программа при потере порта останавливает чтение, а при подключении порта к ПК открывает его же и продолжает работу.

Когда же специалист по дельфям говорит, что решения в дельфях нет, ему нет оснований не верить.
0
klass2323
26.02.2019, 20:30  [ТС]
  #7

Не по теме:

Цитата Сообщение от Rius Посмотреть сообщение
Ничего смешного.
Мне такая же точно проблема встречалась и решилась легко. Программа при потере порта останавливает чтение, а при подключении порта к ПК открывает его же и продолжает работу.

Когда же специалист по дельфям говорит, что решения в дельфях нет, ему нет оснований не верить.
Ну если бы там одна "тыкалка" USB-шная была, то можно было бы хоть на китайском, а так... Переписывать тысячи строк кода на другой язык, это как минимум его выучить надо, хоть частично... Да и вообще, не могу, язык сменить для меня почти как ориентацию. Не могу смотреть на синтаксис других языков, прям бесит. :wall: (не хочу никого обидеть и не считаю другие языки хуже или лучше, просто не родные)

0
1 / 1 / 0
Регистрация: 10.03.2023
Сообщений: 8
03.11.2023, 11:47 8
Добрый день!

С аналогичной проблемой столкнулся... Может появилось решение +- )).

Проблема возникла при использовании: если из USB порта удаляем устройство, то, конечно, ошибка обрабатывается, но как корректно закрывать потоки и порт и обнулять handle. Пробовал свой дорабатывать компонент, но все равно при повторном включении в этот же порт лезут ошибки. Обработчик USBRemove есть и он срабатывает на принудительное удаление. А вот BComPort валит ошибками (поскольку Connected остается true) и как все корректно закрыть (или приостановить - не понятно.
0
5786 / 4528 / 1431
Регистрация: 14.04.2014
Сообщений: 20,158
Записей в блоге: 20
03.11.2023, 17:31 9
общий смысл любого решения при упавшей коммуникации - хоть порты, хоть интернет:
узнать мы это можем либо по ошибке при попытке читать/писать, либо по таймауту

соответственно, этот поток, или что там отвечает за этот коннект, закрываем, бросаем, забываем
новый стартуем в попытке подключиться.
далее - повтор - либо да либо нет либо таймаут
0
1 / 1 / 0
Регистрация: 10.03.2023
Сообщений: 8
03.11.2023, 19:10 10
Цитата Сообщение от krapotkin Посмотреть сообщение
общий смысл любого решения при упавшей коммуникации - хоть порты, хоть интернет:
узнать мы это можем либо по ошибке при попытке читать/писать, либо по таймауту

соответственно, этот поток, или что там отвечает за этот коннект, закрываем, бросаем, забываем
новый стартуем в попытке подключиться.
далее - повтор - либо да либо нет либо таймаут
Общий смысл в общем-то понятен.

Интересует, получилось ли у кого в текущей реализации ИМЕННО TComPort и TBComProt компонент реализовать эту аварийную ситуацию.

С визуальной компонентой вообще не получилось ничего. Создание своего потомка и try...exept дало некоторый результат, когда работает приложение (освобождать вообще поток), но все равно нестабильно все, при закрытии приложения что-то остается висеть и выход не корректный.

В остальном TBComPort с данными работает вроде очень даже стабильно. Проблема еще в том, что не сильно я в теме. Как собрать все эти уничтожения в рабочую реализацию, не ломая рабочий компонент - не пойму...

Добавлено через 32 минуты
Возможно ли использовать .Close (там и ошибка) TBComPorta, когда устройство уже отключено от USB (handle хранится)? Или это нужно искать на более низком уровне? Поток сам не убивается при потере USB и Connected остается все равно True и Open.
0
Эксперт .NET
10571 / 6495 / 1506
Регистрация: 25.05.2015
Сообщений: 19,673
Записей в блоге: 14
03.11.2023, 19:32 11
Тут дело не в компоненте.
Если у вас usb-uart bridge на базе stm32 с виндовым драйвером, то страдать вам и страдать.
В драйверах нормальных производителей, типа silabs или ftdi, эту проблему решили более-менее.

Добавлено через 4 минуты
См. Не пойму как очистить массив строк
Ну и всю тему тоже почитайте, хотя там первые страницы эдак 3 вообще не понятно было, в чём дело.
1
1 / 1 / 0
Регистрация: 10.03.2023
Сообщений: 8
03.11.2023, 19:50 12
Да, именно это)).
Т.е. это "чистить" и убивать должны драйвера нормальные к устройству?

Сейчас реализована (не мной) usbutils, там, в частности, идет отлов до ошибок, что com порт удален:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
procedure TComponentUSB.WMDeviceChange(var Msg: TMessage);
var
  devType: Integer;
  Datos: PDevBroadcastHdr;
begin
  if (Msg.wParam = DBT_DEVICEARRIVAL) or
    (Msg.wParam = DBT_DEVICEREMOVECOMPLETE) then
  begin
    Datos := PDevBroadcastHdr(Msg.lParam);
    devType := Datos^.dbch_devicetype;
    if devType = DBT_DEVTYP_DEVICEINTERFACE then
    begin // USB Device
      if Msg.wParam = DBT_DEVICEARRIVAL then
      begin
        if Assigned(FOnUSBArrival) then
          FOnUSBArrival(Self);
      end
      else
      begin
        if Assigned(FOnUSBRemove) then
          FOnUSBRemove(Self);
      end;
    end;
  end;
end;
но я не пойму как тут поубивать все процессы.

а в TBComPort затык идет во 5-7 строках при попытке разъединить при уже отключенном com.

Delphi
1
2
3
4
5
6
7
8
9
 function TBComPort.Close: Boolean;
 begin
   if FConnected then
  begin
    SetDTR(False);
    SetRTS(False);
    AbortAllAsync;
    FEventThread.Free;
...
Но и если своим каким-то динамическим предком делать destroy всего, то в процессе все ок, разорвали-соединили - сигнал возобновился, но при потере порта и закрытии программы лезут утечки, т.е. получается потоки эти где-то не убиваются до конца
0
Эксперт .NET
10571 / 6495 / 1506
Регистрация: 25.05.2015
Сообщений: 19,673
Записей в блоге: 14
03.11.2023, 19:57 13
Цитата Сообщение от yotolozpjkjnjq Посмотреть сообщение
Т.е. это "чистить" и убивать должны драйвера нормальные к устройству?
Да.
Всякими танцами с бубном, типа приведённых выше, вы можете лишь поправить работу программы с нормальным мостом. С stm32, точнее использующими usbser.sys, это не поможет.
0
1 / 1 / 0
Регистрация: 10.03.2023
Сообщений: 8
03.11.2023, 22:14 14
Спасибо!

Печально, конечно). Думал я что не так делаю...

Подскажите, AsyncPro компоненты рекомендуют вместо T(B)ComPort - ов. Вроде как с корявыми драйверами готов работать. Не пользовались? Поможет ли?
0
пофигист широкого профиля
4735 / 3168 / 860
Регистрация: 15.07.2013
Сообщений: 18,255
04.11.2023, 02:33 15
Цитата Сообщение от yotolozpjkjnjq Посмотреть сообщение
Подскажите, AsyncPro компоненты рекомендуют вместо T(B)ComPort - ов. Вроде как с корявыми драйверами готов работать. Не пользовались?
Всю жизнь пользовался. Неразрешаемых проблем не имел.
Цитата Сообщение от Rius Посмотреть сообщение
С stm32, точнее использующими usbser.sys, это не поможет
А много вы встречали приборов usb-uart bridge на базе stm32?
0
Эксперт .NET
10571 / 6495 / 1506
Регистрация: 25.05.2015
Сообщений: 19,673
Записей в блоге: 14
04.11.2023, 08:37 16
Цитата Сообщение от northener Посмотреть сообщение
А много вы встречали приборов usb-uart bridge на базе stm32?
На этом форуме мне попадалось минимум 2 случая до этой темы, где было CDC + STM32 с этой проблемой.
А вообще гугл говорит о CDC + STM32 здесь примерно 719 раз.
0
1 / 1 / 0
Регистрация: 10.03.2023
Сообщений: 8
08.11.2023, 16:37 17
Может в будущем кому пригодится:
проблема решилась скачиванием последнего BComPort-а (https://github.com/nikitayev/BComPort) там чуть подзаменили разработчики некоторые вещи, все удаляется, все убивается, с ошибками справиться можно, в целом приложение не виснет, не падает, порт теряется-находится. Все ок. Практически с минимальными потерями (либо вообще без них), если код свой уже под TBComPort написан

Ваша программа с портами, кстати, из предложенной темы (спасибо) нормально у меня себя показывала, все чистилось и т.д., поэтому не стал я грешить на корявое железо, а стал искать проблему в компоненте. И, да, какие-то вещи внутри старого варианта я не дожал. А новый вариант с гитхаб очень даже ок работает.
1
08.11.2023, 16:37
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.11.2023, 16:37
Помогаю со студенческими работами здесь

Как правильно работать с port.ReceivedBytesThreshold (ComPort)?
Всем привет подскажите как правильно работать с port.ReceivedBytesThreshold . К примеру по нажатию...

Как использовать полтора стоповых бита для настройки ComPort при использовании termios.h?
Здравствуйте! Есть необходимость настроить ком порт используя termios.h. Необходимые настройки: 1)...

Как досрочно заврешить выполнение скрипта? Как сбросить переменные сессии?
1. Как досрочно заврешить выполнение скрипта? 2. Как сбросить переменные сессии?

Как сбросить конденсатор?
Братцы, помогите убогому! Делаю схему определения направления на источник звука. 8 микрофонов...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru