Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.95/21: Рейтинг темы: голосов - 21, средняя оценка - 4.95
0 / 0 / 0
Регистрация: 05.10.2023
Сообщений: 116

Работа с ComPort

05.10.2023, 16:03. Показов 6587. Ответов 149
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, работаю с ComPort и хочу передать данные через Writeport. Столкнулась с такой проблемой, что при вызове функции OutputBuffer заполнен, а когда перехожу по дебагу, то в этой функции значение буфера=no value (размер вычислился и передался).
Почему буфер не передался?

Вообще для чего мне это надо. Мне надо принять данные со сторонней программы подключенное к ComPort . Как я понимаю для того,чтобы принять, мне надо сигнализировать,что принимаю. Поэтому изначально использую Writeport.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
05.10.2023, 16:03
Ответы с готовыми решениями:

Асинхронная работа с ComPort
Приветствую великих умов форума, столкнулся с проблемой работы с comPort, а конкретнее я использую модем который поддерживает ComPort и вот...

Работа с ComPort Library
Здравствуйте, помогите разобраться, кое в чем с компонентой ComPort Library 3.10 . Проблема такова, есть устройство соединенное с ПК через...

RS-232 ComPort
Не знал куда задать вопрос задал здесь, извиняюсь конечно что ни туда залез я не программист просто возникла одна проблема, которое...

149
0 / 0 / 0
Регистрация: 05.10.2023
Сообщений: 116
10.10.2023, 08:20  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Constcat Посмотреть сообщение
TForm1.SomeProc(var Buf; Size: Word): Integer;
Если я так делаю, то оно как WritePort не понимает, что принимать.
Buf= no value

А это не поняла. Если я хочу слушать, почему я что-то должна так передавать?
Цитата Сообщение от Constcat Посмотреть сообщение
S[1]:='.....'; //1 символ, например char(100)
S[2]:='.....'; //.........
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
10.10.2023, 08:58
Цитата Сообщение от OdinNastya Посмотреть сообщение
Если я так делаю, то оно как WritePort не понимает, что принимать.
Buf= no value
На Buf нужно накладывать какой-то тип, либо смотреть непосредственно на память.
Цитата Сообщение от OdinNastya Посмотреть сообщение
А это не поняла. Если я хочу слушать, почему я что-то должна так передавать?
Это общий принцип при использовании ShortString в качестве буфера. Передается S[1] (с первого символа) и читается так же - в качестве буфера указывается S[1].
Разумеется, можно не париться и сразу выделить под буфер какой-то массив, но если фиксированный, то ShortString уже такой))), а если динамический, то нужно следить за памятью.
0
0 / 0 / 0
Регистрация: 05.10.2023
Сообщений: 116
10.10.2023, 12:30  [ТС]
Цитата Сообщение от Constcat Посмотреть сообщение
Передается S[1] (с первого символа) и читается так же
я не понимаю, что изначально присваивать.
S[1]:='.....';

Если бы мы указали,что буфер будет этого типа,хорошо, но тут это S[1]:='.....';

а мне принять еще надо, следовательно наложения типа только ShortString

и если я делаю
Delphi
1
 function TForm1.ReadPort(var Buf : ShortString; Size: Word): Integer;
то приходит,чо изначально я передала S[1]:='.....';

Если реализую
Delphi
1
function TForm1.ReadPort(var Buf : Byte  ; Size: Word): Integer;
и при вызове
Delphi
1
2
3
4
5
var
  ErrorCode: integer;
  InputBuffer : Byte;
begin
  ErrorCode:= ReadPort(InputBuffer, SizeOf(InputBuffer));  // приём пакета
то мне надо несколько раз нажимать на кнопку, чтобы всю посылку получить))


Наверное, ShortString скорее всего будет правильно, но не догоняю с изначальным присвоением. Поняла,что показывает длину строки,но а дальше

Добавлено через 10 минут
Цитата Сообщение от Constcat Посмотреть сообщение
Не-не-не. Не так.
В качестве параметра нужно так и оставлять var Buf - это позволит передавать в процедуру любую переменную в качестве буфера, нужно только Size правильно назначать.
Delphi
1
TForm1.SomeProc(var Buf; Size: Word): Integer;
вот так у меня не проходит buf = no value



