2014-06-03 3 views
2

Я тестирую последовательную реализацию и открываю последовательный порт (у меня есть Arduino, выплевывающие линии данных компаса). Иногда я получаю кучу нулей. Я думал, что это были оставшиеся данные ранее, но это, похоже, не так (0)Чтение последовательного порта с исходными данными приводит к множеству нулей

Это реализация на языке программирования языка программирования, написанная на C, и я тестирую это на Linux, но имели аналогичные результаты с Windows.

strace вывод показывает это на первом прочтении:

read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 34815) = 1544 
write(1, "== ", 3==)      = 3 
write(1, "#{\n00000000000000000000000000000"..., 503#{ 
0000000000000000000000000000000000000000000000000000000000000000 
0000000000000000000000000000000000000000000000000000000000000000 
0000000000000000000000000000000000000000000000000000000000000000 
0000000000000000000000000000000000000000000000000000000000000000 
0000000000000000000000000000000000000000000000000000000000000000 
0000000000000000000000000000000000583A20353333202020593A20313020 
20205A3A2033313920202058733A2033393520202059733A203136312020205A 
733A20323933202020483A20302E3436202020413A...) = 503 

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

tcflush(ttyfd, TCIOFLUSH); 

но, похоже, не помогает в этом вопросе. Любые мысли о том, как очистить это?

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

Открытие порта:

ttyfd = open(&devpath[0], O_RDWR | O_NOCTTY | O_NONBLOCK); // ttyUSB0 in this case 

Изменение настроек:

if (speeds[n] == 0) speed = B115200; // invalid, use default 

    cfsetospeed (&attr, speed); 
    cfsetispeed (&attr, speed); 

    // C-flags - control modes: 
    attr.c_cflag |= CREAD | CS8 | CLOCAL; 

    // L-flags - local modes: 
    attr.c_lflag = 0; // raw, not ICANON 

    // I-flags - input modes: 
    attr.c_iflag |= IGNPAR; 

    // O-flags - output modes: 
    attr.c_oflag = 0; 

    // Control characters: 
    // device is non-blocking (polled for changes): 
    attr.c_cc[VMIN] = 0; 
    attr.c_cc[VTIME] = 0; 

    // Make sure OS queues are empty: 
    tcflush(ttyfd, TCIOFLUSH); 

    // Set new attributes: 
    if (tcsetattr(ttyfd, TCSANOW, &attr)) return 2; 

Это код Arduino передачи данных из модуля OSEPP Compass

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

+2

, не видя фактического кода, особенно обработчики прерываний RX и TX, похоже, что прерывания стреляют и читают/записывают символ, даже если ни один из них недоступен. – user3629249

+0

Добавил часть кода – kealist

+0

Предполагая, что обработка вашей программы буферов чтения является разумной, я бы сказал, что, поскольку Andrino отправляет, она несет ответственность за то, что получено. – alk

ответ

1

Проанализировано техническое описание IC.

Смотрите страницу 14: Link

режим непрерывного измерения. В режиме непрерывного измерения устройство непрерывно выполняет измерения и помещает результат в регистр данных. RDY поднимается, когда новые данные размещаются во всех трех регистрах. После включения питания или записи в регистр режима или конфигурации первый измерительный набор доступен из всех трех регистров вывода данных после периода 2/f_DO, и последующие измерения доступны с частотой f_DO, где f_DO является частота вывода данных

Согласно документации Arduino, библиотека проводов работает на частоте 100 кГц. 2/100KHz == 20uS. Предполагая, что ваш Arduino работает на частоте 16 МГц (1 цикл == 62.5ns), вы, вероятно, не дожидаетесь достаточно долго, чтобы читать регистры.

Чтобы сделать ваш код более надежным, я рекомендую проверить бит RDY регистра состояния, прежде чем выполнять какие-либо чтения. Данные, скорее всего, верны, но вам нужно учитывать время запуска, которое проводит IC.

Если вы сделаете это и обнаружите ту же проблему, которая по-прежнему происходит, то по крайней мере вы еще выделите проблему.


В качестве альтернативы вы можете поместить 500мс задержки в нижней части основного контура в верхней части, если вы просто хотите быстро взломать.

+0

Не успел это подтвердить, но я считаю, что это, вероятно, причина. Спасибо! – kealist

Смежные вопросы