2017-09-17 3 views
0

두 달 전에 파이썬을 배우기 시작했고 라즈베리 파이 프로젝트 코드를 작성했습니다. 내 문제는 몇 시간 동안 작동 한 후에 프로그램이 멈추는 것입니다. 모든 경우에 일부 Wi-Fi 연결이 끊긴 후에 중단 된 것 같습니다. 하지만 왜 와이파이 연결에 문제가 있으면 전체 프로그램이 멈추는 지 이해할 수 없습니다. 값을 업로드하는 것을 멈추고 인쇄 한 LCD 화면 메시지를 갱신합니다. (읽기 쉽도록이 코드와 다른 코드를 코드에서 제거했습니다.)wifi 연결 불연속 후 파이썬 프로그램이 중지됩니다.

코드는 시작시 시작됩니다 (sudo python/home/pi/test.py &) 두 스레드가 포함되어 있습니다 :

"제어"스레드는 온도 임계 값에 따라 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

except : block이 틀리면'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 
관련 문제