雷竞技注册
项目

时序灯:用Arduino MEGA搭建一个交通灯控制器

2016年6月22日经过约瑟夫Corleto

学习如何使用Arduino模拟交通灯。

学习如何使用Arduino模拟交通灯。

对大多数人来说,交通灯似乎融入了日常生活的景观中。只要有适量的汽车,就可能会有这样的设备。现代的交通灯内部相当复杂,有各种各样的传感器、计时器,甚至交通监控系统,它们用来帮助有效地控制交通速度。

现在我们不打算尝试建造一个真正的红绿灯,但我们肯定可以用Arduino模拟一个!做这个练习是一个很好的方法,可以让你更熟悉Arduino的基本和最常用的命令。它还将有助于思考问题和符合特定标准的逻辑设计。作为奖励,这个项目帮助我们了解交通信号灯是如何工作的,至少在基本功能层面。

该项目将实施美国和英国风格的灯。

材料清单

硬件

  • 发光二极管
    • 2个红色
    • 2绿色
    • 2个黄色或琥珀色
  • 电阻器
    • 6个电阻(你可以坚持330到1k欧姆为每个颜色。)
  • Arduino
    • MEGA(实际上任何类型都可以,但我们这里使用的是MEGA。)
  • 烙铁+焊料
  • 钢丝钳(用于简单的铅饰)

软件

  • Arduino IDE

理论

基本交通灯的概念是控制交通的速度。如前所述,现代交通灯可以监控交通,为要求过马路的行人改变信号灯周期,知道何时改变计时器以增加交通流量,等等。

对于我们的项目,我们将基于每个灯的固定时间间隔实现一个四通路口。也就是说,交通灯没有反馈,将简单地运行而不考虑交通量。尽管这不是一盏智能灯,但我们可以用一种智能的方式来实现这个系统。也许这样做还能省点钱!

例如,我们有一个四通路口,它的街道是Busy Bunny Lane和Lazy Tortoise Ave(都是单行道)。从当地警方对该镇交通历史的调查中,我们发现忙碌的兔子巷比懒惰的乌龟大道更繁忙(令人震惊!)由于我们知道这个交叉口的典型交通流,简单的基于计时器的控制是合适的。在这里增加任何其他功能都是在浪费钱,这是这个城市承受不起的。

我们的模拟需要的是一种表示交通灯的方法;led将用于此。其余的控制和逻辑将由Arduino执行。它将作为我们的智能控制器和计时器。这意味着它将打开和关闭每个灯,并计算每个灯应该打开的时间。

对于添加的奖金,通过在代码中更改常量,此模拟设置将能够在美国和英国风格的灯光之间切换。您可以使用数字输入来切换操作,但这需要在材料清单上列出的电线!

循环序列(美国风格)

简单的美国式红绿灯由红色,琥珀色和绿灯组成。典型的序列如下:

  1. 绿色(保险箱继续)
  2. 琥珀色(减速,红灯马上亮)
  3. 红色(停止)

然而,这只是一个街道的循环。另一个十字路口也必须通过。为了使这更容易说明,我们将使用时序表来帮助我们更好地可视化整个循环序列。

让我们假设忙碌的兔子车道必须在12秒内拥有绿色红绿灯,懒惰的乌龟Ave的绿色交通灯4秒钟。对于两条街道,允许将琥珀色的红绿灯灯置于3秒钟。对于红绿灯,绿色和琥珀色循环时间将直接影响这一点。研究下面的时间表以了解这意味着什么。

如您所见,这使情况更容易理解。没有必要把它分成几秒,但为了举例和说明,如果你第一次尝试这样做,可能会更容易理解。

如果你对这个表还不太清楚,那么可以这样想:系统第一次打开时,第一行(时间秒= 0)是积极和将继续活跃,直到下一次运行第二次(时间秒= 1)。光序列秒= 1将活跃的系统是否在1.20秒或1.99秒的操作。这个概念遍及整个表。

整个周期时间是26秒,这意味着这是当两条街道都有一个转弯,让交通通过他们的灯。一旦你走到桌子的尽头,整个过程又重新开始。如果你仔细看,有两种情况,两个灯都是红色的。在继续阅读之前,试着想想为什么会做出这样的设计选择。

如果你仔细想想,如果你让一条街道变成红色,而另一条马上变成绿色,你可能会发生事故。当然,这取决于街道的大小、限速和其他因素。但为了安全起见,我们可以假设,也许在这两条街上的琥珀色灯上的人可能没有及时停车,而是在灯变红时闯了过去。如果其他街道没有注意,他们可能会撞到这个人,造成可怕的事故!最好是让双方都变红,让事情“安定下来”,然后从一个更可预测和稳定的状态开始。

循环序列(英国风格)

一个简单的英式交通灯由红色、琥珀色和绿色组成,但与美式交通灯略有不同。典型的序列如下:

  1. 绿色(保险箱继续)
  2. 琥珀色(减速,红灯马上亮)
  3. 红色(停止)
  4. 红色/琥珀色(停下来,但只是想让你知道灯很快就会变绿)

所以你可以看到美国一个人略有不同。琥珀色光线而不是一个即时绿色,琥珀色灯亮了红灯,警告驾驶员,绿灯即将到来,但请停止停止。下面是说明这一点的时序图。

把它拉开

这个项目的硬件部分并不是那么复杂,也不需要一个面包板;连一根电线也没有!

我们将首先通过布线第一个红绿灯开始。

取红色LED的正极,将其插入引脚31。正面通常是较长的引线,但如果它们的长度相同,外壳的平面是负面的。

现在采取330到1k欧姆电阻,并将其插入引脚30。

接下来,将电阻器的另一端焊接到LED的另一端,这将是负的一面。为了更合适,可能需要一些修剪。通常,一个LED有一端连接到电源的正极或负极(我们的情况是+5V),但这需要一些电线。相反,我们将使用引脚30作为我们的地面,当我们设置低。这不是很常见的做法,但对于这个交通灯模拟,它将做得很好!再次重复这些步骤,并使用下面的图表进行引脚到led的映射。

下面是我焊接led的方法:

最后,它应该全部最终看起来如下所示:

更正式地说,是你们正在看的一个示意图:

Arduino Code.

这里发现的代码有很大的评论,应该帮助您与文章一起。如果您要上传这一点,它将立即循环光线序列。要从美国和英国风格变动,请阅读顶部的评论以了解。一如既往,如果您需要任何帮助,请在下面的评论或论坛之旅。雷电竞newbee

关于代码,有一件事需要注意。当打开和关闭led输出时,有一个短暂的时刻,一些led被关闭和非常快地打开。正如您将在代码注释中发现的那样,我这样做是为了更容易遵循前面的时间表。对于我们的应用程序,LED看起来就像它根本没有关闭!这是因为开关开关的转换非常快,我们的眼睛无法捕捉到它们。不过,作为一个警告,这种代码可读性技术可能会在其他项目中导致问题,比如时钟触发器。我们看不到它,但人字拖肯定会知道转变已经发生了!但也有一些时候可以利用这一点,比如并行显示7段时。你看到的大多数数字都是一次打开一个,但我们从来没有意识到这一点。在我们的例子中,交通灯既不帮助也不伤害我们,所以我就让它去吧。

