さて。
Raspberry Piに、登録していきましょうかね。
まず今回は、ファイル使うので。
SDカードへの負担を減らすため、RAMディスクを登録。
root@raspberrypi:/# mkdir /ramdisk
root@raspberrypi:/# chmod -R 777 /ramdisk
root@raspberrypi:/# cat /etc/fstab
proc /proc proc defaults 0 0
PARTUUID=1bee5e28-01 /boot vfat defaults 0 2
PARTUUID=1bee5e28-02 / ext4 defaults,noatime 0 1
# a swapfile is not a swap partition, no line here
# use dphys-swapfile swap[on|off] for that
tmpfs /ramdisk tmpfs defaults,size=16m 0 0
root@raspberrypi:/#
ま、マウント用ディレクトリ作って、fstabに登録、mount-aか再起動でRAMディスクが16MBできますよ、と。
で、出力はbmp、入力はppmなので、image-magickをセットアップ
root@raspberrypi:/# apt-get install imagemagick
LEDに表示する画像を作製するスクリプトと、LEDに画像を表示するスクリプトを、サービスとして作製。
root@raspberrypi:/# cd /etc/systemd/system
root@raspberrypi:/etc/systemd/system# cat makeledinfo.service
[Unit]
Description = makeledinfo
[Service]
ExecStart=/usr/bin/perl /data/ledinfo/makeledinfo.pl
Restart=always
Type=simple
[Install]
WantedBy=multi-user.target
root@raspberrypi:/etc/systemd/system# cat ledimageloader.service
[Unit]
Description = ledimageloader
[Service]
ExecStart=/usr/bin/python /data/ledinfo/ledimageloader.py -r 32 -c 2 -b 30 --led-slowdown-gpio 2 -p 5
Restart=always
Type=simple
[Install]
WantedBy=multi-user.target
root@raspberrypi:/etc/systemd/system#
systemctlで登録、と。
もう動かしてるので、ステータスで!。
root@raspberrypi:/etc/systemd/system# systemctl status makeledinfo.service
● makeledinfo.service - makeledinfo
Loaded: loaded (/etc/systemd/system/makeledinfo.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2017-11-26 19:57:04 JST; 1 weeks 5 days ago
Main PID: 7990 (perl)
CGroup: /system.slice/makeledinfo.service
tq 7990 /usr/bin/perl /data/ledinfo/makeledinfo.pl
mq30184 /usr/bin/python /data/ledinfo/hummeas.py
Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.
root@raspberrypi:/etc/systemd/system# systemctl status ledimageloader.service
● ledimageloader.service - ledimageloader
Loaded: loaded (/etc/systemd/system/ledimageloader.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2017-12-09 11:55:01 JST; 45min ago
Main PID: 26104 (python)
CGroup: /system.slice/ledimageloader.service
mq26104 /usr/bin/python /data/ledinfo/ledimageloader.py -r 32 -c 2 -b 30 --led-slowdown-gpio 2 -p 5
12月 09 11:55:01 raspberrypi systemd[1]: Started ledimageloader.
root@raspberrypi:/etc/systemd/system#
数日動かしっぱなしにしてると、なんか盛大にハングしたので、たまにサービス再起動を仕込みました。
root@raspberrypi:/# cd /etc
root@raspberrypi:/etc# cat crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
55 * * * * root /usr/sbin/service ledimageloader restart
root@raspberrypi:/etc#
ま、これで、無事?動作。
動画だと、こんな感じです。
https://twitter.com/eucalydqx/status/934809174143221761
なかなか視認性も良く、取り扱いしやすいブツに仕上がり、まんぞくまんぞく。
最後に、実際に登録している、perlスクリプト、置いておきます。
/data/ledinfo とか、/ramdisk とかがキーワードかな。
あと、温度計計測用のスクリプトも、ここからキックしてますー。
makeledinfo.pl
$inputbitmapfontfilename = "/data/ledinfo/bfont.bmp";
$inputbitmapbackgroundfilename = "/data/ledinfo/back.bmp";
$humdatafilename2 = "/ramdisk/humoutput1.txt";
$humdatafilename1 = "/ramdisk/humoutput2.txt";
$outputfilename = "/ramdisk/ledoutput.bmp";
&inputbitmapfont;
while (){
&meashum;
&makeinfo;
&imageconvert;
sleep(2);
}
exit;
sub meashum {
$systemcommand = "/usr/bin/python /data/ledinfo/hummeas.py";
system ($systemcommand);
$systemcommand = "/usr/bin/python /data/ledinfo/hummeas2.py";
system ($systemcommand);
}
sub imageconvert {
$systemcommand = "/usr/bin/convert /ramdisk/ledoutput.bmp /ramdisk/ledoutput.ppm";
system ($systemcommand);
}
sub makeinfo{
open (FILE,$humdatafilename1);
(@humdataarray) = (<FILE>);
close (FILE);
chomp($humdataarray[0]);
if ($humdataarray[0] < 0){
$j = abs(int ($humdataarray[0]));
$k = abs(int ($humdataarray[0] * 10));
$k = $k - ($j * 10);
$j = sprintf("%03d",$j);
$k = sprintf("%01d",$k);
$output_it = "-$j.$k";
}
else {
$j = abs(int ($humdataarray[0]));
$k = abs(int ($humdataarray[0] * 100));
$k = $k - ($j * 100);
$j = sprintf("%02d",$j);
$k = sprintf("%02d",$k);
$output_it = "$j.$k";
}
chomp($humdataarray[1]);
$j = abs(int ($humdataarray[1] / 100));
$k = abs(int ($humdataarray[1]));
$k = $k - ($j * 100);
$j = sprintf("%04d",$j);
$k = sprintf("%02d",$k);
$output_ip = "$j.$k";
chomp($humdataarray[2]);
$j = abs(int ($humdataarray[2]));
$k = abs(int ($humdataarray[2] * 100));
$k = $k - ($j * 100);
$j = sprintf("%02d",$j);
$k = sprintf("%02d",$k);
$output_ih = "$j.$k";
open (FILE,$humdatafilename2);
(@humdataarray) = (<FILE>);
close (FILE);
chomp($humdataarray[0]);
if ($humdataarray[0] < 0){
$j = abs(int ($humdataarray[0]));
$k = abs(int ($humdataarray[0] * 10));
$k = $k - ($j * 10);
$j = sprintf("%03d",$j);
$k = sprintf("%01d",$k);
$output_ot = "-$j.$k";
}
else {
$j = abs(int ($humdataarray[0]));
$k = abs(int ($humdataarray[0] * 100));
$k = $k - ($j * 100);
$j = sprintf("%02d",$j);
$k = sprintf("%02d",$k);
$output_ot = "$j.$k";
}
chomp($humdataarray[1]);
$j = abs(int ($humdataarray[1] / 100));
$k = abs(int ($humdataarray[1]));
$k = $k - ($j * 100);
$j = sprintf("%04d",$j);
$k = sprintf("%02d",$k);
$output_op = "$j.$k";
chomp($humdataarray[2]);
$j = abs(int ($humdataarray[2]));
$k = abs(int ($humdataarray[2] * 100));
$k = $k - ($j * 100);
$j = sprintf("%02d",$j);
$k = sprintf("%02d",$k);
$output_oh = "$j.$k";
#tokoyami
$timenow = time;
$timeseed = $timenow - 1510434000;
$timeseed = int ($timeseed / 86400);
$timeseed %= 4;
if ($timeseed == 0){($toko_r,$toko_d,$toko_m) = (1,3,2);}
if ($timeseed == 1){($toko_r,$toko_d,$toko_m) = (2,4,3);}
if ($timeseed == 2){($toko_r,$toko_d,$toko_m) = (3,1,4);}
if ($timeseed == 3){($toko_r,$toko_d,$toko_m) = (4,2,1);}
#boueigun
$timenow = time;
$timeseed = $timenow - 1510434000;
$timeseed = int ($timeseed / 3600);
$timeseed %= 7;
if ($timeseed == 0){($defe_i,$defe_j) = ("Yy","Yy");}
if ($timeseed == 1){($defe_i,$defe_j) = ("Yy","Ww");}
if ($timeseed == 2){($defe_i,$defe_j) = ("Ww","Ww");}
if ($timeseed == 3){($defe_i,$defe_j) = ("Ww","Xx");}
if ($timeseed == 4){($defe_i,$defe_j) = ("Xx","Xx");}
if ($timeseed == 5){($defe_i,$defe_j) = ("Xx","Zz");}
if ($timeseed == 6){($defe_i,$defe_j) = ("Zz","Yy");}
(@date) = localtime (time);
$time_format = sprintf("%02d:%02d",$date[2],$date[1]);
$dataone = " " .$output_it."c ".$output_ot."c";
$datatwo = " " .$output_ih."p ".$output_oh."p";
$datathr = $output_ip."h".$output_op."h";
$datafou = "R".$toko_r."D".$toko_d."M".$toko_m." ".$defe_i.$defe_j.$time_format;
#print "$dataone\n$datatwo\n$datathr\n$datafou\n";
&inputbasebitmap;
$outputline = 0;$outputcol = 0;
foreach $ch (split //, $dataone) { &renderfont($ch);$outputcol++;}
$outputline = 1;$outputcol = 0;
foreach $ch (split //, $datatwo) { &renderfont($ch);$outputcol++;}
$outputline = 2;$outputcol = 0;
foreach $ch (split //, $datathr) { &renderfont($ch);$outputcol++;}
$outputline = 3;$outputcol = 0;
foreach $ch (split //, $datafou) { &renderfont($ch);$outputcol++;}
$bitmapoutput = "424d361800000000000036000000280000004000000020000000010018000000000000180000120b0000120b00000000000000000000";
for $i (0..31){
for $j (0..63){
for $k (0..2){
$bitmappointer = (( 31 - $i ) * 64 + $j) * 3 + $k;
$bitmapoutput .= $bitmapoutputbase[$bitmappointer];
}
}
}
$bitmapbinary = pack("H*",$bitmapoutput);
open (OUTPUT,">$outputfilename");
binmode(OUTPUT);
print OUTPUT $bitmapbinary;
close (OUTPUT);
}
sub inputbitmapfont {
open (IN,$inputbitmapfontfilename);
binmode (IN);
$buffersize = 1;
$count = 0;
$output = "";
undef (@rawdata);
$rawcount = 0;
while (){
$count++;
read(IN,$readdata,$buffersize);
if ($count < 55){next;}
if ($count > 20000){last;}
$readdata = unpack("H2",$readdata);
$rawdata[$rawcount] = $readdata;
$rawcount++;
}
close (IN);
カ# コゥ・ E コヨAア・ゥ鈬ノ
?Bト
for ($i=1;$i>-1;$i--){
for ($j=0;$j<16;$j++){
$fontseed = "$i:$j";
for ($k=7;$k>-1;$k--){
for ($l=0;$l<4;$l++){
$imagex = (( $j * 4 ) + $l) * 3;
$imagey = ( $i * 8 ) + $k;
$imagepointerbase = ( $imagey * 64 * 3 ) + $imagex;
for ($m=0;$m<3;$m++){
$imagepointer = $imagepointerbase + $m;
$fontdata{$fontseed} .= $rawdata[$imagepointer];
}
}
}
}
}
}
sub inputbasebitmap {
open (IN,$inputbitmapbackgroundfilename);
binmode (IN);
$buffersize = 1;
$count = 0;
$output = "";
undef (@bitmapoutputbase);
$colcount = 0;
$rowcount = 31;
while (){
$count++;
read(IN,$readdata,$buffersize);
if ($count < 55){next;}
if ($count > 20000){last;}
$readdata = unpack("H2",$readdata);
$rawcount = $rowcount * 64 * 3;
$rawcount += $colcount;
$bitmapoutputbase[$rawcount] = $readdata;
$colcount++;
if ($colcount > 191){
$rowcount--;
if ($rowcount < 0){last;}
$colcount = 0;
}
}
close (IN);
}
sub renderfont {
my $data = $_[0];
#0123456789.ch:p-
#RDMぶけラ
$fontseed = "1:15";
if ($data eq " "){$fontseed = "1:15";}
if ($data eq "0"){$fontseed = "0:0";}
if ($data eq "1"){$fontseed = "0:1";}
if ($data eq "2"){$fontseed = "0:2";}
if ($data eq "3"){$fontseed = "0:3";}
if ($data eq "4"){$fontseed = "0:4";}
if ($data eq "5"){$fontseed = "0:5";}
if ($data eq "6"){$fontseed = "0:6";}
if ($data eq "7"){$fontseed = "0:7";}
if ($data eq "8"){$fontseed = "0:8";}
if ($data eq "9"){$fontseed = "0:9";}
if ($data eq "."){$fontseed = "0:10";}
if ($data eq "c"){$fontseed = "0:11";}
if ($data eq "h"){$fontseed = "0:12";}
if ($data eq ":"){$fontseed = "0:13";}
if ($data eq "p"){$fontseed = "0:14";}
if ($data eq "-"){$fontseed = "0:15";}
if ($data eq "R"){$fontseed = "1:0";}
if ($data eq "D"){$fontseed = "1:1";}
if ($data eq "M"){$fontseed = "1:2";}
if ($data eq "W"){$fontseed = "1:3";}
if ($data eq "w"){$fontseed = "1:4";}
if ($data eq "X"){$fontseed = "1:5";}
if ($data eq "x"){$fontseed = "1:6";}
if ($data eq "Y"){$fontseed = "1:7";}
if ($data eq "y"){$fontseed = "1:8";}
if ($data eq "Z"){$fontseed = "1:9";}
if ($data eq "z"){$fontseed = "1:10";}
$fontcolcount = 0;
$fontrowcount = 0;
@fontdataarray = $fontdata{$fontseed} =~ /.{2}/g;
foreach $ch (@fontdataarray) {
$fontrow = ($outputline * 8) + $fontrowcount;
$fontcol = ($outputcol * 4 * 3 ) + $fontcolcount;
$injectpointer = ($fontrow * 3 * 64) + $fontcol;
if ($ch ne "00"){
$bitmapoutputbase[$injectpointer] = $ch;
}
$fontcolcount++;
if ($fontcolcount > 11){
$fontrowcount++;
$fontcolcount = 0;
}
}
}