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

Обмен данными через СОМ-порт

02.12.2012, 18:13. Показов 64945. Ответов 36
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Помогите новичку, пожалуйста)
Нужно написать программу, которая ловит нажатия клавиш(стрелок) и соответственно отправляет это все через СОМ-порт на микроконтроллер. Но если с МК я более-менее разобрался, то вот с ПК-частью все очень-очень печально
Я тут на форуме покопался, но ничего не понимаю
Как вообще использовать этот СОМ в программе?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
02.12.2012, 18:13
Ответы с готовыми решениями:

Обмен данными по СОМ-порту
Доброго времени суток. Пишу 2 программы, обменивающиеся данными по COM-порту. Одна посылает управляющий сигнал, другая - в ответ - пакет...

Обмен данными между процессами через файлы, что отображаются в памяти
Добрый вечер. У меня есть код читателей-писателей и 2 консольных приложения, где происходит обмен данных между процессами с помощью файлов,...

Обмен данными через COM порт
Доброго времени суток. Требуется производить обмен данными с неким устройством через СОМ порт. Сейчас использую вот такие функции: ...

36
 Аватар для Fulcrum_013
2083 / 1575 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
14.03.2016, 05:47
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от egorman44 Посмотреть сообщение
Но хотелось бы узнать как можно регулировать время таймаута,
примерно вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool ReadBuffer(HANDLE Port,unsigned char *aBuffer, int TimeOut){
    COMSTAT Status;
    unsigned int Start=GetTickCount();
    while(GetTickCount()-Start<TimeOut){
          memset(&Status,0,sizeof(Status));
          ClearCommError(Port,&Error,&Status);
          if(Status.cbInQue){
             //читаем, считаем что приняли
            if (Done)//прочитали все что ожидали
                return true;
          }
   };
   return false;
};
0
0 / 0 / 0
Регистрация: 22.03.2016
Сообщений: 9
23.03.2016, 09:40
Помогите "чайнику"! Есть задача принимать команды из COM4 вида 11,12,13 и т.д. и в соответствии с полученной командой отправлять в COM5 строковые команды. Вроде бы всё получилось, но в результате работы программы исполняется только первая принятая команда, вторая уже не исполняется и такое впечатление, что COM5 чем-то занят и не принимает следующую команду...
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
while(1)
{
      while (true)
      {
        ReadFile(hSerialIn, &sReceivedChar, 2, &iSize, 0);  
        if (iSize > 0) 
        {
            int i = atoi(&sReceivedChar);   
            if (i==11) // Выключить ТВ Гостиная
            {
                char data[] = "POWR0   \r";  //  строка для передачи
                DWORD dwSize = sizeof(data);
                DWORD dwBytesWritten;   
                BOOL iRet = WriteFile (hSerial1,data,dwSize,&dwBytesWritten,NULL); //Посылаем строку
                Sleep(200);
                i=0;
            }
            if (i==12) // Включить ТВ Гостиная
            {               
                char data[] = "POWR1   \r";  //  строка для передачи
                DWORD dwSize = sizeof(data);  
                DWORD dwBytesWritten;    
                BOOL iRet1 = WriteFile (hSerial1,data,dwSize,&dwBytesWritten,NULL); //Посылаем строку
                Sleep(200);
                i=0;
            }
        }
      }
}
Добавлено через 10 часов 28 минут
Вообщем заработал такой вариант:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ReadFile(hSerialIn, &sReceivedChar, 3, &iSize, 0);  
        if (iSize > 0) 
        {
            int i = atoi(&sReceivedChar);   
            if (i==11) // Выключить ТВ Гостиная
            {
                DWORD dwBytesWritten;   
                BOOL iRet = WriteFile ( hSerial1, "POWR0   \r",9,&dwBytesWritten,NULL); //Посылаем строку
                Sleep(200);
                i=0;
            }
            if (i==12) // Включить ТВ Гостиная
            {               
                DWORD dwBytesWritten;    
                BOOL iRet1 = WriteFile (hSerial1,"POWR1   \r",9,&dwBytesWritten,NULL); //Посылаем строку
                Sleep(200);
                i=0;
            }
        }
Проблема была в подсчёте передаваемых данных через порт. Символ "перевода каретки" sizeof(data) считает как два байта, когда же я вписал количество байт вручную (на байт меньше) - всё заработало как надо...
0
 Аватар для RAFA91
