PySerial - Utilize o Python para controlar a interface serial
[Warning: This post is a backup recovery from my previous Wordpress blog. All content was automatically converted accessing a MySQL database using a Python script (details). Mostly are in Portuguese but if you are interest I can translate to English. If you found any problem dont’t hesitate to contact me in comments.]
Embora seja uma tecnologia antiga ainda utilizada amplamente, muitos dos projetos eletrnicos no estilo "faa voc mesmo" utilizam o protocolo de comunicao serial. Este post mostra como possvel (e fcil) utilizar a linguagem Python para fazer a interface com a porta serial (RS232) seja no Windows, GNU/Linux, *BSD, Solaris, etc. Com o PySerial dentro de um sistema embarcado pode-se fazer coisas muito interessante como direcionamento do fluxo de dados e coleta de dados para depurao.
1. Instalao
Consideraremos a utilizao algum sistema operacional GNU (com a linguagem Python instalada) para o desenvolvimento, a instalao do mdulo feita atravs do gerenciador de pacotes da sua distribuio ou pelo easy_install
easy_install pyserial
2. Uso
Se voc no possuir onde testar utilize o prprio cabo serial: faa um curto entre os pinos 2 (RX) e 3 (TX).
Abra um programa para acessar a serial como o gtkterm (modo grfico) ou minicom (modo texto) e veja que o que voc digitar ir ecoar. Para os exemplos utilizaremos o gtkterm e o primeiro ser para escrita.
#!/usr/bin/python import serial ser = serial.Serial(0) # abre a primeira serial que encontrar # (/dev/ttySX). No Windows seria a COMX. print ser.portstr # mostra a porta utilizada ser.write("hello") # envia ser.close() # fecha a porta
Aps rodar esse exemplo voc ir ver no gtkterm o texto "hello". Agora vamos ver como fazer uma leitura:
#!/usr/bin/python import serial ser = serial.Serial(0) ser.read() # espera 1 byte (um caracter) ser.close()
O programa ficar travado esperando receber algum dado da serial (veja o parmetro timeout). Ao utilizar o gtkterm e o cabo em curto no ir funcionar muito bem para enviar muitos bytes (teste feito com o conversor USB/Serial), mas possvel fazer a prova do conceito. Se voc digitar uma letra no gtkterm ir v-la na interface de linha de comando do Python.
3. Parmetros
At agora no falamos dos parmetros da porta serial, eles vo depender muito do equipamento que voc ir se conectar. Por padro o construtor define os seguintes valores:
ser = serial.Serial( port=None, # nmero do device, a numerao comea no zero # Se algo falhar, o usurio pode # espeficiar a string do device (/dev/ttyX, COMX, # etc). Se nada especificado um objeto com a # porta fechada e no configurada criado. baudrate=9600, # baud rate bytesize=EIGHTBITS, # nmero de databits parity=PARITY_NONE, # bit de paridade stopbits=STOPBITS_ONE, # nmero de bits de parada timeout=None, # ajusta um timeout, coloque "None" para no haver xonxoff=0, # ativa controle de fluxo por software rtscts=0, # ativa controle de fluxo RTS/CTS interCharTimeout=None # Inter-character timeout, "None" para desabilitar )
Veja que se no preenchermos nada ele ir utilizar os valores padro. Pode-se ajustar os valores no construtor da classe ou ento separadamente, por exemplo, para reajustar o timeout faa:
ser.timeout=3 # Aguarda 3 segundos quando for fazer # um read() ou at completar o tamanho em bytes # especificado.
No mbito geral importante definir os valores de port, baudrate e o timeout, embora em muitas aplicaes embarcadas e modens o acesso aos pinos de controle RTS/CTS so essenciais . Os mtodos mais populares para as instncias so:
# abre a porta serial open() # fecha a porta imediadamente close() # muda o baudrate setBaudrate(baudrate) # l "size" caracteres , por padro l 1 byte read(size=1) # escrever um dado na porta serial write(s) # limpa o buffer de entrada, desconsidera todo o contedo flushInput() # limpa o buffer da sada, interrompe a sada. flushOutput()
Exemplo:
>>> import serial >>> ser = serial.Serial(0) >>> ser Serial(port='/dev/ttyUSB0', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=0, rtscts=0, dsrdtr=0) >>> print ser.isOpen() True
4. Dicas
Estas dicas so arbitrrias, so pequenas partes que fui utilizando ao longo do tempo e tentei organiz-las aqui.
- Para enviar um contedo hexadecimal utilze \x, por exemplo, para enviar o caracter '1' e '2' faa ser.write('\x31\x32')
- Pode-se converter para outras bases entre 2 e 36 utilizando int(), exemplo:
>>> print int('g',18) 16
- No GNU/Linux, se voc utilizar algum conversor USB/Serial e seu sistema produzir um erro ao tentar iniciar a porta pelo construtor serial.Serial(0) porqu o device /dev/ttyUSBX no foi encontrado, uma soluo a abordagem abaixo.
import serial import glob def scan(): """busca por portas disponveis, retorna uma lista de dispositivos""" return glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyS*') ser = serial.Serial(scan()[0])
- Sobre os conversores USB/Serial: normalmente as distribuies entregam o Linux (kernel) com o suporte aos conversores seriais. Se o seu kernel no suportar ou voc tem alguma particularidade, veja no menu de configurao:
Device Drivers ---> Character devices ---> Serial drivers --->
- Utilize o PyQT ou PyGTK para incrementar a interface com o usurio.
Como uma aplicao especfica para cada caso, preferiu-se no dar nenhum detalhe do uso particular, acredito que o objetivo motivar o leitor a acessar a documentao disponvel e procurar fazer os prprios testes. Na referncia h bons exemplos e rapidamente voc ir fazer seus programas utilizando a serial. Com Python nem a imaginao o limite ;-)