Python 和 Raspberry Pi:如何在 while 循环中仅执行一次操作

Python and Raspbery Pi: How to perform an action only once in a while loop

第一次来。我不是程序员,我正在尝试用我的 RPi 创建一个简单的监控系统,但是 运行 遇到了一些问题。希望有人能帮助我吗?

我的设置几乎与这里显示的完全一样(除了按钮是 lever/switch):http://razzpisampler.oreilly.com/ch07.html#SEC11.1 并在这里遵循了一些关于 GPIO 清理的建议: https://www.youtube.com/watch?v=Bqk6M_XdIC0

我需要的是,当按下控制杆并持续按下时,我想发送一封电子邮件。然后释放控制杆时,我希望程序 "restart" 以便在将来某个时间再次按下控制杆时,发送另一封邮件。

我已经让单独导入的邮件脚本正常工作,硬件设置似乎正常工作。

发生的情况是:

  1. 使用 sudo python pellets.py
  2. 启动程序
  3. 按住控制杆,成功发送 1 封邮件,但程序一直打印 "SENT 1 MAIL" 每 3 秒,直到我松开控制杆 (?).
  4. 第二次按住控制杆时,没有发送邮件(?), 但是程序一直打印 "SENT 1 MAIL" 直到我释放 杠杆。

为了让程序再次发送邮件,我需要CTRL+C并中断程序并手动重启程序。

我错过了什么?

我试图清除 if 循环内的 GPIO 通道,但没有像我想的那样工作。然后,即使在我松开​​控制杆后,文本仍会继续打印。但是没有更多的邮件被发送。

这是我的代码:

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BOARD)

GPIO.setup(GPIO.IN, pull_up_down=GPIO.PUD_UP)

mail_sent = 0

try:
    while True:
        input_state = GPIO.input(12)
        if input_state == 0 and mail_sent == 0:
            import pellets_sendmail
            print ('SENT 1 MAIL')
            mail_sent = 1
            time.sleep(3)
        else:
            mail_sent = 0
except KeyboardInterrupt:
    GPIO.cleanup(12)

你的问题实际上是两个问题

首先,它会连续打印 "SENT 1 MAIL",因为 else 子句将重置您的 mail_sent 杠杆是否向上 mail_sent不为 0。您可能想要指定杠杆应该在 mail_sent 可以重置之前抬起:

    if input_state == 0 and mail_sent == 0:
        ...
    elif input_state == 1: # Whatever your "up" state is
        mail_sent = 0

其次,您只能导入另一个 python 模块一次。我假设 pellets_sendmail.py 发送了您的邮件消息。第一次导入它时,该文件正常运行,但之后它不再执行该文件。我建议在 pellets_sendmail.py 中创建一个发送消息的函数,而不是让您的脚本直接发送消息

import pellets_sendmail    # put this at the top of your script
...
     if input_state == 0 and mail_sent == 0:
        pellets_sendmail.sendmail()
     ...

Here's a tutorial on writing functions 如果您不确定如何操作。只需将您现在用于发送邮件的任何代码移动到它自己的离散函数中(我在示例中将其称为 sendmail(),但您可以随意调用它)。