質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
cron

cronは、Unix系OS上でデーモンプロセスとして動作する、スクリプトの自動実行が可能なジョブスケジューラです。

Raspbian

Raspbianは、DebianベースのRaspberry Pi用ディストリビューション。ハードウェア浮動小数点演算を有効にすることが可能で、Webブラウズなどの速度を向上できます。

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Q&A

解決済

2回答

1828閲覧

Pythonで2つの処理をそれぞれ一定時間ごとに実行したい

tamasa

総合スコア11

cron

cronは、Unix系OS上でデーモンプロセスとして動作する、スクリプトの自動実行が可能なジョブスケジューラです。

Raspbian

Raspbianは、DebianベースのRaspberry Pi用ディストリビューション。ハードウェア浮動小数点演算を有効にすることが可能で、Webブラウズなどの速度を向上できます。

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

0グッド

0クリップ

投稿2018/03/28 01:11

編集2018/03/28 08:24

ラズベリーパイにセンサーを接続して取得したデータをpythonにて液晶のlcdディスプレイに数秒ごとに表示させて、かつcsvファイルに数分ごとに保存したいと考えています。cronにてcsvファイルを保存するソースコードを作成し、回しましたがエラーが出て何度修正しても止まります。lcdの表示のみでは止まりません。
そこでthreading関数で実行したいのですが、下記のソースコードを実行してもエラーが表示されて動きません。
どう修正すれば良いかお教えください。プログラミング初心者です。python2.7です。どうか宜しくお願い致します。

(エラー)
temp : 27.79 ℃
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "dht11_faq.py", line 128, in func2
csv = readData()
File "dht11_faq.py", line 41, in readData
t = Tm()
File "dht11_faq.py", line 17, in Tm
data = bus.read_i2c_block_data(0x45, 0x00, 6)
IOError: [Errno 5] Input/output error

Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "dht11_faq.py", line 106, in func1
readData()
File "dht11_faq.py", line 43, in readData
h = Hu()
File "dht11_faq.py", line 27, in Hu
bus.write_i2c_block_data(0x45, 0x2C, [0x06])
IOError: [Errno 121] Remote I/O error

python