Кстати!
Если я делаю
Delphi
1
function TForm1.ReadPort(var Buf  ; Size: Word): Integer;
и посылаю
Delphi
1
2
3
4
5
var
  ErrorCode: integer;
  InputBuffer : Byte ;
begin
  ErrorCode:= ReadPort(InputBuffer, SizeOf(InputBuffer));  // приём пакета
Все проходит,только да,несколько раз надо нажимать

Добавлено через 2 минуты
Эххх, сделала извращение...
Мне очень не нравится.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
procedure TForm1.Button3Click(Sender: TObject);
var
  ErrorCode: integer;
  InputBuffer : Byte ;
  Str : string;
  MyArray : array[0..7] of short;
  i: integer;
  b: short;
begin
  ErrorCode:= ReadPort(InputBuffer, SizeOf(InputBuffer));  // приём пакета
  b:= 0;
  i := 0 ;
  While b=0  do
  begin
      ErrorCode:= ReadPort(InputBuffer, SizeOf(InputBuffer));  // приём пакета
      if InputBuffer = 0 then  b:= 1;
       MyArray[i] := InputBuffer; // заполнение массива
       Inc(i);
       Str := Str + IntToStr(InputBuffer) + ' ';
  end;
 
  if ErrorCode = -1 then MessageDlg('Ошибка приёма пакета', MtWarning, [mbOK], 0)
  else
  begin
    Form1.Memo1.Lines.Add(str);
    MessageDlg('Порт прочитан', MtConfirmation, [mbOK], 0);
    end;
end;
0
 Аватар для Beltar
1071 / 512 / 41
Регистрация: 05.05.2022
Сообщений: 3,603
10.10.2023, 12:34
то мне надо несколько раз нажимать на кнопку, чтобы всю посылку получить))
Приход частями - это нормально. Зависит от аппаратуры, надо накапливать ожидаемое число байт в буффере, или ждать маркер конца передачи.
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
10.10.2023, 12:39
Цитата Сообщение от OdinNastya Посмотреть сообщение
я не понимаю, что изначально присваивать.
S[1]:='.....';
Допустим, у нас объявлены две фнукции
Delphi
1
2
procedure ReadData(var Buf; var Size: word); //здесь в Size процедура возвращает количество прочитанных байт
procedure WriteData(var Buf; Size: word);//здесь мы передаем в Size размер буфера в байтах.
Допустим, нужно послать команду 1A1B;
Тогда
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var S: ShortString;
    Size: word;
    I: Integer;
begin
S[1]:=char($1A);
S[2]:=char($1B);
Size:=2;
WriteData(S[1],Size);
//тут что-то делаем, ждем, т.д.
//теперь нужо принять данные.
//Принимаем:
ReadData(S[1],Size); //В Size мы получили количество данных.
//Теперь можно с ними работать.
//Например
for I:=1 to Size do
   if S[I]=char($1A) then
//и так далее.
0
0 / 0 / 0
Регистрация: 05.10.2023
Сообщений: 116
10.10.2023, 12:58  [ТС]
Constcat, теперь понятно. Тут подразумевается тандем WriteData и ReadData.
А у меня понятие было, что я отправила WriteData и хотела не поминать его лихом)))
и просто заняться чтением порта)

у меня просто две кнопки на передачу и чтения,а действительно сейчас так попробую.

Добавлено через 2 минуты
Цитата Сообщение от Beltar Посмотреть сообщение
Приход частями - это нормально.
ну вот я пока идиотство сделала
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
procedure TForm1.Button3Click(Sender: TObject);
var
  ErrorCode: integer;
  InputBuffer : Byte ;
  Str : string;
  MyArray : array[0..7] of short;
  i: integer;
  b: short;
begin
  ErrorCode:= ReadPort(InputBuffer, SizeOf(InputBuffer));  // приём пакета
  b:= 0;
  i := 0 ;
  While b=0  do
  begin
      ErrorCode:= ReadPort(InputBuffer, SizeOf(InputBuffer));  // приём пакета
      if InputBuffer = 0 then  b:= 1;
       MyArray[i] := InputBuffer; // заполнение массива
       Inc(i);
       Str := Str + IntToStr(InputBuffer) + ' ';
  end;
 
  if ErrorCode = -1 then MessageDlg('Ошибка приёма пакета', MtWarning, [mbOK], 0)
  else
  begin
    Form1.Memo1.Lines.Add(str);
    MessageDlg('Порт прочитан', MtConfirmation, [mbOK], 0);
    end;
