![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | 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 разнести как две независимые ветки(возможно функции). В любом случае Спасибо за помощь. Если что то не пойму я отпишусь в теме. Еще раз Спасибо. Беру таймаут.
|