Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
volodymir
0 / 0 / 0
Регистрация: 20.02.2014
Сообщений: 20
#1

Работа с СОМ-портом - C++

04.03.2014, 11:04. Просмотров 1042. Ответов 26
Метки нет (Все метки)

Пишу программу для работы с устройством через COM-порт. Я отсылаю устройству запрос так:
C++
1
WriteFile(hComPort, buff, buffSize, &bytesWritten, NULL);
и жду ответа от прибора. buff -- это массив типа BYTE.

Ситуация такая. Присылаю запрос номер 1, приходит только его часть. Затем посылаю любой другой запрос, и приходит остаток от запроса 1. Пробовал соединить два компьютера через COM-порты. Я присылаю что-то -- на том компьютере отображается переданная строка. Мне присылают, тоже приходит. Затем я снова отправляю строку тому компьютеру, и тут же мне приходит строка из элементов 20, хотя с того компьютера ничего не отсылали.

Буфер COM-порта очищаю после каждого чтения данных следующей функцией:
C++
1
PurgeComm(hComPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
В чем может быть дело? Если для ответа на мою тему нужны уточнения, спрашивайте.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.03.2014, 11:04
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Работа с СОМ-портом (C++):

Работа с COM портом - C++
Доброго времени суток, уважаемые форумчане! Помогите разобраться с COM портом. Хотя бы с чего начать. :help: На большинстве ресурсов...

Работа с COM портом - C++
Добрый день! Решил поработать с COM портом. в строке Port=CreateFile("COM2",GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);...

Работа с COM - портом - C++
Не могу сделать чтобы, при работе с соm - портом возможно было выбирать как автоматические настройки по(default), так и ручные настройки....

работа с ком портом? - C++
Добрый день! Я ещё только учусь. Но мне очень бы хотелось научиться работать с ком портами в винде. посылка прием данных, и пр. ...

Работа с COM портом запись и чтение в один заход-как сделать? - C++
Столкнулся с тем что оборудование которое прицеплено к компорту не отвечает если сразу же после отправки пакета затребовать у него...

работа с COM портом - C++
здравствуйте всем,я в форумах в первие ,и просил бы не судить очень строго. помогите пожалуйста , хочу реализовать приложение работающую с...

26
THE--MASTER
Заблокирован
04.03.2014, 11:10 #2
Что за устройство? Какой протокол? Случаем не над после каждой команды обрабатывать телетайповские ACK и NCK ?

Добавлено через 1 минуту
Цитата Сообщение от volodymir Посмотреть сообщение
Ситуация такая. Присылаю запрос номер 1, приходит только его часть.
куда присылаю? откуда приходит?
0
volodymir
0 / 0 / 0
Регистрация: 20.02.2014
Сообщений: 20
04.03.2014, 11:12  [ТС] #3
Устройство -- счетчик на воду. Протокол -- Modbus.
Даже если два компьютера соединить, то все равно лишние данные приходят, хотя с того компьютера ничего мне не присылали. Может, буфер очищать какой-нибудь или что? И влияет ли на это, что у меня работа без OVERLAPPED?
0
dzrkot
zzzZZZ...
519 / 349 / 53
Регистрация: 11.09.2013
Сообщений: 2,004
04.03.2014, 11:12 #4
А сам протокол соблюдаете? Мб у вас кол-во стоп битов отличается там и там?
0
volodymir
0 / 0 / 0
Регистрация: 20.02.2014
Сообщений: 20
04.03.2014, 11:13  [ТС] #5
Присылаю на устройство, от него дальше жду ответ в отдельном потоке через WaitCommEvent.
0
CheshireCat
Эксперт С++
2893 / 1242 / 78
Регистрация: 27.05.2008
Сообщений: 3,379
04.03.2014, 11:13 #6
Таймауты у тебя на прием - какие? Если истек таймаут приема, то функция ReadFile вернет ту часть ответа, которая к этому моменту успела дойти до приемника. Независимо от того, что ответ пришел еще не весь.
0
volodymir
0 / 0 / 0
Регистрация: 20.02.2014
Сообщений: 20
04.03.2014, 11:23  [ТС] #7
dzrkot, стоп-бит пробовал и 1, и 2 ставить -- нет разницы.

Добавлено через 9 минут
CheshireCat, таймауты так выставляю:
C++
1
2
3
4
5
6
7
8
9
10
11
COMMTIMEOUTS timeOuts;
 
GetCommTimeouts(hPort, &timeOuts);
 
timeOuts.ReadIntervalTimeout = MAXDWORD;
timeOuts.ReadTotalTimeoutMultiplier = 0;
timeOuts.ReadTotalTimeoutConstant = 0;
timeOuts.WriteTotalTimeoutMultiplier = 0;
timeOuts.WriteTotalTimeoutConstant = 0;
 
if (!SetCommTimeouts(hPort, &timeOuts))
0
THE--MASTER
Заблокирован
04.03.2014, 11:27 #8
попробуй так:
COMMTIMEOUTS ctout;
ctout.ReadIntervalTimeout = 50;
ctout.ReadTotalTimeoutMultiplier = 5;
ctout.ReadTotalTimeoutConstant = 2000;
ctout.WriteTotalTimeoutConstant = 200;
ctout.WriteTotalTimeoutMultiplier = 5;
0
volodymir
0 / 0 / 0
Регистрация: 20.02.2014
Сообщений: 20
04.03.2014, 11:34  [ТС] #9
THE--MASTER, попробовал -- проблема та же. Порт/устройство/программа как будто помнят предыдущие данные и их повторно отсылают.
0
THE--MASTER
Заблокирован
04.03.2014, 11:35 #10
Цитата Сообщение от volodymir Посмотреть сообщение
Присылаю запрос номер 1, приходит только его часть
Ты покажи код чтения из COM порта, ты скорее всего читаешь меньшее кол - во байт, чем должно быть по протоколу и у тебя в буфере остаются байты

Добавлено через 1 минуту
Цитата Сообщение от volodymir Посмотреть сообщение
Порт/устройство/программа как будто помнят предыдущие данные и их повторно отсылают.
их не помнят - они хранятся в буфере, если ты буфер не до конца считал - то в нём хранятся байты с предыдущего запроса, PurgeComm далеко не всегда правильно отрабатывает, особенно на USB - to COM
0
volodymir
0 / 0 / 0
Регистрация: 20.02.2014
Сообщений: 20
04.03.2014, 11:43  [ТС] #11
Вот код чтения из СОМ-порта:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
WaitCommEvent(hPort, &dwMask, NULL);
ClearCommError(hPort, &dwError, &comstat);
        
dwRead = comstat.cbInQue;
 
if (dwRead > 0)
{
    ReadFile(hPort, buf, dwRead, &dwRead, NULL);
 
    PurgeComm(hPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
        
    for (int i = 0; i < (int)dwRead; i++)
        printf_s("Byte read #%d: %u\n", i, buf[i]);
}
0
THE--MASTER
Заблокирован
04.03.2014, 11:53 #12
Цитата Сообщение от volodymir Посмотреть сообщение
ReadFile(hPort, buf, dwRead, &dwRead, NULL);
ты зачем одну и туже переменную суёшь dwRead ?
C++
1
2
3
4
5
6
7
BOOL WINAPI ReadFile(
  _In_         HANDLE hFile,
  _Out_        LPVOID lpBuffer,
  _In_         DWORD nNumberOfBytesToRead,
  _Out_opt_    LPDWORD lpNumberOfBytesRead,
  _Inout_opt_  LPOVERLAPPED lpOverlapped
);
nNumberOfBytesToRead - это сколько ты байт хочешь считать,
lpNumberOfBytesRead - это сколько байт фактический считалось.
Тебе нужно сравнивать эти переменные для определения корректности чтения

Дай мне результат байтов, который ты читаешь первым запросом и вторым, в котором у тебя остаток первого. А так же сообщи где во втором запросе у тебя кончаются байты первого
0
volodymir
0 / 0 / 0
Регистрация: 20.02.2014
Сообщений: 20
04.03.2014, 12:00  [ТС] #13
Исправил:
C++
1
2
DWORD dwRead = comstat.cbInQue, dwGot = 0;
ReadFile(hPort, buf, dwRead, &dwGot, NULL);
Цитата Сообщение от THE--MASTER Посмотреть сообщение
Дай мне результат байтов, который ты читаешь первым запросом и вторым
Прямо последовательность написать? Она пока на экран только выводится, а байты переводятся из шестнадцатиричной системы в десятичную.
0
THE--MASTER
Заблокирован
04.03.2014, 12:04 #14
Цитата Сообщение от volodymir Посмотреть сообщение
Исправил:
ну и теперь сравни их, они одинаковые или же читается меньше, чем ты запрашиваешь? Кстате, сколько байт ты хотел прочитать?

Цитата Сообщение от volodymir Посмотреть сообщение
Прямо последовательность написать?
да, можешь скриншот консоли дать
0
volodymir
0 / 0 / 0
Регистрация: 20.02.2014
Сообщений: 20
04.03.2014, 12:22  [ТС] #15
Сравнил -- совпадают.

Внизу приложен скриншот. Я ввожу 1, приходит часть. Потом еще раз 1 -- приходит довесок. А должно единым блоком приходить. Если в третий раз введу любое число, то одним блоком придет уже целиковый блок от запроса 1 (как бы объединенные первая и вторая части).
0
Миниатюры
Работа с СОМ-портом  
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.03.2014, 12:22
Привет! Вот еще темы с ответами:

управление через СОМ порт - C++
Как сдельть сигнал на RTS,DTR по нажатию BUTTON1и2 соответственно. Причём при их отпускании сигналы должны обнульться! Кто шарит в этом?!

Получить сигнал с СОМ-порта - C++
Здравствуйте.Собсно поставлена такая задача - получить по COM-порту код,преобразовать в число и вывести на экран.Тоесть например идет набор...

С++ код с использованием СОМ объектов. - C++
Пообещал другу написать прогу, кликер мыши в броузере(IE) на с++ с COM объектами. Вот код: #include &lt;iostream&gt; #include...

Как на с++ прочитать данные из СОМ порта? - C++
Мне нужно под MS-DOS 6.22 прочитать несколько слов через СОМ порт (в пределах 2х десятков и потом эти слова проанализировать). Какое...


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

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
04.03.2014, 12:22
Ответ Создать тему
Опции темы

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