Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.02.2022, 12:18   #1
rodionov_uv
Пользователь
 
Регистрация: 21.12.2009
Сообщений: 15
По умолчанию Работа с СОМ портом

Всем привет!!!!!!!
Столкнулся с проблемой работы программы в отдельном потоке (раньше с этим дело не имел), а именно: мне нужно -> послать в СОМ порт запрос -> получить ответ -> если ответ равен 43 байтам, послать ещё пару запросов и получить на них ответ. А у меня получается -> запрос, а ответ может придти после третьего запроса, причем сразу на три этих запроса, а может и сразу после запроса и получается куйня. Куски из кода прилагаю

Код:
procedure TNewThread.Execute;
var
i, q, j, k: Integer;
s, str, sum, xOut: String;
x: Byte;
PLC1, PLC2, PLC3: TStringList;
pop: array of Byte;
WritteBuffer: array[1..21] of Byte;
ReadBuffer: array[1..43] of Byte;
BytesWritten, BytesRead: DWORD;
begin
  if PortConnect = True then  //функция открытия СОМ порта
  if InitModem = True then  //функция дозвона модема
  begin

    .............................

    for q := 1 to 3 do  //цикл поиска в трёх устройствах
    begin
      MyForm.LogMemo.Lines.Add('');
      MyForm.LogMemo.Lines.Add(TimeToStr(Now) + ' : Начинаем поиск.....');
      for i := StrToInt(MyForm.AdrPLC1.Text) to StrToInt(MyForm.AdrPLC2.Text) do  //цикл поиска в устройстве в ячейках памяти
      begin

       .................................  //здесь идёт преобразование запроса

        WriteFile(Port, WritteBuffer[1], Length(WritteBuffer), BytesWritten, nil);  //запрос в СОМ порт
        ReadFile(Port, ReadBuffer, SizeOf(ReadBuffer), BytesRead, nil); //ответ из СОМ порта
       
       .............................  //Здесь идёт проверка на принятый ответ и вот здесь получается куйня
       
        if BytesRead = 43 then
        begin
        
        .............. //Остальной запрос
          
        end;
 
     ....................... //Закрытие СОМ порта, перезагрузка модема   

end;
А если я это делаю не в потоке, то у меня всё работает как надо, за исключением того, что приложение зависает минут на тридцать, а то и больше пока идёт цикл.
rodionov_uv вне форума Ответить с цитированием
Старый 02.02.2022, 02:34   #2
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,872
По умолчанию

Цитата:
Сообщение от rodionov_uv Посмотреть сообщение
Куски из кода прилагаю
А полный код приложить ФСБ или ФБР запрещают?
А по сути - код не годится для использования в доппотоке. Ибо есть обращения к VCL компонентам, которые по определению не потокобезопасны.
Есть явное непонимание работы с асинхронным устройство типа СОМ-порт. Ожидание что функция ReadFile вернет именно то, что вам хочется.
northener вне форума Ответить с цитированием
Старый 02.02.2022, 09:21   #3
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Цитата:
Сообщение от rodionov_uv Посмотреть сообщение
а ответ может придти после третьего запроса, причем сразу на три этих запроса, а может и сразу после запроса и получается куйня. Куски из кода прилагаю
Похоже на то, что у вас несколько потоков одновременно пишут в один порт.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 02.02.2022, 10:31   #4
rodionov_uv
Пользователь
 
Регистрация: 21.12.2009
Сообщений: 15
По умолчанию

northener
Просто я не программист, а программы пишу для себя (для работы) и выставлять на показ ужасный код ........ Мне бы лишь бы работало.

Если вставляю Sleep(2000), то всё работает, но скорость падает раза в четыре

Код:
...................
 WriteFile(Port, WritteBuffer[1], Length(WritteBuffer), BytesWritten, nil);  //запрос в СОМ порт
Sleep(2000);
 ReadFile(Port, ReadBuffer, SizeOf(ReadBuffer), BytesRead, nil); //ответ из СОМ порта
....................

Последний раз редактировалось rodionov_uv; 02.02.2022 в 10:36.
rodionov_uv вне форума Ответить с цитированием
Старый 02.02.2022, 10:46   #5
rodionov_uv
Пользователь
 
Регистрация: 21.12.2009
Сообщений: 15
По умолчанию

Вот полный код, сильно не пинайте.

Всё работает, только медленно.
Вложения
Тип файла: rar PLC Poisk.rar (221.9 Кб, 7 просмотров)
rodionov_uv вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Шлагбаум через СОМ портом очень надо MACTAK Помощь студентам 1 13.12.2012 22:10
программа для работы с СОМ-портом cambit Visual C++ 1 16.02.2012 17:57
Работа с СОМ портом Ivanko Общие вопросы Delphi 2 16.02.2010 10:58
Нужна программа-пользовательская для ПК желательно на С, простая,но работающая с сом-портом Alexa Фриланс 2 30.04.2009 16:50