/ *================================================================================文件 ...........交通灯控制器测试代码目的........模拟美国和英国风格的红绿灯作者......... Joseph Corleto电子邮件......... corleto.joseph@gmail.com开始……06/11/2016完成了……06/11/2016更新........  - / - / -  -================================================================================笔记================================================================================——请访问m.bettowin66th.com搜索完整的文章!================================================================================更新================================================================================* ///===============================================================================/ /头文件//===============================================================================//===============================================================================/ /常量//===============================================================================常量intTRAFFIC_LIGHT_STYLE=1;//用来挑选风格的红绿灯常量int格林=12;//绿灯时间,单位为秒常量intAMBER_LIGHT=3.;//在几秒钟内琥珀色灯光时间常量intDEAD_LIGHT.=2;//光死时间,单位为秒常量intRED_AMBER_LIGHT=1;//红/黄灯时间,单位为秒//我知道你在想什么,为什么defaut价值观?它变得更加清晰//后面的代码。我基本上是根据懒乌龟街的周期计算出来的//从Busy Bunny Lane的值循环时间。继续阅读!//===============================================================================//变量//===============================================================================//===============================================================================/ /销声明//===============================================================================/ /输入://您可以在交换机中放入美国和英国的模式//踌躇满志!/ /输出:intgreenBusyBunnyLane=30.;//绿灯输出:繁忙的兔子巷intamberbusybunnylane.=32;//琥珀色灯输出:Busy Bunny LaneintRedbusybunnylane.=34;//红光输出:繁忙的兔子巷intGreenbusybunnylanengnd.=31;//绿灯地面:忙碌的兔子巷intamberBusyBunnyLaneGnd=33;//琥珀色的灯光地面:忙碌的兔子巷intredBusyBunnyLaneGnd=35;//红灯地面:忙碌的兔子巷intgreenLazyTortoiseAve=48;//绿灯输出:Lazy Tortoise AveintamberLazyTortoiseAve=50;//琥珀色的光输出:懒乌龟大道intredLazyTortoiseAve=52;//红灯输出:Lazy Tortoise AveintGreenlazytortoiseavegnd.=49;//绿灯地:懒乌龟大街intamberLazyTortoiseAveGnd=51;//琥珀色的光线:懒人龟大道intredlazytortoiseavegnd.=53;//红灯区:懒乌龟大街//===============================================================================//初始化//===============================================================================无效设置{//为Busy Bunny Lane设置合适的引脚光输出pinModegreenBusyBunnyLane输出;pinModeamberbusybunnylane.输出;pinModeRedbusybunnylane.输出;pinModeGreenbusybunnylanengnd.输出;pinModeamberBusyBunnyLaneGnd输出;pinModeredBusyBunnyLaneGnd输出;//为Lazy Tortoise Ave设置适当的PIN光输出pinModegreenLazyTortoiseAve输出;pinModeamberLazyTortoiseAve输出;pinModeredLazyTortoiseAve输出;pinModeGreenlazytortoiseavegnd.输出;pinModeamberLazyTortoiseAveGnd输出;pinModeredlazytortoiseavegnd.输出;//设置初始状态digitalWritegreenBusyBunnyLane;digitalWriteamberbusybunnylane.;digitalWriteRedbusybunnylane.;digitalWriteGreenbusybunnylanengnd.;digitalWriteamberBusyBunnyLaneGnd;digitalWriteredBusyBunnyLaneGnd;digitalWritegreenLazyTortoiseAve;digitalWriteamberLazyTortoiseAve;digitalWriteredLazyTortoiseAve;digitalWriteGreenlazytortoiseavegnd.;digitalWriteamberLazyTortoiseAveGnd;digitalWriteredlazytortoiseavegnd.;}//===============================================================================// 主要的//===============================================================================无效循环{//程序需要知道使用哪种类型的交通灯。幸运的是,//在这个程序的顶部,在常量下,我们为此保留了Traffic_light_Style //非常目的。现在,我们可以只使用下面的交换机条件//语句选择用于该//程序的寿命的哪一个。如果您想要的话,您可以随时添加更多信息!开关TRAFFIC_LIGHT_STYLE{情况下0.Usatrafficlight.;打破;情况下1ukTrafficLight;打破;默认的打破;}}//===============================================================================/ /函数//===============================================================================////////////////////// / usaTrafficLight / //////////////////////无效Usatrafficlight.{//记得为定时表咨询allaboutcircuits.com!这会//对理解下面的代码存在的原因非常有帮助。这是//只有一种方法使整个循环发生。当我编写代码时,我喜欢这样//使所有内容尽可能具有可读性。如果我不需要额外的//计算速度,我将以记住的签发重新介绍陈述//最后一个条件是什么。所以如果你想"嘿,他转身了//先开红灯,然后关灯,再开灯!”我想//让事情更容易阅读!//首先拥有繁忙的兔子巷,有绿灯。根据//图表,懒乌龟大街是红色的。我将在一秒内使用FOR循环//增量,因为这将有助于保持逻辑连续性从计时// 桌子。每个周期后不要忘记关闭灯光!为了int=0.;<格林;++{digitalWritegreenBusyBunnyLane;digitalWriteredLazyTortoiseAve;延迟1000;}digitalWritegreenBusyBunnyLane;digitalWriteredLazyTortoiseAve;//现在Busy Bunny Lane的绿灯时间已经过去了,我们可以//转到我们的琥珀光时间。为了int=0.;<AMBER_LIGHT;++{digitalWriteamberbusybunnylane.;digitalWriteredLazyTortoiseAve;延迟1000;}digitalWriteamberbusybunnylane.;digitalWriteredLazyTortoiseAve;//前方有盲区,防止交通事故发生。为了int=0.;<DEAD_LIGHT.;++{digitalWriteRedbusybunnylane.;digitalWriteredLazyTortoiseAve;延迟1000;}digitalWriteRedbusybunnylane.;digitalWriteredLazyTortoiseAve;//终于轮到懒乌龟大街了!为了int=0.;<格林/3.;++{digitalWriteRedbusybunnylane.;digitalWritegreenLazyTortoiseAve;延迟1000;}digitalWriteRedbusybunnylane.;digitalWritegreenLazyTortoiseAve;//懒乌龟大道现在变成了琥珀色的灯光。为了int=0.;<AMBER_LIGHT;++{digitalWriteRedbusybunnylane.;digitalWriteamberLazyTortoiseAve;延迟1000;}digitalWriteRedbusybunnylane.;digitalWriteamberLazyTortoiseAve;//再一次,一个死区为了int=0.;<DEAD_LIGHT.;++{digitalWriteRedbusybunnylane.;digitalWriteredLazyTortoiseAve;延迟1000;}digitalWriteRedbusybunnylane.;digitalWriteredLazyTortoiseAve;//循环结束了!}/////////////////////// / ukTrafficLight / ///////////////////////无效ukTrafficLight{//这将非常类似于usatrafficlight//首先拥有繁忙的兔子巷,有绿灯。根据//图表,懒乌龟大街是红色的。我将在一秒内使用FOR循环//增量,因为这将有助于保持逻辑连续性从计时// 桌子。每个周期后不要忘记关闭灯光!为了int=0.;<格林;++{digitalWritegreenBusyBunnyLane;digitalWriteredLazyTortoiseAve;延迟1000;}digitalWritegreenBusyBunnyLane;digitalWriteredLazyTortoiseAve;//现在Busy Bunny Lane的绿灯时间已经过去了,我们可以//转到我们的琥珀光时间。为了int=0.;<AMBER_LIGHT;++{digitalWriteamberbusybunnylane.;digitalWriteredLazyTortoiseAve;延迟1000;}digitalWriteamberbusybunnylane.;digitalWriteredLazyTortoiseAve;//前方有盲区,防止交通事故发生。为了int=0.;<DEAD_LIGHT.;++{digitalWriteRedbusybunnylane.;digitalWriteredLazyTortoiseAve;延迟1000;}digitalWriteRedbusybunnylane.;digitalWriteredLazyTortoiseAve;//这就是英国灯光的不同之处!为了int=0.;<RED_AMBER_LIGHT;++{digitalWriteRedbusybunnylane.;digitalWriteredLazyTortoiseAve;digitalWriteamberLazyTortoiseAve;延迟1000;}digitalWriteRedbusybunnylane.;digitalWriteredLazyTortoiseAve;digitalWriteamberLazyTortoiseAve;//终于轮到懒乌龟大街了!为了int=0.;<格林/3.;++{digitalWriteRedbusybunnylane.;digitalWritegreenLazyTortoiseAve;延迟1000;}digitalWriteRedbusybunnylane.;digitalWritegreenLazyTortoiseAve;//懒乌龟大道现在变成了琥珀色的灯光。为了int=0.;<AMBER_LIGHT;++{digitalWriteRedbusybunnylane.;digitalWriteamberLazyTortoiseAve;延迟1000;}digitalWriteRedbusybunnylane.;digitalWriteamberLazyTortoiseAve;//再一次,一个死区为了int=0.;<DEAD_LIGHT.;++{digitalWriteRedbusybunnylane.;digitalWriteredLazyTortoiseAve;延迟1000;}digitalWriteRedbusybunnylane.;digitalWriteredLazyTortoiseAve;//这又是英国灯光的不同之处!为了int=0.;<RED_AMBER_LIGHT;++{digitalWriteRedbusybunnylane.;digitalWriteamberbusybunnylane.;digitalWriteredLazyTortoiseAve;延迟1000;}digitalWriteRedbusybunnylane.;digitalWriteamberbusybunnylane.;digitalWriteredLazyTortoiseAve;//循环结束了!}

