0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

用树莓派控制交通红绿灯(进阶版)

CHANBAEK 来源:和娃一起玩树莓派 作者:老孟K 2023-07-02 15:10 次阅读

哇奥,今天才发现上一次建造的红绿灯居然不对,绿灯一般在下方,当红灯变绿灯时黄灯闪烁,我做的是绿灯变红灯时黄灯闪烁!。这在我们开发时也会碰到,就像找bug一样,对于发现的问题要及时修正。在修正问题之前,我们还是先看看如何让红绿灯更快的响应按钮操作,然后修正红绿灯问题。

要想更快的响应按钮,则需要找出原因,上一讲提到因为程序运行时没有及时检测按钮是不是被按下了,那么我们第一反应可能是在程序中加上更多的检测语句,但这样程序将变得特别臃肿,也不容易被别人理解。其实,计算机设计者早就考虑到了这个问题,他们利用一个叫做“中断”的概念来对需要及时响应的事情进行处理。

什么是中断

中断是指计算机运行过程中,出现某些需要及时处理时,计算机能自动暂停正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。中断发生时运行的程序叫做中断程序。

在我们的红绿灯程序中,当按钮被按下时,我们希望计算机可以把它作为一个中断,然后运行中断程序,及时修改运行状态。

研究gpiozero的文档,我们发现Button类有一个when_pressed的方法,说明如下

图片

意思是说当按钮按下时将调用一个函数(function)。那么什么是函数呢?

函数是什么

函数是可以完成某些任务的代码块,而且这些代码块可以被重复使用,就像我们玩具里的积木块一样。在python中,用def来定义或者说创建函数,其语法如下

def 函数名(参数):     #注意最后的冒号
   函数代码(完成工作需要的代码)
   return 返回值      #不是必须的,当需要向调用函数的程序返回数值或对象时使用

函数是编程语言非常重要的一部分内容,参数有形参和实参,参数也可以是多个,返回值可以是各种数据类型,有了函数后,变量也就分为全局 变量和局部变量了,这些内容我们会逐步涉及到。今天我们先从最简单的无参数函数开始,顾名思义,这样的函数没有参数。

创建参数

回过头来看我们的红绿灯程序,只闪烁黄灯还是正常工作取决于其中的一个变量kaiguan。

from gpiozero import LED,Button


from time import sleep


kaiguan = False   


red = LED(26)  #红灯链接了GPIO26
yellow= LED(5)   #黄灯链接了GPIO5
green = LED(22)  #绿灯连接了GPIO22
control = Button(17) #按钮连接了GPIO17
while True:
    if kaiguan == False:   #当kaiguan变量为False时,黄灯闪烁
        yellow.on()
        sleep(0.5)
        yellow.off()
        sleep(0.5)
    else:          #当kaiguan变量为True时
        green.on()   
        sleep(3)    #绿灯亮3green.off()
        yellow.on()  #黄灯亮1sleep(1)
        yellow.off()
        red.on()     #红灯亮3sleep(3)
        red.off()
    if control.is_pressed:  ##判断按钮是否被按下
            print("Pressed")
            kaiguan = bool(1-kaiguan)

所以,利用中断,我们的需要在按钮按下时及时改变kaiguan这个变量的数值,然后在程序中及时判断这个值是否已经变化了,从而作出正确的逻辑控制。

现在我们创建一个叫做changeKaiguan的函数:

def changeKaiguan():   #创建无参数函数:修改kaiguan变量,从而控制红绿灯
    print("Pressed")
    global kaiguan       #kaiguan是全局变量,在主程序中已经声明
    kaiguan = bool(1 - kaiguan)    #取反操作
    print(kaiguan)                #打印kaiguan的数值,True或False

因为kaiguan变量是在主函数声明的,函数如果要使用它,需要用global关键字,表示它是一个全局变量 。

当控制按钮按下时,调用changeKaiguan函数,通过如下代码实现:

control.when_pressed = changeKaiguan  #按下按钮时调用changeKaiguan函数

注意: 这一个语句应该在changeKaiguan函数创建之后才行,否则就会报变量没有定义的错误。

验证中断程序

通过上面的代码,我们创建了一个中断函数,当按钮按下时,每次都调用changeKaiguan函数。让我们来测试一下,完整代码如下:

from gpiozero import LED,Button


from time import sleep


kaiguan = False   


green = LED(26)  #green灯链接了GPIO26
yellow= LED(5)   #黄灯链接了GPIO5
red = LED(22)  #red灯连接了GPIO22
control = Button(17) #按钮连接了GPIO17




def changeKaiguan():   #创建无参数函数:修改kaiguan变量,从而控制红绿灯
    print("Pressed")
    global kaiguan       #kaiguan是全局变量,在主程序中已经声明
    kaiguan = bool(1 - kaiguan)    #取反操作
    print(kaiguan)                #打印kaiguan的数值,True或False


control.when_pressed = changeKaiguan  #按钮按下时调用changeKaiguan函数


while True:
    if kaiguan == False:   #当kaiguan变量为False时,黄灯闪烁
        yellow.on()
        sleep(0.5)
        yellow.off()
        sleep(0.5)
    else:          #当kaiguan变量为True时,
        red.on()   
        sleep(3)    #绿灯亮3秒
        red.off()
        yellow.on()  #黄灯亮1秒
        sleep(1)
        yellow.off()
        green.on()     #红灯亮3秒 
        sleep(3)
        green.off()

运行上面的程序,可以发现,无论程序运行在那个阶段,当按下按钮时,都可以马上在Shell界面看到打印“Pressed"以及最新的kaiguan参数数值。

图片

我们发现每次按钮按下,都马上进入了中断程序changeKaiguan,在程序中修改了kaiguan变量的值并打印了出来,当前程序运行在sleep还是其他语句都没有影响。

进阶版红绿灯程序

现在,是时候完成我们的进阶版程序,让红绿灯可以在按钮按下后及时切换工作状态。在此之前,我们需要调整红绿灯连接线,把红灯和绿灯互换位置,同时修改程序。最新的电路图:

图片

电路实物照片:

图片

要修改程序,需要考虑在什么时候探测kaiguan变量值,然后作出逻辑调整,原程序红绿灯正常工作时不能及时探测kaiguan变量才造成对按钮的反应迟钝,所以需要修改这部分代码,为了保证控制操作的完整性,我们不能在某个灯还亮着时进行切换,需要在灯灭后进行,所以修改如下:

from gpiozero import LED,Button


from time import sleep


kaiguan = False   


green = LED(26)  #green灯链接了GPIO26
yellow= LED(5)   #黄灯链接了GPIO5
red = LED(22)  #red灯连接了GPIO22
control = Button(17) #按钮连接了GPIO17




def changeKaiguan():
    print("Pressed")

    global kaiguan
    kaiguan = bool(1 - kaiguan)
    print(kaiguan)



control.when_pressed = changeKaiguan


while True:
    if kaiguan == False:   #当kaiguan变量为False时,黄灯闪烁
        yellow.on()
        sleep(0.5)
        yellow.off()
        sleep(0.5)
    else:          #当kaiguan变量为True时,
        red.on()   
        sleep(3)    #绿灯亮3秒
        red.off()
        if kaiguan == False: #判断kaiguan是否已经变为False,如果是,则跳出当前操作,继续下一个循环
            continue     #跳过下面的代码,开始下一个循环
        yellow.on()  #黄灯亮1秒
        sleep(1)
        yellow.off()
        if kaiguan == False: #判断kaiguan是否已经变为False,如果是,则跳出当前操作,继续下一个循环
            continue
        green.on()     #红灯亮3秒 
        sleep(3)
        green.off()

运行程序,看看是不是按我们期望的正常运作了呢?

是的,现在只要我们按下按钮,程序都可以及时切换,即使在红灯或绿灯亮时按下按钮,当灯灭时也会判断出kaiguan值变为False,从而中止当前循环,进入下一个循环中。如此,进阶版的红绿灯大功告成!

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 计算机
    +关注

    关注

    19

    文章

    6652

    浏览量

    84569
  • 中断
    +关注

    关注

    5

    文章

    884

    浏览量

    41029
  • python
    +关注

    关注

    51

    文章

    4678

    浏览量

    83476
  • 红绿灯
    +关注

    关注

    2

    文章

    34

    浏览量

    11869
  • 树莓派
    +关注

    关注

    113

    文章

    1640

    浏览量

    104752
