Возникла проблема с чтением последовательных данных USB - PullRequest
0 голосов
/ 22 апреля 2019

Я пытался прочитать данные с USB-адаптера (PL2303), используя этот код.

Моя спецификация USB-чипа - 57600, Без контроля четности, 1 стоп-бит, 8-битный режим данных

IЯ могу получить некоторые волновые данные из buf [], но я не знаю, что означает это число.

3, -1225386821, 0, 0, 1934713408, 6, 400, 520192, 45826, 0, 15971,0, 2, -1091179996, 3, -1226244648, -1225242284, -1227820936, 524408, 2, 45826, 0, 0, 15971, 33188

Это гекса или что-то?

Какя могу получить значимые данные из этого?Есть ли проблема в моем коде c ++?

int open_port(void)
{
    int fd;
    fd=open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NDELAY);

    if(fd==-1)
    {
        fprintf(stderr, "open_port: Unable to open - %s\n", strerror(errno));
    }
    return (fd);
}

Этот код используется в Linux.

int main()
{
    int mainfd=0,fd;
    //char chout;
    int buf[5000];    
    struct termios options;
    FILE *pFile;
    pFile = fopen("rawdata.txt","w+");

    mainfd=open_port();
    fcntl(mainfd, F_SETFL, FNDELAY);

    tcgetattr(mainfd, &options);
    cfsetispeed(&options, B57600);
    cfsetospeed(&options, B57600);

    options.c_cflag |= (CLOCAL/CREAD);
    options.c_cflag &= PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag &= CS8;
    options.c_cflag &= ~CRTSCTS;

    options.c_cflag &= ~(ICANON | ECHO | ISIG);


    read(mainfd, buf, 5000);

    for(int i=0;i<5000;i++)     
    {
        cout<<buf[i]<<endl;

        fprintf(pFile,"%d\n",buf[i]);

    }    
    return 0;
}

Ответы [ 2 ]

1 голос
/ 23 апреля 2019

Это Гекса или что-то?

Если вы имеете в виду шестнадцатеричное, то нет.

Как я могу получить значимые данные из этого?

Сначала вы должны написать свою программу, чтобы она соответствовала полученным данным (например, байты и слова, текст по сравнению с двоичными данными), а затем ваша программа должна отслеживать, какие фактические полученные данные сравниваются с неинициализированной памятью.

Есть ли проблема в моем коде c ++?

Да, в вашем коде есть несколько существенных проблем.

1. Ваша программа использует неблокирующий режим.

    fd=open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NDELAY);  
    ...
    fcntl(mainfd, F_SETFL, FNDELAY);

open () использует опцию O_NDELAY, а затем программа избыточно обеспечивает активацию неблокирующего режима с помощью вызова fcntl () .
Неблокирующий режим может быть допустимым методом выполнения операций ввода-вывода, но ваша программа явно не реализует методы для обработки дополнительных сложностей.

Вам было бы лучше получить доступ к последовательному терминалу в режиме блокировки.
Просто перекодируйте fcntl () вызов:

    fcntl(mainfd, F_SETFL, 0);

2. Инициализация termios содержит ошибки и является неполной.

Следующие два утверждения являются неоднозначными операциями termios:

options.c_cflag &= PARENB;
options.c_cflag &= CS8;

Оба оператора просто сохраняют существующее состояние этих атрибутов. Но вы не знаете, что это за существующее состояние, и, что еще хуже, вы не знаете, будет ли полученное состояние тем состоянием атрибута, которое вам требуется.

Следующее утверждение является ошибочным, поскольку эти атрибуты termios не существуют в элементе структуры c_cflag:

options.c_cflag &= ~(ICANON | ECHO | ISIG);

Инициализация termios, которая пытается неканонический режим, не завершена. Программа оставляет некоторые другие атрибуты неизмененными (например, VMIN и VTIME), и поэтому поведение при чтении может быть непредсказуемым.

3. Настройки termios никогда не применяются.

В вашей программе отсутствует вызов tcsetattr () , так что новые настройки termios действительно применяются.

4. Код возврата из системного вызова read () никогда не обрабатывается.

Код возврата из следующего системного вызова игнорируется:

   read(mainfd, buf, 5000);  

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

5. Программа обращается к неинициализированной памяти.

Ваша программа безоговорочно обрабатывает весь массив из 5000 элементов целочисленного массива.
Однако в соответствии с семантикой системного вызова read () было указано максимум 5000 байтов (а не элементов массива или целых чисел), и системный вызов может (и, скорее всего, будет) возвращать даже меньше данных, чем этот максимум.
Вместо слепой обработки всего массива программа должна получать доступ только к числу байтов (как указано положительным read () кодом возврата), фактически сохраненным в буфере.

Вопрос о том, следует ли рассматривать полученные данные как целые числа со знаком, а не как беззнаковые байты, сомнителен. Поскольку read () не гарантирует и не может возвращать целое число sizeof(int) байтов, слепая обработка полученных данных как целых чисел, вероятно, неверна. Вы пренебрегаете описанием этих данных, кроме упоминания " wave ".

0 голосов
/ 22 апреля 2019

Как прокомментировал @ πάτα ῥεῖ, проблема в том, что буфер объявлен int.

Пожалуйста, измените int в int buf [5000]; на unsigned char или uint8_t.

...