Получаю неправильную информацию из 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 шт):

Автор решения: Alexey Vesker

Как уже сказал @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;

}
→ Ссылка