1 2#!/usr/bin/python 3#coding: utf-8 4 5import smbus 6import time 7import datetime 8import os 9import threading 10 11bus = smbus.SMBus(1) 12 13def Tm(): 14 time.sleep(0.2) 15 bus.write_i2c_block_data(0x45, 0x2C, [0x06]) 16 17 time.sleep(0.2) 18 data = bus.read_i2c_block_data(0x45, 0x00, 6) 19 20 temp = data[0] * 256 + data[1] 21 cTemp = -45 + (175 * temp / 65535.0) 22 23 print "temp : %-6.2f ℃" % (cTemp) 24 return "%.2f" % (cTemp) 25 26def Hu(): 27 time.sleep(0.2) 28 bus.write_i2c_block_data(0x45, 0x2C, [0x06]) 29 30 time.sleep(0.2) 31 data = bus.read_i2c_block_data(0x45, 0x00, 6) 32 33 34 humidity = 100 * (data[3] * 256 + data[4]) / 65535.0 35 36 print "hum : %6.2f %" % (humidity) 37 return "%.2f" % (humidity) 38 39def readData(): 40 41 time.sleep(0.2) 42 t = Tm() 43 time.sleep(0.2) 44 h = Hu() 45 46 print("---") 47 48 return t + "," + h 49 50 #time.sleep(5) 51 52class i2clcd: 53 54 i2c = smbus.SMBus(1) 55 addr = 0x3e 56 contrast = 40 # 0~63 57 58 def __init__(self): 59 time.sleep(1) 60 self.i2c.write_byte_data(self.addr, 0, 0x38) # function set(IS=0) 61 self.i2c.write_byte_data(self.addr, 0, 0x39) # function set(IS=1) 62 self.i2c.write_byte_data(self.addr, 0, 0x14) # internal osc 63 self.i2c.write_byte_data(self.addr, 0, 64 (0x70 | (self.contrast & 0x0f))) # contrast 65 self.i2c.write_byte_data(self.addr, 0, 66 (0x54 | ((self.contrast >> 4) & 0x03))) # contrast/icon/power 67 self.i2c.write_byte_data(self.addr, 0, 0x6B) # follower control 68 # self.i2c.write_byte_data(self.addr, 0, 0x6c) # follower control 69 70 time.sleep(0.2) 71 72 def clear(self): 73 time.sleep(0.3) 74 self.i2c.write_byte_data(self.addr, 0, 0x38) # function set(IS=0) 75 self.i2c.write_byte_data(self.addr, 0, 0x70) # Constract 76 self.i2c.write_byte_data(self.addr, 0, 0x0C) # Display On 77 self.i2c.write_byte_data(self.addr, 0, 0x01) # Clear Display 78 self.i2c.write_byte_data(self.addr, 0, 0x06) # Entry Mode Set 79 80 time.sleep(0.1) 81 82 83 def puts(self, msg): 84 85 self.i2c.write_byte_data(self.addr, 0, 0x38) # function set(IS=0) 86 [self.i2c.write_byte_data(self.addr, 0x40, ord(c)) for c in msg] 87 88 def setaddress(self, line, col): 89 time.sleep(0.5) 90 self.i2c.write_byte_data(self.addr, 0, 0x38) # function set(IS=0) 91 time.sleep(0.5) 92 self.i2c.write_byte_data(self.addr, 0, 0x80 | (0x40 if line > 0 else 0) | col) 93 94 def setcg(self, no, cg): 95 self.i2c.write_byte_data(self.addr, 0, 0x38) # function set(IS=0) 96 self.i2c.write_byte_data(self.addr, 0, 0x40 | (no << 3)) 97 [self.i2c.write_byte_data(self.addr, 0x40, c) for c in cg] 98 99 def putcg(self, line, col, no): 100 self.setaddress(line, col) 101 self.i2c.write_byte_data(self.addr, 0x40, no) 102 103 104def func1(): 105 while True: 106 107 readData() 108 109 data = readData().split(",") 110 t = data[0] 111 h = data[1] 112 113 lcd = i2clcd() 114 lcd.clear() 115 time.sleep(1) 116 117 lcd.setaddress(0, 0) 118 lcd.puts(str(t).rjust(9)+" 'C") 119 lcd.setaddress(1, 0) 120 lcd.puts(str(h).rjust(9)+" %") 121 122def func2(): 123 124 dir_path = '/home/pi/dht11-data' 125 126 now = datetime.datetime.now() 127 filename = now.strftime('%Y%m%d') 128 label = now.strftime('%H:%M') 129 csv = readData() 130 131 if not os.path.exists('/home/pi/dht11-data'): 132 os.makedirs('/home/dht11-data') 133 f = open('/home/pi/dht11-data/'+filename+'.csv','a') 134 f.write("'"+label+"',"+csv+"\n") 135 f.close() 136 137 138if __name__ == "__main__": 139 thread_1 = threading.Thread(target=func1) 140 thread_2 = threading.Thread(target=func2) 141 142 thread_1.start() 143 thread_2.start() 144

<追記>
下記のようにスレッドを削除し、while Trueで処理すると動作しますが、二つ目のwhile Trueが同時に実行されません。

python

