Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > ОС и железо
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 11.08.2015, 15:16
Yes_Maks Yes_Maks вне форума
Прохожий
 
Регистрация: 22.07.2014
Сообщения: 7
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Грамотно организовать поток для отлова событий COM порта

Уважаемые форумчане, всем добрый день! Подскажите путь решения. Ситуация следующая. Пишу приложение на delphi7, которое через ком порт общается с устройствами в сети (до 255 устройств может быть). Пользуюсь компонентом-библиотекой для работы с ком-портом ComPort Library 4.10 от Dejan Crnila. Приложение сначала сделал однопоточное, ибо программка большую часть времени простаивает и ждет пакет, приходящий в ком порт от любого из устройств. События прихода данных в ком порт отслеживаются и обрабатываются процедурой onRxChar, которая является частью класса этой самой библиотеки. В этой процедуре-обработчике выполняется вся обработка поступивших пакетов, вся реакция на них. Все бы было хорошо, если бы не 2 нюанса.
1. Иногда из сети от устройства может прийти пакет, который должен "усыпить" программу на определенное время. Усыпление я делаю с помощью вызова модального окна без кнопки закрыть его, а только с предупреждением о том, что программа временно приостановлена. (Такой способ приемлем или можно как-то более красиво?):
Код:
procedure TF_Main.ComPort1RxChar(Sender: TObject; Count: Integer);
begin
  ComPort1.Read(P_vhod,15);
  If (P_vhod[9]=1) and (P_vhod[10]=2) and (P_vhod[12]=20)//Если пришел пакет на "засыпание" программы
    then
      begin
        FWait:= TFWait.Create(Self);
        FWait.ShowModal;
      end;
  if (P_vhod[9]=1) and (P_vhod[10]=2) and (P_vhod[12]=21)//Программе надо проснуться
    then
      FWait.Close;
...
еще много других реакций
...

Но когда запущено модальное окно, управление не переходит на прием следующего пакета, который выведет программу
из спящего состояния, а все выполнение останавливается на строчке FWait.ShowModal. Типа программа зависла.
2.В программе есть кнопка опроса устройств и отправки данных на устройства. В обработчике кнопки "опросить" запускается цикл от 1 до 255 каждые 50 мс по 3 раза на каждое устройство (765 итераций). Цикл длится примерно 40 секунд. В цикле я отправил пакет на устройство 1. Оно ответило пакетом. Этот пакет пришел в порт, НО обработчик ComPort1RxChar НЕ может пока сработать, ибо сейчас выполняется обработчик нажатия кнопки и выполняется цикл. Первое устройство ответило, мы не обработали пакет, второе ответило, мы не обработали....Я так понимаю, пока размера буфера хватает, эти байты там сохраняются. После окончания цикла мы, может быть, сможем обработать первые 10-15 пакетов с первых 10-15 устройств. И пропустим почти все пришедшие пакеты с остальных устройств. А если еще вдруг в процессе опроса придет пакет на засыпание программы. Мы его тоже можем не отловить получается. Я решил по нажатии кнопки "опросить" запустить дополнительный поток, слушающий ком порт:
Код:
procedure TF_Main.Btn_SchitSoStellyClick(Sender: TObject);
var
  i,t:integer;
begin
...
  T1:= ToolkPort.Create(false);
  T1.FreeOnTerminate:= True;

Но в самом потоке не знаю, как вызвать процедуру из основного потока, что бы она продолжала слушать ком порт и обрабатывать пакеты, а в случае чего еще и приостанавливать поток основной программы и выводить модальное окно с предупреждением? и Так же в потоке ловить пакет выхода из спячки и убирать модальное окно
Код:
unit U_PortToolk;
interface
uses
  Classes, CPortCtl, ExtCtrls, CPort, Dialogs, Windows, Messages,
  SysUtils, Formirovatel_Paketov, U_StopModal;

type
  ToolkPort = class(TThread)
  ComPort: TComPort;

  private
    
  protected
    procedure Execute; override;
  end;

implementation

uses
  U_Main;

procedure ToolkPort.Execute;
begin
  {Вот здесь не знаю как правильно вызвать обработчик TF_Main.ComPort1RxChar, чтобы и в цикле он реагировал 
    на приходящие пакеты}
  until Terminated;
end;

end.

Что в Execute потока прописать, что бы корректно все работало? Не заново же дублировать весь код обработчика TF_Main.ComPort1RxChar...

Спасибо всем кто откликнется
Ответить с цитированием
 


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 22:00.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter