LoginSignup
1
1

More than 5 years have passed since last update.

Pythonでデバイスをリアルタイムに読み書きをする方法?

Last updated at Posted at 2019-02-01

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)
1
1
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1