-28 / 35 / 25
Регистрация: 14.06.2013
Сообщений: 1,452
27.04.2016, 16:44
Kuzia domovenok как я понял из поста #4 Вы используете замкнутый поток ThreadProc

этот же поток формирует событие SetEvent(hEvent);

а функция WaitForSingleObject(hEvent, INFINITE); ждет это событие .

___________________________

собственно вопрос !

строки идущие за WaitForSingleObject(hEvent, INFINITE);

будут выполняться только после получения события от потока функцией SetEvent(hEvent); ?
0
0 / 0 / 0
Регистрация: 30.09.2015
Сообщений: 18
02.05.2016, 03:07
Подскажите, пожалуйста, как перерисовывать окно, в соответствии с принимаемыми значениями с COM-порта? Я шлю с Ардуино на COM-порт 0 или 1, на экране должен выводиться текст - Closed или Open.
0
 Аватар для RAFA91
-28 / 35 / 25
Регистрация: 14.06.2013
Сообщений: 1,452
02.05.2016, 11:51
Цитата Сообщение от VladislavY Посмотреть сообщение
Подскажите, пожалуйста, как перерисовывать окно,
http://www.vsokovikov.narod.ru... terect.htm
0
0 / 0 / 0
Регистрация: 30.09.2015
Сообщений: 18
02.05.2016, 15:03
Цитата Сообщение от RAFA91 Посмотреть сообщение
http://www.vsokovikov.narod.ru/New_M...lidaterect.htm
проблема не с перерисовкой окна, проблема с работой COM-порта. если я создаю кнопку и перерисовываю своим способом, то все перерисовывается, если из массива записываю в переменную "а", то ничего не происходит.

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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#include <windows.h>
#include <vfw.h>
#include <CommCtrl.h>
#include <stdio.h>
#include <conio.h>
#include <locale.h>
char buf [128];
char* pbuf=buf;
int counter=0;
 
#pragma comment(lib, "ComCtl32.lib")
#pragma comment(lib, "vfw32.lib")
 
TCHAR czClassName[] = "myClass";
TCHAR czFormName[] = "Smart Home";
HWND hwndA;
HWND camhwnd;
 
HANDLE hCom, hEvent;
DWORD bytesRead, bWritten;
 
BOOL fSuccess;
HANDLE hThread;
DWORD dwParam, dwThreadId;
int a;
int id, alarm;
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HINSTANCE hInstance = GetModuleHandle(NULL);
    
 
    HWND DoorStatus, OpenT, ClosedT;
 
    switch (message)
    {
    case WM_DESTROY: PostQuitMessage(0); break;
 
    case WM_CREATE:
    {
        //hStatic1 = CreateWindowEx (0, TEXT("STATIC"), TEXT(""), WS_CHILD | WS_VISIBLE, 640, 0, 640, 480, hwnd, (HMENU)(-3), hInstance, NULL);
        DoorStatus = CreateWindowEx (0, TEXT("STATIC"), TEXT("Door Status Sensors"), WS_CHILD | WS_VISIBLE, 700, 110, 200, 20, hwnd, (HMENU) (-1) , NULL, NULL);
 
 
        break;
    }
        case WM_PAINT:
        PAINTSTRUCT ps;
        HDC hDC;
 
        hDC = BeginPaint ( hwnd, &ps );
 
        if ( a==1 ){//
            OpenT = CreateWindowEx (0, TEXT("STATIC"), TEXT("Open"), WS_CHILD | WS_VISIBLE, 850, 110, 100, 20, hwnd, (HMENU) (1) , NULL, NULL);
            UpdateWindow(hwnd);
            EndPaint( hwnd, &ps );
        }
        else if( a==0){// 
            ClosedT = CreateWindowEx (0, TEXT("STATIC"), TEXT("Closed"), WS_CHILD | WS_VISIBLE, 850, 110, 100, 20, hwnd, (HMENU) (1) , NULL, NULL);
            UpdateWindow(hwnd);
            EndPaint( hwnd, &ps );
        }
 
        EndPaint( hwnd, &ps );
        break;
 
    default: return DefWindowProc(hwnd, message, wParam, lParam); break;
    }
    
}
 
