久々のlubuntuのインストール
SSDをつんだノートにubuntu18.04を入れたら、以外に苦労した。まず、USBメモリにisoを入れて、そこからブートしてインストールを開始した。しかし、swapパーティションを無くすのを忘れたと思ってと中で止めたのがいけなかったか、それ以降苦労することになった。
partitionerが途中で止まって動かないようになってしまったので、レスキューモードで立ち上げたら、最後までインストール出来た。そのためにユーザーの設定がされない状態になってしまった。そこで、同じくレスキューモードでユーザーを作成した。
後で調べたら、今のubuntuはswapパーティションが無くなって、swapファイルになっていたので、最初のインストールを止める必要が無かったことが分かった。
さらに、aptでupdateをすると、「ハッシュサムが適合しません」と出てしまう。そのようなバグも報告されていたようである。/var/lib/apt/lists/*
を消去することによって、この問題も解決した。そして、upgradeをしたら、それなりに使えるようになってきた。
軌道の絵
Rのrglを使った原子軌道の角度部分の絵
原子軌道の角度部分の立体的な絵を、ソフトを使って書いてみた。webを調べるとpovrayを使って書いている人が多かったが、特殊関数などの定義が面倒だし、Rのrglを使って書いた方が良い気がして、その方針でやってみた。ソースは以下のとおりです。
library(misc3d) library(gsl) theta<-function(x,y,z)acos(z/sqrt(x^2+y^2+z^2)) phi<-function(x,y,z)atan( (sqrt(x^2+y^2)-x)/y )*2 th<- 0:100/100*pi ph<- 0:200/200*2*pi fc <- function(x,y,z)ifelse(fr(theta(x,y,z),phi(x,y,z))<0,'blue','red') fx <- function(t,p)abs(fr(t,p))*sin(t)*cos(p) fy <- function(t,p)abs(fr(t,p))*sin(t)*sin(p) fz <- function(t,p)abs(fr(t,p))*cos(t) for(l in 0:5){ for(m in 0:l){ fr <- function(t,p)legendre_Plm(l,m,cos(t))*cos(m*p) parametric3d(fx, fy, fz, th, ph,color=fc) play3d(spin3d(c(0, 0, 1), 10),5) }}
ライブラリとしては、特殊関数を使うためにrglを使って、プロットにはmisc3dのparametric3dを使った。極座標のphiは、tan(2phi)から計算するようにして、条件分岐を減らすことができた。とりあえず、h軌道ぐらいまで書いて、五秒間10rpmで回すようにしてみたが、分かりやすくなったかな。
Rで球面調和関数
ルジャンドル陪多項式
Rを使って、球面調和関数展開をしようと思ったら、ルジャンドル陪多項式が見当たらない。調べてみたらgslにあった。r-cran-gslをaptで入れたら、
library(gsl) legendre_Plm(l,abs(m),cos(theta))*exp(-1i*m*phi)
という感じで使うことができた。これで、必要なら軌道の絵なども書けるようになった。しかし、普段使っているノートは、少し古いubuntuで、これにはパッケージが無くて使えないという罠があった。
windowsの共有は難しい
raspberry pi3を通じて
windowsで制御している装置のデータを、LANを通じて別のPCから見れるようにする際に、そのwindows PCはインターネットに接続したくなかったので、間にraspberry pi3を入れてみた。
raspberry pi3とそのwindows PCを有線LANで繋ぐ計画だったのだが、装置の制御に有線LANを使っていたので、まずはIPを調べる必要があった。その結果、PCが1で、装置が10と20のようだった。重複しないように、raspberry piは53にしてみた。なんとなく素数にしたくなってしまう。routerは未設定にした。これで、制御PCと装置とraspberry piのみのLANが構築できる。
次は、windows10でwindows共有をするのだが、これは非常に苦労した。ネットの情報を元にして、いろいろなところをいじったり、何度も再起動していたら、なんとか共有をすることができた。特に最近のwindowsはwindows共有をするのが非常に難しい。
あとはraspberry piにその共有フォルダをマウントするように/etc/fstabを書き換えた。このとき、単にautoとしてもダメで、下記のようにしたらうまく行くようだ。
//ip.1/Data /home/pi/public cifs username=user,password=pass,noauto,x-systemd.automount 0 0
そして、raspberry piを無線LANで繋ぎ、共有したフォルダをftpでanonymousから読み取りのみでアクセスできるようにしておいた。本当はsftpにしたいのだが、windowsからアクセスするのに面倒らしいので、ftpで我慢している。
今の所、装置との干渉も気にならないようだし、自動mountもうまく働いているので、このまま問題が起きないと良いな。あとはUSBの穴を塞いで。
内蔵LANとWifi
二系統のLAN
ラズベリーパイで二系統のLANに接続するために、内蔵のLANとUSB-LANを使おうと思っていたが、よくよく考えると、raspberry pi 3で内蔵LANとWifiを使えば良いことに気がついた。
まずは、sshを有効にするために、
sudo systemctl enable ssh
とする。そして、wifiのパスワードを
sudo sh -c 'wpa_passphrase SSID PASSPHRASE >> /etc/wpa_supplicant/wpa_supplicant.conf'
として設定する。そして、/etc/dhcpcd.confを編集する。
interface eth0 static ip_address=192.168.0.3/24 interface wlan0 static ip_address=172.16.0.3/24 static routers=172.16.0.1 static domain_name_servers=172.16.0.1
こんな感じです。これで、一応二系統のLANに接続できた。本当はさらにいろいろと設定して、やりたいことがあるけど、まだ接続するPCが無いのでできません。
ESP8266のmicropythonでSPI
micropythonでadt7310を読む
micropythonで温度測定するために、adt7310を使う方法を模索してみた。adt7310のpinとesp8266は以下のように接続した。
1 SCK D5 14 2 DOUT D6 12 3 DIN D7 13 4 CS D8 15
まず、初期化は以下のように行う。
from machine import Pin,SPI spi=SPI(baudrate=1000000,sck=Pin(14),mosi=Pin(13),miso=Pin(12),firstbit=SPI.MSB,polarity=1,phase=1) cs=Pin(15, Pin.OUT) cs(1)
ここで、polarityはclockが何もしていない時にはhighであることを示し、phaseはclockが元に戻るedgeで読み取りを行うことを示す。 adt7310のモードの設定は、以下のように行う。
cs(0) #spi.write(bytearray([1<<3,0xa0])) #one shot spi.write(bytearray([1<<3,0x80])) #continuous cs(1)
そして、温度の読み取りは
cs(0) spi.write(bytearray([0x40|2<<3])) ret=spi.read(2) cs(1) (ret[0]*256+ret[1])/128
とすれば良い。本当は符号の処理も行わないといけないけど、零下になることはまず無いので、良しとしよう。bytearrayの扱いもよく分かっていないけど、まあ良いか。
Rで複雑なfitting
optimizeとoptim
Rをつかって複雑な式でfittingをやることがある。線形の場合にはlmを、非線型の場合にはnlsを使えば良い。しかし、単純な関数で表せなかったり、媒介変数で表されるような場合には、これらは使えない。どうしたら良いかを考えていたら、fittingとの差を表すような関数を定義して、それを最小化すれば良いことに気がついた。例えば、xをax^2で近似するときの最適なaを求める場合には、差を表す関数を定義して、optimizeでその関数と変数の範囲を指定して、最小値を求めれば良い。
x<-0:10/10 f<-function(a){return(sum((x-a*x^2))^2)} res<-optimize(f,c(0,2)) res$minimum
二変数の場合には、optimを使う。このとき、関数の引数はベクトルとして与え、optimには初期値をベクトルとして与える必要がある。
x<-0:10/10 f<-function(a){return(sum((x-a[1]*x^2-a[2]))^2)} res<-optim(c(0,0),f) res$par
ここでの例は、単純で通常の方法でもできるだろうが、複雑なfittingではこれが有効になった。
micropythonでLチカ
まずはLチカから
ESP8266にmicropythonが入ったので、それを使ってLEDを光らせてみた。 14番pinとGNDの間にLEDを繋ぐと、薄っすらと光ったが、おそらくpull upされているのだろう。
import machine pin=machine.Pin(14, machine.Pin.OUT)
としてから、pin(1)とpin(0)でON/OFFができる。pythonからLEDを制御できたことで、少し喜んでいたら、他の人にはUSB接続をしたままLEDのON/OFFできても当たり前だ、と言われてしまった。折角esp8266を使っているのだから、wifiからON/OFFさせろという意味なのだろう。
ESP8266にmicropythonを入れて動かしてみた.
無事に動いた
インストール作業には古いubuntuのPCを使ったが,まず準備としてこのPCにesptoolをインストールする.
sudo aptitude install python-pip sudo pip install esptool
そして,esp8266用のmicropythonのbinaryをdownloadしてから,ESP8266をUSBで接続して,これを書き込む.
sudo esptool.py --port /dev/ttyUSB0 erase_flash sudo esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=32m 0 esp8266-20180511-v1.9.4.bin
これで準備が整ったので,実行してみるが,シリアル接続するためにscreenをインストールして,次のように実行する.
sudo screen /dev/ttyUSB0 115200
そこで,esp8266のボードをリセットすると,ターミナルにpythonのプロンプトが表示される.ここにscriptを打ち込むと,その結果が返ってくる.試しに足し算などをしてみたが,足し算ができただけで一人で喜んでいた.
試しにプログラムを実行してみるには,ターミナルで打ち込んで挙動を見るのは有用であるが,実際に使う時には不便である.micropythonは,起動時にboot.pyが,次いでmain.pyが実行される.これらのファイルを転送すれば,自動的に実行される.そこで,ファイルの転送ツールをインストールする.
sudo pip install adafruit-ampy
ampyを使うと,ftpのような感じのコマンドで,ファイルの転送ができ,それを実行することができた.
ampy --port=/dev/ttyUSB0 ls ampy --port=/dev/ttyUSB0 put main.py ampy --port=/dev/ttyUSB0 rm main.py
実行したい命令をmain.pyに入れて,それを転送すれば,リセット後に実行することができる.
様々なマイコン
esp8266でmicropython
いろいろなマイコンをいじってみたくて、今年はstm32を少し触り始めたところです。最近は、ESP32というのも流行っているようなので、調べてみると、以前使ったESP8266の上位のマイコンであることが分かった。さらに、micropythonやmrubyというpythonやrubyも動かせるらしい。しかし、stm32やesp8266もろくに使いこなせていないのに、esp32に手を出すのは早い気がする。
esp8266でもmicropythonを使えるようになってきているようなので、まずはそれを試してみる方が良いだろうという考えに至った。ここからfirmwareを落として、書き込んだら、シリアルからpythonのプログラムを動かせるようになるらしい。でも、時間が無いのでまだ試していない。