0

我在编写用于读取树莓派上的一些温度传感器(DS18B20)的脚本时遇到了麻烦。我有一个工作脚本,但有时传感器会掉下来,然后脚本也会停止。我正在尝试通过集成 try-except 语句来制作更强大的版本。如果其中一个传感器没有反应,目标是继续到范围内的下一个传感器。如果我通过拔出其中一个传感器来模拟传感器故障,则脚本将停止对所有传感器进行测量(而不是对已拔出的传感器进行测量)。它不会给我一个错误。有任何想法吗?

这是带有 try 语句的脚本部分:

if time.time() <= timeout:
    for index in range (numsensors):
        try: 

                def read_temp_raw(): # gets the temps one by one
                        f = open(device_file[index], 'r')
                        lines = f.readlines()
                        f.close()
                        return lines
                def read_temp(): # checks the received temperature for errors
                     lines = read_temp_raw()
                     while lines[0].strip()[-3:] != 'YES':
                        time.sleep(0.2)
                        lines = read_temp_raw()
                     equals_pos = lines[1].find('t=')
                     if equals_pos != -1:
                        temp_string = lines[1][equals_pos+2:]
                        # set proper decimal place for deg C
                        temp = float(temp_string) / 1000.0
                        # Round temp to x decimal points --> round(temp,x)
                        temp = round(temp, 2)
                        return temp


                reading = (read_temp())
                temp[index].append(reading)
                print device[index],"=", temp[index]
                continue
        except IOError:
            print "Error"
4

1 回答 1

0

“问了什么”清单:

  1. 使用try-except构造使底层系统更健壮吗

  2. 为什么代码在指示传感器故障时没有给出任何错误?


A1:try-except条款听起来是不言自明的救生包,但事实并非如此。

必须完全理解代码exceptions期望面对面遇到的各种类型以及如何处理它们中的每一个。天真或错误地使用此语法结构有效地掩盖了调试雷达屏幕中的其余异常,使未处理的案例在黑暗的沉默中失败,超出您的控制并且根本不知道它们。真正的“稳健性”和“故障恢复能力”并非如此。

此代码示例将隐藏所有现实生活中的碰撞,除了列出的唯一碰撞,IOError但如果不会发生,则不会处理所有其他发生的碰撞:

if time.time() <= timeout:              # START if .time() is still before a T/O
    for index in range (numsensors):    #       ITERATE over all sensors
        try:                            #           TRY:
            <<<something>>>             #                 <<<something>>>
        except IOError:                 #           EXC IOError:
            <<<IOError__>>>             #                 Handle EXC.IOError

猜猜你所有的def...(..):-s 可能属于代码的非重复部分,if:/for:因为你不需要“即时”修改代码,是吗?

def read_temp_raw():                    # DEF: gets the temps one by one
    f = open(device_file[index],'r')    #      SET aFileHANDLE access to IO.DEV ( beware var index "visibility" )
    lines = f.readlines()               #      IO.DEV.READ till <EoF>
    f.close()                           #      IO.DEV.CLOSE
    return lines                        #      RET all lines

def read_temp():                        # DEF: checks the received temperature for errors
    lines = read_temp_raw()             #      GET lines from read_temp_raw()
    while lines[0].strip()[-3:]!='YES': #      WHILE last-3Bytes of 1st-line!="YES"
        time.sleep(0.2)                 #          NOP/Sleep()
        lines = read_temp_raw()         #          GET lines again (beware var index)
        equals_pos =lines[1].find('t=') #          SET position of 't=' in 2nd-line
        if equals_pos != -1:            #          IF  position != -1
            temp_string = lines[1][equals_pos+2:]                
            temp = float(temp_string) \
            / 1000.0                    #              DIV( 1000) decimal place for deg C
            temp = round(temp, 2)       #              ROUND temp to x decimal points --> round(temp,x)
            return temp                 #              RET->

        # ----------------------------- #          ELSE: re-loop in WHILE
     # -------------------------------- #     LOOP AGAIN AD INFIMUM

A2:try-except在发布的代码中的子句期望它只处理一种异常IOError- 只有当实际 IO.DEV 操作因 I/O 相关原因而失败时才会实例化,这并不意味着情况下,您在物理上“拔下”传感器,而 IO.DEV 仍然存在并且可以携带它的 IO.DEV.READ(s),因此不exceptions.EnvironmentError.IOError应该是raise-d

这意味着,IO.DEV.READ(s) 发生并且代码结果,根据条件WHILE last-3Bytes of 1st-line指示,在一个无限循环中,因为第一行“still”不以“YES”结尾。量子点


目标焦点

回到这个问题,您可能宁愿为真实世界的案例设置一个更安全的测试,在您的传感器网络扫描期间可能会出现错误的输入。

原理可能如下:

f.close()                           #      IO.DEV.CLOSE
if ( len(lines) < 2 ):              #      IF <<lines>> are nonsense:
    return [ "NULL_LENGTH_READING still with CODE EXPECTED ACK-SIG-> YES",        \
             "SIG ERROR FOR POST-PROCESSOR WITH AN UNREALISTIC VALUE t=-99999999" \
             ]
return( lines )                     #      OTHERWISE RET( lines )
于 2014-10-05T15:33:57.050 回答