ATOM myRegistryClass(HINSTANCE hInst, int cmdMode)
{
    WNDCLASS cw;
 
    cw.style = CS_VREDRAW | CS_HREDRAW;
    cw.cbClsExtra = 0;
    cw.cbWndExtra = 0;
    cw.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    cw.hCursor = LoadCursor(NULL, IDC_ARROW);
    cw.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    cw.hInstance = hInst;
    cw.lpfnWndProc = WndProc;
    cw.lpszClassName = czClassName;
    cw.lpszMenuName = NULL;
 
    RegisterClass(&cw);
 
    return 0;
}
 
 
BOOL InitInstance(HINSTANCE hInst, int Mode)
{
 
 
    hwndA = CreateWindow(
        czClassName,
        czFormName,
        WS_OVERLAPPEDWINDOW&~WS_THICKFRAME , // WS_OVERLAPPEDWINDOW
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInst,
        NULL);
 
    ShowWindow(hwndA, Mode);
    UpdateWindow(hwndA);
 
    return TRUE;
}
 
VOID WINAPI ThreadProc(PVOID* dummy){
       while(true){
        ReadFile(hCom, pbuf, 1, &bytesRead, NULL);
        if (bytesRead>0)
        {
            WriteFile(hCom, pbuf++, 1, &bWritten, NULL);
            counter++;
            if(counter==10){
                SetEvent(hEvent);
                buf[counter]='\0';
                counter=0;
                pbuf=buf;
            }
        }
    }
}
 
/*Главная функция*/
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR IpszCmdParam, int cmdShow)
{
    MSG msg;
 
    myRegistryClass(hInst, cmdShow);
    InitInstance(hInst, cmdShow);
 
    InitCommonControls();
    
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
 
    setlocale(LC_ALL, "Russian");
    char* pcComPort= "COM3";
    DCB dcb;
    FILE* fout;
    hCom=CreateFile("COM3", GENERIC_READ | GENERIC_WRITE, 
        0, NULL, OPEN_EXISTING, 0, NULL);
   
    GetCommState(hCom, &dcb);
    dcb.BaudRate=CBR_9600;
    dcb.ByteSize=8;
    dcb.Parity=NOPARITY;
    dcb.StopBits=ONESTOPBIT;
    fSuccess=SetCommState(hCom, &dcb);
    if (!fSuccess){
        
       // while(!kbhit());
        return 1;
    }
    //printf("COM порт %s успешно сконфигурирован\n", pcComPort);
    GetCommState(hCom, &dcb);
    hEvent= CreateEvent(NULL, FALSE, FALSE, NULL);
    hThread=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc,&dwParam, 0, &dwThreadId);
    //if ((fout=fopen("C:\\test", "a+"))==NULL){
    //    printf("Не могу создать файл C:\\test");
    //    while(!kbhit());
    //    return 1;
    //}
    //printf("Нажмите клавишу для выхода...\n");
    do{
        WaitForSingleObject(hEvent, INFINITE);
        if (buf[1]=='1'){
            a=1;
            //printf("%s\n", "Open");
        }
        else if (buf[1]=='0'){
            a=0;
            //printf("%s\n", "Closed");
        }
 
        //printf("%s\n", buf);
        //fwrite(buf, sizeof(char), 10, fout);
    }while(!_kbhit());
    //fclose(fout);
    CloseHandle(hCom);
    return 0;
}
0
 Аватар для RAFA91
-28 / 35 / 25
Регистрация: 14.06.2013
Сообщений: 1,452
02.05.2016, 15:17
я вместо CreateWindowEx использую CreateWindow

первый параметр должен быть из описания

указатель на зарегистрированное имя класса
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
20.10.2016, 13:06
Цитата Сообщение от egorman44 Посмотреть сообщение
Здравствуйте товарищи. Извиняюсь за вмешательство. Но хотелось бы узнать как можно регулировать время таймаута, между отправленными посылками. Необходимо для реализации протокола modbus . Посылаю запрос по определенному адресу и если ответ от ведомого не приходит, то по истечению тайм-аута , необходимо обратиться к ведомому со следующим адресом.
Для этого можно использовать overlapped-режим в WaitForSingleObject указывать таймаут ожидания данных.
0
 Аватар для Fulcrum_013
2083 / 1575 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
21.10.2016, 23:58
Цитата Сообщение от Avazart Посмотреть сообщение
Для этого можно использовать overlapped-режим в WaitForSingleObject указывать таймаут ожидания данных.
Только есть одна байда - работа с COM-портом аки с файлом тормозная неуправляемая и для дел управления чем либо абсолютно непригодна.
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.10.2016, 00:03
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Только есть одна байда - работа с COM-портом аки с файлом тормозная неуправляемая и для дел управления чем либо абсолютно непригодна.
Это ты скажи разработчикам ОС, гений
0
 Аватар для Fulcrum_013
