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

Delphi Sources



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

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 09.12.2018, 14:20
Рубь Рубь вне форума
Прохожий
 
Регистрация: 09.12.2018
Сообщения: 6
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Получить данные из потока

Доброго времени суток. Профи, подскажите, как решить проблемку чтения из Мемо, если в мемо строка передается из потока читающего Сом порт.
В двух словах – пишу обмен между компом и внешним контроллером (для отладки взял Ардуино).
Команды проходят – ардуино отрабатывает и отвечает, ответы я вижу в Мемо, но тут как раз и проблема. Если посылать команды кнопкой
как пример:
Код:
procedure TForm1.Button5Click(Sender: TObject);
begin
 WriteComm(Form1.ComboBox1.Text);
end;

То ответ в мемо виден, и его другой кнопкой можно обработать,  нпример так:

 procedure TForm1.Button7Click(Sender: TObject);
begin
  Form1.Memo2.Text:=Form1.Memo1.Text;
end;

и эта строка доступна для анализа.
Но,  если  это делать в процедуре типа :

procedure TForm1.Button6Click(Sender: TObject);
var
motorX :string;
begin
motorX:= ‘  ATS=X200 ’;
WriteComm(motorX);
  sleep(100);
  Memo2.Lines.Text:= Memo1.Lines.Text;
……..
………
end;
Админ: Пользуемся тегами при оформлении кода!

то строка(ответ от контроллера) в мемо1 приходит, но не копируется из мемо1 в мемо2 и проанализировать ответ нельзя.
Я понимаю, что поток чтения порта , процедурой синхронизации блокирует чтение мемо1 , что это разные потоки, но если запускать копирование кнопкой из главной формы то оно проходит. Как получить данные в процедуре ? Подскажите плизз.

Последний раз редактировалось Admin, 09.12.2018 в 17:40.
Ответить с цитированием
  #2  
Старый 10.12.2018, 00:49
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Просто ответ не успевает, видимо, прийти за время задержки.
Лови OnChange в Memo1 и копируй в Memo2 в этот момент.

ЗЫ. Почитай об ассинхронных вызовах для понимания теории.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
Рубь (11.12.2018)
  #3  
Старый 10.12.2018, 12:06
Рубь Рубь вне форума
Прохожий
 
Регистрация: 09.12.2018
Сообщения: 6
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Спасибо за ответ,
но про задержку я подумал в первую очередь, не причём оказалась пробовал до
Код:
sleep(1000);
от момента отправки строки в контроллер. Отклик приходит гарантированно раньше
------
Чтение порта и запись в Мемо1 синхронизируется между основным потоком и потоком чтения порта:
Код:
 begin
    ClearCommError(ComFile, Temp, @ComStat);                 //Заполняем структуру ComStat;
    Btr:=ComStat.CbInQue;                                    //Получаем из структуры количество байт;
    If (Btr > 0) then                                      //Если байты присутствуют,
    begin
        ReadFile(ComFile, Buffer, SizeOf(Buffer), Temp, @OverRead); //Читаем порт;
        Synchronize(OutToMemo);              //Делаем синхронный вызов процедуры загрузки буфера в Memo;
    end;
 end;
......
......
procedure MyThread.OutToMemo;
begin
  Form1.Memo1.Lines.Text:=Form1.Memo1.Lines.Text+(String(buffer)); {Загружаем в Memo содержимое буфера;}
  Buffer:=''; //Очищаем переменную буфера;