1#!/usr/bin/python 2#coding: utf-8 3 4import smbus 5import time 6import datetime 7import os 8import threading 9 10bus = smbus.SMBus(1) 11 12def Tm(): 13 time.sleep(0.2) 14 bus.write_i2c_block_data(0x45, 0x2C, [0x06]) 15 16 time.sleep(0.2) 17 data = bus.read_i2c_block_data(0x45, 0x00, 6) 18 19 temp = data[0] * 256 + data[1] 20 cTemp = -45 + (175 * temp / 65535.0) 21 22 print "temp : %-6.2f ℃" % (cTemp) 23 return "%.2f" % (cTemp) 24 25def Hu(): 26 time.sleep(0.2) 27 bus.write_i2c_block_data(0x45, 0x2C, [0x06]) 28 29 time.sleep(0.2) 30 data = bus.read_i2c_block_data(0x45, 0x00, 6) 31 32 33 humidity = 100 * (data[3] * 256 + data[4]) / 65535.0 34 35 print "hum : %6.2f %" % (humidity) 36 return "%.2f" % (humidity) 37 38def readData(): 39 40 time.sleep(0.2) 41 t = Tm() 42 time.sleep(0.2) 43 h = Hu() 44 45 print("---") 46 47 return t + "," + h 48 49 #time.sleep(5) 50 51class i2clcd: 52 53 i2c = smbus.SMBus(1) 54 addr = 0x3e 55 contrast = 40 # 0~63 56 57 def __init__(self): 58 time.sleep(1) 59 self.i2c.write_byte_data(self.addr, 0, 0x38) # function set(IS=0) 60 self.i2c.write_byte_data(self.addr, 0, 0x39) # function set(IS=1) 61 self.i2c.write_byte_data(self.addr, 0, 0x14) # internal osc 62 self.i2c.write_byte_data(self.addr, 0, 63 (0x70 | (self.contrast & 0x0f))) # contrast 64 self.i2c.write_byte_data(self.addr, 0, 65 (0x54 | ((self.contrast >> 4) & 0x03))) # contrast/icon/power 66 self.i2c.write_byte_data(self.addr, 0, 0x6B) # follower control 67 # self.i2c.write_byte_data(self.addr, 0, 0x6c) # follower control 68 69 time.sleep(0.2) 70 71 def clear(self): 72 time.sleep(0.3) 73 self.i2c.write_byte_data(self.addr, 0, 0x38) # function set(IS=0) 74 self.i2c.write_byte_data(self.addr, 0, 0x70) # Constract 75 self.i2c.write_byte_data(self.addr, 0, 0x0C) # Display On 76 self.i2c.write_byte_data(self.addr, 0, 0x01) # Clear Display 77 self.i2c.write_byte_data(self.addr, 0, 0x06) # Entry Mode Set 78 79 time.sleep(0.1) 80 81 82 def puts(self, msg): 83 84 self.i2c.write_byte_data(self.addr, 0, 0x38) # function set(IS=0) 85 [self.i2c.write_byte_data(self.addr, 0x40, ord(c)) for c in msg] 86 87 def setaddress(self, line, col): 88 time.sleep(0.5) 89 self.i2c.write_byte_data(self.addr, 0, 0x38) # function set(IS=0) 90 time.sleep(0.5) 91 self.i2c.write_byte_data(self.addr, 0, 0x80 | (0x40 if line > 0 else 0) | col) 92 93 def setcg(self, no, cg): 94 self.i2c.write_byte_data(self.addr, 0, 0x38) # function set(IS=0) 95 self.i2c.write_byte_data(self.addr, 0, 0x40 | (no << 3)) 96 [self.i2c.write_byte_data(self.addr, 0x40, c) for c in cg] 97 98 def putcg(self, line, col, no): 99 self.setaddress(line, col) 100 self.i2c.write_byte_data(self.addr, 0x40, no) 101 102 103 104while True: 105 106 readData() 107 108 data = readData().split(",") 109 t = data[0] 110 h = data[1] 111 112 lcd = i2clcd() 113 lcd.clear() 114 time.sleep(1) 115 116 lcd.setaddress(0, 0) 117 lcd.puts(str(t).rjust(9)+" 'C") 118 lcd.setaddress(1, 0) 119 lcd.puts(str(h).rjust(9)+" %") 120 121while True: 122 123 dir_path = '/home/pi/dht11-data' 124 125 now = datetime.datetime.now() 126 filename = now.strftime('%Y%m%d') 127 label = now.strftime('%H:%M') 128 csv = readData() 129 130 if not os.path.exists('/home/pi/dht11-data'): 131 os.makedirs('/home/dht11-data') 132 f = open('/home/pi/dht11-data/'+filename+'.csv','a') 133 f.write("'"+label+"',"+csv+"\n") 134 f.close() 135

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coco_bauer

2018/03/28 01:47

作ったプログラムのソースコードと、表示されるエラーメッセージを質問に追加してください。
KojiDoi

2018/03/28 03:18 編集

「5秒ごとに処理を繰り返す」機能を内蔵しているならcronから呼び出す必要性がないように思いますが、何か事情があるのでしょうか。
tamasa

2018/03/28 05:35

ソースコードを書き替え、内容を修正しました。2つ実行したい処理があり、一つは数秒ごとに、もう一方は数分ごとに実行させたいです。
guest

回答2

0

ベストアンサー

まずはcronthreadも使わずに、単純ループで実現させることをお勧めします。
以下は、異なる時間間隔で複数処理する概念コード例(Python3.x用)です。
前回の処理日時を保持することで、複数処理できるようにしています。

Python

1from datetime import datetime as dt 2import time 3 4# 前回の処理日時 5prev_disp = dt.now() 6prev_file = dt.now() 7 8# 処理間隔[sec] 9INTERVAL_DISP = 5 10INTERVAL_FILE = 10 11 12try: 13 # 必要に応じセンサーやディスプレイの初期化 14 print('init') 15 16 while True: 17 cur = dt.now() 18 print('get data') 19 20 # ディスプレイ表示 21 if (cur - prev_disp).total_seconds() >= INTERVAL_DISP: 22 prev_disp = cur 23 print('display data') 24 25 # ファイル出力 26 if (cur - prev_file).total_seconds() >= INTERVAL_FILE: 27 prev_file = cur 28 print('save data') 29 30 time.sleep(1) 31 32except KeyboardInterrupt: 33 # 終了するには(プロセスをフォアグラウンドに戻してから)Ctrl+C入力 34 print('break') 35finally: 36 # 必要に応じ終了処理 37 print('exit') 38 39print('end')

投稿2018/03/28 06:59

can110

総合スコア38266

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tamasa

2018/03/28 08:48

有難うございます。参考にさせて頂きます。
guest

0

ツッコミどころがたくさん。

まず、func1が無限ループになってるけど、これであってるの?


んで、スレッド実行させるのはやめましょう

この2点の修正でとりあえず動くようにはなるかと。

投稿2018/03/28 05:39

編集2018/03/28 05:44
y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tamasa

2018/03/28 05:44

ご回答有難うございます。初心者でthredingを初めて実行しています。ツッコんで頂けると助かります。
tamasa

2018/03/28 05:55

ご連絡有難うございます。def func1()とdef func2()を削除し、if _name・・・以下を削除して実行しますと動きますが、func1の内容を数秒ごと、func2の内容を数分ごとに同時に実行したいのですができません。別の方法で、crontabでfunc2の内容を実行しますとしばらくは動くのですが、止まってしまいます。同じデータをreadData()で使用していることが原因と思うのですが、解決方法が分かりません。特にスレッドにこだわりはなく、どうすればうまく動作するようになるかお教えいただけると助かります。
y_waiwai

2018/03/28 06:02

func1 って、最初の > while True: で繰り返し実行されていて終了しないけど、これでいいの?
tamasa

2018/03/28 06:05

はい、無限にデータを取り続けたいです。
y_waiwai

2018/03/28 06:10

えー、cronで一定時間ごとにこれ実行させると、func1が終わらない、動き続けるため、次々と同じプログラムが重なっていくんだけど、本当にこれでいいの? たぶん、cronの2回目以降の実行で、IIC通信ができなくてエラーで落ちると思うけど
tamasa

2018/03/28 06:23 編集

おっしゃる通り、しばらくするとセンサーのデータが読めずにエラーにまります。行ったことは、func1はこのままでwhile Trueで実行し、func2を別ファイルにしてデータをインポートしてcrontabで動作させましたが、しばらくすると止まってしまいます。どうすればよろしいでしょうか。
y_waiwai

2018/03/28 06:23

cron で実行させるなら、func1のアタマのwhileは削除してきちんと終わるようにしないとダメです そのプログラム単体で動かせるなら、無限ループしててもいいけど
y_waiwai

2018/03/28 06:26

ああ、質問追記したのね。 それだと、最初の whie true: で繰り返しになるので2回めにはいかなくなる
tamasa

2018/03/28 06:30 編集

説明不足ですみません。while trueは理解できました。有難うございます。func1は単体で動作させて、func2をcronでwhileなしで動かしましたが、エラーで止まってしまいます。I2Cで取得したデータを二つのソースコードで別々の時間に動かいたいのですがうまくできません。お教え頂けると助かります。
y_waiwai

