backportを使って
jessieのkicad
kicadを使って回路を考えていたが、開こうとすると、“some files could not be found"というエラーが出て、うまく行かない。いろいろと調べたら、debian jessieだと、backportのkicadを使うと良いらしい。/etc/apt/source.listに
deb http://httpredir.debian.org/debian jessie-backports main contrib non-free
を加えて、
aptitude update
aptitude -t jessie-backports install kicad
として、インストールした。でも、前のバージョンで作ったやつは、動かないようなので、作り直しだ。
beamerのエラー
図の取り込みとbb
beamerを使ってtexでコンパイルしようとしたら、図の取り込みのところでエラーが出る。bbが無いから作ろうとしているが、すでにきちんと作ってある。こういうときは、dvipdfmxオプションなどが抜けていることが、今回はきちんと指定してある。エラーメッセージをよく見て、
platex --shell-escape tempj
としたらうまくいった。
同じアドレスを持つデバイス
アドレスの重複するデバイスとI2Cで通信 I2Cでは,複数のデバイスと二本の信号線だけで通信することができます.しかしそれには,アドレスが重複していないという条件が必要です.同じアドレスのデバイスが二個あり,これらと通信するためには,二系統のI2Cを使うか,切り替え機能のあるICを使って,通信を実現することができ,そうしている人が多いようである. ICを使って切り替えるとしても,デバイスを選択するために信号線が必要なので,その信号線を使って通信を行なってしまえば,新たなICを使わないでも二個のデバイスと通信ができる.この際,SCLは共通に使って,SDAをそれぞれのデバイスに一本ずつ使えば,三本の信号線で二個のデバイスと通信できる.逆に,クロックが送られなければ通信は行なわれないと考えて,SDAを共通にして,SCLをそれぞれのデバイスに割り当てることもできるだろう.前者の場合には,クロックが共通なので,同時に二個のデバイスと,同じバイト数の通信を行なうことになる.後者の場合には,別々のタイミングで,それぞれのデバイスと通信することになる. 上記の考えを拡張すると,アドレスが重複しているn個のデバイスとの通信は,(n+1)本の信号線を使うと実現できることが分かる.ほぼ同じデータをやりとりする場合には,SCL共通の方が一度に通信できるという点で優れており,送受信するデータ数やタイミングがデバイス毎に違う場合には,SDA共通が良いだろう. arduinoを使って,SCL共通でこれを実現するためのプログラムを試しに書いてみた.mulWireBegin()で初期化を行い,mulWireBeginTransmittion()とmulWireWrite()とmulWireEndTransmittion()を使って,デバイスに送信する.受信は,mulWireRequestFrom()とmulWireRead()とmulWireEndRequest()を使って行なう.バッファなどは無く,これらのコマンドの実行と同時に通信が行なわれるので,受信のときにもその終了操作を行なうコマンドが必要になる点が,通常のarduinoのI2Cのコマンドと異なる.参考にソースを載せておくが,まだ動作確認を行なっていないので,動作は保証できません. #define MulWireDelay 6 // 6 micro second 100kHz #define mwNUM 2 #define mwSCL A5 uint8_t mwSDA[mwNUM]={A4,A3}; uint8_t mwadrs[mwNUM]={0x68,0x68}; void mulWireBegin(){ char i; pinMode(mwSCL,OUTPUT); for(i=0;i<mwNUM;i++){pinMode(mwSDA[i],OUTPUT);} digitalWrite(mwSCL,HIGH); for(i=0;i<mwNUM;i++){digitalWrite(mwSDA[i],HIGH);} delay(10); } void mulWireBeginTransmission(uint8_t *adrs){ char i; for(i=0;i<mwNUM;i++){digitalWrite(mwSDA[i],LOW);} delayMicroseconds(MulWireDelay); digitalWrite(mwSCL,LOW); mulWireData(2,adrs); //*2 } void mulWireRequestFrom(uint8_t *adrs){ char i; for(i=0;i<mwNUM;i++){digitalWrite(mwSDA[i],LOW);} delayMicroseconds(MulWireDelay); digitalWrite(mwSCL,LOW); mulWireData(3,adrs); //*2+1 } void mulWireEndTransmission(){ char i; for(i=0;i<mwNUM;i++){digitalWrite(mwSDA[i],LOW);} delayMicroseconds(MulWireDelay); digitalWrite(mwSCL,HIGH); delayMicroseconds(MulWireDelay); for(i=0;i<mwNUM;i++){digitalWrite(mwSDA[i],HIGH);} } void mulWireEndRequest(){ mulWireEndTransmission(); } uint8_t mulWireWrite(uint8_t *data){ mulWireData(0,data); } uint8_t mulWireData(char mode,uint8_t *data){ // mode: 0:raw, 2:*2, 3:*2+1 char i,m,a; uint8_t temp; m=(mode>1)?
それぞれのコマンドでやっていること
arduino UNOでI2C
I2Cを使うと,二本の信号線でアドレスの異なる128個のICと通信できる.AVRやESP8266でI2Cを使ったことはあったが,arduino UNOでI2Cをやろうとしたら,少し間違えたので,その仕組みを調べてみた.
初期化はWire.begin()で行なう.
ICに命令を送るときには,Wire.beginTransmission(adrs)とWire.write(data)とWire.endTransmission()を使う.ソースを見てみると,beginTransmissionではアドレスを定義するだけで,実際には通信は行なわず.writeではバッファに書き込んで,ここでも通信は行なわない.実際に通信が行なわれるのは,endTransmissionのときで,twi_writeToというコマンドを使って,アドレスやデータが送られる.
一方データを読み込むときには,Wire.requestFrom(adrs,bytes)とWire.read()を使うのだが,最初はbeginTransmissionとreadなどでやろうとしてしまった.読み込みでも,アドレスの送信を行なうので,そう考えてしまった.しかし,実際には,requestFromのときにtwi_readFromというコマンドを使って一気にバッファに読み込んでおり,このコマンドが無いと読み込みは行なわれない.その後で使うreadでは,バッファから読み込んでいるだけなのである.
書き込みの時はコマンドを三つ使って,読み込みの時は二つなのは,対称性が悪いなと思っていたが,このように,コマンドの内容を理解すると,そうなってしまう必然性が分かった.
大容量のHDD
exfatをdebianで読むには
大容量のHDDを繋いだら、認識はするのだが、exfatは見つから無いというエラーが出て使えない。調べてみたら、exfat-fuseとexfat-utilsを入れれば使えるようになるようだ。実際aptitudeで入れたら、ファイラーからマウントして使えるようになった。
raspberry pi zero発売
待ちに待った発売
2017年の第一四半期に日本で発売と発表されて依頼、なかなか情報が出なかったraspberry pi zeroですが、やっと明日発売されるようです。税抜き650円と、A+の四分の一である。pi zeroを動かす上で問題になるのが、HDMIがminiである点だ。既に入手している人達は、結構値段のする変換アダプタを使っている人が多いようだが、百均でも売っているのを見つけて、すでに準備済である。しかし、発売されてもすぐに入手するのは困難だろうから、少し落ちつくのを待つことにしよう。
IoTで温度、湿度、気圧を記録
BME280とESP8266
esp8266を使って温度のログを取っていたが、ようやく温度、湿度、気圧の記録を取れるようになった。BME280からI2Cを使ってデータを取得して、それをwifiでuploadする、と書くと簡単そうだが、BME280を扱うのに、それなりに苦労した。途中で一つeps8266を殺してしまった。
I2Cの通信自体は、それほど難しく無いが、ピン番号を間違えていて、しばらく苦戦してしまった。次に苦労したのが、BME280から取得したデータの変換だ。BME280の中に、校正するためのパラメーターが入っていて、これらを用いて複雑な計算をすると、温度などの値が得られる。これらを内部であらかじめやってくれていると楽なのにと思うのだが、計算が大変だからか、自分で計算しないといけない。パラメータの格納の順序が、私の書いたサブルーチンと相性が悪く、その変換のために、プログラムが汚くなってしまった。また、32bitや64bitのsignedやunsignedの変数をいろいろと使った式で、かなり複雑な計算をする必要がある。最初は32bitの変数としてlongを使っていたが、おそらくこれが32bitでは無いようで、signedのときに変な挙動をした。あからさまにint32_tなどと書かないと負の数のときに、値が変になってしまう。
これらの苦労を経て、なんとか記録を開始することができた。今後、これらのデータを使って、いろいろと検討することができるだろう。
lubuntuでSDを使う
SDをユーザーの領域に
古いnoteのメインのSSDの容量が小さくて、データをあまり入れる余裕がないので、SDカードをデータの保存用に使うことにした。 SDカードを挿入すると、/mediaの下にmountされて使うことができるようになるが、SDに保存していることを意識せずに使いたかったので、/homeのユーザーのdirectoryの下にマウントすることにした。ユーザーの権限などの問題に少し苦労したので、メモしておこう。
まず、idでユーザーのuidを調べる。そして、/etc/fstabにそのuidなどを用いて
/dev/mmcblk0p1 /home/name/data auto defaults,user,uid=1000,gid=1000 0 0
などと記述する。オプションの指定は、通常のuserでもmount,umountができるようにして、そのときのownerとgroupをuidとgidで指定したユーザーにするという意味である。これをやっておかないと、rootになってしまって、通常のユーザーが書き込みをできなくなってしまった。
lxdeを使いやすく
pcmanfmのアプリケーション設定
lxdeのファイラーであるpcmanfmで、ファイルを開くときのアプリケーションを指定するには、プロパティを開いて開くアプリケーションを設定すれば良い。例えば、自分で作ったスクリプトなどで処理したいときなどには、その部分でカスタマイズを選択して設定すれば、自由度が高くなる。このときの設定がどこに保存されるのか調べてみたら、~/.local/share/applicationsにあることが分かった。この中身を変更すれば、設定を変えることもできる。これまで、いちいちターミナルを立ち上げてやっていた作業を、ダブルクリックだけでできるようにしてみた。作業効率はかなり良くなった気がする。
時間を含むプロット
Rでの日付や時刻のプロットの仕方
dayが12/12のような日付を表す文字列のベクトルのときには、as.Date(day)としてプロットすると、軸を日付にしたプロットをすることができる。体重などの記録をプロットするときにも、利用していた方法である。今回、さらにtimeが12:12のように時刻を表す文字列のベクトルが与えられているときに、日付と時刻を考慮してプロットする必要だ出てきた。このときには、strptime(paste(day,time),"%m/%d %H:%M")とすると、時間に変換されるので、プロットすることができる。