end;
тут как бы то же всё стандартно.......................
приоритет потока в котором крутится чтение порта - tpNormal,
однако чтение Мемо1 в Мемо2 не проходит (

Последний раз редактировалось Рубь, 10.12.2018 в 12:23.
Ответить с цитированием
  #4  
Старый 10.12.2018, 19:12
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Onchange в Memo1 срабатывает?
Ответить с цитированием
  #5  
Старый 10.12.2018, 20:40
Рубь Рубь вне форума
Прохожий
 
Регистрация: 09.12.2018
Сообщения: 6
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Вечер добрый.
Да срабатывает, но не так как ожидаю.
К стати, спасибо за идею про Onchange , программка по другому себя ведёт,
чем при прямом копировании , хотя и не позволяет анализировать ответ.
Вот думаю, как вопрос по другому сформулировать , чтобы понятнее было, я возможно косноязычно об'ясняюсь. Чуть позже отпишусь.
Ответить с цитированием
  #6  
Старый 10.12.2018, 21:46
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Видимо да, я просто не понимаю, в чем проблема.
Данные копируются - копируются. Вызвать их обработку/анализ в этот момент можно - можно. В чем проблема?
Ответить с цитированием
  #7  
Старый 10.12.2018, 22:22
Рубь Рубь вне форума
Прохожий
 
Регистрация: 09.12.2018
Сообщения: 6
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Извиняюсь заранее за об'ем, но так наверно понятнее будет почему я хочу получить доступ к анализу данных из порта.
Есть простой файл с координатами, структура строки X2.54Y10.16
для примера 3 строки.
читаем, строим команды для моторХ и моторY, отправляем на контроллер проверяем ответ.
Если есть ответ значит есть связь, значит можно отправлять запрос на окончание отработки команды. Ситуация стандартная.
Вот как это пытался реализовать (на получении доступа к ответу из порта застрял )
Код:
procedure TForm1.Button6Click(Sender: TObject);
var
i,k,z  :integer;
motorX :string;
motorY :string;
memstr :string;

begin
  if form1.OpenDialog1.Execute then Memo3.Lines.LoadFromFile(OpenDialog1.FileName);
  i:=Memo3.Lines.Count;
  while i >= 0   do
  begin
    if (copy(Memo3.Lines.Strings[i],1,1) <>'X') then Memo3.Lines.Delete(i);
    i:=i-1;
  end;
//-------------------------------------файл загрузили в мемо3
k:=0;
while(k <= Memo3.Lines.Count-1) do     // цикл по записям(всего 3 строки по 2е координаты
                                       // структура строки X2.54Y7.62)
begin
  memstr := Memo3.Lines.Strings[k];
  i:=2;
  while memstr[i]<>'Y' do                         //собираем в tmpstr координату Х
  begin
    if memstr[i]<>'.'then motorX := motorX+memstr[i];  //игнорим разделитель х100
    inc(i);
  end;
  inc(i);

  while i<= length(memstr) do                     //собираем в tmpstr координату Y
  begin
    if memstr[i]<>'.'then motorY := motorY+memstr[i];  //игнорим разделитель х100
    inc(i);
  end;
//-------------------------------------------------------
 // точки вытащили  далее отправляем команды

//  ststX:='NO';               //глобальный флаг состояния мотора X
//  ststY:='NO';               //глобальный флаг состояния мотора Y
//  Memo1.Lines.Clear;         // чистим мемо
//  Memo2.Lines.Clear;

  motorY := 'ATS=Y'+motorY;  //собираем команду для X
  WriteComm(motorY);         // отправляем на двигатель
  sleep(100);                //это очень много но для отладки норм

  motorX := 'ATS=X'+motorX;  //собираем команду для Y
  WriteComm(motorX);         // отправляем на двигатель
  sleep(100);                //это очень много но для отладки норм

  // в контроллере код написан так, что ответка формируется сразу при приёме команды
  // т.е время отклика небольшое менее ~10мс
  // Т.О. в этот момент должен дважды прийти ответ и отработать TForm1.Memo1Change.
  // если я правильно понимаю то должно быть 6 вызавов TForm1.Memo1Change из 3х строк

  if((ststX='OK')and(ststY='OK'))then
  begin
   Form1.Caption:= IntToStr(k)+'  OK';
   sleep(1000);         // это что бы понять где мы
  //сдесь планировалось послать запрос на окончание отработки команды
  //проанализировать окончание и перейти к след. строке
  inc(k);
  end
  else
  begin
    Form1.Caption:= IntToStr(k)+'  No';
    sleep(1000);         // это что бы понять где мы
    inc(k);              //пока переход на след строку, нодолжен быть обработчик ошибки
  end;

end;
end;

procedure TForm1.Memo1Change(Sender: TObject);
var
j :integer;
begin
  Memo2.Lines.Text := Memo1.Lines.Text;
  for j:=0 to Memo2.Lines.Count-1 do
  begin
    if pos('ATSXOK',Memo2.Lines.Strings[j])>0 then ststX:='OK' else ststX:='NO';
    if pos('ATSYOK',Memo2.Lines.Strings[j])>0 then ststY:='OK' else ststY:='NO';
  end;
  inc(nn);
  Form1.Caption:= Form1.Caption + '  '+ IntToStr(nn); //считаем сколько раз отработало
end;

после выполнения в caption метки о трёх проходах, о трех вызовах Memo1Change и не одного успешного отклика.
Ответить с цитированием
  #8  
Старый 10.12.2018, 22:29
Рубь Рубь вне форума
Прохожий
 
Регистрация: 09.12.2018
Сообщения: 6
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

данные копируются только при завершении всей процедуры Button6Click,
и только после этого можно их анализировать, мне бы хотелось получить их в процессе её работы, а не как результат.
Ответить с цитированием
  #9  
Старый 10.12.2018, 22:57
Рубь Рубь вне форума
Прохожий
 
Регистрация: 09.12.2018
Сообщения: 6
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

По моему в логике есть ошибка. надо немного переписать. Надо обработку команд для Х и Y разнести как две независимые ветки(возможно функции). В любом случае Спасибо за помощь. Если что то не пойму я отпишусь в теме. Еще раз Спасибо. Беру таймаут.
Ответить с цитированием
Ответ


Delphi Sources

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

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

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

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


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


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

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

ВКонтакте   Facebook   Twitter