2018/03/28 06:35

IIC通信している相手は1つしか無い。 それをcron なんかで重複させて実行させるのは無理。そこでエラーが出る なので、cronで実行させるのはまずあきらめれ。 全体をループさせて実行させてみれ。それはうまくいくのか?
y_waiwai

2018/03/28 06:37

そのプログラムの中で、時刻を判定してfunc2を実行させる、というふうにするべし
tamasa

2018/03/28 06:41

なるほど、それでエラーが出るのですね。有難うございます。時刻を判定してfunc2を実行する方法が分かりません。マルチスレッド処理というものでしょうか。初心者なので難しいです。
y_waiwai

2018/03/28 06:59 編集

いや、マルチスレッドにしたらエラーになるという話なのでw while true:  次の時刻設定  func1()  if 時刻になった?   func2()   次の時刻設定 こゆこと
y_waiwai

2018/03/28 07:13

マルチスレッドとかマルチタスクにすると、処理の間に他の処理が並行して実行される、というかんじになる 双方別のことをやってるならそれはふつーにうごく。 だけど、この場合はIIC通信でセンサを読むという操作が双方に入る。 実行タイミングが重ならないなら動くんだろうが、それが重なった場合にエラーとなる #実際はIICのライブラリの方で不当な重複アクセスが起これば例外で落とすようにしてるんだろうけど
tamasa

2018/03/28 07:25 編集

詳細なご説明有難うございます。大変勉強になります。 while true: ・・・ifの考え方は分かりましたのでやってみます。できましたら厚かましくてすみません、このページ記載されている内容で合っていますでしょうか。https://teratail.com/questions/40583 具体例があれば実行できそうになってきました。
y_waiwai

2018/03/28 07:28

そんなかんじね。 疑問があったら、とにかく思いつくキーワードいれてぐぐればいい。 ぐぐる技術もスキルのうちですぜ #んで、別の回答の方もよく見ておこう
tamasa

2018/03/28 07:50

ご回答有難うございます。ソースコードを追記しました。動かしてみましたが、エラーは起きませんがcsvファイルが生成されません。どこが間違っておりますでしょうか。度々すみませんがご回答頂けると助かります。宜しくお願いします。別の方の回答も参照してみます。
tamasa

2018/03/28 08:25

一つ目のwhile True以下をすべて削除し、下記を追記しました。動作しましたが、60秒経過してもcsvファイルが生成されません。なぜでしょうか。 ```python while True : t0 = time.time() if time.time() - t0 < 60 : readData() data = readData().split(",") t = data[0] h = data[1] lcd = i2clcd() lcd.clear() time.sleep(1) lcd.setaddress(0, 0) lcd.puts(str(t).rjust(9)+" 'C") lcd.setaddress(1, 0) lcd.puts(str(h).rjust(9)+" %") else: dir_path = '/home/pi/dht11-data' now = datetime.datetime.now() filename = now.strftime('%Y%m%d') label = now.strftime('%H:%M') csv = readData() if not os.path.exists('/home/pi/dht11-data'): os.makedirs('/home/dht11-data') f = open('/home/pi/dht11-data/'+filename+'.csv','a') f.write("'"+label+"',"+csv+"\n") f.close() time.sleep(0.5) ```
y_waiwai

2018/03/28 08:40

まず、このopenのところに制御が来てるかなんかメッセージでも出して確認すること。 LCDになんか出してもいい openの実行が成功してるかを確認。fをみてなんか出してみる それとファイル云々は関係ないけど、これまちがってますで if not os.path.exists('/home/pi/dht11-data'):  os.makedirs('/home/dht11-data')
tamasa

2018/03/28 08:50

!、どこが間違っていますでしょうか。現在はファイルを作成しておかないと動かいないのですが、別のソースではフォルダとファイルが自動で生成していました。お教えいただけますと助かります。宜しくお願いします。
y_waiwai

2018/03/28 08:54

makedirs のディレクトリ名を確認汁
tamasa

2018/03/29 00:56

ご指摘有難うございます。動作しなかった原因が分かりました。助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問