Python e Arduino - Comunicação Serial

python e arduino

Antes de trabalhar com Python e Arduino para comunicação serial, é importante entender esse linguagem. Python é uma linguagem dinâmica e robusta que foi criada por Guido Van Rossum (1991) e escrita em C (CPython). É interpretada e multiplataforma. Sim! "Roda" em Linux, Windows, Mobile, Web, embedded, VxWorks e dentre outras plataformas.

 

É fácil de aprender, muito poderosa e produtiva por diversos aspectos. Vamos citar alguns: sua sintaxe; tipagem forte; funções e blocos de códigos delimitados por indentação; é uma linguagem dinâmica; e oferece estruturas de dados de alto nível (tuplas, listas e dicionários). Precisa de algo rápido para prototipação e validação? Vá de Python!

 

Com poucas linhas e com módulos poderosos é possível implementar fácilmente aplicações que façam uso de comunicação cliente-servidor TCP/UDP, FTP, XML, REST, PDI, threads, GUI, Signal, IPC, banco de dados e comunicação com protocolos industriais, tais como Modbus, RS485 e RS232. Também é possível desenvolver aplicações Web.

 

E no mundo embarcado, Python interpretado é lento! Será? Python não é apenas interpretado (vem novidade por aí, aguarde), você consegue ter acesso ao GPIO pela interface /sys/class/gpio, manipulando de uma maneira muito simples e elegante o seu hardware. Agora vamos conhecer um pouco do leque de opções desse framework começando com uma comunicação serial.

 

Vamos ver do que precisamos e em poucas linhas como comunicamos via serial entre Python e Arduino.

 

 

Configuração do ambiente host

 

Para este artigo será utilizada a distribuição Ubuntu 13.04 (Raring Ringtail) de 64 bits e a seguir são listados os seus pré-requisitos: 

  • Python instalado (eu estou usando a versão 2.7.2);
  • A library python-serial (pyserial);
  • Arduino UNO;
  • Firmware para comunicação serial gravado no Arduino. Na próxima seção do post mostraremos seu sketch.

 

Confirmando a versão do Python e do Pyserial:

 

 

Se por algum motivo o comando --version do python não exibir a versão e/ou o pip não existir na máquina, podemos instalá-los com os seguintes passos:

 

 

Agora Python e pip (Install Python Package) estão instalados. Caso não apareça nada com o comando “pip freeze | grep serial”, você deve executar o comando abaixo:

 

 

Sketch Arduino

 

Para o nosso exemplo usaremos o seguinte programa gravado no Arduino:

 

 

O firmware exemplo irá retornar a temperatura quando for enviado o caractere 't' pela porta serial.

 

Programas de Exemplo com Python e Arduino para comunicação serial

 

Vejamos um exemplo básico para trabalhar com o módulo pyserial:

 

 

Vamos entender como funciona o código acima. Primeiro, na linha 4, antes de qualquer coisa, é importado o módulo serial. Depois deve-se iniciar a conexão com a porta serial com a chamada ao método serial.Serial(PORTA_SERIAL, BAUD_RATE). Como estamos usando Linux e o Arduino é um hardware da classe Serial USB CDC, o dispositivo serial criado é /dev/ttyUSB0. Esse processo não foi testado no Windows, mas me parece que é apenas o número sem o COM. Após feita essa configuração e o baudrate ajustado corretamente, que no meu caso é 9600 bps, na linha seguinte 7 é enviado o caractere ‘5’ ao dispositivo pela porta serial. Se tudo ocorrer bem e algum dispositivo estiver programado para responder, na linha 9 é realizada a leitura dos dados que chegarem na porta serial do computador. Facil não? Python é demais!

 

Agora, utilizando o firmware exemplo, vamos escrever uma aplicação para comunicar com ele.

 

Código (exemplo01.py):

 

 

Saída:

 

 

Beleza, funcionou! Agora vamos entender o que mudou nesse script porque tem coisa nova. Importamos o módulo time (explicaremos a frente o porquê) e para iniciar a porta serial foi realizado o mesmo procedimento do código anterior, porém logo abaixo, comentado, tem o mesmo código de inicialização, com uma diferença. Foi acrescentado um parâmetro novo, o timeout=1, porque no caso de tentarmos conectar e o dispositivo não responder, o programa vai ficar ocioso aguardando, de forma blocante. Porém se usamos timeout=1 tem-se um tempo de 1s para a conexão responder.

 

Foram criadas duas variáveis, uma com o caractere 't' na linha 11 e outra na linha 12 com o mesmo conteúdo, só que usando o valor em ASCII. Na linha 15 implementamos algo que não foi encontrado na documentação, mas como já havia passado por isso antes, achei interessante mencionar. É o tempo necessário para conexão, criando um delay para a escrita de dados. No caso deste exemplo, valores entre 1.5 s e 1.8 s causou um resultado perfeito, mas já teve caso que um delay de .2 ou .5 causarem o mesmo resultado. Na linha 17 ou 18 escrevemos na serial usando codificação ASCII ou o caractere. Logo na sequência são lidos dados da porta serial por meio do método comport.readline() na linha 20, que recebe o valor lido e o armazena na variável VALUE_SERIAL, cujo valor, em seguida, é exibido na tela por meio da função print. Tudo isso ocorrendo sem grandes emoções, terminamos indicando o fim da conexão com comport.close() na linha 25.

 

