python - 未在RPI中断上定义全局名称XXX

时间:2014-12-05 19:42:57

标签: python global-variables global

我是Raspberry Pi的python新手。以下是使用GPIO的示例程序。我的问题是,在我的条件中,我看不到任何变量跨越块

中的其他语句

整个程序包含问题代码示例如下:

打开GPIO引脚23

            print uptime

NameError:未定义全局名称'uptime'

有什么建议吗?

提前感谢

**************************** python代码***************** ************************

!/ usr / bin / env python2.7

导入时间;

将RPi.GPIO导入为GPIO 从时间导入睡眠#这让我们有一个时间延迟(见第12行)

GPIO.setwarnings(假)

GPIO.setmode(GPIO.BCM)#设置BCM GPIO编号 GPIO.setup(17,GPIO.IN)#将GPIO17设置为输入(按钮)

GPIO.setup(23,GPIO.OUT)##将GPIO引脚23设置为OUT

GPIO.output(23,False)##关闭GPIO引脚23

定义线程回调函数,以便在检测到事件时在另一个线程中运行

def my_callback(频道):

global start_time, uptime




    if GPIO.input(17):     # if port 17 == 1
            end_time = time.time()
            #print (end_time)
        print "Rising edge detected on 17"
            uptime = end_time - start_time            
            #uptime = int(uptime)
            print uptime
            GPIO.output(23,False) 
            ## Turn off GPIO pin 2




    elif (GPIO.input(17)== 0):
            start_time = time.time()
            #print (start_time)
        print "Falling edge detected on 17"
            GPIO.output(23,True) 
            ## Turn on GPIO pin 23
            print uptime

当在端口17上检测到更改边缘时,无论

是什么

正在程序中发生,函数my_callback将运行

GPIO.add_event_detect(17,GPIO.BOTH,callback = my_callback)

raw_input(“准备就绪时按Enter键\ n>”)

尝试:     打印“按下时,您将看到:17上检测到上升沿”     打印“当发布时,你会看到:在17上检测到下降边缘”     睡觉(10)#等待30秒     打印“时间到了。完了!”     打印正常运行时间 最后:#无论try块如何退出,这个块都会运行     GPIO.cleanup()#自己清理

1 个答案:

答案 0 :(得分:0)

如果第一次调用my_callback时,GPIO.input(17)为1,那么您将设置uptime,一切都会正常。

但如果第一次调用GPIO.input(17)为0,会发生什么?然后你赢了设置uptime。而且,因为这是您第一次调用此功能,并且您没有设置uptime的任何其他代码,所以它没有&#t已经设定。但无论如何你试着print。所以你得到NameError

您可以通过例如在问题开始时将其设置为初始值来解决此问题,例如:

def my_callback(channel):
    # your existing code

uptime = 0

当然,我假设您的代码有一些合理的缩进。粘贴时,您的代码只是IndentationError例外的混乱,并且不会执行任何,而且您的真实代码很可能还有代码导致的其他错误没有在正确的流量控制声明下缩进。

而且,由于看起来您可能正在混合制表符和空格,因此很难发现缩进错误:为自己创建一个更好的文本编辑器,它会自动将制表符转换为空格,自动缩进,和/或显示制表符一些可见的方式。或者至少使用-tt标志运行代码以将标签捕获为错误,以便您可以修复它们。


作为旁注,你的elif绝对是浪费,甚至可能已经破碎。

如果if GPIO.input(17):部分没有触发,那么你知道结果是0(或其他假的,但是因为input只返回数字,所以只能是0)。那么,为什么0再次对它进行测试呢?

但与此同时,您不仅仅是在这里不必要地重新测试一个值,而且您实际上已经出去并且再次从硬件中读取值。因此,如果边缘从1变为0并且足够快地返回1,则第一次读取可能返回0,然后第二次读取可能返回1,这意味着您的分支都不会触发。 (另外,通过阅读,你可能也吸收了边缘触发器,因此你不会再接到另一个回调,虽然我不确定。)

您只需使用else:而不是尝试编写完全捕获elif相反意义的if即可解决所有这些问题。