Arduino教程 04 呼吸灯「DFR0100」
【本篇课程内容于 2024年9月3日更新】>课程配套Arduino器材:Arduino入门套件 DFR0100项目 - 呼吸灯
在前面几章中,我们知道了如何通过程序来控制LED亮灭。但Arduino还有个很强大的功能,就是通过程序来控制LED的明亮度。Arduino UNO数字引脚中有六个引脚标有“~”,这个符号就说明该口具有PWM功能。我们动手做一个呼吸灯,在做的过程中体会PWM的神奇力量!所谓呼吸灯,就是让灯有一个由亮到暗,再到亮的逐渐变化的过程,感觉像是在均匀的呼吸。
元件清单
硬件连接
这个项目的硬件连接与项目【闪烁第一个LED】类似。但需要注意连接的引脚有所区别,请参考下面的连线图进行连接。
图 1 呼吸灯连线图
示例代码
样例代码:
//项目 – 呼吸灯
int ledPin = 10;
void setup() {
pinMode(ledPin,OUTPUT);
}
void loop(){
fadeOn(1000,5);
fadeOff(1000,5);
}
void fadeOn(unsigned int time,int increament){
for (byte value = 0 ; value < 255; value+=increament){
analogWrite(ledPin, value);
delay(time/(255/5));
}
}
void fadeOff(unsigned int time,int decreament){
for (byte value = 255; value >0; value-=decreament){
analogWrite(ledPin, value);
delay(time/(255/5));
}
}
代码上传完成后,我们可以看到LED会有个逐渐由暗到亮的一个缓慢过程,而不是直接的亮灭,如同呼吸一般,均匀变化。
代码回顾
大部分代码我们已经很熟悉了,比如初始化变量声明、引脚设置、for循环、以及函数调用。
在主函数中,只有两个调用函数,先看其中一个就能明白了。
void fadeOn(unsigned int time,int increament){
for (byte value = 0 ; value < 255; value+=increament){
analogWrite(ledPin, value);
delay(time/(255/5));
}
}
fadeOn()函数有两个传递参数,从参数名称中就可以简单看出,int time指的是时间,int increament指的是增量。函数中包含了一个for循环,循环条件是value<255,变量的增量由 increament决定。
for语句中涉及了一个新函数:
analogWrite(ledPin, value);
如何发送一个模拟值到一个数字引脚呢?就要用到该函数,使用这个函数是要具备特定条件的——该数字引脚需具有PWM功能。观察一下Arduino板,查看数字引脚,你会发现其中6个引脚(3、5、6、9、10、11)旁标有“~”,这些引脚不同于其他引脚,因为它们可以输出PWM信号。
函数格式如下:
analogWrite()函数用于给PWM口写入一个0~255的模拟值。特别注意的是,analogWrite()函数只能对具有PWM功能的数字引脚进行模拟写入。
PWM
PWM是一项通过数字方法来获得模拟量的技术。数字控制来形成一个方波,方波信号只有开关两种状态(也就是我们数字引脚的高低)。通过控制开与关所持续时间的比值就能模拟到一个0到5V之间变化的电压。开(学术上称为高电平)所占用的时间就叫做脉冲宽度,所以PWM也叫做脉冲宽度调制。
通过下面五个方波来更形象的了解一下PWM。
上图绿色竖线代表方波的一个周期。每个analogWrite(value)中写入的value都能对应一个百分比,这个百分比也称为占空比(Duty Cycle),指的是一个周期内高电平持续时间比上低电平持续时间得到的百分比。图中,从上往下,第一个方波,占空比为0%,对应的value为0。LED亮度最低,也就是灭的状态。
高电平持续时间越长,也就越亮。所以,最后一个占空比为100%的对应value是255,LED最亮。50%就是最亮的一半了,25%则更暗一些。
PWM比较多的用于调节LED灯的亮度,或者是电机的转动速度。在玩一些Arduino小车时,更能体现PWM的好处,通过控制电机转动的速度来控制车速,还能通过控制左右电机的速度来控制转向。
这一章介绍结束了!同样的硬件连接,通过软件的变化,可以呈现出完全不一样的效果,是不是觉得Arduino很神奇!
课后练习
1、用LED能否做个火焰的效果,通过PWM使LED产生随机的亮度变化,来模拟一个火焰闪烁的效果。用个浅色罩子盖住效果更佳,可以放在家中作为小夜灯。
主要材料:一个红色LED、两个黄色LED以及三个220欧电阻。在这个练习中,推荐使用random()函数来实现火焰不规则变化的效果。
random()函数的功能是产生一定范围内的随机数。
提示:可以先给LED设定一个基础亮度,在基础亮度值附近产生一个随机数,比如random(-60, 60)+135,让其值稳定在135附近,并产生产生小幅变化,就更具有火焰跳跃感。不妨写程序来尝试一下。
具体用法可以查看下面链接的编程参考手册,会详细介绍这个函数的用法。之后的学习中,如果遇到了新的函数或者想尝试使用没有讲解过的函数,你可以通过编程参考手册来学习某个新函数。
点击查看:DFRobot中文版Arduino编程参考手册(位置:入门教程- Arduino编程参考手册)
点击查看:Arduino官方编程参考手册
2、再尝试一个稍微有点难度的,通过两个按键,一个按键控制LED逐次变亮,另一个按键控制LED逐次变暗。
下一篇教程:Arduino教程 05 炫彩RGB LED
DFRobot版权所有,欢迎转载。
转载请务必标注来源: DF创客社区+作者姓名+原文网址。
int ledPin = 10;
int a,b;
void setup() {
pinMode(ledPin,OUTPUT);
Serial.begin(9600);
}
void loop(){
fadeOn(1000,5);
}
void fadeOn(unsigned int time,int increament){
byte value=random(-180,+50)+200;
Serial.println(value);
analogWrite(ledPin, value);
delay(random(50,70));
}
分享一下后文的火焰习题,现在快瞎了~不要把delay调太小 fadeOn(2000,50);
fadeOff(2000,50);
大手子们问一下,我的理解是time这个参数决定了led从灭到亮,或者亮到灭一共要多久,后面creament 决定了我以多大的间隔去决定灯亮度,那么creament应该越小led的亮度变化越均匀,但是我在wokwi模拟的时候led会缓慢的亮但是会突然灭是什么原因? 老师,请问
void loop(){
fadeOn(1000,5);
这句fadeOn后括号里的内容
和下句
void fadeOn(unsigned int time,int increament){
中fadeOn后括号里的内容
为什么不一样?为什么要这么写呢?
多谢分享!!! 占空比是一个周期内高电平持续时间占一个周期的百分比。 ZeroPoint 发表于 2015-1-10 10:39
占空比是一个周期内高电平持续时间占一个周期的百分比。
恩 可以这么理解 应该写成delay(time/(255/increment)) Mr.why 发表于 2015-2-1 17:20
应该写成delay(time/(255/increment))
哈哈 慧眼~ 大神,怎么我改不了亮度,无论改哪个都不行 学习 跟着老师学习一下:lol 大连林海 发表于 2015-2-7 20:12
学习 跟着老师学习一下
欢迎欢迎~ 老师,为什么我好像改不了亮度+.+ 是改哪个参数 a920496044 发表于 2015-2-12 11:02
老师,为什么我好像改不了亮度+.+ 是改哪个参数
analogWrite()函数是用于改亮度的,你试试看(老师喊得我太不好意思了:$) 重新认真看,终于搞懂了,谢谢了老师XD a920496044 发表于 2015-2-14 12:32
重新认真看,终于搞懂了,谢谢了老师XD
赞一个~哈哈 void loop(){
fadeOn(1000,5);
fadeOff(1000,5);
}
这句是什么意思:'( time/(255/increament)
不是很理解是什么意思 siska 发表于 2015-7-14 14:39
void loop(){
fadeOn(1000,5);
fadeOff(1000,5);
这里是调用了两个外部函数 fade on和fade off for (byte value = 0 ; value < 255; value+=increament) 老师想问一下这句里这个byte 有什么用啊 1522631876 发表于 2015-8-2 09:38
for (byte value = 0 ; value < 255; value+=increament) 老师想问一下这句里这个byte 有什么用啊 ...
定义一个变量类型的,你也可以用int Jane 发表于 2015-8-3 10:57
定义一个变量类型的,你也可以用int
哦哦 好的 谢谢老师啦 本帖最后由 joyyazi 于 2015-8-9 08:10 编辑
上面的代码
fadeOn(1000,5);
fadeOff(1000,5);
其中的1000,5什么意思啊。
fadeOn(1000,5);
fadeOff(1000,5);
其中的1000,5什么意思?
还有random(120)+135加在哪里???
谢谢楼主!!!