1 / 1 / 0
Регистрация: 20.02.2014
Сообщений: 23
|
|||||||||||
1 | |||||||||||
Работа с СОМ-портом04.03.2014, 11:04. Показов 2521. Ответов 26
Метки нет (Все метки)
Пишу программу для работы с устройством через COM-порт. Я отсылаю устройству запрос так:
Ситуация такая. Присылаю запрос номер 1, приходит только его часть. Затем посылаю любой другой запрос, и приходит остаток от запроса 1. Пробовал соединить два компьютера через COM-порты. Я присылаю что-то -- на том компьютере отображается переданная строка. Мне присылают, тоже приходит. Затем я снова отправляю строку тому компьютеру, и тут же мне приходит строка из элементов 20, хотя с того компьютера ничего не отсылали. Буфер COM-порта очищаю после каждого чтения данных следующей функцией:
0
|
04.03.2014, 11:04 | |
Ответы с готовыми решениями:
26
Работа с COM портом Работа с com-портом Работа с COM - портом Работа с COM портом |
Заблокирован
|
|
04.03.2014, 11:10 | 2 |
Что за устройство? Какой протокол? Случаем не над после каждой команды обрабатывать телетайповские ACK и NCK ?
Добавлено через 1 минуту куда присылаю? откуда приходит?
0
|
1 / 1 / 0
Регистрация: 20.02.2014
Сообщений: 23
|
|
04.03.2014, 11:12 [ТС] | 3 |
Устройство -- счетчик на воду. Протокол -- Modbus.
Даже если два компьютера соединить, то все равно лишние данные приходят, хотя с того компьютера ничего мне не присылали. Может, буфер очищать какой-нибудь или что? И влияет ли на это, что у меня работа без OVERLAPPED?
0
|
zzzZZZ...
527 / 358 / 94
Регистрация: 11.09.2013
Сообщений: 2,041
|
|
04.03.2014, 11:12 | 4 |
А сам протокол соблюдаете? Мб у вас кол-во стоп битов отличается там и там?
0
|
1 / 1 / 0
Регистрация: 20.02.2014
Сообщений: 23
|
|
04.03.2014, 11:13 [ТС] | 5 |
Присылаю на устройство, от него дальше жду ответ в отдельном потоке через WaitCommEvent.
0
|
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
|
|
04.03.2014, 11:13 | 6 |
Таймауты у тебя на прием - какие? Если истек таймаут приема, то функция ReadFile вернет ту часть ответа, которая к этому моменту успела дойти до приемника. Независимо от того, что ответ пришел еще не весь.
0
|
1 / 1 / 0
Регистрация: 20.02.2014
Сообщений: 23
|
||||||
04.03.2014, 11:23 [ТС] | 7 | |||||
dzrkot, стоп-бит пробовал и 1, и 2 ставить -- нет разницы.
Добавлено через 9 минут CheshireCat, таймауты так выставляю:
0
|
Заблокирован
|
|
04.03.2014, 11:27 | 8 |
попробуй так:
COMMTIMEOUTS ctout; ctout.ReadIntervalTimeout = 50; ctout.ReadTotalTimeoutMultiplier = 5; ctout.ReadTotalTimeoutConstant = 2000; ctout.WriteTotalTimeoutConstant = 200; ctout.WriteTotalTimeoutMultiplier = 5;
0
|
1 / 1 / 0
Регистрация: 20.02.2014
Сообщений: 23
|
|
04.03.2014, 11:34 [ТС] | 9 |
THE--MASTER, попробовал -- проблема та же. Порт/устройство/программа как будто помнят предыдущие данные и их повторно отсылают.
0
|
Заблокирован
|
|
04.03.2014, 11:35 | 10 |
Ты покажи код чтения из COM порта, ты скорее всего читаешь меньшее кол - во байт, чем должно быть по протоколу и у тебя в буфере остаются байты
Добавлено через 1 минуту их не помнят - они хранятся в буфере, если ты буфер не до конца считал - то в нём хранятся байты с предыдущего запроса, PurgeComm далеко не всегда правильно отрабатывает, особенно на USB - to COM
0
|
1 / 1 / 0
Регистрация: 20.02.2014
Сообщений: 23
|
||||||
04.03.2014, 11:43 [ТС] | 11 | |||||
Вот код чтения из СОМ-порта:
0
|
Заблокирован
|
||||||
04.03.2014, 11:53 | 12 | |||||
ты зачем одну и туже переменную суёшь dwRead ?
lpNumberOfBytesRead - это сколько байт фактический считалось. Тебе нужно сравнивать эти переменные для определения корректности чтения Дай мне результат байтов, который ты читаешь первым запросом и вторым, в котором у тебя остаток первого. А так же сообщи где во втором запросе у тебя кончаются байты первого
0
|
1 / 1 / 0
Регистрация: 20.02.2014
Сообщений: 23
|
||||||
04.03.2014, 12:00 [ТС] | 13 | |||||
Исправил:
0
|
Заблокирован
|
|
04.03.2014, 12:04 | 14 |
ну и теперь сравни их, они одинаковые или же читается меньше, чем ты запрашиваешь? Кстате, сколько байт ты хотел прочитать?
да, можешь скриншот консоли дать
0
|
1 / 1 / 0
Регистрация: 20.02.2014
Сообщений: 23
|
|
04.03.2014, 12:22 [ТС] | 15 |
Сравнил -- совпадают.
Внизу приложен скриншот. Я ввожу 1, приходит часть. Потом еще раз 1 -- приходит довесок. А должно единым блоком приходить. Если в третий раз введу любое число, то одним блоком придет уже целиковый блок от запроса 1 (как бы объединенные первая и вторая части).
0
|
Заблокирован
|
|
04.03.2014, 12:38 | 16 |
1. Попробуй захардкодь переменную dwRead = 60; - посмотри что получится
2. Попробуй поставить Sleep(5000); перед ReadFile - пусть для теста будет 5 секунд, будем твои таймауты наабум подбирать, раз ты не хочешь доки читать :-) P.S.: у тебя DWORD dwRead = comstat.cbInQue здесь dwRead вообще чему равно?
0
|
1 / 1 / 0
Регистрация: 20.02.2014
Сообщений: 23
|
||||||
04.03.2014, 12:50 [ТС] | 17 | |||||
Исправил. Теперь в коде стало так:
0
|
1 / 1 / 0
Регистрация: 20.02.2014
Сообщений: 23
|
|
04.03.2014, 12:52 [ТС] | 18 |
dwRead всего ответа должен быть равен 221. Когда дробно приходит, то сначала 14, а потом -- 207.
0
|
Заблокирован
|
|
04.03.2014, 12:54 | 19 |
А с чего ты взял, что ответ дробно приходит? Я же задавал уже вопрос, сколько байт тебе конкретно нужно считывать в ответе??????
!!! У тебя после 59-го байта идут нули, т.к. твой приёмный буфер больше 60-и байт и ты его нулями инициализируешь наверное, а читаешь в него только 60 байт = тут всё правильно Добавлено через 52 секунды тогда пиши тут для теста так: DWORD dwGot = 0; Sleep(5000); ReadFile(hPort, buf, 221, &dwGot, NULL); P.S.: покажи инициализацию buf
0
|
1 / 1 / 0
Регистрация: 20.02.2014
Сообщений: 23
|
||||||
04.03.2014, 13:03 [ТС] | 20 | |||||
Не для всех запросов оговорено, что должна быть такая-то длина ответа. Но в данном случае это, наверно, 221.
Инициализация buf:
0
|
04.03.2014, 13:03 | |
04.03.2014, 13:03 | |
Помогаю со студенческими работами здесь
20
работа с ком портом? Работа с COM портом запись и чтение в один заход-как сделать? работа с COM портом Работа с COM-портом в C++ (соединение с Arduino) Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |