#!/usr/bin/perl # マルツ電波 [12x38URL-R2] https://www.marutsu.co.jp/user/shohin.php?p=65028 # # Usage: eabadge.pl [opts] メッセージ # -D debug表示 # -S no-send # -d 出力デバイス # -f スクロールなし # # $ su root # # chown root eabadge.pl # # chmod u+s eabadge.pl use strict ; use Getopt::Std ; use Jcode ; use GD ; use Device::SerialPort ; use Time::HiRes ; my %opt ; getopts( "DSd:f" , \%opt ) ; my $debug = $opt{D} ; my $nodev = $opt{S} ; my $device = ( ($opt{d} eq "") ? "/dev/ttyUSB1" : $opt{d} ) ; my $format = $opt{f} ; # LEDディスプレィのサイズ my $maxy = 12 ; my $maxx = 38 ; my $maxsize = 256 ; my $mesize = 8 ; # 表示フィールドはmax=8 # 漢字フォントの設定 my $font = '/usr/share/fonts/truetype/kochi/kochi-gothic.ttf'; my $fsize = $maxy - 2 ; # 英字10dot,漢字12dot # 表示形式 sub attr { # 8bit = SSSS,FLLL # S:表示速度0〜7, # F:Flash, # L:000:Left,001:Right,010:Up,011:Down,100:FIX my ( $speed , $flash , $disp ) = @_ ; return ($speed % 8) * 16 + ($flash ? 8 : 0) + ($disp % 8) ; } # 送信するデータを生成する sub strImage { my @str = ( @_ ) ; # ヘッダ my @head = ( 0x48 , 0x65 , 0x6C , 0x6C , 0x6F , 0x00 ) ; # Hello\0 # 表示方式 my @form = () ; for( my $i = 0 ; $i < $mesize ; $i++ ) { push( @form , ($format ? attr( 3 , 0 , 4 ) : attr( 3 , 0 , 0 )) ) ; } push( @form , 0x00 ) ; # データの配置テーブル my @table = () ; # 表示する画像データを生成 my @idata = () ; # 生成する画像データ my $image = new GD::Image( $maxsize * 8 , $maxy ) ; my $white = $image->colorAllocate( 255 , 255 , 255 ) ; my $black = $image->colorAllocate( 0 , 0 , 0 ) ; my $gxx = 0 ; my $sxx = 0 ; my $col = 0 ; foreach my $str ( @str ) { $str =~ s/^\s+// ; $str =~ s/\s+$// ; next if ( $str eq "" ) ; last if ( $sxx >= $maxsize ) ; # 文字の表示位置 my $gx = 0 ; my $sx = 0 ; while( $str ne "" ) { # 一文字毎に文字画像を書き込む my ($c,$x1,$y1,$x2,$y2,$x3,$y3,$x4,$y4,$dx) ; if ( $str =~ /^[\x8E\xA1-\xFE][\xA1-\xFE]/ ) { # 2byte漢字 $c = substr( $str , 0 , 2 ) ; $str = substr( $str , 2 ) ; $dx = 2 ; # バイト幅 } else { # 1byte英数字 $c = substr( $str , 0 , 1 ) ; $str = substr( $str , 1 ) ; $dx = 1 ; } ($x1,$y1,$x2,$y2,$x3,$y3,$x4,$y4) = $image->stringFT( $black , $font , $fsize , 0 , $gxx + $gx , $fsize , Jcode->new( $c )->utf8 ) ; $gx += $x2-$x1-2 ; # ドット幅を積算 $sx += $dx ; # byte幅を積算 } # データの保存テーブルを作る push( @table , ( 0x08 , $sxx , 0x00 , $sx ) ) ; # 表示場所などをずらす $gxx += 8 * $sx ; $sxx += $sx ; $col++ ; } # データの保存テーブルの未使用部分を埋める for( ; $col < $mesize ; $col++ ) { push( @table , ( 0x08 , $sxx , 0x00 , 0 ) ) ; } # 画像ファイルからビットイメージを生成 my ($r , $g , $b) ; for( my $y = 0 ; $y < $maxy ; $y++ ) { for( my $x = 0 ; $x < $gxx ; $x += 8 ) { my $byte = 0 ; for( my $i = 0 ; $i < 8 ; $i++ ) { ($r , $g , $b) = $image->rgb( $image->getPixel( $x+$i , $y ) ) ; $byte = $byte * 2 + (($r != 0) ? 0 : 1) ; } push( @idata , $byte ) ; } } # すべての書き込みデータをまとめて返す return ( @head , @form , @table , @idata ) ; } my $port ; my $count = 0 ; unless( $nodev ) { # シリアルデバイスを初期化 $port = Device::SerialPort->new( $device ) ; $port->baudrate( 1200 ) ; $port->databits( 8 ) ; $port->parity( "none" ) ; $port->stopbits( 1 ) ; } # 出来上がったデータをまとめて送る my @data ; if ( @ARGV > 0 ) { @data = @ARGV ; } else { @data = ; } foreach my $b ( strImage( @data ) ) { unless( $nodev ) { # 1byte送信 $port->write( chr( $b ) ) ; # 単方向送信なので1byte毎にちゃんと待たないと誤認識しやすい Time::HiRes::usleep( 10000 ) ; } # デバッグ表示 printf( "0x%02x," , $b ) if ( $debug ) ; if ( ++$count > 16 ) { $count = 0 ; print( "\n" ) if ( $debug ) ; } } print( "\n" ) if ( $debug ) ; ### Local Variables: ### ### mode: perl ### ### tab-width: 4 ### ### End: ###