【问题标题】:python program stops after wifi connection discontinuitywifi连接不连续后python程序停止
【发布时间】:2017-09-17 12:58:03
【问题描述】:

两个月前我开始学习 Python,我为一个 Raspberry pi 项目编写了代码。我的问题是程序在运行几个小时后卡住了。我认为在所有情况下,它都会在一些 wifi 连接断开后停止。但我不明白为什么如果 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()

【问题讨论】:

  • file.close() in the except: 块是错误的,filewith 语句的范围内并且也被该语句自动关闭。
  • 感谢您的更正!
  • 您还应该考虑使用with tLock: 而不是显式调用acquire()release() 方法。如果在 I/O 操作中抛出异常,锁将处于获取状态,这将导致程序死锁。
  • 再次感谢您!我想也许这会导致问题。我会尝试并留下反馈。您还有其他建议吗?

标签: python multithreading upload raspberry-pi sensors


【解决方案1】:

问题解决了。正如 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

【讨论】:

    猜你喜欢
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-08
    • 2019-02-11
    • 1970-01-01
    相关资源
    最近更新 更多