可能的下一个步骤

如果你想扩大这个项目,你可以考虑买一个真正的交通灯,并把它连接起来!当然,你需要适应工作电压(例如,在美国~120伏)。如果你不是,不要想它!你需要一个叫继电器的东西。为了了解接力赛的建设,我建议从这里开始在这里

在哪里可以找到一个真正的红绿灯来玩呢?我看到的最好的来源是易趣、车库/庭院拍卖、跳蚤市场和古董店。所以,如果你碰巧找到一款价格合理的产品(取决于市场需求,但一般塑料产品的价格在25美元到100美元之间),抓住一款,在本文的指导下使用它,很快,你的客人就会有一个很好的话题!

当然,所有这些学习灯光顺序和时间的努力并不一定要因为交通灯而停止。你可以很容易地使用这个设置来计时圣诞灯或简单的舞台灯光效果。你仍然可以使用一个时间表来帮助整个过程。你也可以用它作为一个简单的计时器,用来打开和关闭延迟较长的东西,比如露台灯或泳池水泵。基本上,有些事情需要围绕一个特定的时间表,但不是确切的。希望这能打开你的想象力,让你看到交通信号灯之外的其他东西。

玩得开心!

你自己试试这个项目吧!BOM。

Traffic_Light_Controller_Test_Code.zip

4评论
  • go4sail 2016年6月30日

    谢谢你那个好的DIY实验。
    我的观点是:

    谁能模拟GND使用Uno R3与那打引脚´s。
    没有足够的引脚来设置每个灯一个引脚作为GND。
    现在我先从繁忙的兔子巷开始(德国的交通堵塞)
    非常感谢你给我的建议
    问候

    喜欢的。 回复
    • j
      约瑟夫Corleto 2016年7月01日
      你好!我的建议是,你可以直接将本文中程序显示的所有地面信号,直接连接到地面。换句话说,我使用的I/O引脚产生一个地,只是将它连接到GND。当然,这意味着有6根导线连接到一个点。为了插入Arduino,你要么需要一个面包板,要么必须将所有东西焊接成一条线。我使用I/O引脚作为接地的原因是我不想经历额外接线到共同接地的麻烦,我希望这有帮助!
      喜欢的。 回复