Python com порт windows

Доступ к портам с использованием WinApi и dll из Python

или взлет на рожденном ползать

Предыдущие реализации на Питоне аналога проприетарного софта, оказались вполне ничего себе, т. е. все работает, и все похоже на Excel, а значит endusers будут довольны-). Дальнейший простор для полета фантазии немного сдерживается невозможностью доступа к более детальным настройкам портов из стандартных модулей. Но оказывается в Питоне есть такая изумительная вещь как доступ к WinApi функциям, что расширяет перспективы чуть ли не до Cpp-шных. Причем это касается не только портов, а еще кучи всяких вещей. Список и краткое описание поддерживаемых WinApi функций для Питона здесь-
docs.activestate.com/activepython/3.3/pywin32/win32file.html, прорва примеров на Nullege здесь — nullege.com/codes/search/win32file и здесь www.programcreek.com/python/index/1133/win32file, ну и как это принято в Питоне избавление от несовершенства модулей — доступ к WinApi функциям, осуществляется через модуль-) — win32file,- соответственно — pip install win32file.
Вот например как может выглядеть настройка и работа Com порта —
сначала понятно импортируем модуль:

import win32file

hFile = win32file.CreateFile(«COM2», win32file.GENERIC_READ | win32file.GENERIC_WRITE, 0,None,win32file.OPEN_EXISTING, 0,None)

тут разница в названиях — стандартным предшествует ‘win32file.’, и вместо NULLNone
(в названии порта кавычки верхние см. рис. и комменты).
Далее аналогично стандартным процедурам, например в Visual Studo — структура настройки — создаем:

comDCB = win32file.DCB()

comDCB.ByteSize = 8
comDCB.Parity = win32file.NOPARITY
comDCB.StopBits = win32file.ONESTOPBIT
comDCB.BaudRate = 9600

записываем:

win32file.SetCommState(hFile,comDCB)

рамер входного/выходного буфера:

win32file.SetupComm(hFile, 4096, 4096)

вот например маска(1) по приему первого байта, то чего нет в стандартном модуле pyserial:

win32file.SetCommMask(hFile, 1)

win32file.WaitCommEvent(hFile, None)

ну и чтение и запись-

buff=’пишем чего-нибудь-)’

не забываем, что передаем поток байт — переконвертируем строку в массив байт:

ttt=bytearray(buff, encoding=’cp1251′)

win32file.WriteFile(hFile,ttt,None)

ждем эвента по приему первого байта и читаем 19 байт:

win32file.WaitCommEvent(hFile, None)
win32file.ReadFile(hFile, 19)



ну и закрыть:

win32file.CloseHandle(hFile)

C LPT все немного по-другому, хотя и можно создать хэндл как показано выше — запись и чтение в файл повидимому приведет к обращению к стандартному драйверу и невозможности записи без получения ‘ASK’ от ‘принтера’. Поэтому, как мне кажется, более удобное — широко известное решение — inpout32.dll.
Для возни с параллельным портом я использую следующий гипердевайс-

по мотивам того, который был представлен на pcports — www.kernelchip.ru/pcports/PS005.php Повторять мне было лень, я сделал проще — задействованы два регистра из трех — чтения нет(регистр Status не задействован). Питание светодиодов счетверенного семисегментного индикатора от высокого состояния одного порта и низкого состояния другого. Такая схема дает возможность использовать динамическую индикацию и оценить быстродействие разных способов вывода через порт, но… не будем забегать вперед-) Итак, пока просто выведем циферку скажем ‘7’ на второй индикатор:
from ctypes import windll
p = windll.LoadLibrary(«C:\Python34\DLLs\inpout32.dll»)
p.Out32(890, 9)
p.Out32(888, 241)

Читайте также:  Parallel processing in windows

(в названии пути кавычки верхние см. рис. и комменты)

функция возвращает 1 — типа все нормально-)

тут только одно тонкое место, часть выводов в регистре ‘Control’ инвертирована — ru.wikipedia.org/wiki/Параллельный_порт и это надо учитывать.

Ну и в заключение небольшой сравнительный тест результаты которого меня просто поразили. Две аналогичные программы — на старом VC6 и на Python — функционально это динамическая индикация через LPT порт. В VC6 в обработчике таймера производится пересчет(преобразование) числа в первом окошке в семисегментный код, во втором окне — задается время переключения (таймера). Запуск преобразования кнопка ‘Start indicate’, остановка — ‘Stop’.

Short introduction¶

Opening serial ports¶

Open port at “9600,8,N,1”, no timeout:

Open named port at “19200,8,N,1”, 1s timeout:

Open port at “38400,8,E,1”, non blocking HW handshaking:

Configuring ports later¶

Get a Serial instance and configure/open it later:

Readline¶

Be careful when using readline() . Do specify a timeout when opening the serial port otherwise it could block forever if no newline character is received. Also note that readlines() only works with a timeout. readlines() depends on having a timeout and interprets that as EOF (end of file). It raises an exception if the port is not opened correctly.

Do also have a look at the example files in the examples directory in the source distribution or online.

The eol parameter for readline() is no longer supported when pySerial is run with newer Python versions (V2.6+) where the module io is available.

To specify the EOL character for readline() or to use universal newline mode, it is advised to use io.TextIOWrapper:

Testing ports¶

Listing ports¶

python -m serial.tools.list_ports will print a list of available ports. It is also possible to add a regexp as first argument and the list will only include entries that matched.

The enumeration may not work on all operating systems. It may be incomplete, list unavailable ports or may lack detailed descriptions of the ports.

Accessing ports¶

pySerial includes a small console based terminal program called serial.tools.miniterm . It can be started with python -m serial.tools.miniterm

(use option -h to get a listing of all options).

