Последовательный протокол вызывает проблемы с переносом кода с C на Python

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

Я нахожусь в процессе переноса протокола связи для последовательного устройства (микроманипулятора) с C на Python для использования в приложении Python, которое разрабатывает моя лаборатория. Компания предоставила нам исходный код небольшой утилиты командной строки, используемой для взаимодействия с устройством. Используя эту логику, наш модуль Python может генерировать правильные/идентичные блоки данных, включая CRC. Однако когда блок данных (идентичный блоку данных, сгенерированному кодом C) отправляется кодом Python, он не получает ответа от устройства. Используя программу мониторинга последовательного порта (Free Serial Port Monitor), я заметил, что связь между Python и устройством в некоторых случаях отличается от утилиты, предоставляемой компанией.

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

Пример журнала из утилиты

А вот скриншот того, что происходит с нашим кодом Python; как вы можете видеть, он отправляет блок данных без ответа.

Пример журнала из python

Что касается другой информации, которая может быть полезной, я использую стандартные последовательные библиотеки Python. Структура блока данных — 14 символов ASCII, начиная с STX и заканчивая ETX. Первые восемь символов данных соответствуют функциям, адресам, значениям и т. д., а последние четыре символа — CRC.

Как я уже сказал, я немного нуб в этом, и я действительно понятия не имею, с чего начать. Любые советы или помощь, или ресурсы, которые могут помочь мне понять это, будут очень признательны, и дайте мне знать, если есть какая-то более конкретная информация, которую я должен предоставить!

http://reentry.mit.edu/extserialport.c

http://reentry.mit.edu/extserialport.h


person DivideByZer0    schedule 20.09.2012    source источник
comment
Возможно, вам следует опубликовать часть вашего кода C и Python. Возможно, вы не настраиваете порт таким же образом. Используете ли вы управление потоком? Кроме того, нет такой вещи, как стандартные последовательные библиотеки Python. В большинстве случаев люди используют pyserial.   -  person TJD    schedule 20.09.2012
comment
В отправленных вами журналах я вижу, что исходная утилита использует STX (0x02) в качестве символа начала сообщения, в то время как вы используете SOH (0x01)   -  person Serge    schedule 20.09.2012
comment
Ах, в таком случае я, скорее всего, использую PySerial, который я установил. Я понятия не имею, использую ли я управление потоком. Я немного повозился с некоторыми параметрами конфигурации, такими как self.setDsrDtr(True) self.setDTR(True) self.setRTS(0) в качестве примера, чтобы индикаторы на последовательном мониторе соответствовали индикаторам, когда программа C работает (хотя я действительно не знаю, что я здесь делаю.)   -  person DivideByZer0    schedule 20.09.2012
comment
Спасибо, Серж, я проверю это.   -  person DivideByZer0    schedule 20.09.2012
comment
Хорошо, @Serge, я еще раз взглянул на файл, и оказалось, что для блока данных (.21000000EABC.) первый символ - 0x02, STX. Что касается предыдущих данных, я не знаю, что это такое и что делает, но они не генерируются кодом блока данных. Возможно ли, чтобы для предварительной связи начальный символ был установлен на STX?   -  person DivideByZer0    schedule 20.09.2012
comment
многие последовательные устройства ждут, пока \r обработает запрос... Я также нашел...   -  person Joran Beasley    schedule 20.09.2012
comment
@ Брендан, да, блок данных в конце разговора начинается с STX. как насчет остальных? Что вы поймете, если я начну писать эту фразу, например, на хинди и только два последних слова на английском? Ваше устройство имеет некоторую логику внутри и имеет некоторые состояния. Почему вы думаете, что он даст правильный ответ для правильно сформированного пакета, если вы заранее отправили мусор с его точки зрения? ;)   -  person Serge    schedule 20.09.2012
comment
@Serge, этот блок данных действительно единственная часть упомянутого разговора, в которой я понимаю, что происходит (и которая напрямую генерируется написанным мной кодом; остальное обрабатывается внутри PySerial). Если у вас есть какие-либо предложения о том, что я должен изучить, чтобы понять это, пожалуйста, дайте мне знать!   -  person DivideByZer0    schedule 20.09.2012
comment
@JoranBeasley, спасибо за предложение, но не повезло с добавлением '\ r' к блоку данных или отправкой его отдельно сразу после...   -  person DivideByZer0    schedule 20.09.2012
comment
??? Вы имеете в виду, что PySerial выдает какие-то данные без вашей воли? К сожалению, у меня нет знаний о python и его библиотеках. Поскольку мы говорим о python, PySerial, скорее всего, распространяется под лицензией GPL, поэтому исходники доступны в сети. Найдите исходники и проанализируйте, что происходит внутри этой библиотеки.   -  person Serge    schedule 20.09.2012
comment
@TJD, я разместил ссылку на код C для интерфейса последовательного порта. Он находится по адресу reentry.mit.edu/extserialport.c и reentry.mit.edu/extserialport.h, если это вообще поможет.   -  person DivideByZer0    schedule 20.09.2012
comment
@Серж рег. предварительные данные, которые передаются (до блока данных), я не уверен, отправляются ли эти данные на само устройство или они информируют Windows API о том, как следует настроить соединение. (Я склоняюсь к последнему.) Такие же данные отправляет рабочая программа.   -  person DivideByZer0    schedule 20.09.2012
comment
Хорошо, не могли бы вы сделать еще один снимок экрана с оригинальной программой, в которой второй столбец расширен настолько, чтобы увидеть тип выполненных IOCTL?   -  person Serge    schedule 21.09.2012
comment
@Serge Вот рабочий: imgur.com/m72rw А вот код из кода Python: imgur.com/1bNm3 Спасибо, что нашли время взглянуть на это!   -  person DivideByZer0    schedule 21.09.2012
comment
отлично. а теперь для вашего приложения. извините, что не спросил в прошлый раз.   -  person Serge    schedule 21.09.2012
comment
@Serge Конечно, это на reentry.mit.edu/SensapexUnit.py. Он собран из кода для взаимодействия с другим последовательным устройством; main() внизу отправляет текстовый пример. Материал после print self.serial_write(chars) относится к другому классу, но никогда не выполняется, так как ответ никогда не получен. Словари вверху предназначены для использования в будущем; теперь они ничего не делают, кроме символов ASCII.   -  person DivideByZer0    schedule 21.09.2012
comment
@Brendan Callahan - исходный код C переводит последовательный порт в необработанный или неканонический режим и, похоже, использует аппаратное управление потоком. Диалоговое окно C указывает на операцию Clear RTS, тогда как ваш код Python, кажется, устанавливает RTS. Кстати, xmitted \r или 0x0D является лишним и должно быть удалено. Вы должны использовать осциллограф, вольтметр или монитор линии и сравнивать состояния линий рукопожатия HW во время передачи оригинального C и Python.   -  person sawdust    schedule 21.09.2012
comment
@sawdust, Спасибо, это очень полезно знать! Упомянутые вами строки, набор RTS и / r, обе закомментированы; они из предыдущей работы с кодом. Однако я понял, что стандартная библиотека pyserial (serial.Serial) не имеет параметров, которые мне нужны для настройки этих параметров, однако я нашел Win32Serial.py, который, похоже, имеет определенные параметры конфигурации, которые установлены по коду C, а также вариант для RAW io. Я не портировал код для использования этого модуля, но я думаю, что я на правильном пути! Спасибо!   -  person DivideByZer0    schedule 21.09.2012
comment
@BrendanCallahan Привет, извините за тормоз. Я согласен с Опилками, что единственная ценная разница заключается в сигнале RTS. Есть еще два отличия, но они не должны влиять на возможность общения. Оба приложения (исходное и ваше) устанавливают для управления потоком значение DTR_CONTROL_ENABLE (см. Справочник по WinAPI), что означает, что DTR включен и остается включенным. Вы упомянули, что используете «стандартную» последовательную библиотеку Python. Этот: pyserial.sourceforge.net? Если ответ «да», то вы можете изменить сигнал RTS с помощью метода setRTS(level=True/False) после инициализации порта.   -  person Serge    schedule 22.09.2012
comment
@Серж, извини за поздний ответ, я не был на работе с прошлой пятницы. Я обнаружил, что win32serial.py, поставляемый с pyserial, предоставляет прямые (привязки?) к серийным настройкам Windows API, которые, похоже, сработали после того, как я скопировал настройки из кода C построчно, включая управление потоком и RTS. Большое спасибо за ваше время и помощь!   -  person DivideByZer0    schedule 27.09.2012
comment
Привет, @Brendan, судя по комментариям, ты сам нашел ответ? Если да, можете ли вы опубликовать его в разделе ответов ниже и принять его, чтобы этот вопрос не отображался как оставшийся без ответа? Спасибо.   -  person dsolimano    schedule 05.10.2012


Ответы (1)


Я обнаружил, что win32serial.py, поставляемый с pyserial, предоставляет прямые (привязки?) к серийным настройкам Windows API, которые, похоже, сработали после того, как я скопировал настройки из кода C построчно, включая управление потоком и RTS. Большое спасибо @Serge за ваше время и помощь!

person DivideByZer0    schedule 06.05.2013