Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
1 / 1 / 0
Регистрация: 23.11.2013
Сообщений: 51

Чтение данных из COMport

14.06.2017, 11:28. Показов 1158. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Хоть эта тема уже поднималось не раз, но проблему я так решить и не смог.
Задача: Нужно что бы программа считывала информацию из com порта и отправляла ответ на пришедшие данные (то есть считывала и записывала в com порт данные). Данные посылаются с arduino он же и принимает.
Проблема: С записью данных всё отлично, arduino принимает и распознаёт то что программа посылает. А вот считать те данные которые arduino отправляет нормально прочитать не получается, выводит непонятные символы.

Сначала я думал что проблема в тайм-аутах но поигравшись с ними проблему это никак не решило. Потом думал что он выдаёт ASCII код но в этом я не уверен.
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
DWORD WINAPI ReadThread(LPVOID)
{
 COMSTAT comstat;       //структура текущего состояния порта, в данной программе используется для определения количества принятых в порт байтов
 DWORD btr, temp, mask, signal; //переменная temp используется в качестве заглушки
 overlapped.hEvent = CreateEvent(NULL, true, true, NULL);   //создать сигнальный объект-событие для асинхронных операций
 SetCommMask(COMport, EV_RXCHAR);                               //установить маску на срабатывание по событию приёма байта в порт
 while(1)                       //пока поток не будет прерван, выполняем цикл
  {
   WaitCommEvent(COMport, &mask, &overlapped);                  //ожидать события приёма байта (это и есть перекрываемая операция)
   signal = WaitForSingleObject(overlapped.hEvent, INFINITE);   //приостановить поток до прихода байта
   if(signal == WAIT_OBJECT_0)                      //если событие прихода байта произошло
    {
     if(GetOverlappedResult(COMport, &overlapped, &temp, true)) //проверяем, успешно ли завершилась перекрываемая операция WaitCommEvent
      if((mask & EV_RXCHAR)!=0)                 //если произошло именно событие прихода байта
       {
        ClearCommError(COMport, &temp, &comstat);       //нужно заполнить структуру COMSTAT
        btr = comstat.cbInQue;                              //и получить из неё количество принятых байтов
        if(btr)                                     //если действительно есть байты для чтения
        {
         ReadFile(COMport, bufrd, btr, &temp, &overlapped);     //прочитать байты из порта в буфер программы
         counter+=btr;                                          //увеличиваем счётчик байтов
         ReadPrinting();
        }
       }
    }
  }
}
 void ReadPrinting(){
 Form1->Memo1->Lines->Add((char*)bufrd);
 if(bufrd=="1111")
 Form1->Shape1->Brush->Color=clRed;
 memset(bufrd,0,BUFSIZE);
   }
Вот настройки порта

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
void COMOpen()
{
String portname;
DCB dcb;
COMMTIMEOUTS timeouts;
portname=Form1->ComboBox1->Text; //\\\\.\\COM72
COMport=CreateFile(portname.c_str(),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
 if(COMport == INVALID_HANDLE_VALUE)            //если ошибка открытия порта
  {
   //вывести сообщение в строке состояния
   Form1->StatusBar1->Panels->Items[0]->Text = "Не удалось открыть порт";
   return;
  }
  else
  Form1->StatusBar1->Panels->Items[0]->Text = "Порт открыт";
dcb.DCBlength = sizeof(DCB);
dcb.BaudRate=StrToInt(Form1->ComboBox2->Text);
dcb.fBinary=TRUE;
dcb.fParity=TRUE;
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity = FALSE;
dcb.fNull = FALSE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fAbortOnError = FALSE;
dcb.ByteSize = 8;
dcb.Parity = SPACEPARITY;
dcb.StopBits = 0;
 if(!SetCommState(COMport, &dcb))
  {
   //если не удалось - закрыть порт и вывести сообщение об ошибке в строке состояния
   COMClose();
   Form1->StatusBar1->Panels->Items[0]->Text  = "Не удалось установить DCB";
   return;
  }
timeouts.ReadIntervalTimeout = 0xFFFFFFFF;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
if(!SetCommTimeouts(COMport, &timeouts))
  {
   COMClose();
   Form1->StatusBar1->Panels->Items[0]->Text  = "Не удалось установить тайм-ауты";
   return;
  }
SetupComm(COMport,2000,2000);
handle = open("test.txt", O_CREAT | O_APPEND | O_BINARY | O_WRONLY, S_IREAD | S_IWRITE);
 
 reader = CreateThread(NULL, 0, ReadThread, NULL, 0, NULL);         //создаём поток чтения, который сразу начнёт выполняться (предпоследний параметр = 0)
 writer = CreateThread(NULL, 0, WriteThread, NULL, CREATE_SUSPENDED, NULL); //создаём поток записи в остановленном состоянии (предпоследний параметр = CREATE_SUSPENDED)
 
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
14.06.2017, 11:28
Ответы с готовыми решениями:

Приём большого массива данных через COMport
Есть МК, по команде с компьютера он в ответ отправляет 32772 байт. Вопрос, как лучше принимать данные, чтоб ничего не потерять. Скорость...

Некорректный вывод данных через comport Delphi 7
Хай! Как показано на картинке вывод данных через com порт программы Arduino и программы Delphi немного не корректны. В чем может быть...

Некорректный вывод данных через comport Delphi 7 - Arduino
Хай! Как показано на картинке вывод данных через com порт программы Arduino и программы Delphi немного не корректны. В чем может быть...

2
+1
345 / 178 / 53
Регистрация: 24.08.2010
Сообщений: 1,028
16.06.2017, 19:07
Ставь бряк на
C++
1
21         counter+=btr;                                          //увеличиваем счётчик байтов
Смотри содержание bufrd.
Что-то кажется мне, что проблема здесь:
C++
1
Form1->Memo1->Lines->Add((char*)bufrd);
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
21.06.2017, 16:22
Цитата Сообщение от Триган Посмотреть сообщение
Хоть эта тема уже поднималось не раз, но проблему я так решить и не смог.
Используй компонент BComPort.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
21.06.2017, 16:22
Помогаю со студенческими работами здесь

Какой способ измерения времени лучше использовать для получения данных с comport?
Нужно получать время между измерениями с comport что лучше, использовать? Точность нужна до 0,01с

Чтение файла, чтение названия папки где находится файл, запись данных на PHP
Допустим у нас есть структура с папками типа Large -> Vehicles -> Firetruck_0 В этой папке лежит файл формата .dat Что нужно сделать? ...

Comport vs Delphi
Вечер в хату! Хочу спросить в 100500-й раз)) Есть прога на Delphi, есть Arduino. Скетч Arduino void setup() { ...

PHP+ComPort
Добрый день всем, как можно отправить сообщения на компорт через php ?, в интернете поискал нашел примеры `mode com1: BAUD=9600...

Не читает с ComPort
Добрый день, форумчане! Помогите, пожалуйста! Не могу считать с компорта. Затыкается на чтении, хотя терминал показывает, что данные...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru