2017-09-17 13 views
0

2ヶ月前にPythonを学習し始めました。ラズベリーパイプロジェクトのコードを書いています。私の問題は、プログラムが数時間の操作の後に固まってしまうことです。私はすべてのケースで、いくつかのWiFi接続が終了した後に停止したと思います。しかし、なぜ私はwifi接続に何か問題があれば、プログラム全体が停止するのを理解していません。wifi接続の不連続性の後にPythonプログラムが終了する

コードは起動時に開始されます(sudo python/home/pi /)。このコードは、値のアップロードを停止し、プリントするlcdスクリーンメッセージを更新します(より簡単に読むために、)、2つのスレッドがあります。

「制御」スレッドは、i2cバスとセンサーam2315を使用して温度と湿度を読み取り、温度しきい値に応じてGPIOでリレーを制御します。

"Thingspeak"スレッドは、 'Thingspeak'チャンネルから温度しきい値を読み取り、以前のスレッドの測定値を 'Thingspeak'にアップロードします。

私は実際に何をすべきか、どのように解決策を探すのか分かりません。 ご協力いただければ幸いです。

#! /usr/bin/env python 
from time import sleep 
import datetime 
import urllib2 
import RPi.GPIO as GPIO 
import threading 
import smbus 
from tentacle_pi.AM2315 import AM2315 
import smtplib 
import contextlib 

sleep(120) 
# Lock 
tLock = threading.Lock() 
# Global variables 
tem_global = 0; hum_global = 0 
tem_hi = 35; relay = 21 
# GPIO setup 
GPIO.setmode(GPIO.BCM) 
GPIO.setup(relay, GPIO.OUT) 
GPIO.output(relay, False) 
sleep(1) 

def Control(): 
     global temg, humg, tem_hi, relay 
     # AM2315 setup 
     am = AM2315(0x5c,"/dev/i2c-1") 
     I2C_address = 0x70; I2C_bus_number = 1; i2c_channel_setup = 1 
     bus = smbus.SMBus(I2C_bus_number)     
     bus.write_byte(I2C_address, i2c_channel_setup) 
     sleep(1) 

     while True: 
       try: 
         tem_local, hum_local = am2315meas() 
       except: 
         tem_local = -1; hum_local = -1 

       tLock.acquire() 
       tem_global = tem_local; hum_global = hum_local 
       if tem_local < tem_hi: 
         GPIO.output(relay, True) 
       else: 
         GPIO.output(relay, False) 
       tLock.release() 
       sleep(150) 

def Thingspeak(): 
     global tem_global, hum_global, tem_hi 
     myAPI = "..." 
     channelID = "..." 
     baseURL = 'https://api.thingspeak.com/update?api_key=%s' % myAPI 
     while True: 
       sleep(30) 
       try: 
         # Reading value from thingspeak 
         tLock.acquire() 
         with contextlib.closing(urllib2.urlopen("https://api.thingspeak.com/channels/%s/fields/1/last?" % channelID)) as f_read: 
           tem_hi = float(fread.read()) 
         t.Lock.release() 
         sleep(30) 
         # Uploading values to thingspeak 
         tLock.acquire() 
         with contextlib.closing(urllib2.urlopen(baseURL + "&field1=%s" % tem_global + "&field2=%s" % hum_global)) as f_upload: 
           pass 
         tLock.release() 
       except: 
         with open('/home/pi/errors.txt', mode='a') as file: 
           file.write('Network error recorded at %s.\n' % datetime.datetime.now()) 
         file.close() 
         sleep(60) 
         continue 

def Main(): 
     t1 = threading.Thread(target=Thingspeak) 
     t2 = threading.Thread(target=Control) 
     t1.start() 
     t2.start() 
     t1.join() 
     t2.join() 
     GPIO.cleanup() 

if __name__ == '__main__': 
     Main() 
+1

以外で 'file.close()':ブロックは、間違って 'file'が' WITH'文の範囲にあり、同様にその文によって自動的に閉じられます。 –

+0

この修正をありがとうございます! – Gus87

+0

'acquire()'と 'release()'メソッドを明示的に呼び出すのではなく、 'with tLock:'を使うことも考えてください。 I/O操作で例外がスローされた場合、ロックは取得済みの状態になり、プログラムがデッドロックされます。 –

答えて

0

問題を解決しました。 James K Polkが指摘するように、tLock.acquire()の後、インターネット接続が解除されるたびにエラーが発生し、プログラムのデッドロックが発生しました。以下は、誰にとっても興味深いコードの修正部分です。

def Control(): 
     global tem_global, hum_global, tem_hi, relay 
     # AM2315 setup 
     am = AM2315(0x5c,"/dev/i2c-1") 
     I2C_address = 0x70; I2C_bus_number = 1; i2c_channel_setup = 1 
     bus = smbus.SMBus(I2C_bus_number)     
     bus.write_byte(I2C_address, i2c_channel_setup) 
     sleep(1) 

     while True: 
       try: 
         tem_local, hum_local = am2315meas() 
       except: 
         tem_local = -1; hum_local = -1 

       with tLock: 
         tem_global = tem_local; hum_global = hum_local 
         if tem_local < tem_hi: 
           GPIO.output(relay, True) 
         else: 
           GPIO.output(relay, False) 
       sleep(150) 

def Thingspeak(): 
     global tem_global, hum_global, tem_hi 
     myAPI = "..." 
     channelID = "..." 
     baseURL = 'https://api.thingspeak.com/update?api_key=%s' % myAPI 
     while True: 
       sleep(30) 
       try: 
         # Reading value from thingspeak 
         with tLock: 
           with contextlib.closing(urllib2.urlopen("https://api.thingspeak.com/channels/%s/fields/1/last?" % channelID)) as f_read: 
             tem_hi = float(fread.read()) 
         sleep(30) 
         # Uploading values to thingspeak 
         with tLock: 
           with contextlib.closing(urllib2.urlopen(baseURL + "&field1=%s" % tem_global + "&field2=%s" % hum_global)) as f_upload: 
             pass 
       except: 
         with open('/home/pi/errors.txt', mode='a') as file: 
           file.write('Network error recorded at %s.\n' % datetime.datetime.now()) 
         sleep(60) 
         continue