Последовательный порт время от времени получает странные данные - PullRequest
0 голосов
/ 03 июля 2019

Я использую микроконтроллер Arduino с самым простым фрагментом кода:

void loop(){Serial.write('b');}

Таким образом, он посылает постоянный поток 'b'. С другой стороны, я использую Visual Studio для получения данных:

#include <iostream>
#include <windows.h>
#include <string>

using namespace std;

LPCTSTR comPort = TEXT("COM3");

int main()
{

    HANDLE hSerial;
    hSerial = CreateFile(comPort,
        GENERIC_READ | GENERIC_WRITE,
        0,
        0,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        0);
    if (hSerial == INVALID_HANDLE_VALUE) {
        if (GetLastError() == ERROR_FILE_NOT_FOUND) {
            //serial port does not exist. Inform user.
            cout << "ERROR WITH COM PORT" << endl;
        }
        //some other error occurred. Inform user.
    }

    DCB dcbSerialParams = { 0 };
    dcbSerialParams.DCBlength = sizeof(DCB);
    if (!GetCommState(hSerial, &dcbSerialParams)) {
        //error getting state
        cout << "ERROR GETTING SERIAL STATE" << endl;
    }
    dcbSerialParams.BaudRate = CBR_9600;
    dcbSerialParams.ByteSize = 8;
    dcbSerialParams.StopBits = ONESTOPBIT;
    dcbSerialParams.Parity = NOPARITY;
    if (!SetCommState(hSerial, &dcbSerialParams)) {
        //error setting serial port state
        cout << "ERROR SETTING SERIAL STATE" << endl;
    }

    COMMTIMEOUTS timeouts = { 0 };
    timeouts.ReadIntervalTimeout = 5;
    timeouts.ReadTotalTimeoutConstant = 5;
    timeouts.ReadTotalTimeoutMultiplier = 1;
    timeouts.WriteTotalTimeoutConstant = 5;
    timeouts.WriteTotalTimeoutMultiplier = 1;
    if (!SetCommTimeouts(hSerial, &timeouts)) {
        //error occureed. Inform user
        cout << "ERROR SETTING TIMEOUT" << endl;
    }

    const int n = 500;
    char szBuff[n + 1] = { 0 };
    DWORD dwBytesRead = 0;
    if (!ReadFile(hSerial, szBuff, n, &dwBytesRead, NULL)) {
        //error occurred. Report to user.
        cout << "ERROR READING FROM ARDUINO" << endl;
    }
    cout << szBuff << endl;
    //cout << szBuff << endl;

    CloseHandle(hSerial);
}

Когда я собираю и запускаю, консоль показывает мне это: enter image description here

Или иногда это: enter image description here

Есть идеи, почему? Я следовал всем инструкциям этого руководства: http://bd.eduweb.hhs.nl/micprg/pdf/serial-win.pdf, и я много чего перепробовал (изменив TimeOut, количество байтов для получения, ...)

С уважением

РЕДАКТИРОВАТЬ: Я забыл сказать вам, что Arduino полностью в порядке. Я использую Matlab для получения большего количества данных, и он отлично работает (без странного поведения, как сейчас).

Ответы [ 2 ]

0 голосов
/ 03 июля 2019

Как вы, похоже, пришли к выводу, судя по тому, как методом проб и ошибок добавлялись случайные вещи, простое не всегда приводит к правильному ответу.

Код на вашем Arduino работает впереди себя и продолжает перезаписывать свой TX-буфер, что приводит к повреждению данных. Чтобы исправить это, вам просто нужно Serial.flush() после написания и, возможно, добавить небольшую задержку (или просто идти с задержкой, как вы сделали).

Две другие строки, которые вы вынули из своей волшебной шляпы, не имеют ничего общего с вашими забавными персонажами.

Как забавное примечание: впервые после прочтения здесь вопросов и ответов у меня возникло подозрение, что он написан квази-ИИ-ботом (надеюсь, вы воспримете это как комплимент).

0 голосов
/ 03 июля 2019

Решение: я должен добавить эти 3 строки:

dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE;
PurgeComm(hSerial, PURGE_RXCLEAR | PURGE_TXCLEAR);
Sleep(ARDUINO_WAIT_TIME);

Я думаю, что первая строка не позволяет этим странным символам проходить через последовательный порт, а вторая строка очищает буфер в случае, если эти странные символы переданыдо первой строки.

...