Неправильные данные в серийном порту
От: indee  
Дата: 17.03.16 09:27
Оценка:
Из Raspberry Pi в серийный порт пишу строку "0123456789\r".
Кабель серийного порта подключен к компьютеру где считываю данные.

В основном посланная строка "0123456789\r" считывается правильно:

number char int
0 0 48
1
1 49
2 2
50
3 3 51
4
4 52
5 5
53
6 6 54
7
7 55
8 8
56
9 9 57
10 13

Но иногда вместо ожидаемого набора символов получаю такую последовательность:

number char int
0 ᆰ 86
1 10
2 ᄁ 94
3 j 106
4 ハ 118
5 ᄄ 88
6 8
7 * 42
8 ᅠ 96
9 ( 40
10 8


код:

struct termios PortSettings;


bool OpenPort(){
          
    Port = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);
    
    if(Port == -1){
        printf("%s", "Error of opening port /dev/ttyUSB0");
        printf("error %d opening %s: %s", errno, "", strerror (errno));
        return false;
    }
    else{
        printf("%s", "\n  ttyUSB0 Opened Successfully\n");        
    }    
    
    
    tcgetattr(Port, &PortSettings);
    
    cfsetispeed(&PortSettings,B9600);
    cfsetospeed(&PortSettings,B9600);
    
    PortSettings.c_cflag |=  PARENB;
    PortSettings.c_cflag &= ~CSTOPB;
    
    PortSettings.c_cflag &= ~CSIZE;
    PortSettings.c_cflag |=  CS8;    
    
    PortSettings.c_cflag |= CREAD | CLOCAL;
    
    PortSettings.c_cc[VMIN]  = 0; 
    PortSettings.c_cc[VTIME] = 20;
    
    PortSettings.c_iflag = 0;
    
    
    PortSettings.c_oflag = 0;
    PortSettings.c_lflag = 0;
    
    tcflush(Port, TCIFLUSH);
    
    tcsetattr(Port,TCSANOW,&PortSettings);    
    
    return true;
}


void WriteToPort(){
            
    tcflush(Port, TCIOFLUSH);
    
    write(Port, "0123456789\r", 11);
        
}


Параметры серийного порта: 9600, 8, evenparity, onestopbit

В чем может быть ошибка?

Спасибо!
Re: Неправильные данные в серийном порту
От: kov_serg Россия  
Дата: 17.03.16 15:10
Оценка:
Здравствуйте, indee, Вы писали:

I>Из Raspberry Pi в серийный порт пишу строку "0123456789\r".

I>Кабель серийного порта подключен к компьютеру где считываю данные.
...
I>Параметры серийного порта: 9600, 8, evenparity, onestopbit

I>В чем может быть ошибка?


Дребизг (плохой контакт). Или паразитная ёмкость.
10000110011 11000110001 10100110001 11100110011 10010110001 11010110011 10110110011 11110110001 10001110001 11001110011 11011000001
10110101011 10101000011 10111101001 10101011011 10110111001 10001101001 10001000001 10101010001 10000011011 10001010011 10001000001
Re[2]: Неправильные данные в серийном порту
От: indee  
Дата: 17.03.16 15:51
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Здравствуйте, indee, Вы писали:


I>>Из Raspberry Pi в серийный порт пишу строку "0123456789\r".

I>>Кабель серийного порта подключен к компьютеру где считываю данные.
_>...
I>>Параметры серийного порта: 9600, 8, evenparity, onestopbit

I>>В чем может быть ошибка?


_>Дребизг (плохой контакт). Или паразитная ёмкость.

_>
_>10000110011 11000110001 10100110001 11100110011 10010110001 11010110011 10110110011 11110110001 10001110001 11001110011 11011000001
_>10110101011 10101000011 10111101001 10101011011 10110111001 10001101001 10001000001 10101010001 10000011011 10001010011 10001000001
_>


Вряд ли, паразитный набор символов для строки "0123456789\r" всегда постоянен.
Re[3]: Неправильные данные в серийном порту
От: kov_serg Россия  
Дата: 17.03.16 18:37
Оценка:
Здравствуйте, indee, Вы писали:

I>Здравствуйте, kov_serg, Вы писали:


_>>Здравствуйте, indee, Вы писали:


I>>>Из Raspberry Pi в серийный порт пишу строку "0123456789\r".

I>>>Кабель серийного порта подключен к компьютеру где считываю данные.
_>>...
I>>>Параметры серийного порта: 9600, 8, evenparity, onestopbit

