Continuando os posts sobre comunicação serial com o Arduino utilizando varias linguagens hoje vou trabalhar com Perl, muitas pessoas não conhecem principalmente quando comento com desenvolvedores Windows :), não é meu forte em desenvolver projetos longos mas com pequenos scripts e algo que irá processar uma quantidade grande de dados ele se sai/saiu muito bem, vamos lá então…
Primeiramente o ambiente utilizado será Linux :) novidade né! Bom, para este exemplo precisaremos do Device::SerialPort como não é trivial ele vir junto vamos verificar se possuímos este Modulo.
cleiton@linuxVM:~/projetos/perl/comunicao_serial$ sudo instmodsh Available commands are: l - List all installed modules m <module> - Select a module q - Quit the program cmd? l Installed modules are: DateTime::Format::Mail Perl cmd? q
Como é a primeira vez que nessa VM eu uso algo com Perl, eu não tenho o Device::SerialPort, então vamos instalar que pode ser feito de duas maneiras:
Primeira maneira a la estilo how-to:
cleiton@linuxVM:~/projetos/perl/comunicao_serial$ sudo apt-cache search perl | grep serial [sudo] password for cleiton: libjson-xs-perl - module for serializing/deserializing JSON libanyevent-serialize-perl - serializer and deserializer for AnyEvent libbencode-perl - Perl module for BitTorrent serialisation format libcgi-session-serialize-yaml-perl - YAML and YAML::Syck support for CGI::Session's serializers libdata-amf-perl - Perl module for serialize / deserialize AMF data libdata-dump-streamer-perl - module for serializing a data structure as Perl code libdata-serializer-perl - module that serializes data structures libdata-streamdeserializer-perl - non-blocking deserializer libdata-streamserializer-perl - non-blocking serializer libdevice-serialport-perl - emulation of Win32::SerialPort for Linux/POSIX libfreezethaw-perl - module to serialize and deserialize Perl data structures libmoosex-storage-perl - serialization framework for Moose classes libphp-serialization-perl - Perl module to manipulate serialized PHP data structures libthread-serialize-perl - module to serialize data-structures between threads cleiton@linuxVM:~/projetos/perl/comunicao_serial$ cleiton@linuxVM:~/projetos/perl/comunicao_serial$ cleiton@linuxVM:~/projetos/perl/comunicao_serial$ sudo apt-get install -f libdevice-serialport-perl
Segunda maneira e a que eu prefiro :) baixar o modulo do cpan e compilar, vamos ver :)
cleiton@linuxVM:~/projetos/perl/comunicao_serial$ wget http://search.cpan.org/CPAN/authors/id/C/CO/COOK/Device-SerialPort-1.002.tar.gz cleiton@linuxVM:~/projetos/perl/comunicao_serial$ tar -xvzf Device-SerialPort-1.002.tar.gz ; cd Device-SerialPort-1.002 cleiton@linuxVM:~/projetos/perl/comunicao_serial$ cat README ... cleiton@linuxVM:~/projetos/perl/comunicao_serial$ perl Makefile.PL cleiton@linuxVM:~/projetos/perl/comunicao_serial$ make cleiton@linuxVM:~/projetos/perl/comunicao_serial$ sudo make install
O procedimento acima para construir o modulo pode ser visulizado no arquivo README, onde peguei as informações sobre compilar e instalar o modulo mas ocultei aqui a saída, sobre o make test no meu deu alguns erros porque ele usou o ttyS1 e o meu ftdi esta usando ttyS2 mas enfim, nesta etapa não importaria e atenção ao usar sudo make install ou usar permissão de super-usuário para instalar o modulo, e vamos ver novamente se o modulo esta instalado agora.
cleiton@linuxVM:~/projetos/perl/comunicao_serial$ instmodsh Available commands are: l - List all installed modules m <module> - Select a module q - Quit the program cmd? l Installed modules are: DateTime::Format::Mail Device::SerialPort Perl cmd? q
Mas no nosso script Perl também tem uma etapa que irá checar se o modulo esta OK, caso a mensagem “Device::SerialPort nao encontrado!” for exibida ao executar o script verifique os passos acima pois o modulo não foi encontrado.
Vamos ao nosso código agora:
#!/usr/bin/perl use strict; use warnings; die "Device::SerialPort nao encontrado!" unless(eval{require Device::SerialPort}); use Device::SerialPort; my ($device, $baudrate, $send_write) = @ARGV; my $portcom = Device::SerialPort->new($device); #9600, 8, 1, N do meu FTDI para o Arduino $portcom->baudrate($baudrate); # you may change this value $portcom->databits(8); # but not this and the two following $portcom->parity("none"); $portcom->stopbits(1); $portcom->read_const_time(1000); # 1 segundo para leitura while (1) { # Esse tem varias definicoes e tarefas em outras combinações mas o foco é limpar buffer $portcom->lookclear; # Esse acho que sem misterio, vai escrever na serial meu terceiro parametro enviado $portcom->write($send_write); # $count => numero de caracteres (bytes) # $data => meu dado que chegou, ou nao # read(10) => Quantos bytes irei ler my ($count,$data) = $portcom->read(10); # Se o que foi recebido é maior que 0 ou nosso dado diferente de "" # Tem uns macete com os amigos read_interval(), read_char_time(), read_const_time(), # read_interval(), write_char_time(), write_const_time() if ($count > 0 or $data ne "") { print "nTotal caracteres recebidos: $countn"; print "Dado recebido: $data"; print "Temperatura: $datan"; print "----------------------------------n"; } else { print "n########################################nAguardando recebimento dos dados...n########################################n"; next; } sleep(5); }
Vamos testar nosso código, meu device USB é /dev/ttyS2, meu baudrate 9600 e o caractere a ser enviado é o ‘t’:
cleiton@linuxVM:~/projetos/perl/comunicao_serial$ perl perl_com_arduino.pl /dev/ttyS2 9600 t ######################################## Aguardando recebimento dos dados... ######################################## ######################################## Aguardando recebimento dos dados... ######################################## Total caracteres recebidos: 7 Dado recebido: 27.86 Temperatura: 27.86 ---------------------------------- Total caracteres recebidos: 7 Dado recebido: 27.37 Temperatura: 27.37 ----------------------------------
A tela acima esta funcionando como previsto, caso você ver algo como abaixo:
Use of uninitialized value $nameOrConf in -f at /usr/local/lib/perl/5.12.4/Device/SerialPort.pm line 286. Use of uninitialized value in subroutine entry at /usr/local/lib/perl/5.12.4/Device/SerialPort.pm line 312. Can't call method "baudrate" on an undefined value at perl_com_arduino.pl line 17. cleiton@linuxVM:~/projetos/perl/comunicao_serial$
Provavelmente o /dev/ttyS2 não é o correto, substitua pelo correto do seu device, agora caso o baudrate ou o carácter a ser enviado estiver incorreto a mensagem “Aguardando recebimento dos dados…” ficara aparecendo direto, além do mais o firmware que estou usando para o Arduino é o clássico default para todos desta serie de comunicação serial, caso precisar aqui esta o link.
Não abordei aqui a linguagem em Perl em si, o foco foi trabalhar comunicação serial com ela, então a parte de repetição, condicional, argumentos, variáveis e declarações eu abstrai, mas uma pesquisa rápida no google deve resolver, não sou um desenvolvedor Perl Expert mas sempre digo que Perl é linguagem de macho, não é tão amigável iniciar e tem umas particularidades punk.
Não se limite a apenas as funções passadas, é o básico para funcionar, mas o modulo é extenso e possui N possibilidades e recursos para ajudar.
Bom pessoal, fico por aqui espero ter ajudado com mais esta etapa e até a próxima!
Referências
http://search.cpan.org/~cook/Device-SerialPort-1.002/SerialPort.pm
http://playground.arduino.cc/Interfacing/PERL
Perl – Comunicação serial com Arduino by Cleiton Bueno is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.