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

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

ただいまの
回答率

89.69%

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

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,120

tamasa

score 9

ラズベリーパイにセンサーを接続して取得したデータを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

#!/usr/bin/python
#coding: utf-8

import smbus
import time
import datetime
import os
import threading

bus = smbus.SMBus(1)

def Tm():
    time.sleep(0.2)
    bus.write_i2c_block_data(0x45, 0x2C, [0x06])

    time.sleep(0.2)
    data = bus.read_i2c_block_data(0x45, 0x00, 6)

    temp = data[0] * 256 + data[1]
    cTemp = -45 + (175 * temp / 65535.0)

    print "temp : %-6.2f ℃" % (cTemp)
    return "%.2f" % (cTemp)     

def Hu():
    time.sleep(0.2)
    bus.write_i2c_block_data(0x45, 0x2C, [0x06])

    time.sleep(0.2)
    data = bus.read_i2c_block_data(0x45, 0x00, 6)


    humidity = 100 * (data[3] * 256 + data[4]) / 65535.0

    print "hum : %6.2f %" % (humidity)
    return "%.2f" % (humidity)

def readData():

    time.sleep(0.2)
    t = Tm()
    time.sleep(0.2)
    h = Hu()

    print("---")

    return t + "," + h

        #time.sleep(5)

class i2clcd:

    i2c = smbus.SMBus(1)
    addr = 0x3e
    contrast = 40   # 0~63

    def __init__(self):
        time.sleep(1)
        self.i2c.write_byte_data(self.addr, 0, 0x38)    # function set(IS=0)
        self.i2c.write_byte_data(self.addr, 0, 0x39)    # function set(IS=1)
        self.i2c.write_byte_data(self.addr, 0, 0x14)    # internal osc
        self.i2c.write_byte_data(self.addr, 0,
                    (0x70 | (self.contrast & 0x0f)))    # contrast
        self.i2c.write_byte_data(self.addr, 0,
                    (0x54 | ((self.contrast >> 4) & 0x03)))      # contrast/icon/power
        self.i2c.write_byte_data(self.addr, 0, 0x6B)    # follower control
        # self.i2c.write_byte_data(self.addr, 0, 0x6c)    # follower control

        time.sleep(0.2)

    def clear(self):
        time.sleep(0.3)
        self.i2c.write_byte_data(self.addr, 0, 0x38)    # function set(IS=0)
        self.i2c.write_byte_data(self.addr, 0, 0x70)    # Constract
        self.i2c.write_byte_data(self.addr, 0, 0x0C)    # Display On
        self.i2c.write_byte_data(self.addr, 0, 0x01)    # Clear Display
        self.i2c.write_byte_data(self.addr, 0, 0x06)    # Entry Mode Set

        time.sleep(0.1)


    def puts(self, msg):

        self.i2c.write_byte_data(self.addr, 0, 0x38)    # function set(IS=0)
        [self.i2c.write_byte_data(self.addr, 0x40, ord(c)) for c in msg]

    def setaddress(self, line, col):
        time.sleep(0.5)
        self.i2c.write_byte_data(self.addr, 0, 0x38)    # function set(IS=0)
        time.sleep(0.5)
        self.i2c.write_byte_data(self.addr, 0, 0x80 | (0x40 if line > 0 else 0) | col)

    def setcg(self, no, cg):
        self.i2c.write_byte_data(self.addr, 0, 0x38)    # function set(IS=0)
        self.i2c.write_byte_data(self.addr, 0, 0x40 | (no << 3))
        [self.i2c.write_byte_data(self.addr, 0x40, c) for c in cg]

    def putcg(self, line, col, no):
        self.setaddress(line, col)
        self.i2c.write_byte_data(self.addr, 0x40, no)


def func1():
    while True:

        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)+" %")

def func2():

    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()


if __name__ == "__main__":
    thread_1 = threading.Thread(target=func1)
    thread_2 = threading.Thread(target=func2)

    thread_1.start()
    thread_2.start()

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

#!/usr/bin/python
#coding: utf-8

import smbus
import time
import datetime
import os
import threading

bus = smbus.SMBus(1)

def Tm():
    time.sleep(0.2)
    bus.write_i2c_block_data(0x45, 0x2C, [0x06])

    time.sleep(0.2)
    data = bus.read_i2c_block_data(0x45, 0x00, 6)

    temp = data[0] * 256 + data[1]
    cTemp = -45 + (175 * temp / 65535.0)

    print "temp : %-6.2f ℃" % (cTemp)
    return "%.2f" % (cTemp)     

def Hu():
    time.sleep(0.2)
    bus.write_i2c_block_data(0x45, 0x2C, [0x06])

    time.sleep(0.2)
    data = bus.read_i2c_block_data(0x45, 0x00, 6)


    humidity = 100 * (data[3] * 256 + data[4]) / 65535.0

    print "hum : %6.2f %" % (humidity)
    return "%.2f" % (humidity)

def readData():

    time.sleep(0.2)
    t = Tm()
    time.sleep(0.2)
    h = Hu()

    print("---")

    return t + "," + h

        #time.sleep(5)

class i2clcd:

    i2c = smbus.SMBus(1)
    addr = 0x3e
    contrast = 40   # 0~63

    def __init__(self):
        time.sleep(1)
        self.i2c.write_byte_data(self.addr, 0, 0x38)    # function set(IS=0)
        self.i2c.write_byte_data(self.addr, 0, 0x39)    # function set(IS=1)
        self.i2c.write_byte_data(self.addr, 0, 0x14)    # internal osc
        self.i2c.write_byte_data(self.addr, 0,
                    (0x70 | (self.contrast & 0x0f)))    # contrast
        self.i2c.write_byte_data(self.addr, 0,
                    (0x54 | ((self.contrast >> 4) & 0x03)))      # contrast/icon/power
        self.i2c.write_byte_data(self.addr, 0, 0x6B)    # follower control
        # self.i2c.write_byte_data(self.addr, 0, 0x6c)    # follower control

        time.sleep(0.2)

    def clear(self):
        time.sleep(0.3)
        self.i2c.write_byte_data(self.addr, 0, 0x38)    # function set(IS=0)
        self.i2c.write_byte_data(self.addr, 0, 0x70)    # Constract
        self.i2c.write_byte_data(self.addr, 0, 0x0C)    # Display On
        self.i2c.write_byte_data(self.addr, 0, 0x01)    # Clear Display
        self.i2c.write_byte_data(self.addr, 0, 0x06)    # Entry Mode Set

        time.sleep(0.1)


    def puts(self, msg):

        self.i2c.write_byte_data(self.addr, 0, 0x38)    # function set(IS=0)
        [self.i2c.write_byte_data(self.addr, 0x40, ord(c)) for c in msg]

    def setaddress(self, line, col):
        time.sleep(0.5)
        self.i2c.write_byte_data(self.addr, 0, 0x38)    # function set(IS=0)
        time.sleep(0.5)
        self.i2c.write_byte_data(self.addr, 0, 0x80 | (0x40 if line > 0 else 0) | col)

    def setcg(self, no, cg):
        self.i2c.write_byte_data(self.addr, 0, 0x38)    # function set(IS=0)
        self.i2c.write_byte_data(self.addr, 0, 0x40 | (no << 3))
        [self.i2c.write_byte_data(self.addr, 0x40, c) for c in cg]

    def putcg(self, line, col, no):
        self.setaddress(line, col)
        self.i2c.write_byte_data(self.addr, 0x40, no)



while True:

        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)+" %")

while True:

    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()
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • coco_bauer

    2018/03/28 10:47

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

    キャンセル

  • KojiDoi

    2018/03/28 12:17 編集

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

    キャンセル

  • tamasa

    2018/03/28 14:35

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

    キャンセル

回答 2

checkベストアンサー

+2

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

from datetime import datetime as dt
import time

# 前回の処理日時
prev_disp = dt.now()
prev_file = dt.now()

# 処理間隔[sec]
INTERVAL_DISP = 5
INTERVAL_FILE = 10

try:
    # 必要に応じセンサーやディスプレイの初期化
    print('init')

    while True:
        cur = dt.now()
        print('get data')

        # ディスプレイ表示
        if (cur - prev_disp).total_seconds() >= INTERVAL_DISP:
            prev_disp = cur
            print('display data')

        # ファイル出力
        if (cur - prev_file).total_seconds() >= INTERVAL_FILE:
            prev_file = cur
            print('save data')

        time.sleep(1)

except KeyboardInterrupt:
    # 終了するには(プロセスをフォアグラウンドに戻してから)Ctrl+C入力
    print('break')
finally:
    # 必要に応じ終了処理
    print('exit')

print('end')

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/28 17:48

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

    キャンセル

+2

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

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


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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/28 17:50

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

    キャンセル

  • 2018/03/28 17:54

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

    キャンセル

  • 2018/03/29 09:56

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

    キャンセル

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

  • ただいまの回答率 89.69%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る