I>>>В чем может быть ошибка?


_>>Дребизг (плохой контакт). Или паразитная ёмкость.

_>>
_>>10000110011 11000110001 10100110001 11100110011 10010110001 11010110011 10110110011 11110110001 10001110001 11001110011 11011000001
_>>10110101011 10101000011 10111101001 10101011011 10110111001 10001101001 10001000001 10101010001 10000011011 10001010011 10001000001
_>>


I>Вряд ли, паразитный набор символов для строки "0123456789\r" всегда постоянен.


Тогда отправляй другой набор данных для опытов

0x00, 0xFF, 0xF0, 0x0F, 0x33, 0xCC, 0x55, 0xAA, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
Re: Неправильные данные в серийном порту
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 17.03.16 20:19
Оценка:
Здравствуйте, indee, Вы писали:

I>В чем может быть ошибка?

Похоже на проблему в памятью. Какой-нибудь буфер не разваливается при чтении/записи?
Sic luceat lux!
Re[4]: Неправильные данные в серийном порту
От: indee  
Дата: 18.03.16 07:43
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Здравствуйте, indee, Вы писали:


I>>Здравствуйте, kov_serg, Вы писали:


_>>>Здравствуйте, indee, Вы писали:


I>>>>Из Raspberry Pi в серийный порт пишу строку "0123456789\r".

I>>>>Кабель серийного порта подключен к компьютеру где считываю данные.
_>>>...
I>>>>Параметры серийного порта: 9600, 8, evenparity, onestopbit

I>>>>В чем может быть ошибка?


_>>>Дребизг (плохой контакт). Или паразитная ёмкость.

_>>>
_>>>10000110011 11000110001 10100110001 11100110011 10010110001 11010110011 10110110011 11110110001 10001110001 11001110011 11011000001
_>>>10110101011 10101000011 10111101001 10101011011 10110111001 10001101001 10001000001 10101010001 10000011011 10001010011 10001000001
_>>>


I>>Вряд ли, паразитный набор символов для строки "0123456789\r" всегда постоянен.


_>Тогда отправляй другой набор данных для опытов


_>0x00, 0xFF, 0xF0, 0x0F, 0x33, 0xCC, 0x55, 0xAA, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80


При другом наборе данных, другой постоянный и неправильный набор данных.
Re[2]: Неправильные данные в серийном порту
От: indee  
Дата: 18.03.16 07:49
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Здравствуйте, indee, Вы писали:


I>>В чем может быть ошибка?

K>Похоже на проблему в памятью. Какой-нибудь буфер не разваливается при чтении/записи?

Как это проверить?
Пробовал Valgrind, все чисто.
Проверял чтение снифером, вроде, кленту данные приходят уже битые, похоже, дисторшен на записи.
Re[3]: Неправильные данные в серийном порту
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 18.03.16 10:03
Оценка:
Здравствуйте, indee, Вы писали:

I>Как это проверить?

I>Пробовал Valgrind, все чисто.
I>Проверял чтение снифером, вроде, кленту данные приходят уже битые, похоже, дисторшен на записи.
Или уходят битыми, например. Если это таки проблема железа, то советы выше дали, но ИМХО, на железо грешить последнее дело.
Sic luceat lux!
Re[5]: Неправильные данные в серийном порту
От: kov_serg Россия  
Дата: 19.03.16 01:04
Оценка:
Здравствуйте, indee, Вы писали:

_>>Тогда отправляй другой набор данных для опытов


_>>0x00, 0xFF, 0xF0, 0x0F, 0x33, 0xCC, 0x55, 0xAA, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80


I>При другом наборе данных, другой постоянный и неправильный набор данных.


Вы меня не поняли. Я имею ввдиду что на таком наборе данных проще смотреть дребизг.
Данные в ком порте идут последовательно [ 0 (Стратовый бит), Бит0, Бит1, Бит2 ... Бит7, Четность, 1 (стоп бит) ] [...] при этом штатно 0=+12в, 1=-12в
И комбинации 1111 [010101010P1] [010101010P1] [010101010P1] [010101010P1] [010101010P1] 1111 Сответстует строка 0x55,0x55,0x55,0x55,0x55.
Вызывает самую высокую частоту можно даже послушать динамиком.
Далее стартовая последовательнось обычно должна быть максимально энергоёмкой, так что 0x00 0xFF самое оно.

Еще вопрос как часто приходят неправильные данные?

