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

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

Восстановить пароль Регистрация
 
 
volodymir
0 / 0 / 0
Регистрация: 20.02.2014
Сообщений: 20
04.03.2014, 11:04     Работа с СОМ-портом #1
Пишу программу для работы с устройством через 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);
В чем может быть дело? Если для ответа на мою тему нужны уточнения, спрашивайте.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
THE--MASTER
Заблокирован
04.03.2014, 11:10     Работа с СОМ-портом #2
Что за устройство? Какой протокол? Случаем не над после каждой команды обрабатывать телетайповские ACK и NCK ?

Добавлено через 1 минуту
Цитата Сообщение от volodymir Посмотреть сообщение
Ситуация такая. Присылаю запрос номер 1, приходит только его часть.
куда присылаю? откуда приходит?
volodymir
0 / 0 / 0
Регистрация: 20.02.2014
Сообщений: 20
04.03.2014, 11:12  [ТС]     Работа с СОМ-портом #3
Устройство -- счетчик на воду. Протокол -- Modbus.
Даже если два компьютера соединить, то все равно лишние данные приходят, хотя с того компьютера ничего мне не присылали. Может, буфер очищать какой-нибудь или что? И влияет ли на это, что у меня работа без OVERLAPPED?
dzrkot
zzzZZZ...
 Аватар для dzrkot
516 / 346 / 53
Регистрация: 11.09.2013
Сообщений: 1,977
04.03.2014, 11:12     Работа с СОМ-портом #4
А сам протокол соблюдаете? Мб у вас кол-во стоп битов отличается там и там?
volodymir
0 / 0 / 0
Регистрация: 20.02.2014
Сообщений: 20
04.03.2014, 11:13  [ТС]     Работа с СОМ-портом #5
Присылаю на устройство, от него дальше жду ответ в отдельном потоке через WaitCommEvent.
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,309
04.03.2014, 11:13     Работа с СОМ-портом #6
Таймауты у тебя на прием - какие? Если истек таймаут приема, то функция ReadFile вернет ту часть ответа, которая к этому моменту успела дойти до приемника. Независимо от того, что ответ пришел еще не весь.
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))
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;
volodymir
0 / 0 / 0
Регистрация: 20.02.2014
Сообщений: 20
04.03.2014, 11:34  [ТС]     Работа с СОМ-портом #9
THE--MASTER, попробовал -- проблема та же. Порт/устройство/программа как будто помнят предыдущие данные и их повторно отсылают.
THE--MASTER
Заблокирован
04.03.2014, 11:35     Работа с СОМ-портом #10
Цитата Сообщение от volodymir Посмотреть сообщение
Присылаю запрос номер 1, приходит только его часть
Ты покажи код чтения из COM порта, ты скорее всего читаешь меньшее кол - во байт, чем должно быть по протоколу и у тебя в буфере остаются байты

Добавлено через 1 минуту
Цитата Сообщение от volodymir Посмотреть сообщение
Порт/устройство/программа как будто помнят предыдущие данные и их повторно отсылают.
их не помнят - они хранятся в буфере, если ты буфер не до конца считал - то в нём хранятся байты с предыдущего запроса, PurgeComm далеко не всегда правильно отрабатывает, особенно на USB - to COM
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]);
}
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 - это сколько байт фактический считалось.
Тебе нужно сравнивать эти переменные для определения корректности чтения

Дай мне результат байтов, который ты читаешь первым запросом и вторым, в котором у тебя остаток первого. А так же сообщи где во втором запросе у тебя кончаются байты первого
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 Посмотреть сообщение
Дай мне результат байтов, который ты читаешь первым запросом и вторым
Прямо последовательность написать? Она пока на экран только выводится, а байты переводятся из шестнадцатиричной системы в десятичную.
THE--MASTER
Заблокирован
04.03.2014, 12:04     Работа с СОМ-портом #14
Цитата Сообщение от volodymir Посмотреть сообщение
Исправил:
ну и теперь сравни их, они одинаковые или же читается меньше, чем ты запрашиваешь? Кстате, сколько байт ты хотел прочитать?

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