end;
сейчас буду по другому пытаться.
0
 Аватар для Beltar
1071 / 512 / 41
Регистрация: 05.05.2022
Сообщений: 3,603
10.10.2023, 13:17
Цитата Сообщение от OdinNastya Посмотреть сообщение
А у меня понятие было, что я отправила WriteData и хотела не поминать его лихом)
Ну вообще-то это правильно, отправить запрос и включить таймер на таймаут, собирая данные. Таймер обязателен, если у вас ожидаемое время ответа, скажем 100 мс, то если не пришло за 200 мс, значит уже не придет. Если данные не набраны в нужном количестве, то вы должны обнулить буфер, т. к. прийти мог вообще мусор.

По поводу WinAPI, в примере, что я вам выкладывал, оповещение о приходе данных сделано через посылку основной программе сообщения. До того, она ничего не читает. Компонент он точно так же отслеживает состояние линий, и если появляется сигнал готовности передачи, начинает эти данные выбирать. Зачем вы мучаетесь с прямым чтением, и кому это надо, я не понимаю. Если вы используете компонент, то и делать должны через компонент, иначе зачем вы его используете, или не делать через компонент вообще, если у вас требование, что не используются нестандартные компоненты. Иногда это может быть оправдано. Есть много заброшенных библиотек, особенно со времен D7, которые могут не подойти новым версиям Delphi. Но в случае библиотеки comport411f, ее последняя версия была для Delphi XE, она давно не обновляется, т. к. сами интерфейсы RS-232, RS-485, RS-422 давно устарели (или правильнее сказать, достигли своего совершенства) и не обновляются, и без проблем ставится на любую версию.
0
0 / 0 / 0
Регистрация: 05.10.2023
Сообщений: 116
10.10.2023, 14:45  [ТС]
Цитата Сообщение от Beltar Посмотреть сообщение
включить таймер на таймаут, собирая данные
Говорят это сложней с таймером делать. За цикл собирания в массив все приходит. Но просто думаю это коряво.

Так же Ответ на то,что "Те ли мне данные приходят?"
Приходят правильные.

В стороннем приложении есть для экрана. Первый Экран с командой(температура-это команда 30) и его параметром/значением команды (Пример вывода температуры: >30<0 1A 1A 1A 1). Во втором экране подсоединенная БД с читабельной для человека цифрой=13,5(это и есть 0 1A 1A 1A 1) в нашем случае температуры.
Этот параметр сейчас читается( 0 1A 1A 1A 1) и потом необходимо уже в моей программе сделать читабельным и записать в БД, и вывести))))

А сейчас хочется адекватно сделать ReadPort.

Добавлено через 18 минут
Цитата Сообщение от Constcat Посмотреть сообщение
ReadData(S[1],Size);
А вывод S[1] в memo стандартно будет?

Просто Передача/WritePort прошла и сторонне приложение получила команду. Но когда по дебагу иду я не могу посмотреть буфер. Меня это бесит, хотя пишется, что пакет передан.

В чтении/ReadPort такая же шляпа( не могу посмотреть буфер) , но приходит,что порт прочитан. Значит, может я в memo не так передаю.

