背景を透明に
texに図を貼り付けている時に、図が重なって、下になった図の一部が見えなくなってしまうことがあった。図の形式はpngであったが、その図の背景は透明では無く、白色になっていた。背景を透明にすれば、図が重なっても大丈夫なのでは無いかと思い、やってみた。
元のpngファイルとGimpで開いて、「レイヤー-透明部分-アルファチャンネルの追加」としてから、「ツール-選択ツール-色域を選択」とし、白い部分をクリックしてdelキーを押すと、白い背景が透明になる。最後に「ファイル-エクスポート」でpngでセーブすれば、背景を透明化したファイルができる。
これをtexに取り込んでみると、図が重なっても問題無く表示できるようになった。
povrayでネジを描画
arduinoでモーター制御
ステッピングモーターの信号
PCから信号を送ってステッピングモーターを回したくなるときが時々ある。最初にやったときには、何の信号を使おうか迷って、結局RS232Cの信号を使って、文字の情報をパルスにみたてて送ることで、これを実現した。幼稚な考えだが、それなりにうまく行った。面倒だったのは、RS232Cの信号の電圧をMAX232でTTLレベルに変換することぐらいかな。
マイコンを使うようになってからは、いろいろな方法をやったけど、PCとマイコンをどのように通信するかが結局課題になった。RS232Cと通信したり、GPIBをエミュレートしたり。
で気がついたのだが、arduinoを使えば、PCとはUSBで通信できて、終わりでは無いかと。arduinoを使うほどでは無いとも言えるが、まあ中華のだと安いし、はんだ付けはほぼ不要だし、これで良いかなと思う。
ADCの比較
arduino UNOとstm32 blue pillのADC
stm32のblue pillをarduinoから使えるようになったので、いろいろと試してみようと思っている。stm32に慣れていくために、arduino UNOと比較しながら、少しずつ勉強していこうと思う。
arduino UNOには、A0-A5の6本のアナログピンがあり、これらは10bitのADCとして使うことができる。5Vを最大値として、電圧を0-1023までの値として測定することができる。プログラムは、
void setup() { pinMode(PA0, INPUT_ANALOG); Serial.begin(9600); } void loop() { delay(1000); Serial.println(analogRead(PA0)); }
のようにすれば、良い。一方、blue pillでは、PA0-PA7とPB0-PB1の合計10本のピンがDCとして使うことができる。主な違いは、12bitであることと、最大値が3.3Vであることである。プログラムは、ピンの名前を変えるとそのまま使うことができる。ADCを詳細に設定するプログラムも作れるようだが、単に使うだけなら、これで良いだろう。
AVRからstm32へ
Linuxのarduinoでstm32
マイコンとしては,AVRの90s2313から始めて, tiny2313, tiny261, tiny861, mega8といくつかのAVRを使った後,半田付けが面倒になってarduino UNOやnanoの互換機を主に使うようになった.arduinoだと,AVRの性能のすべてを引き出すのが難しいが,いろいろなlibraryがあるので,短く手軽に書けるのは良いことだと思う.また,LANと通信したいときには,wifiを簡単に使えるESP8266を使うようになった.
今後はどのマイコンを使っていこうかと考えていたのだが,stm32の人気が出てきたので,私も少し使ってみた.stm32は,安価であるにも関わらず,32bitでsramやflashも比較的大きく,今後もより発展していく可能性を持っている.
今回,STM32F103C8T6を搭載したBlue Pillと呼ばれるボードを使ってみた.このボードは安いのだが,R10のチップ抵抗に誤った抵抗値の部品が使われており,これを訂正する必要がある.本来は1.5kであるべきところに,10kが載っていたので,2.2kを並列に追加して,1.8kにしておいた.
arduino UNOとかarduino nanoは,USBをserialに変換してからマイコンに接続されている.一方,stm32は,直接USBと接続されており,そのままではUSBを認識しないので,まずはbootloaderをインストールする必要がある.
bootloaderは,https://github.com/rogerclarkmelbourne/STM32duino-bootloader/tree/master/binariesからdownloadするが,今回のボードはLEDがPC13につながっているので,generic_boot20_pc13.binを選択する.また,書き込みするためのツールなどは,https://github.com/rogerclarkmelbourne/Arduino_STM32に含まれているので,一括でdownloadしておく. ここでは,手持ちのUSB-serialを使ってbootloaderをインストールすることにした.まず,ボード上のjumperを,上側を1,下側を0にする.そして,serialのGNDと3.3Vを接続し,RXDはA9と,TXDはA10と接続する.tools/linux/stm32flashにあるstm32flashを使って,
../stm32flash -w generic_boot20_pc13.bin -v /dev/ttyUSB0
として,書き込む.書き込み終わったら,jumperを両方共に0に戻しておく.それから,udevの設定をするために,tools/linuxの中のinstall.shを実行する.これで,PCからUSBを通して認識出来るようになった.
次にarduinoの設定だが,1.6.9以降を使って,board managerからarduino Dueを探して,インストールする.そして、hardwareの下にArduino_STM32 というフォルダを作って,先程downloadしたファイルをすべて置く.boardとしては,STM32F103C8を選べば良い.これで,arduinoからstm32が使えるようになるはずなのだが,resetがうまく働かないことが分かった.そこで,書き込む時には,3.3VとPC14を繋いでからresetしてperpetual bootloader modeしてから書き込むか,うまいタイミングでresetを押す必要がある.少し面倒だったが,stm32が使えるようになった.
温度モニター
MsTimer2.hとWire.hを同時に使うときの注意点
年末年始に,arduino UNOを使った温度モニターを作ろうと思っていたが,時間が取れなった.ようやく時間ができたので,いろいろと試してみた.
I2Cで通信してADT7410から温度を取得する部分は,以前書いたプログラムを使えば良いと思っていたら,そのプログラムが実は間違っていたことが分かった.レジスタに格納されたデータを読み出すのだが,温度のデータは2byteで二つのレジスタに格納されている.これを1byteずつ読み出していたのだが,実は2byte一度に読み出さないといけなかったのだ.datasheetの一部を読んで1byteずつ取り出せば良いと解釈しまっていた.
一定の時間おきに,温度を測定するために,タイマーを使ってみた.MsTimer2.hを使ったのだが,MsTimer2::set(time,routine);でms単位の時間と呼び出すサブルーチンを指定して,MsTimer2::start();でタイマーをスタートするだけなので,問題無く動いた.しかし,タイマー割り込みの部分でi2cを読もうと思ったら,そこで止まってしまうことが分かった.調べてみると,i2cを読むWire.hでも,割り込みを使っているが,タイマーから割り込みがかかると,割り込みが禁止されてしまい,i2cが読めなくなっていることが分かった.そこで,タイマー割り込みがかかったときに,sei();を実行すれば,i2cもうまく読める.
信号の有効利用
arduino UNOの空きランド
arduino UNOを時々使っているが、純正品はそれなりに高い。そこで、CH340のチップを使った中国製のUNO互換機を主に利用している。このUNOには、X1という四ピンをはんだ付けできる場所があり、これが何なのかを調べてみた。CH340との接続を調べてみると、左からCTS, DSR, DCD, RIの信号に繋がっている。これらは、いずれもRS232Cの入力信号である。つまり、これらのピンに電圧をかけると、その情報をPCから読み取れるようになるはずである。
ちなみに、出力信号であるDTRは、arduinoのresetに使われているので、highに保つ必要がある。同じく出力信号であるRTSは、使っていないのかな。
rubyからだと、serialportを使えば、これらの信号を扱うことができるはずである。今考えているのは、arduinoが重い処理をしているときに、その状態をこれらのピンに与えておいて、PCからはそのピンの状態を見て、処理が終わってから、アクセスするという使い方が出来ないかというものである。
Rで式量計算
元素記号処理と原子量抽出
最近は必要なデータ処理の多くの部分をrubyでやっている。しかし、様々なデータ処理を行う上で、rubyには二つの欠点があると思う。一つは配列同士の四則演算などが面倒である点で、もう一つはすぐにグラフが書けない点である。配列にもいくつかの演算が定義されているが、+は配列を結合だし、*は繰り返しだし、通常の四則演算では無い。mapをつかってゴリゴリ書くか、Vectorを変換すれば、この問題は一部解決する。しかし、グラフを書くことは出来ない。というわけで、今回はRでデータ処理を行うことにした。 Rのスキルも少しは上がってきたので、主要なデータ処理の部分は無事に書き終えた。計算には式量の値が必要なのだが、式量は手で入力している。できれば化学式から式量を自動で計算するようにしたいというのが、次の課題である。rubyを使って式量を計算するプログラムは随分前に書いて、よく使っている。これをRで書くに当たって、二つのプロセスが必要になる。一つは化学式から元素記号と数字を探して取り出すところで、もう一つは元素記号を原子量に変換する部分である。
元素記号と数字を探すのには正規表現を使うのだが、gregexprを使うと、これが可能であることが分かった。しかし、gregexprは文字列の場所と長さを返すので、そこから文字列を取り出すためにsubstrを使ったり、長さを取り出すのにattrを使ったりと、文字列を取り出すまでが非常に面倒である。そこで、stringrというlibraryを使うことにした。library(stringr)としてこれを読み込むと、便利な関数が使えるようになる。最終的に使ったのがstr_match_allというもので、マッチした文字列と、括弧内の文字列を取り出してくれる。これで元素記号と数値を容易に取り出すことができた。
あとは、元素記号から原子量に変換すれば良い。原子量はファイルから読み込むが、read.tableで読み込むと、元素記号のベクトルと原子量のベクトルを合わせたdataframeとなる。ハッシュを使えれば、aw["Cl"]のように原子量を取り出せるのだが、Rではそう簡単にはいかない。まず考えた方法は、aw$V2[which(aw$V1=="Cl")]とか、subset(aw,V1=="Cl")$V2として、原子量を取り出す方法である。しかしこれだと、長い上に元素記号のベクトルを使って、原子量のベクトルを一度に取り出すということができなくなってしまう。
そこで考えたのがnamesを使う方法である。
aww<-aw$V2 names(aww)<-aw$V1
として、原子量のベクトルであるawwにnames属性をつけてやると、aww["Cl"]で原子量を取り出すことができる。さらに、aww[c("Na","Cl")]といくつかの原子量を一度に取り出すこともできる。しかし、dataframe以外にawwという余分なベクトルを作らないといけないのが欠点である。
最終的には、dataframeの列に元素記号の名前をつけると良いことが分かった。read.tableでrow.namesオプションを使うと列の名前を取り込むことができ、列の名前を使うとaw["Cl",]で原子量を取り出すことができる。カンマとかの意味がよく分かっていないが、動けば良いだろう。
そして、最終的にできた関数が次のようなものである。
library(stringr) fw<-function(fml){ aw<-read.table("formula.dat",row.names=1) el<-str_match_all(fml,"([A-Z][a-z]?)([0-9.]*)")[[1]] return(sum( aw[el[,2],] * ifelse(el[,3]=="",1,as.numeric(el[,3])) )) }
fw("H2O")などとすると、無事に原子量が計算できる。rubyに比べたら、長くなったし、書くのに苦労したが、これでまた少しRのスキルが上がっていたら良いな。
フォントの問題
中国語の周期表
私の環境のfirefoxでは、utf-8で作った中国語の周期表の104番元素以降のいくつかが表示されなかった。OSを新しくしても、残念ながらこれは変わらなかった。何かのフォントを入れる必要があるのだろうということで、fonts-arphic-ukaiとfonts-arphic-umingを入れてみた。すると、繁体字は116番までは表示できるようになった。簡体字もMt,Cnは新たに表示できるようになったが、それ以外はだめだった。fonts-cns11643-kaiとfonts-cns11643-sungも入れると、Ds,Fl,Lvも表示できるようになった。でもまだ9個も表示できない。
OSをupgradeして
不具合発見
昨日OSをupgradeしてDebianのstretchにした。特に問題なく使っていたのだが、ちょっとした問題が発覚した。
今回のupgradeでは、homeをすべて引き継いでいるので、個人の設定ファイルもそのまま使っている。そのことは、メールなどの設定をし直さなくても良いという意味では利点である。しかし、新しい環境用に更新されないという問題も抱えているように思う。
また、新たに発見したバグとしては、lxterminalがlxpanelから起動できないという点がある。何年か前に、そういうバグが報告されているのだが、それと関係あるのかも知れない。pcmanfmからは立ち上がるので、あまり問題は無かったが、.config/openbox/lxde-rc.xmlの中のkeybindを書き換えて、ショートカットを定義したので、それから立ち上げればlxpanelを使わなくても良くなった。
あと、これは新しいOSの問題では無いのだが、thunderbirdでmacからの添付ファイルが消えてしまう問題も見つけた。これは表示-メッセージの表示形式をプレーンテキストにしていると起こるようだ。添付ファイルが見えるように、シンプルHTMLにしておいた。