Só mais um detalhe sobre a conexão estabelecida na linha 8. As ações com a porta serial podem ser manipuladas pela variável comport, a qual recebe essa conexão e podemos dizer que ela é o seu file descriptor até o momento em que encerramos a comunicação.

 

Agora se você prestar atenção no exemplo básico que criamos e no nosso programa, a parte que trata a recepção é diferente. No primeiro exemplo foi utilizado o método ser.read() e depois comport.readline(). É a mesma coisa? Não!

 

Vamos ver o que muda usando o método comport.read() no exemplo01.py.

 

 

Saída:

 

 

Agora usando o terceiro modo, comport.read(3):

 

 

Saída:

 

 

Conseguiu notar a diferença? Vamos listar o que acontece usando cada um dos métodos utilizados.

 

  • comport.readline(): Efetua a leitura dos dados da porta serial até que o caractere ‘\n’ seja recebido, ou seja, uma linha inteira é lida;
  • comport.read(): Realiza a leitura de somente 1 byte da porta serial;
  • comport.read(N): Um número limitado de bytes são lidos, informado pelo parâmetro N do método.

 

 

No nosso caso “27.37” contém 5 caracteres, portanto, 5 bytes. Vamos tirar a prova.

 

 

Saída:

 

 

Além dessas opções de leitura, contendo derivações da função read(), temos outras que poucos conhecem/utilizam quando se usa pyserial. Entre elas podemos citar isOpen, name, o proprio file descriptor e as N opções de configuração da conexão. Vamos analisar de acordo com exemplo abaixo (exemplo02.py):

 

 

Saída:

 

 

São opções interessantes pois com isOpen pode-se inspecionar se a porta já está aberta antes de prosseguir com algo. Usa-se name para se obter o device name da porta conectada e, tendo-se em mãos o nome do file descriptor da conexão, pode-se exibir as suas configurações que estão sendo utilizadas no momento.

 

E se eu quiser mudar algum parâmetro da configuração da conexão serial?

 

 

Adicionamos algumas variáveis globais com as configurações desejadas nas linhas 11 a 16 e aplicamos os novos parâmetros em serial.Serial().

 

Bom, acredito que abordei um conteúdo consistente sobre conexão serial usando Python e de fácil reprodução. Espero que, assim, todos consigam usufruir. Fique à vontade para publicar a sua dúvida nos comentários. 

 

 

Conclusão

 

Como Python é um framework presente na maioria das distribuições Linux para PC, e também nas distribuições padrões de boards como RaspberryPI e BeagleBone Black, é muito fácil fazer algo funcionar! E não se engane pela simplicidade e elegância da linguagem porque ela pode te surpreender em performance e recursos.

 

 

Agradecimentos

 

Gostaria de agradecer ao Diego Sueiro e Thiago Lima pela oportunidade, Fábio Souza pela motivação e o Henrique Rossi pela paciência, dicas e ajuda na revisão.

 

Saiba Mais

 

Arduino UNO

 

Introdução ao Arduino - Primeiros Passos

 

Comunicação Serial no Arduino

 

Referências

 

http://pyserial.sourceforge.net/

http://playground.arduino.cc/interfacing/python#.UzNiv86Gcno

http://cleitonbueno.wordpress.com/arduino-sensor-de-temperatura-parte1/

http://cleitonbueno.wordpress.com/arduino-sensor-de-temperatura-parte2/

NEWSLETTER

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Cleiton Bueno
Proprietário da B2Open onde oferecemos consultoria, treinamentos e desenvolvimento em Sistemas Embarcados. Entusiasta a filosofia open-source, mais de 10 anos de experiências em Linux e FOSS. Em sistemas embarcado do firmware baremetal ao Linux Embedded, e há aproximadamente 8 anos desenvolvendo em (C, Python, Qt e muito Shell Script), além de profiling, hardening e tuning para targets com Linux Embarcado. Graduado em Engenharia da Computação pela UNICEP com ênfase em robótica e sistemas embarcados.

16
Deixe um comentário

avatar
 
13 Comment threads
3 Thread replies
3 Followers
 
Most reacted comment
Hottest comment thread
3 Comment authors
mayconCleiton BuenoAlexandre Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Alexandre
Visitante
Alexandre

Fala rapaz, tudo bem? Dá pra fazer um controlador de válvula com arduíno escrito em linguaguem python? grande abraço

Alexandre
Visitante
Alexandre

Entendo, poderia me informar se eu poderia colocar 3 micropython no processo conectados entre si, o primeiro funcionaria como sensor, o segundo como uma central pra receber a resposta e fazer os cálculos, e o terceiro para funcionar de transmissor e enviar um comando para a válvula abrir tantos %? Desde já grande abraço.

trackback

[…] Python + Arduino - Comunicação Serial […]

maycon
Visitante
maycon

comé q chove na chuva??

trackback

[…] Python + Arduino - Comunicação Serial […]

trackback

[…] Python + Arduino - Comunicação Serial […]

trackback

[…] Python + Arduino - Comunicação Serial […]

trackback

[…] Python + Arduino - Comunicação Serial […]

trackback

[…] Python + Arduino - Comunicação Serial […]

trackback
trackback

[…] Python + Arduino - Comunicação Serial […]

trackback

[…] Python + Arduino - Comunicação Serial […]