Получаю неправильную информацию из COM port-а
Новичок, но по воле судьбы решил поработать с COM портом на языке C++. Передаю информацию в COM с помощью Arduino nano (Китай, old loader (Вдруг это как-то повлияет)), код представлен ниже.
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.print(95);
}
Ардуинка подключена в COM6. Код программы, с принимающей стороны.
#include <windows.h>
#include <iostream>
#include <cstdlib> // для system
using namespace std;
//. . .
int main()
{
HANDLE Port;
const int READ_TIME = 20;
OVERLAPPED sync = { 0 };
int reuslt = 0;
unsigned long wait = 0, read = 0, state = 0;
unsigned char dst[2] = {0};
unsigned long size = sizeof(dst);
sync.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
//. . .
Port = CreateFile(L"COM6", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (Port == INVALID_HANDLE_VALUE) {
MessageBox(NULL, L"Невозможно открыть последовательный порт", L"Error", MB_OK);
ExitProcess(1);
}
while (true) {
/* Устанавливаем маску на события порта */
if (SetCommMask(Port, EV_RXCHAR)) {
/* Связываем порт и объект синхронизации*/
WaitCommEvent(Port, &state, &sync);
/* Начинаем ожидание данных*/
wait = WaitForSingleObject(sync.hEvent, READ_TIME);
/* Данные получены */
if (wait == WAIT_OBJECT_0) {
/* Начинаем чтение данных */
ReadFile(Port, dst, size, &read, &sync);
/* Ждем завершения операции чтения */
wait = WaitForSingleObject(sync.hEvent, READ_TIME);
/* Если все успешно завершено, узнаем какой объем данных прочитан */
if (wait == WAIT_OBJECT_0)
if (GetOverlappedResult(Port, &sync, &read, FALSE))
reuslt = read;
cout << dst << endl;
}
}
}
А теперь самое интересное - иногда данные проскакиваю верные, но они каким-либо образом инвертированы/искажены. Т.е если шлю в порт с Ардуино 123, на выходе получаю 312. Если 95 - 59. Но чаще всего (99% случаев) - информация просто на просто искажается и вместо 95 на выходе получаю следующее 
Ну или набор беспорядочных цифр по типу

Ответы (2 шт):
Как уже сказал @Vanyamba Electronics, вам нужно настроить порт. Если мне не изменяет память, используя WinAPI, сделать это можно так:
DCB dcb;
hPort=CreateFile("COM1", GENERIC_READ | GENERIC_WRITE,0, NULL, OPEN_EXISTING, 0, NULL);
GetCommState(hPort, &dcb);
dcb.ByteSize = 8; //Биты данных - 8
dcb.Parity = 0; // Четность - N
dcb.StopBits = 0; //Стоп-бит -1
//...Остальные настройки, если нужны
SetCommState(hPort, &dcb);
P.S. Писал по памяти, но должно работать.
Переписал программу. Считаю, что дело было в эвентах и данные как-то искажались, хотя не могу сказать ввиду своей безграмотности и незнания. Новый код работает корректно.
#include <windows.h>
#include <iostream>
using namespace std;
HANDLE hSerial;
void ReadCOM()
{
DWORD iSize;
char sReceivedChar;
while (true)
{
ReadFile(hSerial, &sReceivedChar, 1, &iSize, 0); // получаем 1 байт
if (iSize > 0) // если что-то принято, выводим
cout << sReceivedChar;
}
}
int main()
{
LPCTSTR sPortName = L"COM6";
hSerial = ::CreateFile(sPortName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hSerial == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_FILE_NOT_FOUND)
{
cout << "serial port does not exist.\n";
}
cout << "some other error occurred.\n";
}
DCB dcbSerialParams = { 0 };
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams))
{
cout << "getting state error\n";
}
dcbSerialParams.BaudRate = CBR_9600;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState(hSerial, &dcbSerialParams))
{
cout << "error setting serial port state\n";
}
while (1)
{
ReadCOM();
}
return 0;
}