DebianとPovray
仕方がない
Debian Wheezyにpovrayをインストールしようとしたら、packageから削除されていた。ubuntuにはあるのに。公式サイトにはソースがあるので、それをコンパイルすれば良いのかもしれないが、面倒だ。調べてみると、Debian jessieだとpovrayもあるようだ。まあ、jessieがでて、数カ月経っているし、そろそろインストールしようということで、OSを入れ替えることにした。CDを焼くのに一回失敗したが、無事にOSを入れ替えて、povrayも実行できた。日本語は特に設定無しで使えるし、icedoveとrubyとemacs24とanthy-elを入れたら、まあ今日すべきことはできるかな。/homeは別のパーティションなので、以前の設定はそのまま使えるし。
約二年ぶりに
目覚まし更新
久々に目覚ましを更新した。だんだんと高性能になるにつれて、使い方も複雑になって来ているのを感じる。説明書も少し読んで、最低限の使い方ができるようになった。使っているうちに、だんだんと分かってくるだろう。
大幅なスクリプトの書き換え
golfのテクニックも使って
大昔に書いて、長らく使っていたrubyのスクリプトを、書き換えてみた。古いバージョンのものは、2004年にはほぼ出来上がっていたようなので、十年以上ぶりの大幅の書き換えとなる。
全体としては、rubyっぽい書き方を取り入れた。例えば、以前は
f=open("filename","w") f.print str
という書き方をしていたが、新しいものでは、
open("filename","w"){|f|f.print str}
となっている。また、少しgolfっぽくif文を無くして
n=ARGV[0] || puts("data file: ") || STDIN.readline
などの書き方も使っている。この十年で、私のrubyの書き方もずいぶん変わった気がする。rubyの仕様もそれなりには変わっているし。
AVRでI2C
MCP3425のくせ
マイコンでICと通信するために、UARTやSPIを使ったことがあったが、これらは基本的には一対一の通信である。一方、I2Cは、原理的には128個のICと二本の線で通信できる。
電子工作をしていて、16bitのADコンバーターであるMCP3425をI2Cでマイコンから読み取ることにした。3つのMCP3425を使うことにしたのだが、これを二本の線だけで通信できるのは素晴らしいと思っていたのだが、買ってから資料をよく読むと、アドレスが八種類あるのだが、普通に買うと一種類のアドレスのICとなり、これらを同時に使うことができないことが分かった。六本も使うのは悔しいので、クロックを共通にして、四本で3つのICを使うことにした。
I2CをAVRから使うのは始めてだったので、最初はうまく通信ができなかった。読み取りの時にPINでは無くPORTから読んだり、いくつかのバグを発見して、一応の通信はできるようになったが、まだ何か変であった。
接続してから一回目はうまく読み取れるのだが、二回目以降がうまく行かないことに気がついて、資料をよく読みなおしてみたら、読み取るときの最終データに対しては、ACKを送らないという約束になっているようだ。ううん、ややこしい。
でも、これでMCP3425との通信ができるようになり、ADコンバーターとしてもそれなりに精度もあって使いやすいことが分かった。参照電圧も不用だし。
ubuntu mate on raspberry pi2で計測
ruby2.1とgtkとusb hubに苦しめられたが
数年間計測に使っていたnote PCが遅くなってきたので、制御用のPCを入れ替えることにした。noteは余っていないし、desktopも邪魔なので、raspberry piを使ってはどうかと考えた。しかし、raspbianではusbtmcを使うためにkernelをコンパイルしないといけない。raspberry pi2で動くubuntu mateだと、usbtmcはそのままで使えるというわけで、これを使って測定系を組むことにした。いくつかのハードルはあるとは思っていたが、予想していたよりも、少し苦労させられることになったが、なんとかうまく動くようになった。
まず、最初にはまったのが、rubyのversionによる問題である。それまでのシステムはruby1.8で動いていたのだが、今回はruby2.1で動かしている。version依存の命令は使っていないつもりだったので、そのままで動くと予想していたのだが、考えが甘かった。usb-serialで通信していたのだが、なぜかうまく動かない。オシロを使って信号を読んでみると、送ろうと思っている文字列と違う文字列が送られていることに気がついた。このとき、"%c"%nのような書き方をしていたのだが、このときに、勝手にunicodeに変換されてしまっていた。そこで、[n].unpack(“c”)としたら、変換されなくなり、通信できるようになった。
次の問題は、ruby/tkである。ubuntuでは、なぜかruby/tkがサポートされなくなってきているようなので、ruby/gtk2に移植する必要があった。少し時間はかかったが、tkとほぼ同じ感じでgtk2も使えるようになった。
しかし、実際に動かしてみると、通信エラーを頻繁に起こすことが分かった。いろいろと原因を考えた結果、usbのhubを疑うことにした。raspberry pi2には四つのusb portがある。ここに、mouseとkeyboardとusbtmcとusb-serial*2の合計五つのusb機器をつないでいる。そのため、usbのhubが必要で、それまでは、測定機器はすべてhubを介して接続されていた。そこで、mouseとkeyboardをhubを介して接続し、残りの三つの装置を直接つなぐようにしたら、通信エラーが起こらなくなった。
これで、測定できるシステムが完成した。あとはftpdを入れて、固定IPにして、ntpの設定をして、keyboardのlocaleを合わせるぐらいかな。ftpは以前使っていたvsftpdを入れればよい。固定IPにするのは、/etc/network/interfacesをいじりたくなるのだが、メニューからネットワーク接続を選んで、設定すればよいようだ。ntpはおそらく/etc/ntp.confをいじるのだと予想している。keyboardもmateのメニューのkeyboardで種類を設定できるようだ。あと、自動起動で不要なものを消しておくと良いかも知れない。
ruby/tkからruby/gtk2への移行
tkとgtk2の違い
これまで、rubyでGUIを作る必要があるときには、主にtkを使っていた。しかし、最近のubuntuは、ruby/tkとは相性が悪いようで、今後はruby/tkがどうなって行くのかが不安である。そこで、ruby/tkの代わりにruby/gtk2を使ってみることにした。これまでtkを使って書いていたのものを、gtkに簡単に移植するために、tkライクにgtkを使えるwrapperのようなものを書いたら、なんとかひとつのプログラムの移植は完了した。その作業の中で、tkとgtkの違いについて、いくつか感じたことを書いておこう。
tkの場合には、toplevelの中に、一つずつpackしたり、frameを作ってその中にpackしたりして、配置する。一方、gtkでは、windowの中に入れることができるのは、一つだけで、通常はvboxなどを入れて、その中に配置していく。わざわざboxを入れないといけないのは、少し面倒だなと感じた。
面倒と言えば、gtkではwindowを閉じたときの処理とか、fileを開くための画面などで、ボタンを押したときの処理を一々指定しないといけない。これは、細かい指定ができるという意味ではメリットかも知れないが、何も指定しなくても、cancelのときは、普通にcancelしてくれる方が良い気もする。
gtkでaddしたあとにshowしないといけないのも、面倒かな。
また、tclの仕様のために、tkの場合には、数字という概念があまり無いので、数字を扱うときには、rubyで受け取るときに、数字に変換する必要がある。
まとめると、ruby/tkはオプションの指定などの仕方が独特で、取っ付きにくいけど、意外に指定することが少ない場合もある。ruby/gtkはきめ細やかな設定ができる代わりに、デフォルトの設定が少なくて、いろいろと指定する必要がある。まあ、一応つかえるようになってしまえば、tkもgtkもあまり変わらない気がする。
loginできない
/dev/nullのpermission
今日、debianにloginしようと思ったら、なぜかうまく行かなかった。passwordを打ち間違えたかと思ったけど、そうでは無いようだ。rootではloginができたので、少し調べてみたら、.xsession-errorsには、
cannot create /dev/null: Permission denied
となって、Xが立ち上がらないのが原因のようだ。こうなってしまった理由は良く分からないのだが、/etc/rc.localのexit 0の前に、
chmod 0666 /dev/null
と入れれば良いというのを見つけたので、そうしたらloginできるようになった。なんか、気持ち悪いけど、まあいいか。
code golf
久々にrubyでgolfをやってみた。
このサイトのgolfを試してみた。そのNo.902の1 2 32 4 512というものである。具体的には、2のn乗で1から100までの数字から始まるものを順に探して表示するというものである。まず、普通に書いてみたのが、
100.times{|i|r=1;r*=2 until r.to_s=~/^#{i+1}/;p r}
で50bytesである。そのすぐ後に、スペースを取り除けることに気が付き、
100.times{|i|r=1;r*=2until"#{r}"=~/^#{i+1}/;p r}として、48bytesまでになった。ここから、いろいろな工夫をしてみたが、どうしても48を切ることができなかった。例えば、
1.upto(100){|i|r=1;r*=2until"#{r}"=~/^#{i}/;p r} 1.upto(100){|i|r=1;r*=2until"%s"%r=~/^#{i}/;p r} 1.upto(100){|i|r=1;r*=2until"#{r}"[/^#{i}/];p r} 1.upto(100){|i|r=1;$_="#{r*=2}"until/^#{i}/;p r}
などを作ったが、何をやっても48止まりだった。特に、最後のは1に対する答えが16になってしまうという欠点もあるし。ruby1.8なら、100の代わりに?dを使うという技を使えるのだが。その時、一位の人は46で二位が47だった。10bytesぐらい差をつけられていたら、もう諦めるのだが、数byteとかだと、なんとかなるのでは無いかと思ってしまう。散々考えていたら、昨晩、47に到達した。
($.+=r=1;r*=2until"#{r}"=~/^#$./;p r)until$.>99
というものである。行数を表す組み込み変数$.を使って、初期値の代入と#{}の括弧をなくしたり、最初に1を足すことによって、100の代わりに99を使えるようにして、なんとか1byte減らすことに成功した。これでなんとか二位には追いついたが、一位の46bytesはどうやっているのか、全く見当もつかない。
2015/6/30追記 二位の人は、ruby1.8流のやり方をしていた。これなら、1.9以降でも動く私のscriptの方が上とも言える。一位の人は、これに加えて、補数を求める~演算子を使っていた。なるほど、これなら100を99までで良くなるのでtimesが使えるし、行頭の^も省略できる。
共用PCの入れ替え
debian8のPC
長らく共用のPCとして使っていたnoteが死んだので、別のnoteに入れ替えた。実はそのnoteには、しばらく前にdebian8をインストールしたのだが、起動しようとしたらビープ音が鳴るようになってしまい、電源がおかしいのかなと思って放置してあった。少し調べていたら、どうやらキーボードのどれかのキーが押された状態と認識されており、そのために音がいる可能性があることが分かった。そこで、分解してキーボートのフラットケーブルを外してみたところ、うまく動くようになった。基本的には、外付けのキーボートとマウスを繋いで使うので、これで問題が無い。ftpdやntpの設定をして、共用のPCとして使えるようになった。
debian8のLXDEを少し使ってみたが、windowの移動のときに、遅れて着いてくる感じで、気持ち悪い。単にPCの性能が低いだけかも知れ無いが。