С Новым годом! Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
0 / 0 / 1
Регистрация: 10.01.2016
Сообщений: 46

ReadFile() возвращает 0 считанных байт через COM-порт при приёме пакета ненулевой длины

28.05.2019, 17:15. Показов 938. Ответов 0
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Реализую обмен с датчиком через Modbus RTU. После передачи пакета package1 на устройство, оно отвечает пакетом: 0x09 0x04 0x02 0x00 0x08 0x59 0x37. Вроде все классно, только recivedSize равно нулю. Даже в неинициализированном состоянии. В чем ошибка?

C++
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include "Transmit.h"
 
int Transmit::OpenPort()
{
    // Открытие последовательного порта
    port = CreateFile(L"COM3", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, NULL, NULL);
    if (port == INVALID_HANDLE_VALUE)
    {
        if (GetLastError() == PORT_IS_BUSY_ERROR) return PORT_IS_BUSY_ERROR;
        else return OPEN_PORT_ERROR;
    }
 
    // Настройка порта
    DCB dcb;
    GetCommState(port, &dcb);
    dcb.fBinary = TRUE;                     // Включаем двоичный режим обмена
    dcb.fOutxCtsFlow = FALSE;               // Отключаем режим слежения за сигналом CTS
    dcb.fOutxDsrFlow = FALSE;               // Отключаем режим слежения за сигналом DSR
    dcb.fDtrControl = DTR_CONTROL_DISABLE;  // Отключаем использование линии DTR
    dcb.fDsrSensitivity = FALSE;            // Отключаем восприимчивость драйвера к состоянию линии DSR
    dcb.fNull = FALSE;                      // Разрешить приём нулевых байтов
    dcb.fRtsControl = RTS_CONTROL_DISABLE;  // Отключаем использование линии RTS
    dcb.BaudRate = CBR_9600;                // Скорость передачи данных
    dcb.fParity = NOPARITY;                 // Проверка четности
    dcb.ByteSize = 8;                       // Размер байта данных
    dcb.StopBits = ONESTOPBIT;              // Количество стоповых бит
 
    // Настройка таймаута
    COMMTIMEOUTS commTimeOuts;
    GetCommTimeouts(port, &commTimeOuts);
    commTimeOuts.ReadTotalTimeoutConstant = 500;
 
    if (!SetCommState(port, &dcb) || !SetCommTimeouts(port, &commTimeOuts))
    {
        CloseHandle(port);
 
        return PORT_CONFIGURATION_ERROR;
    }
 
    return SUCCESS;
}
 
int Transmit::ModbusRead(unsigned char startRegisterAddress, unsigned char countOfRegisters)
{
    // Проверка на ошибки открытия порта
    switch (OpenPort())
    {
    case OPEN_PORT_ERROR: return OPEN_PORT_ERROR;
    case PORT_IS_BUSY_ERROR: return PORT_IS_BUSY_ERROR;
    case PORT_CONFIGURATION_ERROR: return PORT_CONFIGURATION_ERROR;
    }
 
    sizeOfRecivedPackage = 7;
    recivedPackage = new unsigned char[sizeOfRecivedPackage];
 
    unsigned char package1[] = { 0x09, 0x04, 0x00, 0x01, 0x00, 0x01, 0x61, 0x42 };
 
    DWORD recivedSize;
    startTime = GetTickCount();
 
    // Отправка пакета
    WriteFile(port, package1, 8, NULL, NULL);
 
    // Прием ответа
    while (recivedSize != sizeOfRecivedPackage)
    {
        ReadFile(port, recivedPackage, sizeOfRecivedPackage, &recivedSize, NULL);
 
        if (GetTickCount() > startTime + WAIT_TIME)
        {
            timeIsUp = true;
            break;
        }
    }
 
    for (int i = 0; i < 9; i++)
        recivedPackage[i];
 
    CloseHandle(port);
 
    if (timeIsUp) return TIME_IS_UP_ERROR;
 
    return SUCCESS;
}
Transmit.h
Кликните здесь для просмотра всего текста

C++
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include "Windows.h"
 
#define TIME_DIVISION_CHANNELS_SENSOR_ADDRESS 0x0F      // Адрес датчика для протокола c временным разделением канала
#define MODBUS_SENSOR_ADDRESS 0x09                      // Адрес датчика для протокола Modbus
 
#define SUCCESS 1                                       // Коды ошибок
#define OPEN_PORT_ERROR 0   
#define PORT_CONFIGURATION_ERROR 2
#define TIME_IS_UP_ERROR 3
#define PORT_IS_BUSY_ERROR 5
 
#define WAIT_TIME 3000                                  // Время ожидания ответа датчика в ms
 
#pragma once
ref class Transmit
{
public:
    HANDLE port;                                        // Адрес порта
 
    unsigned char *package;                             // Сформированный отправляеый пакет. Зависит от входных данных
 
    unsigned int startTime;                             // Время начала отсчета. Необходимо для таймера
    bool timeIsUp;                                      // Флаг конца отсчета таймера
 
    unsigned char *recivedPackage;                      // Ответ датчика
    DWORD sizeOfRecivedPackage;                         // Число принятых пакетов
 
public:
    Transmit();
 
    int TimeDivisionChannelsLoad(   // выавыаыв
        unsigned char *data,    // Указатель на массив data
        unsigned char sizeOfData);                      // Размер data
 
    int ModbusWrite(unsigned char startRegisterAddress, // Адрес начального регистра 
        unsigned char *data,                            // Указатель на массив data
        unsigned char sizeOfData);                      // Размер data
 
    int ModbusRead(unsigned char startRegisterAddress,  // Адрес начального регистра 
        unsigned char countOfRegisters);                // Количество регистров для чтения
 
private:
    int OpenPort();
};


Добавлено через 9 минут
После перезапуска Visual Studio все заработало
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
28.05.2019, 17:15
Ответы с готовыми решениями:

Построить быстрый эхо сервер при приёме и передаче различных по объёму данных от 10 байт до 100 кбайт
Как построить быстрый эхо сервер.при приёме и передаче различных по объёму данных от 10 байт до 100 кбайт.

Передача пакета по протоколу ОВЕН через СОМ порт
задача такая. Я должна сделать скаду-систему контоля микроклимата. Т.е. я как пользователь, задаю параметры работы (т.е. устанавливаю мин...

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

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
28.05.2019, 17:15
Помогаю со студенческими работами здесь

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

Обновление элемента label при приёме данных через serialport
Доброго времени суток! На форме имеются компоненты label и serialport. Через ком порт на комп передаю данные в виде переменной из одной...

порт источника отваливается при передаче сетевого пакета
Здравствуйте, друзья! Подскажите, пожалуйста, при передаче пакета отваливается порт источника. Подробнее: на работе на машине с...

Сообщения фиксированной длины через COM порт
Нужно опрашивать прибор по COM порту. Протокол RS232. Я бы мог спросить в других ветках, суть одна - байты. в ветке шарпа народ кажется...

Com порт ReadFile
Вообшем отправляю команду на устройство и она отправляет 5 байтов назад мне в ответ (hex 04 03 02 01 04) как правильно их(байтов) читать...


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

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru