|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Получить данные из потока
Доброго времени суток. Профи, подскажите, как решить проблемку чтения из Мемо, если в мемо строка передается из потока читающего Сом порт.
В двух словах – пишу обмен между компом и внешним контроллером (для отладки взял Ардуино). Команды проходят – ардуино отрабатывает и отвечает, ответы я вижу в Мемо, но тут как раз и проблема. Если посылать команды кнопкой как пример: Код:
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
|
|||
|
|||
Просто ответ не успевает, видимо, прийти за время задержки.
Лови OnChange в Memo1 и копируй в Memo2 в этот момент. ЗЫ. Почитай об ассинхронных вызовах для понимания теории. |
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
Рубь (11.12.2018)
|
#3
|
|||
|
|||
Спасибо за ответ,
но про задержку я подумал в первую очередь, не причём оказалась пробовал до Код:
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
|
|||
|
|||
Onchange в Memo1 срабатывает?
|
#5
|
|||
|
|||
Вечер добрый.
Да срабатывает, но не так как ожидаю. К стати, спасибо за идею про Onchange , программка по другому себя ведёт, чем при прямом копировании , хотя и не позволяет анализировать ответ. Вот думаю, как вопрос по другому сформулировать , чтобы понятнее было, я возможно косноязычно об'ясняюсь. Чуть позже отпишусь. |
#6
|
|||
|
|||
Видимо да, я просто не понимаю, в чем проблема.
Данные копируются - копируются. Вызвать их обработку/анализ в этот момент можно - можно. В чем проблема? |
#7
|
|||
|
|||
Извиняюсь заранее за об'ем, но так наверно понятнее будет почему я хочу получить доступ к анализу данных из порта.
Есть простой файл с координатами, структура строки 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
|
|||
|
|||
данные копируются только при завершении всей процедуры Button6Click,
и только после этого можно их анализировать, мне бы хотелось получить их в процессе её работы, а не как результат. |
#9
|
|||
|
|||
По моему в логике есть ошибка. надо немного переписать. Надо обработку команд для Х и Y разнести как две независимые ветки(возможно функции). В любом случае Спасибо за помощь. Если что то не пойму я отпишусь в теме. Еще раз Спасибо. Беру таймаут.
|