2083 / 1575 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
22.10.2016, 00:49
Цитата Сообщение от Avazart Посмотреть сообщение
Это ты скажи разработчикам ОС, гений
Вот именно этот момент который еще с 95-ой тянется многократно проверен практикой. А весь остальной асинхронный ввод-вывод остальной действительно через Overlapped нужно делать.
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.10.2016, 13:40
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Вот именно этот момент который еще с 95-ой тянется многократно проверен практикой. А весь остальной асинхронный ввод-вывод остальной действительно через Overlapped нужно делать.
... ты о чем?
Почти все делается в духе "работа как с файлом" что пайпы,что сокеты, что сериал, а Overlapped лишь разновидность это I/O.

Или ты под моментом имеешь виду свой позорный быдлокод?
0
 Аватар для Fulcrum_013
2083 / 1575 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
22.10.2016, 19:36
Цитата Сообщение от Avazart Посмотреть сообщение
Почти все делается в духе "работа как с файлом" что пайпы,что сокеты, что сериал, а Overlapped лишь разновидность это I/O.
Смотря где. Там где можно работать как с файлом все ок и с overlapped. а там где пакетный обмен через COM с оверлаппед обычно начинаются абсолютно ненужные протормозки и т.п.
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.10.2016, 19:43
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Смотря где.
Абсолютно везде...
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
а там где пакетный обмен через COM с оверлаппед обычно начинаются абсолютно ненужные протормозки и т.п.
Какой еще пакетный обмен? Опять психоделические выдумки?
0
 Аватар для Fulcrum_013
2083 / 1575 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
22.10.2016, 19:46
Цитата Сообщение от Avazart Посмотреть сообщение
Или ты под моментом имеешь виду свой позорный быдлокод?
Быдлокод - это к примеру работа с сокетами через оверлаппед. Там для асинхронки другие гораздо более продвинутые средства имеются. А насчет комов- то оверлапед это причина тормозов в пакетном режиме. Видил как то хохму правда еще под хрюшкой. сидят вумники контроллер опрашивают по модбасу, комы через оверлаппед. 2-5 FPS чего явно недостаточно. Два месяца промучались с ускорением - без результата. Выбросилил оверлаппед поставили эту байду. Время отклика контроллера менее 1 мс (т.е более 1000 FPS опрос )

Добавлено через 55 секунд
Цитата Сообщение от Avazart Посмотреть сообщение
Какой еще пакетный обмен?
Команда тудыть ответ оттудыть. Ты че в древней греции ликбез заканчивал?
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.10.2016, 20:06
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Быдлокод - это к примеру работа с сокетами через оверлаппед. Там для асинхронки другие гораздо более продвинутые средства имеются.
Быдлокодство это использовать топор вместо скальпеля и жаловаться чего кишки навыворот торчат и пациент мертв )))
Разные средства используются для разных случаев, не более...
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
выбросилил оверлаппед поставили эту байду. Время отклика контроллера менее 1 мс (т.е более 1000 FPS опрос )
Т.е "байда" это ты про твой быдлокод? Грузящий проц? (Даже если опроса нет, да же данных нет, даже если устройства нет)
Не удевлюсь что с "оверлаппед" вы накатали просто еще более ужасный быдлокод от того ...

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
2-5 FPS чего явно недостаточно.
Недостаточно для чего? Для полета на Марс? Или Сникерс ?
0
 Аватар для Argus19
1428 / 445 / 78
Регистрация: 24.09.2017
Сообщений: 2,531
Записей в блоге: 23
27.02.2020, 21:51
Kuzia domovenok, в приведённом вами примере не используются тайм-ауты порта.
Они в данном случае не нужны?
Видел не очень внятные примеры настроек тайм-аутов. Как их правильно настроить в зависимости от скорости?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
27.02.2020, 21:51
Помогаю со студенческими работами здесь

Обмен данными через ком порт в потоке
Программа выполняется в потоке идёт обмен данными через ком порт с мк! При выполнении программа просто останавливается, не могу понять в...

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

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

Обмен через порт
нужно написать две программки под UNIX, которые общались бы между собой через последовательный порт /dev/ser. Может кто нибудь рассказать...

Взаимодействие процессов, обмен сообщениями через порт
Народ, нужна помощь с лабораторной работой. Нужна вот такая программа на С++: &quot;Вычислить f (x) * g (x), используя 2...


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

Или воспользуйтесь поиском по форуму:
37
Ответ Создать тему
Новые блоги и статьи
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru