Форум программистов, компьютерный форум, киберфорум
Наши страницы
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
Sergey1990
0 / 0 / 0
Регистрация: 29.01.2015
Сообщений: 40
1

Отправка и получение данных с COM-порта

21.05.2015, 12:12. Просмотров 2543. Ответов 28
Метки нет (Все метки)

Здравствуйте! Подскажите пожалуйста в чем может быть дело. Пытаюсь отправить данные на ком порт и прочесть.

Rx и Tx на порте замкнуты, то есть что отправил то и получил. С терминальной программой работает все норм.

Ввожу данные в едит на форме и отправляю их в нужный ком порт

Delphi
1
2
3
4
5
procedure TForm1.Button4Click(Sender: TObject);
begin
CommPortDriver1.SendString(Edit1.Text);
//memo3.Text:= (Edit1.Text);
end;
Пытаюсь прочесть, но выводится лишь часть того, что ввел в едит.

Пробовал менять типы pChar и string, Ansistring и тд,
Delphi
1
For i:=0 to DataSize-1 do s:=s+(pChar(DataPtr)[i]);
не помогает.

Например, ввожу 123456

Получаю 123

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
procedure TForm1.CommPortDriver1ReceiveData(Sender: TObject;
  DataPtr: Pointer; DataSize: Cardinal);
var i:integer;
s:string;
begin
s:='';
For i:=0 to DataSize-1 do s:=s+(pChar(DataPtr)[i]);
 
Memo3.text:=s;
Edit6.Text:=inttostr(i);
Edit7.Text:=s;
end;
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.05.2015, 12:12
Ответы с готовыми решениями:

Получение данных с USB-порта
Есть Электронное средство измерения с программным обеспечением для фиксирования...

Отправка и получение SMS через USB-модем
У меня есть USB модем, и есть программа через которую мне можно позвонить,...

Чтение данных с COM-порта
Доброго времени суток. Уверен тема поднималась не раз, уже все прочитал...

Обработка полученных данных с COM порта
Доброго всем времени суток. Вопрос такого плана - есть некое устройство...

Чтение данных из виртуального COM-порта
Все привет. Суть дела. Мне человек пишет чтение и парсинг данных из...

28
quwy
Native x86
3338 / 2184 / 650
Регистрация: 13.02.2013
Сообщений: 7,239
21.05.2015, 12:26 2
Проще всего сырой указатель преобразовывать в строку так:
Delphi
1
2
3
4
5
var
  s: AnsiString; // именно AnsiString, а не просто string
begin
  SetLength(s, DataSize);
  Move(DataPtr^, PAnsiChar(s)^, DataSize);
И значение переменной-счетчика цикла for нельзя использовать вне цикла.
Чему равен DataSize после отправки 123456?
0
northener
пофигист широкого профиля
3423 / 2323 / 630
Регистрация: 15.07.2013
Сообщений: 13,746
21.05.2015, 12:51 3
Цитата Сообщение от Sergey1990 Посмотреть сообщение
Пытаюсь прочесть, но выводится лишь часть того, что ввел в едит.
Обработчик CommPortDriver1ReceiveData будет вызван несколько раз. Т.е. ты всегда будет принимать по кусочкам.
0
Sergey1990
0 / 0 / 0
Регистрация: 29.01.2015
Сообщений: 40
21.05.2015, 13:52  [ТС] 4
Datasize = 6 при вводе 123456

Добавлено через 5 минут
Цитата Сообщение от northener Посмотреть сообщение
Сообщение от Sergey1990
Пытаюсь прочесть, но выводится лишь часть того, что ввел в едит.
Обработчик CommPortDriver1ReceiveData будет вызван несколько раз. Т.е. ты всегда будет принимать по кусочкам.
А разве он не вызывается при приеме данных 1 раз?
0
northener
пофигист широкого профиля
3423 / 2323 / 630
Регистрация: 15.07.2013
Сообщений: 13,746
21.05.2015, 14:00 5
Цитата Сообщение от Sergey1990 Посмотреть сообщение
А разве он не вызывается при приеме данных 1 раз?
Это невозможно по определению. СОМ-порт работает не с "сообщениями", а с отдельными байтами. И у его драйвера просто нет возможности узнать сколько порту послано байт. Поэтому он передает данные пользовательскому приложению либо тогда, когда данные перестают приходить на порт в течение некоего времени (т.н. таймаут), либо после того как в его буфере наберется определенное количество байт.
0
Sergey1990
0 / 0 / 0
Регистрация: 29.01.2015
Сообщений: 40
21.05.2015, 14:05  [ТС] 6
Цитата Сообщение от northener Посмотреть сообщение
Сообщение от Sergey1990
А разве он не вызывается при приеме данных 1 раз?
Это невозможно по определению. СОМ-порт работает не с "сообщениями", а с отдельными байтами. И у его драйвера просто нет возможности узнать сколько порту послано байт. Поэтому он передает данные пользовательскому приложению либо тогда, когда данные перестают приходить на порт в течение некоего времени (т.н. таймаут), либо после того как в его буфере наберется определенное количество байт.
То есть мне нужно в буфере набрать нужно кол-во байт и только тогда вызвать обработчик? или как то по другому можно это сделать?
0
northener
пофигист широкого профиля
3423 / 2323 / 630
Регистрация: 15.07.2013
Сообщений: 13,746
21.05.2015, 14:12 7
Цитата Сообщение от Sergey1990 Посмотреть сообщение
То есть мне нужно в буфере набрать нужно кол-во байт и только тогда вызвать обработчик?
Этим занимается драйвер СОМ-порта, а не ты. И обработчик вызывается не тобой, а тем компонентом, с помощью которого ты работаешь с портом. Тебе только нужно быть готовым к тому, что данные ты будешь получать кусочками. Поэтому желательно иметь признак окончания сообщения или знать количество посланных байт
0
Sergey1990
0 / 0 / 0
Регистрация: 29.01.2015
Сообщений: 40
21.05.2015, 14:40  [ТС] 8
Цитата Сообщение от northener Посмотреть сообщение
Этим занимается драйвер СОМ-порта, а не ты. И обработчик вызывается не тобой, а тем компонентом, с помощью которого ты работаешь с портом. Тебе только нужно быть готовым к тому, что данные ты будешь получать кусочками. Поэтому желательно иметь признак окончания сообщения или знать количество посланных байт
Спасибо большое за разъяснение!

мне нужно подключится к измерительному прибору через com порт. Прибор получает команды и отвечает на них.
С терминальной программой опять таки работает отлично, команды проходят, ответ приходит.

Через свою программу я подключаюсь к прибору, отправив на него Char(18), эта команда 100% проходит и устройство показывает на дисплее что подключение выполнено. Дальше я посылаю команду, например SRB1; и должен получить ответ либо "0" когда команда прошла и прибор ее понял, либо "?" когда не понял.

В терминальной программе все работает, ответы приходят. В моей программе почему - то ответа не видно, хотя первая команда Chr(18) срабатывает.

Может этот метод не подходит под вышеописанную задачу?

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
procedure TForm1.CommPortDriver1ReceiveData(Sender: TObject;
  DataPtr: Pointer; DataSize: Cardinal);
var i:integer;
s:Ansistring;
begin
s:='';
For i:=1 to 16 do s:=s+(String(DataPtr)[i]);
 
Memo3.text:=s;
Edit6.Text:=inttostr(DataSize);
Edit7.Text:=s;
end;
0
northener
пофигист широкого профиля
3423 / 2323 / 630
Регистрация: 15.07.2013
Сообщений: 13,746
21.05.2015, 14:47 9
А почему тут цикл от 1 до 16 ?
0
Sergey1990
0 / 0 / 0
Регистрация: 29.01.2015
Сообщений: 40
21.05.2015, 14:55  [ТС] 10
Цитата Сообщение от northener Посмотреть сообщение
А почему тут цикл от 1 до 16 ?
For i:=0 to DataSize-1 от 1 до 16 это уже я пытался изгаляться что бы заработала))

Датасайз я вывожу, он не меняется, то есть текст в едите, воторый я его вывожу остается едит1 например. Мне кажется что не срабатывает процедура procedure TForm1.CommPortDriver1ReceiveData.
А при замыкании 2 и 3 пинов на порте дата сайз считает кол во переданных символов

Добавлено через 24 секунды
Цитата Сообщение от northener Посмотреть сообщение
А почему тут цикл от 1 до 16 ?
For i:=0 to DataSize-1 от 1 до 16 это уже я пытался изгаляться что бы заработала))

Датасайз я вывожу, он не меняется, то есть текст в едите, воторый я его вывожу остается едит1 например. Мне кажется что не срабатывает процедура procedure TForm1.CommPortDriver1ReceiveData.
А при замыкании 2 и 3 пинов на порте дата сайз считает кол во переданных символов
0
northener
пофигист широкого профиля
3423 / 2323 / 630
Регистрация: 15.07.2013
Сообщений: 13,746
21.05.2015, 14:58 11
Для начала я бы посоветовал тебе заменить строчку
Delphi
1
Memo3.text:=s;
на строчку
Delphi
1
Memo3.Lines.Add(s);
И тогда ты будешь видеть сколько раз вызывалась эта процедура и сколько всего байт (символов) ты принял.
0
Sergey1990
0 / 0 / 0
Регистрация: 29.01.2015
Сообщений: 40
21.05.2015, 15:10  [ТС] 12
Заменил.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
procedure TForm1.CommPortDriver1ReceiveData(Sender: TObject;
  DataPtr: Pointer; DataSize: Cardinal);
var i:integer;
s:string;
begin
s:='';
For i:=0 to DataSize-1 do s:=s+(Pchar(DataPtr)[i]);
 
Memo3.Lines.Add(s);
Edit6.Text:=inttostr(DataSize);
Edit7.Text:=s;
end;
Edit6 и 7 остаются пустыми, то есть процедура не выполняется, правильно я понял?