© Copyright 2001-2017, Chris Liechti. Revision a27715f3 .

Библиотека pyserial

Введение

Примеры

Инициализировать последовательное устройство

Читать из последовательного порта

Инициализировать последовательное устройство

Читайте также:  Драйвер для принтера canon g1411 для windows 10

читать один байт с последовательного устройства

читать заданное количество байтов из последовательного устройства

прочитать одну строку из последовательного устройства.

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

Проверьте, какие последовательные порты доступны на вашем компьютере

Чтобы получить список доступных последовательных портов, используйте

в командной строке или

из оболочки Python.

Синтаксис

Параметры

Примечания

Научим основам Python и Data Science на практике

Это не обычный теоритический курс, а онлайн-тренажер, с практикой на примерах рабочих задач, в котором вы можете учиться в любое удобное время 24/7. Вы получите реальный опыт, разрабатывая качественный код и анализируя реальные данные.

Модуль heapq

Введение Примеры Самые большие и маленькие предметы в коллекции Для того, чтобы найти самые большие предметы в коллекции, heapq модуль имеет функцию под названием nlargest , мы передаем его два аргумента, то первый из

Python & Arduino. Просто, быстро и красиво

Оборудование


Недавно я заполучил очень интересную плату: Arduino SS Micro. Эта плата, внешне напоминающая Digispark Attiny 85, тем не менее является китайской версией Arduino Micro, с выведенным выходом USB.

Подробно рассказывать о ней я не буду, ведь это уже сделал пользователь YouTube с ником iomoio, и его обзор можно посмотреть здесь.

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

В качестве управляющего компьютера был использован MacBook Pro с операционной системой macOS Mojave, но не надо закрывать статью, если вы используете Windows или Linux — всё описанное в статье будет работать без изменений на любой операционной системе.

Скетч для Arduino

В качестве примера будет использоваться скетч, включающий и выключающий светодиод, по команде из Serial-порта.

Светодиод в Arduino SS Micro висит на порте SS, и поэтому он автоматически выключается. Не смотря на это, стандартный пример Blink — мигающий светодиод работает.

Если вы будете использовать другую Arduino — не забудьте сменить пин светодиода.

Код для компьютера

Одним из достоинств Python, кроме его кроссплатформенности — наличие гигантского числа библиотек. Нам понадобятся:

  • PySerial — библиотека для работы с Serial-портом
  • PyQT5 — библиотека для создания графического интерфейса

Установка

Для установки, воспользуемся встроенным менеджером пакетов — pip.

Для удобства создания GUI можно установить программу QTDesigner.

Интерфейс

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

Исходный код

Вся работа с устройством происходит благодаря библиотеке PySerial. Но есть несколько нюансов. Например, как узнать, в какой из портов подключено устройство?

На всем прекрасно известном сайте stackoverflow, пользователь с ником Thomas предложил уже готовое решение, которое я и использовал.

Читайте также:  Check what is listening on port linux

Кроме этого необходимо хранить список доступных скоростей:

А теперь соберём вместе дизайн(созданный в QtDesigner и сконвертированный с помощью утилиты pyuic5 в .py файл), функции для сканирования портов и основной код программы.

Основной класс, содержащий в себе всю логику программы

Переменные self.Port и self.Speed — это выпадающие списки, содержащие в себе значения доступных портов и скоростей.

При нажатии на кнопку self.ConnectButton вызывается функция connect, в которой производится попытка подключения к заданному порту с заданной скоростью. Если подключение успешно, то кнопка окрашивается в зелёный цвет, и меняется надпись.

Функция send отправляет в наш порт байтовую строку — заставляющую включить режим мигания.

Таким образом можно управлять различными устройствами, подключёнными к USB.

Данная статья является вводной и обзорной, более полную информацию можно найти например тут:

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

COM Порт в python: как ждать данные, не нагружая CPU

Есть программа, которая принимает данные из COM порта. Возникла проблема, как заставить программу ждать данные и не выполняться дальше?

При использовании бесконечного цикла while, программа нагружает ЦП до 50%.

4 ответа 4

У вас порт настроен на неблокирующее чтение, так как установлен timeout=0 , Либо уберите эту опцию, либо напишите timeout=None , тогда порт у вас будет ждать данные, до тех пор пока они не появятся.

Если же вам все таки нужно неблокирующее соединение, то в цикл while надо добавить небольшую задержку time.sleep , тогда нагрузка процессора уйдет.

Еще есть такая конструкция:

Тут выполняется проверка на наличие данных в очереди порта. Такой способ ожидания, ЦП не нагружает совсем.

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

при таком построении алгоритма while True будет выполнятся постоянно и recCode(data) будет вызываться при приёме каждого символа (байта) в порт, а если 1 количество байтов в пакете не известно(работа по стартовому и конечному символу) или 2 надо ещё обслуживать графический интерфейс и в добавок 3 отправлять данные (сообщения ) в порт , то некоторые символы (принимаемые ) могут потеряться , да и программа (не зависимо сколько ядер у процессора ) будет занята только этим , а если надо 2 порта обслуживать ?

в ассемблере (avr контроллеры), в VB6(x86 и 64), есть возможность применения аппаратных прерываний , т е событие (приём символа портом ) может (при правильной настройке аппаратного узла контроллера или машины), остановить выполнение (или перенаправить поток команд) основного тела программы , выполнить подпрограмму (прерывание) приёма одного символа с возможностью формирования строки по стартовым и конечным символам ( \х05 и \r\n ) и после приёма конечного символа непосредственно в подпрограмме (если условий мало ) обработать — изменив переменные или, выставить флаг готовности принятого сообщения для основной программы , или изменив глобальную переменную для других процессов.

Оцените статью