Добавлено через 21 минуту
Цитата Сообщение от Constcat Посмотреть сообщение
ReadData(S[1],Size); //В Size мы получили количество данных.
хотя может в Size проблема у меня
0
0 / 0 / 0
Регистрация: 05.10.2023
Сообщений: 116
10.10.2023, 14:51  [ТС]
и там, и там no value , но передает и "типа" примает))
Миниатюры
Работа с ComPort   Работа с ComPort  
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
10.10.2023, 14:56
Цитата Сообщение от OdinNastya Посмотреть сообщение
Говорят это сложней с таймером делать. За цикл собирания в массив все приходит. Но просто думаю это коряво.
Наверное, нужно кое-что прояснить.
Связь с оборудованием подразумевает, во-первых, частичную передачу данных (кусками), во-вторых - паузы между этими кусками, в-третьих - возможный обрыв передачи. Про поврежденные данные говорить не будем, чтобы совсем не загрузить))))
Т.е., нельзя ожидать, или рассчитывать, что данные придут целиком (они могут прийти куском и не до конца), либо что они прийдут в какой-то заранее определенный интервал времени.
Исходя из этого, протокол связи с оборудованием обычно подразумевает либо фиксированный размер пакета, либо передача этого размера в самом начале пакета - для того, чтобы принимающая сторона понимала, сколько ей еще нужно ждать байт и прекращала связь, если за определенный таймаут пакет не пришел.

Вопрос к вам: У вас размер данных (вот эти вот команды) фиксированный? Или могут быть варианты?
0
0 / 0 / 0
Регистрация: 05.10.2023
Сообщений: 116
10.10.2023, 15:03  [ТС]
Цитата Сообщение от Constcat Посмотреть сообщение
Вопрос к вам: У вас размер данных (вот эти вот команды) фиксированный? Или могут быть варианты?
Вот.
Миниатюры
Работа с ComPort  
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
10.10.2023, 15:10
Цитата Сообщение от OdinNastya Посмотреть сообщение
Но когда по дебагу иду я не могу посмотреть буфер. Меня это бесит, хотя пишется, что пакет передан.
Вот что я имел ввиду:
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
10.10.2023, 15:17
Цитата Сообщение от OdinNastya Посмотреть сообщение
Вот.
Т.е., у вас есть некий максимальный размер буфера 17 байт (байт команды + ответ).
Тогда можно заранее завести некий буфер, хоть array[0..16] of char и читать в него.
После чтения у вас в нулевом элементе будет команда. А в остальных будет пакет данных.
Теперь вопрос такой - как определить, весь ли пакет пришел за один раз?
Пришла команда $11, ожидается 16 байт ответ. Далеко не факт, что они прийдут в этом же пакете.
Поэтому нужно "выгрести" то, что пришло (ориентируясь на количество прочитанных байт) и в случае необходимости повторять цикл чтения пока не придет все. Понятное дело, что в этой ситуации мы уже в нулевом байте команду не смотрим, туда будут приходить остатки данных.
0
0 / 0 / 0
Регистрация: 05.10.2023
Сообщений: 116
10.10.2023, 15:19  [ТС]
Цитата Сообщение от Constcat Посмотреть сообщение
Вот что я имел ввиду:
На приеме сторонней программ все распознало
Миниатюры
Работа с ComPort  
0
0 / 0 / 0
Регистрация: 05.10.2023
Сообщений: 116
10.10.2023, 15:38  [ТС]
Цитата Сообщение от Constcat Посмотреть сообщение
Поэтому нужно "выгрести" то, что пришло
На будущее можно можно в Бд таблицу сделать с командами и размером ответа. В зависимости от команды подставлять размер соответствующий.Хотя,может лучше двумерный массив
В JAVA есть HashMap..Ключ-Значение, но вроде в delphi нет
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
10.10.2023, 15:44
Цитата Сообщение от OdinNastya Посмотреть сообщение
На будущее можно можно в Бд таблицу сделать с командами и размером ответа.
На нужно. Достаточно организовать case, где в зависимости от пришедшей команды, устанавливать в какую-то переменную ожидаемый размер ответа. А буфер пусть будет фиксированным, так даже удобнее.
Цитата Сообщение от OdinNastya Посмотреть сообщение
В JAVA есть HashMap..Ключ-Значение, но вроде в delphi нет
Даже в Delphi 7 есть TStringList, где каждой строке можно привязать какой-то объект. И есть возможность по переданной строке получить привязанный объект.
Т.е., строка - это ключ, объект - это значение. Понятно, что ключ нужно преобразовывать в строку, а значения хранить в виде TObject, но тем не менее)))
0
0 / 0 / 0
Регистрация: 05.10.2023
Сообщений: 116
10.10.2023, 15:50  [ТС]
Цитата Сообщение от Constcat Посмотреть сообщение
Далеко не факт, что они прийдут в этом же пакете.
Согласна.
У меня просто такой подход сейчас,что мне надо хотя бы в идеальных условиях все сделать.
Если получится, то надо идти дальше и уже о разных заковырках думать.
Я этот проект продавать не буду или кому-нибудь втюхивать с таким написание кода))) так- что по этому поводу можно не волноваться за свою безопасность)))
Это просто мне надо попробовать разобраться с такой темой

