Python 基本开关详解

到目前为止,这一定是一次史诗般的旅程!回想一下你开始读这本书的时候,你有没有想过事情会这么简单?值得注意的是,一切开始都非常简单,而且,随着对更复杂系统的需要,技术的复杂性也在增加。回到个人电脑不是真正的东西的时代。它只用于商业领域,像 IBM 这样的公司只为商业客户提供服务。当时,想要个人电脑的人只有一个选择。他们需要从头开始建造,老实说,很多人都是这样做的。至少在我看来,这也没那么难。但是,与当时不同的是,想想他们现在变成了什么样子。有没有想过在家里造一台电脑?通过构建,我指的是设计一切,而不仅仅是 CPU 的组装。这并不容易。

我想告诉你们的是,曾经有一段时间,计算机是异国情调的;它们不是很常见,功能也非常有限。然而,随着时间的推移和史蒂夫·乔布斯、比尔·盖茨、惠普和惠普等人的智慧,计算机变得更加人性化、更容易获得,并且成为一种理想的商品。想一想机器人也一样。它们很贵;对大多数人来说,他们对它们无能为力,而且它们在公共场所也很少见。但是,正如你所了解到的,制造一个供我们个人使用的机器人并不是很难,通过这里和那里的一些调整,以及像你这样有创造力的头脑,事情可以朝着完全不同的方向发展。你可能是下一个史蒂夫·乔布斯或比尔·盖茨。我们所需要的只是热情、激情和开箱思考。你的视力可能会被嘲笑。但请记住,每个发明家在某个时候都被称为疯子。所以下次有人说你疯了的时候,你可以肯定你正在进步!

嗯,我很确定,如果你是一个机器人爱好者,那么你一定看过电影钢铁侠。如果你还没有看过这部电影,那就暂时停止阅读这本书,继续打开 Netflix,看看那部电影。

一旦我看了那部电影,我想做两件主要的事情:一件是钢铁侠的套装,另一件是他的私人助理 Jarvis,他负责照顾他的所有需要。虽然西装似乎是我必须要做一段时间的事情,但是,到那时,你可以继续为自己打造私人助理了。

想象你的家为自己做事。会有多酷?它知道你喜欢什么,你什么时候起床,什么时候回家,基于此,它会自动为你做事。最重要的是,它不是你从货架上买的东西,而是你自己动手做的。

Before you do any of this, I must tell you that you will be dealing with high voltages and considerable currents. Electricity is no joke, and you must take care at all times and wear all the safety equipment. If you are not sure of it, then it would be a good idea to get an electrician to help you. Before you touch or open any of the electrical boards, make sure that you are wearing non-conductive shoes; also inspect whether the tools such as screwdrivers, pliers, nose pliers, cutters, and other tools are well insulated and in good condition. It is a good idea to wear gloves for added safety. If you are under 18, then you must have an adult with you all times to help you.

话虽如此,让我们开始,看看我们在这里得到了什么。

现在,这一个非常有趣,因为你们都知道我们的人体是以某种方式编程的。因此,我们对不同刺激的反应是众所周知的。就像天黑的时候,我们的大脑会产生激素来触发睡眠。一旦阳光照射到我们的眼睛上,我们就会醒来。好吧,至少应该是这样!最近,我们的生活方式发生了巨大的变化,这已经开始挑战这个周期。这就是为什么,我们看到越来越多的失眠病例。被闹钟吵醒肯定是不自然的。因此,即使闹钟的音调是你最喜欢的歌曲,你也永远不会开心地在早上听它。我们的睡眠周期应该与阳光同步,但现在几乎没有人用这种方法醒来。因此,在本章中,让我们首先制作一个智能闹钟,它将复制我们醒来的自然方式。

当我们处理高电压和高电流时,我们将使用继电器。为此,请按如下方式连接导线:

连接完成后,上传以下代码,让我们看看会发生什么:

import RPi.GPIO as GPIO
import time

LIGHT = 23

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(LIGHT,GPIO.OUT)

import datetime

H = datetime.datetime.now().strftime('%H')
M = datetime.datetime.now().strftime('%M') 

while True:

       if H = '06'and M < 20 :
           GPIO.output(LIGHT,GPIO.HIGH)

       else:
           GPIO.output(LIGHT,GPIO.LOW)

好的,那么这是一个相当简单的代码,不需要太多解释。我们以前也做过类似的代码。你记得什么时候吗?在最初的几章中,我们制作了一个园艺机器人,在这个机器人中,我们必须在特定的时间给植物打水。此时所做的只是检查时间,以及时间是否为06小时,分钟是否小于20。也就是说,该灯将在 07:00 至 07:19 之间打开。此后,它将关闭。

但有一个问题。问题是灯会被打开,不管你是否起床,灯都会在 20 分钟内自动关闭。这有点问题,因为不是每次你都能在 20 分钟内醒来。那么,在这种情况下,我们应该怎么做?我们需要做的第一件事是检测你是否醒了。这很简单,这里不需要说太多。如果你早上醒来,你肯定会从床上爬起来。一旦你这样做了,我们可以检测到的议案,可以告诉我们的自动化系统,你是否真的醒了。

现在,我们能做的事情很简单。我们可以检测到你的动作,基于这种检测,我们可以确定你是否真的醒了。这似乎不是什么大任务。我们需要做的就是添加一个运动检测传感器。为此,我们可以使用 PIR 传感器,它可以告诉我们是否检测到运动。那么,让我们继续,在我们的系统顶部添加另一层传感器,看看会发生什么

因此,首先,按如下方式连接电路。安装 PIR 传感器时,务必确保其朝向床,并检测其上和周围的任何运动。设置 PIR 后,如下图所示连接传感器,查看发生的情况:

完成后,继续编写以下代码:

import RPi.GPIO as GPIO
import time 

LIGHT = 23
PIR = 24
Irritation_flag = 3

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

GPIO.setup(LIGHT,GPIO.OUT) 
GPIO.setup(PIR, GPIO.IN)

import datetime

H = datetime.datetime.now().strftime('%H') 
M = datetime.datetime.now().strftime('%M')

    while True:

        if H = '07' and M <= '15' and Iriitation_Flag > 0 and GPIO.input(PIR) == 0:

            GPIO.output(LIGHT,GPIO.HIGH)

        if H = '07'and GPIO.input(PIR)==1:

            GPIO.output(LIGHT,GPIO.LOW)
            time.sleep(10)
            Irritation_Flag = Irritation_Flag - 1

        for H = '07'and M > '15' and Irritation_Flag > 0 and GPIO.input(PIR) = 0:

            GPIO.output(LIGHT,GPIO.HIGH)
            time.sleep(5)
            GPIO.output(LIGHT,GPIO.LOW)
            time.sleep(5)

        if H != '07':

            Irritation_flag = 3
            GPIOP.output(LIGHT, GPIO.LOW) 

好的,让我们看看我们做了什么。代码非常简单,但我们有一个小小的转折,那就是,Irritation_Flag

Irritation_flag = 3

现在这个变量的作用类似于一个 snooze 按钮。正如我们所知,当我们有时醒来,或者事实上大部分时间醒来时,我们再次回到睡眠状态,却发现我们已经迟到了。为了防止这种情况,我们有这个Irritation_flag,它基本上是用来检测您执行停止报警操作的次数。如何使用它,我们将在后面看到:

        if H = '07' and M <= '15' and Irritation_Flag > 0 and GPIO.input(PIR) == 0:

            GPIO.output(LIGHT,GPIO.HIGH)

在这一行中,我们只是按小时和分钟比较时间值。如果小时数为07,分钟数小于或等于15,则灯将关闭。还有一个条件是,Irritation_Flag > 0,因为我们在开始时已经声明,Irritation_flag = 3的值;因此,最初这个条件总是正确的。最后一个条件为GPIO.input(PIR) == 0;这意味着只有当 PIR 未检测到任何运动时,才会满足该条件。简单地说,如果 PIR 未检测到任何运动,则在 07:00 和 07:15 之间的每一次报警都会响起:

        if H = '07'and GPIO.input(PIR)==1:

            GPIO.output(LIGHT,GPIO.LOW)
            time.sleep(10)
            Irritation_Flag = Irritation_Flag - 1

在程序的这一部分中,只有当小时或H等于7且 PIR 检测到某些运动时,该条件才为真。因此,每当时间介于 07:00 和 07:59 之间时,以及每当检测到运动时,该条件都将为真。一旦为真,程序将首先使用线路GPIO.output*LIGHT,GPIO.LOW关闭灯。关闭后,使用time.sleep(10)等待10秒。一旦时间结束,将执行以下操作:Irritation_Flag - Irritation_Flag - 1。现在它所做的是,每次检测到运动时,它都会将Irritation_Flag的值递减1。所以第一次运动发生时,Irritation_Flag的值为2;之后是1,最后是0

如果您查看代码的前一部分,您将能够确定如果Irritation_Flag的值大于0,灯将打开。因此,如果你想关灯,你必须至少移动三次。为什么是三次?因为这样代码Irritation_Flag = Irritation - 1会执行三次,从而使值降到0,这显然使条件GPIO.input(PIR) > 0为假:

        for H = '07'and M > '15' and Irritation_Flag > 0 and GPIO.input(PIR) = 0:

            GPIO.output(LIGHT,GPIO.HIGH)
            time.sleep(5)
            GPIO.output(LIGHT,GPIO.LOW)
            time.sleep(5)

现在,让我们说,即使在这一切之后,你仍然没有醒来。那么会发生什么呢?我们这里有特别的东西给你。现在,我们有一个for循环,而不是if条件。这将检查的是,时间应为07小时,分钟应大于15Irritation_Flag > 0,显然未检测到任何运动。直到所有这些都是真的,灯将在此后打开5秒,它将使用time.sleep(5)保持打开。灯将再次打开。现在,这将持续发生,直到条件为真,或者换句话说,直到时间在 07:15 和 07:59 之间。Irritation)_Flag > 0,也就是说,有三次没有检测到运动,也没有检测到运动。在此之前,for 循环将继续打开和关闭活动中的灯。由于经常骑自行车照明,你醒来的几率非常高。这可能非常有效,但肯定不是最方便的。好吧,不管它多么不方便,它还是会比传统的报警器好:

        if H != '07':

            Irritation_flag = 3

我们已经准备好了所有基于灯光的闹钟,每天早上都可以叫醒我们。然而,有一个问题。一旦关闭,Irritation_Flag的值将为0。一旦调到0,无论什么时间,灯都不会启动。因此,为了确保报警始终在每天的同一时间运行,我们需要将标志值设置为大于0的任何数字。

现在在前一行中,如果H != '07',那么Irritation_flag将是3。也就是说,只要时间不是07小时,那么Irritation_Flag的值就是3

这很简单,不是吗?但我相信确保你按时起床会很好。

你能完全依赖前面的系统吗?如果你真的可以控制早上不起床的情绪,那么,是的,你当然可以。但对于那些只想在床上睡觉的人来说,我相信你一定能够找到一种方法,在没有完全醒来的情况下关闭电灯。因此,就像在代码中一样,只要检测到三次运动,电灯就会关闭。但议案可以是任何东西。你只需在床上挥动你的手,系统就会将其视为一个动作,这违背了整个目的。那我们现在该怎么办呢

我们有一个解决办法!我们可以用一种方法确保你必须起床。为此,我们将使用我们的红外接近传感器,这是我们在项目早期使用的,根据传感器的距离读数,我们可以检测您是否经过任何特定区域。这真的很有趣,因为你可以把这个传感器安装在远离床的地方,或者浴室的门上,直到那时,你才越过那条特定的线。系统无法关闭警报。让我们来看看如何操作。首先,连接硬件,如下图所示:

完成图表后,继续并上载以下代码:

import RPi.GPIO as GPIO
import time 

import Adafruit_ADS1x15
adc0 = Adafruit_ADS1x15.ADS1115()

GAIN = 1

adc0.start_adc(0, gain=GAIN)

LIGHT = 23
PIR = 24
Irritation_flag = 1
IR = 2

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

GPIO.setup(LIGHT,GPIO.OUT) 
GPIO.setup(PIR, GPIO.IN)
GPIO.setup(IR. GPIO.IN)

import datetime

H = datetime.datetime.now().strftime('%H') 
M = datetime.datetime.now().strftime('%M')

  while True:

  if H = '07' and M <= '15' and Iriitation_Flag > 0 and GPIO.input(PIR) == 0:

      GPIO.output(LIGHT,GPIO.HIGH)

  if H = '07'and GPIO.input(PIR)==1:

   M_snooze = datetime.datetime.now().strftime('%M')
   M_snooze = M_snooze + 5

   for M <= M_snooze 

     GPIO.output(LIGHT,GPIO.LOW)

     F_value = adc0.get_last_result()
     F1 =    (1.0 / (F_value / 13.15)) - 0.35

     time.sleep(0.1)

     F_value = adc0.get_last_result()
     F2 =    (1.0 / (F_value / 13.15)) - 0.35

     F_final = F1-F2

     M = datetime.datetime.now().strftime('%M')

     if F_final > 25

         Irritation_flag = 0

  for H = '07'and M > '15' and Irritation_Flag > 0 and GPIO.input(PIR) = 0:

 GPIO.output(LIGHT,GPIO.HIGH)
 time.sleep(5)
 GPIO.output(LIGHT,GPIO.LOW)
 time.sleep(5)

 if H != '07':

 Irritation_flag = 1 

精神崩溃?这段代码看起来相当复杂,包含条件内部的条件,还有更多的条件。向机器人学问好!这些条件构成了很多机器人的编程。机器人必须不断地观察周围发生的事情,并据此做出决定。这也是人类工作的方式,不是吗

这么说来,让我们看看我们到底在做什么。大部分代码与上一个代码几乎相同。主要区别在于编程部分的中间部分:

  if H = '07' and M <= '15' and Iriitation_Flag > 0 and GPIO.input(PIR) == 0:

      GPIO.output(LIGHT,GPIO.HIGH)

我们将在 07:00 到 07:15 之间立即打开灯:

  if H = '07'and GPIO.input(PIR)==1:

   M_snooze = datetime.datetime.now().strftime('%M')
   M_snooze = M_snooze + 5

07小时内,无论何时触发 PIR 传感器,或者换句话说,PIR 传感器检测到任何运动,它都将在if条件内执行一组活动,包括通过函数datetime.datetime.now().strftime('%M')记录时间,然后将其存储在名为M_snooze的变量中。

在下一行中,我们将获取存储在M_snooze中的该分钟的值,并向其添加另一个5分钟。因此,M_snooze的值现在增加了5

   for M <= M_snooze 

现在,在与我们之前使用的相同的if条件下,我们放置了一个for循环,看起来像这样:for M <= M_snooze。但这意味着什么?在这里,我们所做的很简单。for循环内的程序将继续运行,并将一直保持在循环中,直到我们所述的条件为真。现在,这里的条件表示,直到时间M小于或等于M_snooze,该条件将保持为真。正如您之前所了解的,M是当前分钟值,M_snooze是该循环开始时的M值,增加5。因此,从启动开始的5分钟内,循环将为真:

     GPIO.output(LIGHT,GPIO.LOW)

     F_value = adc0.get_last_result()
     F1 =    (1.0 / (F_value / 13.15)) - 0.35

     time.sleep(0.1)

     F_value = adc0.get_last_result()
     F2 =    (1.0 / (F_value / 13.15)) - 0.35

     F_final = F1-F2

