Arduinoã¨AnyEventã使ã£ã¦ï¼ã¢ã¼ã«ã¹ä¿¡å·ã§SOS !
AnyEventã§ã¿ã¤ãã¼
YAPC::Asiaでの宮川さんの発表ãèãã¦
perl -MAnyEvent -le ' map{ $i = $_; my $c = AnyEvent->condvar; my $w; $w = AnyEvent->timer( after => $i, cb => sub {$w; print "OK"; $c->send}); $c->recv }(0.1,0.5,1,2,0.1)'
ãªãã¦ã¯ã³ã©ã¤ãã¼ã§ç°¡åãªã¿ã¤ãã¼ãä½ããäºãç¥ãã¾ããï¼ããã§æãã¤ããã®ãã¢ã¼ã«ã¹ä¿¡å·ï¼ããã¹ããå ¥åããã¨ä½ãã¡ãã¡ãã¨ç¹æ» ãããã®ãä½ã£ã¦ã¿ããã¨æãã¾ããï¼ã¾ãï¼CPANã§Morseããã¼ã¯ã¼ãã«ãã¦æ¤ç´¢ãã¦ã¿ãã¨ããï¼ã¢ã¸ã¥ã¼ã«ã¯ããã¤ãã§ã¦ãã¾ãããï¼ããã¹ããçç¹ï¼'-'ï¼ã¨é·ç¹ï¼'ã¼'ï¼ã«å¤æãããã®ã°ããã§ï¼é·ç¹ãçç¹ã®ä½åã®æéãªã®ããªãã¦ãã¨ã¯ãããã¾ããã§ããï¼ããã§wikipediaãæ¢ãã¦ã¿ãæï¼詳しい説明ãè¼ã£ã¦ãã¾ããï¼
é·ç¹1ã¤ã¯çç¹3ã¤åã®é·ãã«ç¸å½ããåç¹ã®éã¯çç¹1ã¤åã®ééãããããã¾ããæåééã¯çç¹3ã¤åãèªééã¯çç¹7ã¤åããã¦åºå¥ããã
ãã¾ãã«ã符å·åæ¹å¼è©³èª¬ãã¨ããã®ããã£ã¦ï¼ãããå
ã«ãããã¨ã§ç°¡åã«ç¬¦å·åãããã¨ãã§ãã¾ããï¼ããã
以ä¸ã®Converterã¢ã¸ã¥ã¼ã«ã§ãï¼
package Converter; use Moose::Role; use namespace::clean -except => 'meta'; requires 'output'; has 'encoding_rule' => ( is => 'rw', isa => 'HashRef[Str]', lazy_build => 1, ); sub _build_encoding_rule { return { A => '[-_---_]', B => '[---_-_-_-_]', C => '[---_-_---_-_]', D => '[---_-_-_]', E => '[-_]', F => '[-_-_---_-_]', G => '[---_---_-_]', H => '[-_-_-_-_]', I => '[-_-_]', J => '[-_---_---_---_]', K => '[---_-_---_]', L => '[-_---_-_-_]', M => '[---_---_]', N => '[---_-_]', O => '[---_---_---_]', P => '[-_---_---_-_]', Q => '[---_---_-_---_]', R => '[-_---_-_]', S => '[-_-_-_]', T => '[---_]', U => '[-_-_---_]', V => '[-_-_-_---_]', W => '[-_---_---_]', X => '[---_-_-_---_]', Y => '[---_-_---_---_]', Z => '[---_---_-_-_]', '.' => '[-_---_-_---_-_---_]', ',' => '[---_---_-_-_---_---_]', '/' => '[---_-_-_-_---_]', ':' => '[---_---_---_-_-_-_]', '\'' => '[-_---_---_---_---_-_]', '-' => '[---_-_-_-_-_---_]', '?' => '[-_-_---_---_-_-_]', '!' => '[-_-_---_---_-_]', '@' => '[-_-_-_---_-_---_]', '+' => '[-_---_-_---_-_]', 0 => '[---_---_---_---_---_]', 1 => '[-_---_---_---_---_]', 2 => '[-_-_---_---_---_]', 3 => '[-_-_-_---_---_]', 4 => '[-_-_-_-_---_]', 5 => '[-_-_-_-_-_]', 6 => '[---_-_-_-_-_]', 7 => '[---_---_-_-_-_]', 8 => '[---_---_---_-_-_]', 9 => '[---_---_---_---_-_]', ' ' => '[__]', }; } sub encode { my $self = shift; my $str = $self->{plain_text}; $str =~ s/(\w)/uc($1)/eg; $str =~ s/(.)/$self->encoding_rule->{$1}/eg; return $str; } 1;
ããã使ã£ã¦ï¼ã³ã³ã½ã¼ã«ä¸ã§çç¹ã¨é·ç¹ã表示ãããã¨ãã§ããããã«ãªãã¾ããï¼
Arduinoã使ã£ã¦LEDåºå
æåã¯ã¿ã¤ãã¼ã使ã£ã¦ï¼ã³ã³ã½ã¼ã«ä¸ã«'-'ã¨'ã¼'ãåºåããããã¨æã£ã¦ããã®ã§ããï¼èããã ãã§ãé常ã«å°å³ã§ãï¼ããæ°ãè½ã¡ã¦æ¥ãã»ã©ï¼ããã§Arduinoã使ã£ã¦LEDãç¹æ» ããããã¨ã«ãã¾ããï¼ã¾ãï¼Arduinoã使ã£ã¦ï¼port13ã¨GNDã«èãåºããLEDãç¹æ» ãããprocessingã®ã³ã¼ãã¯ä»¥ä¸ã®ããã«ãªãã¾ãï¼
void setup() { Serial.begin(9600); pinMode(13, OUTPUT); } void loop() { if (Serial.available() > 0) { int inByte = Serial.read(); if (inByte == 'I') { digitalWrite(13, HIGH); } if (inByte == 'O') { digitalWrite(13, LOW); } } }
ãããã³ã³ããã¼ã«ããperlã®ã¯ã³ã©ã¤ãã¼ã¯ä¾ãã°æ¬¡ã®ããã«ï¼macã®å ´åï¼ãªãã¾ãï¼
perl -MDevice::SerialPort -le ' $p = Device::SerialPort->new("/dev/tty.usbserial-A6008iod"); $p->baudrate(9600); $p->databits(8); $p->parity("none"); # $p->stopbits(1); $p->write("I")'
以å試ããæã«ã¯stopbits(1)ãå ¥ããªãã¨åããªãã£ãã¯ããªãã§ããï¼ä»åArduino017ã§åããã¦ã¿ããï¼å¤ããªãã¨åããªããªã£ã¦ã¾ããï¼çç±ã¯ãããããã¾ããï¼ããã¯ã¨ãããï¼ãããå ã«ä½ã£ã¦ã¿ãã³ã¼ãã¯ä»¥ä¸ã®ããã«ãªãã¾ããï¼
package Morse; use Moose; use AnyEvent; use Device::SerialPort; with 'Converter'; has 'plain_text' => ( is => 'rw', isa => 'Str', required => 1, ); has 'morse_code' => ( is => 'rw', isa => 'Str', lazy_build => 1, ); has 'port' => ( is => 'rw', isa => 'Device::SerialPort', default => sub {Device::SerialPort->new("/dev/tty.usbserial-A6008iod")}, ); sub _build_morse_code { my $self = shift; return $self->encode; } __PACKAGE__->meta->make_immutable; no Moose; sub output { my $self = shift; my $str = $self->morse_code; $self->port->baudrate(9600); $self->port->databits(8); $self->port->parity("none"); $str =~ s/[\[\]]/_/sg; $str =~ s/(-+)/I$1E/g; $str =~ s/(-+)/length($1)/eg; $str =~ s/(_+)/O$1E/g; $str =~ s/(_+)/length($1)/eg; my @timer = split /E/, $str; map { my ( $state, $time ) = $_ =~ m/(.)(.)/; my $c = AnyEvent->condvar; $self->port->write($state); my $w; $w = AnyEvent->timer( after => $time * 0.1, cb => sub { undef $w; $c->send; } ); $c->recv } @timer; } 1;
ãããã®ã¢ã¸ã¥ã¼ã«ã使ã£ã¦åããã¹ã¯ãªããã¯ç°¡åã§ï¼ä¾ãã°ãããªæãã«ãªãã¾ãï¼
package main; $a = Morse->new( plain_text => "sos" ); $a->output;
åããã¦ã¿ãã¨ï¼ãã¡ãã£ï¼ã¡ãã£ï¼ã¡ãã£ï¼ã¡ã¼ï¼ã¡ã¼ï¼ã¡ã¼ï¼ã¡ãã£ï¼ã¡ãã£ï¼ã¡ãã£ãã¨LEDãå ãã¾ãï¼
ã¾ã¨ã
å½åã¯Acme::MorseCordeã¨ãã£ã¦ã¢ã¸ã¥ã¼ã«ã«ãã¦ã¢ãããããã¨æã£ã¦ããã®ã§ããï¼é£ä¼ä¸ã«ä½ããªãã£ãã®ã§æ«æãã¦ã¾ãï¼ã¤ãã§ã«è¨ãã¨ï¼Mooseã®ä½¿ãæ¹ããã¾ãã¡ããããããªãã®ã§ï¼è²ã å¤æ´ããæ¹ãããããã«æã£ã¦ã¾ãï¼ããããï¼ä¸ã®ã¹ã¯ãªããã¯ä¸ã¤ã®ãã¡ã¤ã«ã«ãã¦åããããã«ä½ã£ã¦ãã¾ãï¼ã¤ã¾ãï¼ä»¥ä¸ã®ããã«ãªãã¾ãï¼ããããã®å±æã¨ãã¦ã¯ï¼LEDã®ç¯ããã»ã³ãµã¼ã§èªã¿è¾¼ãã§ãããæååã«å¤æããããã°ã©ã ãä½ã£ã¦ã¿ãããã§ããï¼ãã¾ãæ¹æ³ãã¾ã æãã¤ãã¦ãã¾ããï¼ãã®ãã¡ãã£ã¦ã¿ããã¨æã£ã¦ãã¾ãï¼ã¾ï¼ãã®åã«Arduinoã§ã»ã³ãµã¼ãåããã¦ADå¤æããæ¹æ³ã調ã¹ãªãã¨ãããªããã§ãããâ¦
package Converter; use Moose::Role; use namespace::clean -except => 'meta'; requires 'output'; has 'encoding_rule' => ( is => 'rw', isa => 'HashRef[Str]', lazy_build => 1, ); sub _build_encoding_rule { return { A => '[-_---_]', B => '[---_-_-_-_]', C => '[---_-_---_-_]', D => '[---_-_-_]', E => '[-_]', F => '[-_-_---_-_]', G => '[---_---_-_]', H => '[-_-_-_-_]', I => '[-_-_]', J => '[-_---_---_---_]', K => '[---_-_---_]', L => '[-_---_-_-_]', M => '[---_---_]', N => '[---_-_]', O => '[---_---_---_]', P => '[-_---_---_-_]', Q => '[---_---_-_---_]', R => '[-_---_-_]', S => '[-_-_-_]', T => '[---_]', U => '[-_-_---_]', V => '[-_-_-_---_]', W => '[-_---_---_]', X => '[---_-_-_---_]', Y => '[---_-_---_---_]', Z => '[---_---_-_-_]', '.' => '[-_---_-_---_-_---_]', ',' => '[---_---_-_-_---_---_]', '/' => '[---_-_-_-_---_]', ':' => '[---_---_---_-_-_-_]', '\'' => '[-_---_---_---_---_-_]', '-' => '[---_-_-_-_-_---_]', '?' => '[-_-_---_---_-_-_]', '!' => '[-_-_---_---_-_]', '@' => '[-_-_-_---_-_---_]', '+' => '[-_---_-_---_-_]', 0 => '[---_---_---_---_---_]', 1 => '[-_---_---_---_---_]', 2 => '[-_-_---_---_---_]', 3 => '[-_-_-_---_---_]', 4 => '[-_-_-_-_---_]', 5 => '[-_-_-_-_-_]', 6 => '[---_-_-_-_-_]', 7 => '[---_---_-_-_-_]', 8 => '[---_---_---_-_-_]', 9 => '[---_---_---_---_-_]', ' ' => '[__]', }; } sub encode { my $self = shift; my $str = $self->{plain_text}; $str =~ s/(\w)/uc($1)/eg; $str =~ s/(.)/$self->encoding_rule->{$1}/eg; return $str; } 1; package Morse; use Moose; use AnyEvent; use Device::SerialPort; with 'Converter'; has 'plain_text' => ( is => 'rw', isa => 'Str', required => 1, ); has 'morse_code' => ( is => 'rw', isa => 'Str', lazy_build => 1, ); has 'port' => ( is => 'rw', isa => 'Device::SerialPort', default => sub {Device::SerialPort->new("/dev/tty.usbserial-A6008iod")}, ); sub _build_morse_code { my $self = shift; return $self->encode; } __PACKAGE__->meta->make_immutable; no Moose; sub output { my $self = shift; my $str = $self->morse_code; $self->port->baudrate(9600); $self->port->databits(8); $self->port->parity("none"); $str =~ s/[\[\]]/_/sg; $str =~ s/(-+)/I$1E/g; $str =~ s/(-+)/length($1)/eg; $str =~ s/(_+)/O$1E/g; $str =~ s/(_+)/length($1)/eg; my @timer = split /E/, $str; map { my ( $state, $time ) = $_ =~ m/(.)(.)/; my $c = AnyEvent->condvar; $self->port->write($state); my $w; $w = AnyEvent->timer( after => $time * 0.1, cb => sub { undef $w; $c->send; } ); $c->recv } @timer; } 1; package main; $a = Morse->new( plain_text => "sos" ); $a->output;
Arduinoé¢ç½ãã§ããï¼