155481| 81
|
[入门教程] Arduino教程 04 互动交通信号灯「DFR0100」 |
项目三 互动交通信号灯有没有试着做上面那个课后作业呢?做出来的话,说明你已经基本掌握上面所学的东西了,如果不会也没关系,我 相信,看完这个章节,前面那个问题就不攻自破了!我们这回就基于上面这个交通灯来进行一个拓展,增加一种行 人按键请求通过马路的功能。当按钮被按下时,Arduino会自动反应,改变交通灯的状态,让车停下,允许行人通 过。 这个项目中,我们开始要实现Arduino的互动了,也会在代码学习到如何创建自己的函数。这次的代码相对长一 点,耐下心来,等看完这一章,相信你能收获不少 所需元件
硬件连接
输入代码输入下面的样例代码3-1,这段代码引自《beginning-arduino》一书。 样例代码 3-1:
下载完成后,可以尝试按下按钮。看看是个什么的效果?我们可以看到整个变化过程是这样的——开始时,汽车灯为绿灯,行人灯为红灯,代表车行人停。一旦行人,也就是你,按下按钮,请求过马路,那么行人灯就开始由红变绿,汽车灯由绿变黄,变红。在行人通行的过程中,设置了一个过马路的时间 crossTime,一旦到点,行人绿灯开始闪烁,提醒行人快速过马路。 闪烁完毕,最终,又回到了开始的状态,汽车灯为绿灯,行人灯为红灯。 整段代码看起来很复杂,其实理清一下思路并不难。如果你还是没有办法理不清里面变化关系的话,可以试着画一个示意图,像项目2的课后作业那样,这样一来可能会方便你理解程序。 代码回顾通过前面两个项目,你应该能够理解这个代码的大部分内容。代码开始是一串的变量的声明,在声明中,出现了一个新名词。这里就解释一下这个新名词:
这是一个新的变量类型。我们之前,只创建过int整型变量,它可以存放一个-32768到32767之间的整数。这次要创建的是一个long的变量类型,它可以存放一个-2147483648到2147483647之间的整数。而unsigned long数据类型,则不存储负数,所以存储的范围就从0到4294967295. 如果我们使用一个int型的话,信号灯状态变化的时间,它只能存储最大32秒(32768毫秒约为32秒),一旦出现变量溢出就会造成程序运行出现错误,所以,为了避免这样的情况,要选用能存储更大数的一个变量,并且不为负,我们就可以考虑使用unsigned long型。你可以用笔算下,这个变量最大能存储的数,时间可达49天。 随即进入setup()函数,对LED和按钮进行一些设置,在设置时,需要注意到的是:
pinMode()函数我们已经很熟悉了,在项目一的时候就介绍过,只是和LED有所不同的是,按钮要设置为INPUT。 在setup()函数中,先给定行人灯和汽车灯的一个初始状态: digitalWrite(carGreen, HIGH); //开始时,汽车灯绿灯digitalWrite(pedRed, LOW); //行人灯为红灯
下表列出了程序中可能用到的变量数据类型:
从上面表格可以看到,变量的类型有很多,不同的数对应不同的变量,int和long是针对整数变 量,char是针对字符型变量,而float,double是针对含有小数点的变量。 此时,一个新函数出现——digitalRead()! 这个函数是用来读取数字引脚状态,HIGH还是LOW(其实HIGH还有一种表达就是“1”,LOW是 “0”,只是HIGH/LOW更直观)。函数需要一个传递参数 --pin,这里需要读取是按键信号,按键所在引脚是数字引脚9,由于前面做了声明,所以这里用 button。 并且把读到的信号传递给变量state,用于后面进行判断。state为 HIGH或者说为1时,说明按键被按下了。state为LOW或者0,表明按键没被按下。 所以,可以直接检查state的值来判断按钮是否被按下:
这里涉及新的语句-- if语句。 if语句是一种条件判断的语句,判断是否满足括号内的条件,如满足则执行花括号内的语句,如不满足则跳出if语句。 if语句格式如下:
表达式是指我们的判断条件,通常为一些关系式或逻辑式,也可是直接表示某一数值。如果if表达式条件为真,则执行if中的语句。表达式条件为假,则跳出if语句。 我们代码中,第一个条件是state变量为HIGH。如果按键被按下,state就会变为HIGH。第二个条件是millis()的值减changeTime的值大于5000。这两个条件之间有个“&&”符号。这是一种逻辑运算符,表示的含义是两者同时满足。
millis()是一个函数,该函数是Arduino语言自有的函数,它返回值是一个时间,Arduino开始运行到执行到当前的时间,也称之为机器时间,就像一个隐形时钟,从控制器开始运行的那一刻起开始计时,以毫秒为单位。变量changeTime初始化时,不存储任何数值,只有在Arduino运行之后,将millis()值赋给它,它才开始有数值,并且随着millis()值变化而变化。通过millis()函数不断记录时间,判断两次按键之间的时间是不是大于5秒,如果在5秒之内不予反应。这样做的目的是,防止重复按键而导致的运行错误。 if语句内只有一个函数:
这是一个函数调用的例子。该函数单独写在了loop()函数之外。我们需要使用的时,直接写出函数名就可以实现调用了。该函数是void型,所以是无返回值、无传递参数的函数。当函数被调用时,程序也就自动跳到它的函数中运行。运行完之后,再跳回主函数。需要特别注意的:函数调用时,函数名后面的括号不能省,要和所写的函数保持一致。changeLights() 函数内部就不做说明了。
硬件回顾按键开关按键一共有4个引脚,图3-2分别显示了正面与背面。而图3-3则说明了按键的工作原理。一旦按下后,左右两侧就被导通了,而上下两端始终导通。 什么是下拉电阻?下拉电阻这个名词可能比较抽象,就从字的含义着手,“下拉”我们就理解为把电压往下拉,降低电压。 按键作为开关。当输入电路状态为HIGH的时候,电压要尽可能接近5V。输入电路状态为LOW的时候,电压要尽可能接近0V。如果不能确保状态接近所需电压,这部分电路就会产生电压浮动。所以,我们在按钮那里接了一个电阻来确保一定达到LOW,这个电阻就是所谓下拉电阻。 课后作业
|
C:\Program Files (x86)\Mind+\Arduino\hardware\tools\avr\bin\avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10804 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR -I C:\Program Files (x86)\Mind+\Arduino\hardware\arduino\avr\cores\arduino -I C:\Program Files (x86)\Mind+\Arduino\hardware\arduino\avr\variants\eightanaloginputs -I C:\Program Files (x86)\Mind+\Arduino\hardware\arduino\avr\cores\arduino -I C:\Program Files (x86)\Mind+\Arduino\hardware\arduino\avr\variants\standard C:\Users\Administrator\AppData\Local\DFScratch\cache\dfrobot.ino.cpp -o C:\Users\Administrator\AppData\Local\DFScratch\cache\dfrobot.ino.cpp.o C:\Users\Administrator\AppData\Local\DFScratch\cache\dfrobot.ino.cpp: In function 'void loop()': C:\Users\Administrator\AppData\Local\DFScratch\cache\dfrobot.ino.cpp:29:24: error: 'changeLights' was not declared in this scope changeLights(); ^ 编译失败 楼主帮看一下,我直接复制代码,就有错误,不知道哪里有问题 |
© 2013-2023 Comsenz Inc. Powered by Discuz! X3.4 Licensed