现在,这是程序中最有趣的部分。在for循环for M <= M_snooze为真之前,前面的代码行将运行。让我们看看它在做什么。在F-value = adc0.get_last_result()行中,它获取红外接近传感器的值并将其存储在F_value中。此后,在F1 = (1.0/(F_value/13.15))-0.35行中,我们只是简单地以厘米为单位计算距离。我们已经研究了这是如何发生的,所以这里不需要做太多解释。距离值存储在名为F1的变量中。此后,使用功能time.sleep(0.1),我们暂停程序0.1秒。此后,我们再次重复同样的任务;也就是说,我们再次计算距离的值。但这一次,计算的距离值存储在另一个名为F2的变量中。最后,在完成所有这些之后,我们正在计算F_final,也就是F_final = F1 - F2。所以我们只是计算第一次和第二次读数之间的距离差。但是,你一定会问我们为什么要这样做。这有什么好处?

嗯,你还记得,我们把红外接近传感器放在浴室门前。现在,如果没有人在它前面经过,这个值将保持相当恒定。但每当有人经过它时,距离就会发生变化。因此,如果从第一个读数到最后一个读数的总距离发生变化,那么我们可以说有人通过了红外传感器

这很酷,但是我们为什么不像以前那样保持一个阈值呢?答案很简单。这是因为如果需要更改传感器的位置,则需要根据位置重新校准传感器。因此,这是一个简单而健壮的解决方案,可以在任何地方使用:

     if F_final > 10

        Irritation_flag = 1

现在我们有了读数,它可以告诉我们是否有人在它前面经过。但是,除非我们把这些数据放在某个地方,否则这些数据不会有用

因此,在条件if F_final > 10中,每当距离变化超过10cm 时,该条件将为真,并且线路Irritation_flag将设置为1

如果您回到前面的几行,那么您将能够看出,只有在 07:00 和 07:15 之间的时间,Irritation_flag必须是0时,灯才会亮起。与此条件一样,我们通过将Irritation_flag = 1设置为 false,将部分条件设置为 false;因此,打开灯的程序将无法工作

现在,让我们回顾一下,看看到目前为止我们做了什么:

非常酷,嗯?话虽如此,让我们从上一个程序中添加另一个附加功能:

  for H = '07'and M > '15' and Irritation_Flag = 0 and GPIO.input(PIR) = 0:

    GPIO.output(LIGHT,GPIO.HIGH)
    time.sleep(5)
    GPIO.output(LIGHT,GPIO.LOW)
    time.sleep(5)

你知道这是怎么回事。如果您在最初的15分钟内(即 07:00 至 07:15)没有走动,则它将开始每五秒钟闪烁一次灯光,迫使您醒来:

        if H != '07':

            Irritation_flag = 0 

最后,我们使用条件if H != '07':。因此,每当H的值不是07时,该条件将为真,这将把Irritation_flag重置为0。到现在为止,你知道把Irritation_flag转到0做什么了

最后,我们制作了我们的第一款迷你 Jarvis,它能在早上叫醒你,如果你不能按时醒来,它甚至会让你感到恼火。我希望你通过学习两个运动传感器以及它们在电器自动化中的应用,真的很喜欢这一章。所以,在家里试试吧,根据你的需要修改代码,拿出一些非常酷的东西。接下来,我们将让我们的 Jarvis 做一些更酷的事情,我们将介绍一些关于人类探测的更令人兴奋的事情。

教程来源于Github,感谢apachecn大佬的无私奉献,致敬!

技术教程推荐

推荐系统三十六式 -〔刑无刀〕

数据分析实战45讲 -〔陈旸〕

深入拆解Tomcat & Jetty -〔李号双〕

浏览器工作原理与实践 -〔李兵〕

RPC实战与核心原理 -〔何小锋〕

手把手带你搭建秒杀系统 -〔佘志东〕

超级访谈:对话汤峥嵘 -〔汤峥嵘〕

Kubernetes入门实战课 -〔罗剑锋〕

大型Android系统重构实战 -〔黄俊彬〕