Добавлено через 5 минут
Цитата Сообщение от Constcat Посмотреть сообщение
Достаточно организовать case
я думала,а потом уже понесло.
Если к баранам вернуться, то вывод ShortString обычный в Memo?
Порт прочитан, но не выводится.
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
10.10.2023, 16:01
Цитата Сообщение от OdinNastya Посмотреть сообщение
У меня просто такой подход сейчас,что мне надо хотя бы в идеальных условиях все сделать.
А смысл, если потом все равно придется переделывать?)))
Чтение данных по частям - это не заковыка, а ситуация, с которой обязательно столкнешься, если придется что-то читать снаружи. Тем более, что то, что я тебе предложил, будет работать и в идеальных условиях.
Смотри:
1. Приходят данные. Кстати, как ты узнаешь, что они к тебе должны прийти? Просто ожидаешь ReadPort?
2. Читаешь нулевой байт, получаешь команду. Хотя бы один байт точно прийдет))).
3. По этой команде получаешь размер пакета, заносишь его в какую-то переменную
4. Вычитаешь из этой переменной количество прочитанных байт из ReadPort - 1 (команду в нулевом байте не учитываем).
5. Если получился 0 - значит условия "идеальные", все прочитали за один раз, всем спасибо, мы молодцы!
6. Если нет - снова ждем ReadPort.
7. Переходим к пункту 4.

Могу еще добавить ситуацию, когда в один буфер может прийти остаток первой команды и кусок следующей. Так тоже бывает)))

Добавлено через 2 минуты
Цитата Сообщение от OdinNastya Посмотреть сообщение
Если к баранам вернуться, то вывод ShortString обычный в Memo?
Если ты в S[0] занесешь размер данных, то у тебя получится обычная строка, с которой можно работать обычным способом.

Добавлено через 3 минуты
Цитата Сообщение от OdinNastya Посмотреть сообщение
я думала,а потом уже понесло.
У тебя case на 7 строк получается.
Для организации ассоциативного массива (твой HashMap) тебе придется писать гораздо больше, потому что у тебя там диапазоны.
0
0 / 0 / 0
Регистрация: 05.10.2023
Сообщений: 116
10.10.2023, 16:16  [ТС]
Цитата Сообщение от Constcat Посмотреть сообщение
У тебя case на 7 строк получается.
Это сделаю.

Сейчас разберусь почему в memo не выводится, хотя в S[1] записывается с ReadPort
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
10.10.2023, 16:20
Цитата Сообщение от OdinNastya Посмотреть сообщение
Сейчас разберусь почему в memo не выводится, хотя в S[1] записывается с ReadPort
Засунь в S[0] размер данных.
Pascal
1
S[0]:=char(Size);
Получится обычная строка. Обычную строку в мемо сможешь вывести?
P.S. Это уже хакерство какое-то получается. Может, на массив перейдем?)))
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
10.10.2023, 16:20

Delphi Comport
Добрый вечер Использую библиотеку CPortLib Два компонента ComPort и ComDataPacket ComPort виртуальный устройство (Arduino UNO)...

Не читает с ComPort
Добрый день, форумчане! Помогите, пожалуйста! Не могу считать с компорта. Затыкается на чтении, хотя терминал показывает, что данные...

Comport vs Delphi
Вечер в хату! Хочу спросить в 100500-й раз)) Есть прога на Delphi, есть Arduino. Скетч Arduino void setup() { ...

PHP+ComPort
Добрый день всем, как можно отправить сообщения на компорт через php ?, в интернете поискал нашел примеры `mode com1: BAUD=9600...

Переназначить comport
Здравствуйте. Имеется клиент-серверное приложение, без возможности смены comport'а... Возможно ли программно переназначить comport...


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

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru