【问题标题】:Raspberry Pi Pico W, Micropython, Threading and Requests, code stops workingRaspberry Pi Pico W、Micropython、线程和请求,代码停止工作
【发布时间】:2023-01-03 23:56:13
【问题描述】:

因此,该项目的基础是从与 pico W 位于同一网络上的工业烤箱的 API 获取温度数据,然后将该输出显示到多路 4 位 7 段显示器。我一直在通过 urequests 和 ujson 执行此操作,并使用 _thread 运行温度数据的检索,并运行 4 位 7 段显示的多路复用。

这一切都很好,但是,我一直在随机地到达一个点,温度数据会冻结(尽管 API 仍然可以访问,并适当更新),所以它最终只是将最后收集的温度保持在显示屏上并对其进行多路复用直到电路板被拔掉,然后它会重新连接,有时会持续数小时,然后才会出现故障并再次冻结温度。

我相信这要么是一个 urequests 问题,要么是一个网络问题,并且我已经尝试实现异常(除了 7 段显示器上的一些符号之外,这在运行时无论如何都看不到记录了什么,并且从未让它冻结连接到 PC 时。)但异常不会解决或说明临时数据冻结时实际发生的情况。

这是代码:

from machine import Pin
import _thread
import utime as time
import network
import urequests as requests
import ujson as json

led = Pin("LED", Pin.OUT)
displaydash = Pin(8, Pin.OUT) #dashpin -
display_list = [2, 3, 4, 5, 6, 7, 8] #a, b, c, d, e, f, g segments
colonpin = Pin(9, Pin.OUT) 
display_obj = [] #to create the display object
dig1 = Pin(10, Pin.OUT) #digit 1 
dig2 = Pin(11, Pin.OUT)
dig3 = Pin(12, Pin.OUT)
dig4 = Pin(13, Pin.OUT) #digit 4
global temp
temp = 0 

for seg in display_list:
    display_obj.append(Pin(seg, Pin.OUT))

arrSeg = [[1,1,1,1,1,1,0], # -> arrSeq[0] displays 0
          [0,1,1,0,0,0,0], # -> arrSeq[1] displays 1
          [1,1,0,1,1,0,1], # -> arrSeq[2] displays 2
          [1,1,1,1,0,0,1], # -> arrSeq[3] displays 3
          [0,1,1,0,0,1,1], # -> arrSeq[4] displays 4
          [1,0,1,1,0,1,1], # -> arrSeq[5] displays 5
          [1,0,1,1,1,1,1], # -> arrSeq[6] displays 6
          [1,1,1,0,0,0,0], # -> arrSeq[7] displays 7
          [1,1,1,1,1,1,1], # -> arrSeq[8] displays 8
          [1,1,1,1,0,1,1]]  # -> arrSeq[9] displays 9

def SegDisplay(toDisplay):
    numDisplay = int(toDisplay.replace(".", ""))
    for a in range(7):
        display_obj[a].value(arrSeg[numDisplay][a])

    if toDisplay.count("-") == 1:
         Pin(3,Pin.OUT).value(1)
    else:
        colonpin.value(0)
        
def clear(): #sets all display output pins to zero 
    Pin(2, Pin.OUT).value(0)
    Pin(3, Pin.OUT).value(0)
    Pin(4, Pin.OUT).value(0)
    Pin(5, Pin.OUT).value(0)
    Pin(6, Pin.OUT).value(0)
    Pin(7, Pin.OUT).value(0)
    Pin(8, Pin.OUT).value(0)
    Pin(9, Pin.OUT).value(0)
    colonpin.value(0)

def error(): #displays EEEE
    clear()
    dig1.value(1)
    dig2.value(1)
    dig3.value(1)
    dig4.value(1)
    Pin(9, Pin.OUT).value(0)
    Pin(8,Pin.OUT).value(1)
    Pin(7,Pin.OUT).value(1)
    Pin(6,Pin.OUT).value(1)
    Pin(5,Pin.OUT).value(1)
    Pin(2,Pin.OUT).value(1)
    dig1.value(0)
    dig2.value(0)
    dig3.value(0)
    dig4.value(0)
        
def dash(): #displays ----
    clear()
    dig1.value(1)
    dig2.value(1)
    dig3.value(1)
    dig4.value(1)
    Pin(9, Pin.OUT).value(0)
    Pin(8,Pin.OUT).value(1)
    dig1.value(0)
    dig2.value(0)
    dig3.value(0)
    dig4.value(0)
    
def outside_dash(): #displays -  -
    clear()
    dig1.value(1)
    dig2.value(1)
    dig3.value(1)
    dig4.value(1)
    Pin(9, Pin.OUT).value(0)
    Pin(8,Pin.OUT).value(1)
    dig1.value(0)
    dig2.value(1)
    dig3.value(1)
    dig4.value(0)
    

def display():
    refresh = 0.0025
    dig1.value(1)
    dig2.value(1)
    dig3.value(1)
    dig4.value(1)
    while True:
        global temp
        value = temp
        if value != None or value != 9998 or value != 9999:
            try:
                value = float(value)
                value = int(value) #not rounding, just getting whole number.
                value = str(value)
                if len(value)==1:
                    pl1 = "0"
                    pl2 = "0"
                    pl3 = "0"
                    pl4 = value[0]
                    dig1.value(1)
                    dig2.value(1)
                    dig3.value(1)
                    dig4.value(1)
                    SegDisplay(pl4)
                    dig4.value(0)
                    time.sleep(refresh)
                    dig4.value(1)
                elif len(value)==2:
                    pl1 = "0"
                    pl2 = "0"
                    pl3 = value[0]
                    pl4 = value[1]
                    dig1.value(1)
                    dig2.value(1)
                    dig3.value(1)
                    dig4.value(1)
                    SegDisplay(pl3)
                    dig3.value(0)
                    time.sleep(refresh)
                    dig3.value(1)
                    SegDisplay(pl4)
                    dig4.value(0)
                    time.sleep(refresh)
                    dig4.value(1)
                elif len(value)==3:
                    pl1 = "0"
                    pl2 = value[0]
                    pl3 = value[1]
                    pl4 = value[2]
                    dig1.value(1)
                    dig2.value(1)
                    dig3.value(1)
                    dig4.value(1)
                    SegDisplay(pl2)
                    dig2.value(0)
                    time.sleep(refresh)
                    dig2.value(1)
                    SegDisplay(pl3)
                    dig3.value(0)
                    time.sleep(refresh)
                    dig3.value(1)
                    SegDisplay(pl4)
                    dig4.value(0)
                    time.sleep(refresh)
                    dig4.value(1)
                    time.sleep(refresh)
                elif len(value)==4:
                    pl1 = value[0]
                    pl2 = value[1]
                    pl3 = value[2]
                    pl4 = value[3]
                    SegDisplay(pl1)
                    dig1.value(0)
                    time.sleep(refresh)
                    dig1.value(1)
                    SegDisplay(pl2)
                    dig2.value(0)
                    time.sleep(refresh)
                    dig2.value(1)
                    SegDisplay(pl3)
                    dig3.value(0)
                    time.sleep(refresh)
                    dig3.value(1)
                    SegDisplay(pl4)
                    dig4.value(0)
                    time.sleep(refresh)
                    dig4.value(1)
            except:
                dash()
                time.sleep(1)
                pass
        elif value == None or value == 9999:
            dash()
            time.sleep(1)
        elif value == 9998:
            error()
            time.sleep(1)
                
def connect():
    #Connect to WLAN
        clear()
        ssid = "networkname" #set up wifi network
        password = 'password' #set up wifi password
        wlan = network.WLAN(network.STA_IF)
        wlan.active(True)
        wlan.config(pm = 0xa11140) 
        wlan.connect(ssid, password)
        max_wait = 10
        while max_wait > 0:
            if wlan.status() < 0 or wlan.status() >= 3:
                break
            max_wait -= 1
            print('Waiting for connection...')
            led.on()
            time.sleep(.5)
            led.off()
            time.sleep(.5)

 # Handle connection error
        if wlan.status() != 3:
            raise RuntimeError('Network connection failed')
            error()
            led.off()
        else:
            led.on()
            print('Connected')
            status = wlan.ifconfig()
            print( 'IP = ' + status[0] )
            
def get_temp():
    temp_url = "the api url goes here" 
    while True:
        global temp
        wlan = network.WLAN(network.STA_IF)
        if wlan.status() != 3: #check if connected first
            led.off()
            print("Lost connection")
            temp = wlan.status()
            connect()
            time.sleep(0.25)
        elif wlan.status() == 3:
            try: #get temp if connected
                r = requests.get(temp_url).json()
                temp = r.get('ispoint')
                time.sleep(1)
            except: #if requests fail, reset 
                print("Couldn't gather data")
                temp = wlan.status()
                outside_dash()
                print(wlan.status())
                machine.reset()
                break
    

connect() #connect to wifi first       
_thread.start_new_thread(display, ()) #start the display thread
get_temp()

我一直在对这段代码进行大量的改组和测试,所以目前关于所有内容的打包和布局还不完整,但正如我所说,这有效,并正确收集温度并将其多路复用在 4数字 7 段显示良好,但我似乎无法弄清楚为什么这么长时间后温度值一直冻结。如果由于某种原因 requests.get 没有响应(这是我认为正在发生的事情),我试图在 get_temp 中对 machine.reset() 实施一个异常,但是当它今天遇到问题时并没有发生。我还尝试在 get_temp 中添加一个部分来监视 wlan.status() 是否有任何断开连接,但这也从未发生过。故障的最终症状只是冻结温度值的 display() 中的无限循环。我还计划使用一种不同的方法来存储温度,一旦我能弄清楚这个问题而不是全局变量,但为了测试,这是迄今为止我唯一能很好地工作的方法。

在这里更新: 实际上,我只是注意到它最终确实再次开始工作,但这至少是它最初冻结后的一个小时或更长时间,而我确信 API 可以访问并提供数据。不幸的是,没有看到实际重启以了解它是否进行了完全重置,或者它是否刚刚开始工作,所以仍然不知道确切的问题,但仍然假设网络请求问题。

【问题讨论】:

    标签: python-requests micropython raspberry-pi-pico


    【解决方案1】:

    您是否调查过 _thread 的一些疑似内存泄漏问题? 有些人使用import gc 取得了成功,然后在正确的位置/线程调用 GC.Collect()。

    【讨论】:

      猜你喜欢
      • 2022-09-25
      • 2022-08-15
      • 2021-06-23
      • 2023-01-31
      • 2022-11-05
      • 2023-02-17
      • 1970-01-01
      • 2021-10-06
      • 2018-12-05
      相关资源
      最近更新 更多