【ラズパイ】【いろいろ計測モニター】HTTPサーバを実装する(修正)

すいません、

昨日のこれ、修正します。

何が問題なのかというと、複数のスレッドが同じデバイスにアクセスしている、と言うことです。

デバイスにアクセスするときには「一連のアクセス処理」が発生します。

温湿度計にアクセスする場合は、I2Cインターフェースを使用しているので、データの要求・応答に2つの端子にパルスパターンを送受信しているはずです。

この処理を複数のスレッドで同時に行った場合、正しくアクセス処理が行われない場合があります。

アクセス処理が競合しちゃうんですね。

これを防ぐために、こういったマルチスレッドのプログラミングでは「待ち合わせ処理」(一方の処理が完了するまで、もう一方の処理を待つ)というのが必要なのですが、

今回は規模が小さいので、アクセスを行うスレッドを一つだけ(メインのスレッドのみ)にして、他のスレッドからはデバイスにアクセスしないようにします。

Humidity = 0
Temperature = 0

def __main__():
    global sw
    global Humidity
    global Temperature

    GPIO.setmode(GPIO.BCM)
    GPIO.setup(22,GPIO.IN) 
    GPIO.add_event_detect(22, GPIO.FALLING, callback=callback, bouncetime=300)
    GLCD.PinsInit(20, 7, 8, 9, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17)
    GLCD.GLCDInit()
    GLCD.GLCDDisplayClear()

    roop = 10 * 60 * 60
    mode = 1
    
    thread = threading.Thread(target=httpServe)
    thread.start()
    
    try:
        while True:
            Humidity = AM2320.GetHum()
            Temperature = AM2320.GetTemp()

            if sw == True:
                GLCD.GLCDDisplayClear()
                mode += 1
                if mode > 4:
                    mode = 1
                sw = False

            if mode == 1:
                if roop >= 10 * 60 * 60:
                    GLCD.GLCDDisplayClear()
                    Weather.RequestAPI()
                    weather = Weather.GetWeather()
                    temp = Weather.GetTemp()
                    roop = 0

                GLCD.GLCDPuts(1, 0, "Date :")
                GLCD.GLCDPuts(5, 8, datetime.datetime.now().strftime('%Y:%m:%d %A '))
                GLCD.GLCDPuts(1, 16, "Weather :")
                GLCD.GLCDPuts(10,24, weather)
                GLCD.GLCDPuts(10,32, "Temp : " + format(temp) + 'C')
                GLCD.GLCDPuts(1, 40, "Time : " + datetime.datetime.now().strftime('%H:%M'))
                GLCD.GLCDPuts(1, 48, "Humidity    : " + Humidity + '%')
                GLCD.GLCDPuts(1, 56, "Temperature : " + Temperature + 'C')

                roop += 1

            #中略

            time.sleep(1)
    except KeyboardInterrupt:
        GLCD.GLCDDisplayClear()
        GPIO.cleanup()

#中略

class StubHttpRequestHandler(BaseHTTPRequestHandler):
    server_version = "HTTP Stub/0.1"

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def do_GET(self):
        enc = sys.getfilesystemencoding()

        data = {
            'datetime' : datetime.datetime.now().strftime('%Y:%m:%d %H:%M:%S'),
            'temperature': Temperature,
            'humidity': Humidity,
        }

        encoded = json.dumps(data).encode()

        self.send_response(HTTPStatus.OK)
        self.send_header("Content-type", "text/html; charset=%s" % enc)
        self.send_header("Content-Length", str(len(encoded)))
        self.end_headers()

        self.wfile.write(encoded)     

__main__()

これで競合は回避できるはず。

「【ラズパイ】【いろいろ計測モニター】HTTPサーバを実装する(修正)」への1件のフィードバック

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください