Improved decoding of signals from PC COM port
By Fuse Jul 15, 2009 8:38 pm (likely describes improvements in version 8000)
Т.к. Михаил Иванович знает о протоколе больше, чем кто-либо, отвечу ему. Раньше считывание производилось следующим образом: крутился цикл, в котором непрерывно проводился опрос состояния линии с данными. Замерялось время, отведённое на одно слово с данными, и в течении этого времени засекались времена в 8.2 мс и определялись состояния линии в течении этих 8.2 мс, т.е. в каком состоянии (логической единицы или нуля) находится линия, которые и давали биты, из которых состоит слово данных. И так до тех пор, пока не пройдёт время, отведённое на всю посылку (163 бита * 8.2 мс = 1.34 с). И привязка к потоку данных (синхронизация) осуществляется программно, а всё распознавание битов протокола происходит на основании времени, прошедшего от начала этой привязки и отведённое на каждый бит, слово, весь пакет. Т.о., сказывается как неточность определения времени в 8.2 мс, так и неточность определения времени в 8.2*11бит (это слово с данными)=90.2 мс, так и определение времени, отведённого на весь пакет (да простит меня Александр ака chem407, если это не так).
Что изменилось? Сейчас считывание проиходит по такому принципу: ожидается событие уведомления о смене состояния линии (из нуля в единицу или обратно) от драйвера порта. При получении уведомления считывается состояние линии и начинается отсчёт времени. При следующей смене состояния (изменении логического уровня) считывается время, в течении которого длилось предыдущее состояние, считывается новое состояние линии и запускается новый отсчёт времени. По ходу дела получаемые времена нахождения линии в определённом состоянии делятся на 8.2 мс (с округлением), т.е. проводится разбивка на последовательность единичных или нулевых битов уже протокольных и заполняется массив вида [состояние, время в этом состоянии в битах по 8.2 мс каждый]. Суммируется по ходу дела и общее количество бит после начала пакета. При нахождении двух последовательностей в не менее 16 бит единиц (начала двух пакетов) вся последовательность между ними считается одним пакетом. Проверяется, что сумма бит в этом пакете равна числу 163. При этом условии такой пакет (массив) вида [1, 16], [0, 1], [1, 8], [0, 4], [1, 2]...[1, 2] обрабатывается дальше так: из этого массива формируются слова протокола - 16 бит начало, 15 бит ID, 13 слов по 11 бит данных. Из последовательности [1, 16], [0, 1], [1, 8], [0, 4], [1, 2] получается: 16 единиц начала, ID - 1 бит нуля, 8 единиц, 4 нуля, 2 единицы = 15 бит ID. По аналогичному принципу идёт заполнение слов данных из массива. Причём осуществляется проверка, что в начале каждого слова есть один стартовый нулевой бит, а в конце - два единичных бита, тогда биты между ними (8 бит) считаются за правильный байт данных. Только пройдя все такие проверки на соответствие протоколу (что в начале пакета - 16 единиц, потом именно один нуль, потом 12 бит отводится на идентификатор, и есть два единичных бита, потом стартовый нулевой бит есть (это начало слова данных), 8 бит данные, 2 нулевых стоповых бита единиц), данные отображаются в программе.
Т.о., первоначально синхронизируется считывание информации на аппаратном уровне (по приходу извещения от драйвера, т.е. по фронту единицы или нуля) в пределах нескольких протокольных бит (т.е. нет накопления ошибки отсчитывания времени за большой период, как ранее), а далее идёт распознавание соответствия пакетов протоколу, их правильность. В подтверждение вышеизложенного можете проделать следующий эксперимент: запустить на чтение версию 7091 и (достаточно двух последовательно соединённых пальчиковых батареек по 1.5Vх2шт. =3V ) и "поморгать" контактом TE2 по +3V при подключенном E1 к минусу последовательно соединённых батареек по 1.5V. При достаточно частом нарушении контакта (имитируем импульсы) в программе появятся несуразные данные. С версией 8000 такое не пройдёт (вряд ли кому-то удастся симитировать правильный протокол Wink )
Ну вот и сказочке конец, за сим и кончаю Smile