при работе с заглушкой на порте в едитах данные есть.
0
northener
пофигист широкого профиля
3423 / 2323 / 630
Регистрация: 15.07.2013
Сообщений: 13,746
21.05.2015, 15:13 13
Цитата Сообщение от Sergey1990 Посмотреть сообщение
Edit6 и 7 остаются пустыми, то есть процедура не выполняется, правильно я понял?
Правильно.
Ну а с заглушкой теперь получаешь все что послал?
0
Sergey1990
0 / 0 / 0
Регистрация: 29.01.2015
Сообщений: 40
21.05.2015, 15:22  [ТС] 14
Нет, получаю по-прежнему половину. Но ни чего не получаю с прибора, хотя на терминал все приходит. Сначала хочу разобраться почему не приходит ни чего, получить хотя бы 1 символ с прибора.

Может дело быть в компоненте?

Добавлено через 3 минуты
Если процедура не срабатывает, то как бы ни чего не приходит, так? Возможно что компонент не "видит"? А на терминал приходит.
0
northener
пофигист широкого профиля
3423 / 2323 / 630
Регистрация: 15.07.2013
Сообщений: 13,746
21.05.2015, 15:30 15
Цитата Сообщение от Sergey1990 Посмотреть сообщение
Если процедура не срабатывает, то как бы ни чего не приходит, так?
Да не приходит.
Цитата Сообщение от Sergey1990 Посмотреть сообщение
Возможно что компонент не "видит"?
Только если ты перед приемом его "выключил".
Скорее прибор не понимает то, что ты ему послал и не отвечает поэтому.
0
Sergey1990
0 / 0 / 0
Регистрация: 29.01.2015
Сообщений: 40
21.05.2015, 15:37  [ТС] 16
Первая команда, которая говорит прибору что бы он перешел в режим управления с ЭВМ проходит и прибор ее понимает. на дисплее появляется соответсвующий значек.

Вот так я посылаю эту команду

Delphi
1
2
3
4
5
procedure TForm1.Button6Click(Sender: TObject);
begin
  CommPortDriver1.SendString(Chr(18));
  //memo3.Text:= Chr(18);
end;
Далее посылаю команды таким образом

Delphi
1
2
3
4
5
procedure TForm1.Button4Click(Sender: TObject);
begin
CommPortDriver1.SendString(Edit1.Text);
//memo3.Text:= (Edit1.Text);
end;
Ответа нет. На первую команду ответа быть не должно.

Теперь я посылаю все то же самое с терминала и он мне отвечает 0 на кждую команду
0
northener
пофигист широкого профиля
3423 / 2323 / 630
Регистрация: 15.07.2013
Сообщений: 13,746
21.05.2015, 15:46 17
Во-первых какая версия Дельфи?
Во-вторых я не знаю посылает ли процедура SendString символ(ы) конца строки.
В-третьих я не знаю нужны ли прибору эти символы.
0
Sergey1990
0 / 0 / 0
Регистрация: 29.01.2015
Сообщений: 40
21.05.2015, 16:22  [ТС] 18
Делфи XE6

Есть кусок программы примера да QB

....

Print #1, CHR(18) // вот это через программу проходит
delay(2)

CALL dmpcmd ("SRB1") посылаем через подпрограмму команду
....

SUB dmpcmd (wrt$)

Print #1,wrt$; ";" //посылаем
LINE INPUT #1,rd$ //читаем
print rd$; // выводим
0
northener
пофигист широкого профиля
3423 / 2323 / 630
Регистрация: 15.07.2013
Сообщений: 13,746
21.05.2015, 16:42 19
Цитата Сообщение от Sergey1990 Посмотреть сообщение
Делфи XE6
Уже плохо. В Д2009+ строки юникодные. Каждый символ двухбайтный.
Попробуй послать команду так
Delphi
1
2
3
4
5
6
7
procedure TForm1.Button4Click(Sender: TObject);
var
  S : AnsiString;
begin
S:='SRB1';
CommPortDriver1.SendString(S);
end;
Добавлено через 5 минут
Цитата Сообщение от Sergey1990 Посмотреть сообщение
Нет, получаю по-прежнему половину.
Теперь уже понятно почему.
0
Sergey1990
0 / 0 / 0
Регистрация: 29.01.2015
Сообщений: 40
21.05.2015, 17:00  [ТС] 20
Цитата Сообщение от northener Посмотреть сообщение
Сообщение от Sergey1990
Нет, получаю по-прежнему половину.
Теперь уже понятно почему.

Почему?
0
21.05.2015, 17:00
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.05.2015, 17:00

Чтение и обработка данных полученных из COM порта
Есть микроконтроллер с датчиком (акселерометр), эмулируется COM порт на USB,...

Считывание данных с COM порта. завтра защита диплома
всем привет, немогу никак понять, как считывать данные с COM порта. пробовал...

Помогите с решением приём-передача данных Com порта..
Доброе время суток уважаемые форумчане.. Мне необходима помощь в решении...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru