Prom Electric
СПб, Швецова, 23Б
mail@prom-electric.ru
+7 (812) 952-38-45
+7 (921) 952-38-45
Отправить сообщение
\/
Сообщение отправлено!

Скрипт для автоматического определения настроек COM порта на Python 3


Возможно проведение работ с доставкой оборудования из Вашего города Ашберн транспортной компанией "Деловые Линии", дополнительная информация по запросу на mail@prom-electric.ru.

 

У многих встраиваемых систем, устройств промышленной электроники для связи с внешними устройствами или выполнения сервисных функций, в том числе считывания диагностических кодов неисправностей, отладки, обноления встроенного программного обеспечения(прошивки) до сих пор присутствует последовательный интерфейс RS232, более известный как COM порт. В подобных устройствах таких интерфейсов может быть несколько и не всегда каждый интерфейс имеет свой разъем DB9. Довольно часто служебные или сервисные интерфейсы выполнены в виде штыръевого male-разъема c 3, 4, 5 пинами или могут быть не распаяны на печатной плате. При наличии исправного источника питания в исследуемом устройстве для связи нам достаточно 3 проводов: RX, TX, GND. Если источник питания отсутствует или неисправен, подключаем дополнительный провод питания Vcc, проверив соотвествие уровней напряжения (5В или 3.3В) порта компьютера и исследуемого устройства. В таких случаях ищем datasheet на используемые микросхемы и подключаемся в удобном месте. 

 

Работа скрипта проверена на системах Windows 7 x64, Windows 10 x64, Ubuntu 16.04 x64, Debian 8 x32. Для запуска программы необходим установленный интерпретатор python3 и библиотека pyserial. Скачать версию для различных операционных систем можно на официальном сайте https://www.python.org/downloads/ . Вне зависимости от разрядности установленной операционной системы лучше устанавливать версию Python 3 x32. В большинстве Linux систем интерпретатор Python присутствует по умолчанию, но необходимо проверить его версию. Для этого запускаем окно терминала и вводим:

sudo apt-get install python3
sudo python3

 

Версия 3.4 установлена, проверяем наличие библиотеки pyserial:

sudo apt-get install python3-pip
sudo pip3 install pyserial

 Далее в домашней директории создаем файл в любом текстовом редакторе:

cd ~
nano comscanner.py

 

 И сохраняем текст скрипта:

#comscanner 0.1
#Скрипт для автоматического определения скорости COM порта путем перебора скорости, четности, стоп-бит
#по заданной сигнатуре в полученном ответе от устройства с возможностью отправки команды перед получением данных
#для отправки команды раскомментировать строку №74 - #ser.write(cmd)
#Работа скрипта проверена на адаптерах USBtoCOM ch340, ft232 в Windows 10 x64, Debian 8 x32, Raspbian jessie
#info@prom-electric.ru


import sys, glob, time, serial, os, struct, subprocess, threading, struct


std_speeds = ['1843200', '921600', '460800', '230400', '115200', '57600', '38400', '19200', '9600', '4800', '2400', '1200', '600', '300', '150', '100', '75', '50'] #Скорость COM порта
paritys = ['N', 'E', 'O']   #Бит четности
stopbitss = [1, 2]             #Количество стоп-бит
bite_size = 8               #Биты данных
t_out = 1                   #Таймаут в секундах, должен быть больше 1с
flag1=0                     #Флаг для остановки программы, устанавливается в 1, если найдена сигнатура  
reading_bytes = 10          #Количество байт для чтения после открытия порта
keyword=b'\x00\x00\x00'     #!Сигнатура для поиска
cmd = b'\x00\x34\x65'       #!Команда перед началом приема
ser = serial.Serial()


################# Поиск доступных портов windows, linux, cygwin, darwin
def serial_ports():
    if sys.platform.startswith('win'):
        ports = ['COM%s' % (i + 1) for i in range(256)]
    elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
        # this excludes your current terminal "/dev/tty"
        ports = glob.glob('/dev/tty[A-Za-z]*')
    elif sys.platform.startswith('darwin'):
        ports = glob.glob('/dev/tty.*')
    else:
        raise EnvironmentError('Unsupported platform')

    result = []
    for port in ports:
        try:
            s = serial.Serial(port)
            s.close()
            result.append(port)
        except (OSError, serial.SerialException):
            pass
    return result
##################################

print('Сигнатура для поиска ', end = '')
print(keyword)

ports=serial_ports()
if ports:
        print('Доступные порты:')
        print(ports)
        if len(ports)>1:
            ser.port = input('Введите адрес COM порта ')
        else:
            ser.port = ports[0]
            print ('Работаем с портом '+ser.port)
else:
    print('\nНет доступных COM портов, проверьте подключние.\n')
    sys.exit()

try:
    for stop_bit in stopbitss:
        for parit in paritys:
            for com_speed in std_speeds:
                ser.close()
                ser.baudrate = com_speed
                ser.timeout = t_out
                ser.bytesize = bite_size
                ser.parity = parit
                ser.stopbits = stop_bit
                ser.open()
                #ser.write(cmd)                                       #!Раскомментировать при необходимости отправки команды в устройство для инициализации связи                    
                message_b=ser.read(reading_bytes)
                if flag1==1:
                    break
                if message_b:
                    print ('\nRAW data on '+ser.port+', '+com_speed+', '+str(ser.bytesize)+', '+ser.parity+', '+str(ser.stopbits)+':')
                    print ('---------------------')
                    print (message_b)
                    print ('---------------------')
                    try:
                        if keyword in message_b:
                            print ('\n\033[0;33mСигнатура ', end = '') #желтый цвет текста
                            print(keyword, end = '')
                            print(' найдена при следующих настройках: \n'+ser.port+', '+com_speed+', '+str(ser.bytesize)+', '+ser.parity+', '+str(ser.stopbits))
                            print('\x1b[0m')
                            ser.close()
                            flag1=1
                            break
                        else:
                            ser.close()
                    except:
                        print ('error decode')
                        print ('---------------------')
                        ser.close()
                else:
                    print('timeout on '+ser.port+', '+com_speed+', '+str(ser.bytesize)+', '+ser.parity+', '+str(ser.stopbits))
                    print ('---------------------')
                    ser.close()
    if flag1 == 0:
        print('Поиск завершен, сигнатура не найдена')
except serial.SerialException:                                
    print ('Ошибка при открытии порта '+ser.port)
    sys.exit()
                                      
sys.exit()

Для запуска вводим:

sudo python3 comscanner.py

Пример работы скрипта:

 

Запуск в Windows 10:

Перезагружаемся после установки интерпретатора Python 3, сохраняем файл comscanner.py, например, в каталог C:/comscanner/ . Нажимаем сочетание Win+X, в появившемся меню выбираем пункт "Командная строка (администратор)" и вводим:

c:
cd c:\comscanner
comscanner.py

Если произошла ошибка "comscanner.py не является внутренней или внешней командой, исполняемой программой или пакетным файлом." - нужно узнать полный путь к установленному Python 3. Запускаем проводник, нажимаем "Вид" - "Показать или скрыть" - отмечаем пункты "Расширения имен файлов" и "Скрытые элементы", открываем - "Локальный диск C:" - Пользователи (Users) - Имя пользователя - AppData - Local - Programs - Python - Python3x . Копируем из адресной строки полный путь как текст и вставляем в открытое окно командной строки. Далее дописываем

python.exe c:\comscanner.py

 

По умолчанию считываются первые 10 байт данных, при необходимости изменяем в переменной reading_bytes. Сигнатуру для поиска (переменная keyword) берем из datasheet на компонент или из инструкции на исследуемое устройство. Если устройство ждет команды для начала передачи дописываем текст команды в переменную cmd и убираем знак комментария # из строки 72   #ser.write(cmd) . Команда отправляется последовательно перед чтением и до получения искомой сигнатуры.

 

Последовательность перебора по умолчанию:

стопбит=1, четность=нет, скорость на уменьшение от 1843200 до 50
стопбит=1, четность=чет, скорость на уменьшение от 1843200 до 50
стопбит=1, четность=нечет, скорость на уменьшение от 1843200 до 50
стопбит=2, четность=нет, скорость на уменьшение от 1843200 до 50
стопбит=2, четность=чет, скорость на уменьшение от 1843200 до 50
стопбит=2, четность=нечет, скорость на уменьшение от 1843200 до 50

 

Скачать скрипт comscanner 0.1

 mail@prom-electric.ru

Ремонт частотных преобразователей в Санкт-Петербурге