收藏 人收藏

    评论

    相关推荐

    红绿灯控制系统的LED城市路灯方案

    将LED路灯装置与交通红绿灯控制系统结合在一起,利用每一路段红绿灯的转换实现对下一路段灯光强弱的控制。将当前市场上 LED 集灯板上的LED灯分为两组,在满足不同时段照明要求前
    发表于 10-17 14:44 3511次阅读

    PLC实现交通红绿灯控制方法及原理

    PLC实现交通红绿灯控制电路熟悉PLC编程原理及方法。掌握定时器使用方法。
    发表于 03-19 15:15

    交通红绿灯带仿真和程序

    交通红绿灯带仿真和程序
    发表于 03-29 10:53

    交通红绿灯

    本帖最后由 samuergao 于 2014-7-3 14:13 编辑 交通灯,并显示当前时间和倒计时,包含了单条路遇到人行道的红绿灯,还有十字路口的红绿灯,大家帮看看有的改进没有。
    发表于 07-03 12:12

    如何去实现一种交通红绿灯设计

    1、功能描述观察十字路口红绿灯工作流程,设计交通灯。1、初始时:南北向、东西向直行左转均为红灯2、南北向直行:①南北向直行绿灯亮,延时若干秒②启动南北向左转数码管显示:倒计时6秒;同时南北向直行
    发表于 11-09 09:21

    基于单片机的交通红绿灯控制系统的设计

    前一段时间,做了一个关于基于单片机的交通红绿灯控制系统的设计
    发表于 11-10 06:34

    交通红绿灯PLC控制系统编程方法与技巧

    本文介绍了交通红绿灯基本控制形式,针对带绿闪的红绿灯和带数显的红绿控制和实现方法,详细论述了相应的编程方法和技巧。实验证明编制的程序运行可靠
    发表于 08-14 10:31 152次下载

    基于可编程控制交通红绿灯模拟系统设计

    本文在综合分析了8255A 及8253 芯片的特点之后,运用二者的特性,进行了交通红绿灯模拟系统设计,在详细阐述了设计思想及电路设计方案之后,对该系统的有效性测试表明了该交通红
    发表于 05-18 11:03 199次下载
    基于可编程<b class='flag-5'>控制</b>的<b class='flag-5'>交通红绿灯</b>模拟系统设计

    基于自定义时钟脉冲的交通红绿灯控制设计

    以三菱FX2N型PLC作为控制核心元件,阐明交通红绿灯控制设计思路和控制方案。以PLC定时器构成的自定义时钟脉冲程序段作为程序基本单元设计的交通红
    发表于 06-19 11:42 5897次阅读
    基于自定义时钟脉冲的<b class='flag-5'>交通红绿灯</b><b class='flag-5'>控制</b>设计

    EDA设计应用之红绿灯交通控制器设计

    红绿灯交通控制器EDA设计
    发表于 01-22 16:28 51次下载

    将VR技术应用于交通红绿灯

    大家都知道,不管是行人还是汽车,在过路口的时候,一般都会有红绿灯的存在,如果没有红绿灯的话,那整个交通都会混乱,交通事故绝对是层出不穷,而且堵车也会堵得水泄不通,所以
    发表于 12-22 09:38 3678次阅读

    使用树莓控制红绿灯的源代码免费下载

    本文档的主要内容详细介绍的是使用树莓控制红绿灯的源代码免费下载。
    发表于 10-28 17:11 9次下载
    使用<b class='flag-5'>树莓</b>派<b class='flag-5'>控制</b><b class='flag-5'>红绿灯</b>的源代码免费下载

    基于8255A和8253芯片实现交通红绿灯模拟系统的应用方案

    本文在综合分析了8255A 及8253 芯片的特点之后,运用二者的特性,进行了交通红绿灯模拟系统设计,在详细阐述了设计思想及电路设计方案之后,对该系统的有效性测试表明了该交通红绿灯模拟系统具有较为
    的头像 发表于 03-23 14:47 4557次阅读

    中文编程鸿蒙Hi3861开发基础案例之-03交通红绿灯

    中文编程鸿蒙Hi3861开发模拟交通红绿灯亮与灭控制
    的头像 发表于 05-11 11:27 1421次阅读
    中文编程鸿蒙Hi3861开发基础案例之-03<b class='flag-5'>交通红绿灯</b>

    树莓控制交通红绿灯(简洁版)

    前面我们通过控制LED灯和读取按钮状态,简单演示了树莓派如何通过GPIO来与外部世界沟通。今天我们要用树莓派模拟一个控制交通
    的头像 发表于 07-02 15:08 1227次阅读
    用<b class='flag-5'>树莓</b>派<b class='flag-5'>控制</b><b class='flag-5'>交通红绿灯</b>(简洁版)