Как вариант
поправь открытие порта
//Port = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);
Port = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);

убери flush
   // tcflush(Port, TCIOFLUSH); -- поробуй без этого
   static const char data[]={ 0x00, 0xFF, 0xF0, 0x0F, 0x33, 0xCC, 0x55, 0xAA, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
   write(Port, data, sizeof(data) );

Еще можешь сделать 2 стоповых бита вместо одного.
Заведи счетчик отправленых пакетов и передавай его в пакете.

Поменяй кабель на более короткий
Обычная отладка.
Re[2]: Неправильные данные в серийном порту
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 20.03.16 09:33
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Дребизг (плохой контакт). Или паразитная ёмкость.

_>10000110011 11000110001 10100110001 11100110011 10010110001 11010110011 10110110011 11110110001 10001110001 11001110011 11011000001
_>10110101011 10101000011 10111101001 10101011011 10110111001 10001101001 10001000001 10101010001 10000011011 10001010011 10001000001

Стартовый бит это логическая 0, соответственно, надо подправить все начала.
(Хотя какой-то чёткой картины от этого всё равно не возникает.)
The God is real, unless declared integer.
Re[6]: Неправильные данные в серийном порту
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 20.03.16 09:36
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Далее стартовая последовательнось обычно должна быть максимально энергоёмкой, так что 0x00 0xFF самое оно.


Хм, откуда такое правило?

_>Еще вопрос как часто приходят неправильные данные?


_>убери flush

_> // tcflush(Port, TCIOFLUSH); -- поробуй без этого

Это сделает только хуже.

_>Поменяй кабель на более короткий


Ещё можно повысить/понизить скорость и сравнить частоту, если с ростом скорости растёт частота ошибки, то это, скорее всего, ошибка аналогового уровня.
The God is real, unless declared integer.
Re[4]: Неправильные данные в серийном порту
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 20.03.16 09:37
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Или уходят битыми, например. Если это таки проблема железа, то советы выше дали, но ИМХО, на железо грешить последнее дело.


Ну да — с какой там ревизии 16550A сделали действительно безглючный fifo?
The God is real, unless declared integer.
Re: Неправильные данные в серийном порту
От: Vain Россия google.ru
Дата: 20.03.16 12:05
Оценка:
Здравствуйте, indee, Вы писали:

I>Но иногда вместо ожидаемого набора символов получаю такую последовательность:

А иногда, это когда? С определённым периодом или случайно?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[7]: Неправильные данные в серийном порту
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 21.03.16 07:32
Оценка:
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, kov_serg, Вы писали:


_>>Далее стартовая последовательнось обычно должна быть максимально энергоёмкой, так что 0x00 0xFF самое оно.


N>Хм, откуда такое правило?


_>>Еще вопрос как часто приходят неправильные данные?


_>>убери flush

_>> // tcflush(Port, TCIOFLUSH); -- поробуй без этого

N>Это сделает только хуже.


_>>Поменяй кабель на более короткий


N>Ещё можно повысить/понизить скорость и сравнить частоту, если с ростом скорости растёт частота ошибки, то это, скорее всего, ошибка аналогового уровня.

Кстати, понижение скорости это реальная тема? например до 2400.
Sic luceat lux!
Re[2]: Неправильные данные в серийном порту
От: indee  
Дата: 21.03.16 07:47
Оценка:
Здравствуйте, Vain, Вы писали:

V>Здравствуйте, indee, Вы писали:


I>>Но иногда вместо ожидаемого набора символов получаю такую последовательность:

V>А иногда, это когда? С определённым периодом или случайно?

Случайно, примерно, 1 к 1000.
Re[3]: Неправильные данные в серийном порту
От: Vain Россия google.ru
Дата: 21.03.16 21:33
Оценка:
Здравствуйте, indee, Вы писали:

I>>>Но иногда вместо ожидаемого набора символов получаю такую последовательность:

V>>А иногда, это когда? С определённым периодом или случайно?
I>Случайно, примерно, 1 к 1000.
Это относительно того набора, что в примере или, к примеру, здесь 1 это 1МБ данных, ну т.е. каждые 1ГБ?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[7]: Неправильные данные в серийном порту
От: kov_serg Россия  
Дата: 22.03.16 03:51
Оценка:
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, kov_serg, Вы писали:


_>>Далее стартовая последовательнось обычно должна быть максимально энергоёмкой, так что 0x00 0xFF самое оно.


N>Хм, откуда такое правило?

Элементарно. Если вы хотите привлечь внимание надо громко рявкнуть потом можно говорить.

_>>Еще вопрос как часто приходят неправильные данные?


_>>убери flush

_>> // tcflush(Port, TCIOFLUSH); -- поробуй без этого

N>Это сделает только хуже.

Не надо предположений. Просто попробуй.

_>>Поменяй кабель на более короткий


N>Ещё можно повысить/понизить скорость и сравнить частоту, если с ростом скорости растёт частота ошибки, то это, скорее всего, ошибка аналогового уровня.

Это правильно. Т.к. если у вас например силовая электроника или авто где рядом система зажигания, то интерфиренция сигналов, помехи
вполне нормальное явление. Поэтому используют контрольные суммы и короткие кадры.
XXX-------------XXX-------------XXX-------------XXX-------------XXX --переодический шум
----DD----DD----DX----DD----DD----XD----DD----DD----DD----DD----DX- --полезный сигнал


Хотя у вас
I>>>Но иногда вместо ожидаемого набора символов получаю такую последовательность:
V>>А иногда, это когда? С определённым периодом или случайно?

I>Случайно, примерно, 1 к 1000.


Очень высокая вероятность. Постоянный неправильный кадр. Скорее всего это прогамный косяк.
Причем очень советую проверить не только передатчик. Но код приёмника.
Т.к. у вас передача с битом четности и не возникает ошибок. То полюбому где-то ляп.
Re[8]: Неправильные данные в серийном порту
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 22.03.16 05:41
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Хотя у вас


Это не у меня, я никак не связан с автором темы.

_>>>убери flush

_>>> // tcflush(Port, TCIOFLUSH); -- поробуй без этого
N>>Это сделает только хуже.
_>Не надо предположений. Просто попробуй.

Мне не на чем пробовать, но я таки прошу обоснований к этому пункту.

По остальному — нет возражений (кроме неоднозначной "энергоёмкости" посылок).
The God is real, unless declared integer.
Re: Неправильные данные в серийном порту
От: andrey82  
Дата: 22.03.16 07:25
Оценка:
Здравствуйте, indee, Вы писали:

I>Из Raspberry Pi в серийный порт пишу строку "0123456789\r".

I>Кабель серийного порта подключен к компьютеру где считываю данные.

I>Параметры серийного порта: 9600, 8, evenparity, onestopbit


Подкину еще версии:
1) Неточно согласованные скорости — частота порта (baudrate) формируется делением исходной частоты на целый коэффициент, что приводит к погрешностям. Актуально для МК со встроенным UART контроллером. К RPi скорее всего неприменимо, и искажения пакетов были бы практически постоянно.
2) В RPi/Raspbian последовательный порт /dev/ttyAMA0 изначально используется системой (консолью), надо отключать использование порта. Возможно, что и в другие порты может какой-то процесс вклиниваться.
3) Копать в сторону железа — как выполнено подключение к компьютеру? Кабель USB-UART на CP1202/FTDI со стороны ПК к UART линиям порта RPi? Или USB-RS232 адаптеры с обеих сторон? (/dev/ttyUSB0 намекает на этот вариант). В идеале посмотреть сигналы на линии логическим анализатором, может там длина битовых интервалов на пределе допустимого.
Re[9]: Неправильные данные в серийном порту
От: kov_serg Россия  
Дата: 29.03.16 12:00
Оценка:
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, kov_serg, Вы писали:


_>>Хотя у вас


N>Это не у меня, я никак не связан с автором темы.


_>>>>убери flush

_>>>> // tcflush(Port, TCIOFLUSH); -- поробуй без этого
N>>>Это сделает только хуже.
_>>Не надо предположений. Просто попробуй.

N>Мне не на чем пробовать, но я таки прошу обоснований к этому пункту.

Некоторрые реализации flush могут не досылать данные, а просто сбрасывать контроллер uart.
соответственно если скорость 9600 то лучше не tcflush, а tcflush, sleep(2ms) т.к. 1байт ~ 1мс
Выдержать паузу очень важно. Т.к. помимо обычных rs232 бывают rs485 с длинной в километры, там еще интереснее глюки бывают.

N>По остальному — нет возражений (кроме неоднозначной "энергоёмкости" посылок).

Не очень понимаю что вызывает возражения. Это больше к физике процесса относится смотри телеграфное уравнение.
Если у тебя на линии есть чему поглащать сигнал, то более энергоёмкий пройдёт дальше и детектировать его проще.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.