Внизу приложен скриншот. Я ввожу 1, приходит часть. Потом еще раз 1 -- приходит довесок. А должно единым блоком приходить. Если в третий раз введу любое число, то одним блоком придет уже целиковый блок от запроса 1 (как бы объединенные первая и вторая части).
Миниатюры
Работа с СОМ-портом  
THE--MASTER
Заблокирован
04.03.2014, 12:38     Работа с СОМ-портом #16
Цитата Сообщение от volodymir Посмотреть сообщение
DWORD dwRead = comstat.cbInQue, dwGot = 0;
ReadFile(hPort, buf, dwRead, &dwGot, NULL);
1. Попробуй захардкодь переменную dwRead = 60; - посмотри что получится
2. Попробуй поставить Sleep(5000); перед ReadFile - пусть для теста будет 5 секунд, будем твои таймауты наабум подбирать, раз ты не хочешь доки читать :-)

P.S.: у тебя DWORD dwRead = comstat.cbInQue здесь dwRead вообще чему равно?
volodymir
0 / 0 / 0
Регистрация: 20.02.2014
Сообщений: 20
04.03.2014, 12:50  [ТС]     Работа с СОМ-портом #17
Исправил. Теперь в коде стало так:
C++
1
2
3
4
DWORD dwGot = 0;
 
Sleep(5000);
ReadFile(hPort, buf, 60, &dwGot, NULL);
Результат (картинка). Так же дробно приходит ответ на запрос 1. Байты после 59 (нумерация с 0, 60 элементов) нулевые.
Миниатюры
Работа с СОМ-портом  
volodymir
0 / 0 / 0
Регистрация: 20.02.2014
Сообщений: 20
04.03.2014, 12:52  [ТС]     Работа с СОМ-портом #18
dwRead всего ответа должен быть равен 221. Когда дробно приходит, то сначала 14, а потом -- 207.
THE--MASTER
Заблокирован
04.03.2014, 12:54     Работа с СОМ-портом #19
Цитата Сообщение от volodymir Посмотреть сообщение
Так же дробно приходит ответ на запрос 1. Байты после 59 (нумерация с 0, 60 элементов) нулевые.
А с чего ты взял, что ответ дробно приходит? Я же задавал уже вопрос, сколько байт тебе конкретно нужно считывать в ответе??????
Цитата Сообщение от THE--MASTER Посмотреть сообщение
P.S.: у тебя DWORD dwRead = comstat.cbInQue здесь dwRead вообще чему равно?
!!!

У тебя после 59-го байта идут нули, т.к. твой приёмный буфер больше 60-и байт и ты его нулями инициализируешь наверное, а читаешь в него только 60 байт = тут всё правильно

Добавлено через 52 секунды
тогда пиши тут для теста так:
DWORD dwGot = 0;

Sleep(5000);
ReadFile(hPort, buf, 221, &dwGot, NULL);

P.S.: покажи инициализацию buf
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.03.2014, 13:03     Работа с СОМ-портом
Еще ссылки по теме:

С++ код с использованием СОМ объектов. C++
C++ СОМ порт - как передать код
C++ Работа с COM портом

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

Или воспользуйтесь поиском по форуму:
volodymir
0 / 0 / 0
Регистрация: 20.02.2014
Сообщений: 20
04.03.2014, 13:03  [ТС]     Работа с СОМ-портом #20
Цитата Сообщение от THE--MASTER Посмотреть сообщение
сколько байт тебе конкретно нужно считывать в ответе?
Не для всех запросов оговорено, что должна быть такая-то длина ответа. Но в данном случае это, наверно, 221.

Инициализация buf:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
BYTE* buf = 0;
 
while (!terminated)
{
    if (!buf) buf = new BYTE[bufferSize];
    else
    {
        delete[] buf;
        buf = new BYTE[bufferSize];
    }
 
    // ...
}
Поставил 221, все равно сначала приходит 14, а потом уже целиком 221. Иногда нажимаешь 1, а приходит один байт 255. Иногда вообще не приходит ничего.
Yandex
Объявления
04.03.2014, 13:03     Работа с СОМ-портом
Ответ Создать тему
Опции темы

Текущее время: 20:34. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru