stackoverflowでも書いたのですが以下のことで悩んでます。
ラズパイマウスで/dev/
以下のデバイスに対してechoやcatで読み書きをすることがあるかと思います。
echo 100 > /dev/rtmotor_raw_l0 # output 100hz frequency
cat /dev/rtswitch0 # read switch state
Pythonで出力をする
一応解決したのですが後学のために古いVerも残しておきます。
Bad case: file.write を用いる
echoで書いていた内容をPythonのwriteで代替できると思って以下のプログラムを書きました。
コード全体で見れば先程のecho文と同様の出力を投げます。
file = open('/dev/rtmotor_raw_l0','w')
file.write('100\n') # I want output in this timing
file.close() # output reflected after closing file
問題は実行されるタイミングで,本来はwrite()したタイミングで反映されてほしいんですが,このプログラムの場合close()のタイミングで反映されてしまいます。困った。
追記にすればいいのかなと思い'w'
を'a'
などに変えても変わりませんでした。
Better case:os.write を用いる
osモジュールを用いることで毎回openが必要となる問題は解決できました。
os.writeの際にファイルのディスクリプタを毎回渡すのでechoと同様の挙動が再現できているということなのでしょうか
file.writeとos.writeの違いについて述べている人も居ますね。
import os
flm = os.open("/dev/rtmotor_raw_l0",os.O_RDWR)
os.write(flm,"100\n")
Pythonで読み込みをする
Bad case: file.readで読み込みをする
同様の問題が読み込みにもあります。
以下のようにして読むことが出来ますが,これはfileをopenした時点での情報しか掴めないのです。
file = open('/dev/rtswitch','r')
file.read() # works
file.read() # after first read it does't work anymore
file.close() # need to reopen the file to get newer value
したがって2回めのreadは空の値を示します。
一旦閉じて開き直さない限り,出力も入力も更新できないというのが今の悩みです。
Streamがどうのこうのとか昔聞いたような気もするのですが,これって解決策があるんでしたっけ?
Better case: os.read()
Currently I have a trouble with lseek
.
>>> os.lseek(fd,0,os.SEEK_SET)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 29] Illegal seek
Codes
第1引数に 周波数,第2引数に持続時間を入れて走らせる自動化コード例です。
これは完全にただのメモっす。
.sh
#!/bin/sh
echo 1 > /dev/rtmotoren0 #enable
# $1 : f [hz]
# $2 : t [ms]
echo $1 > /dev/rtmotor_raw_l0
echo $1 > /dev/rtmotor_raw_r0
sleep $2
echo 0 > /dev/rtmotor_raw_l0
echo 0 > /dev/rtmotor_raw_r0
echo 0 > /dev/rtmotoren0 #disable
.py
import subprocess
import os
import sys
import time
if __name__=='__main__':
arg=sys.argv
res = subprocess.call(["echo 1 > /dev/rtmotoren0"],shell=True)
flm = os.open("/dev/rtmotor_raw_l0",os.O_RDWR)
frm = os.open("/dev/rtmotor_raw_r0",os.O_RDWR)
os.write(flm,arg[1])
os.write(frm,arg[1])
time.sleep(float(arg[2])/1000.0)
os.write(flm,"0\n")
os.write(frm,"0\n")
os.close(flm)
os.close(frm)
res = subprocess.call(["echo 0 > /dev/rtmotoren0"],shell=True)