Arduino教程 04 呼吸灯「DFR0100」

2014-01-1715.7万
AI 快速预览详细 收起
本篇Arduino教程介绍了如何制作呼吸灯。项目名称为“呼吸灯”,所需硬件包括Arduino UNO板、LED灯等。最终效果是LED灯亮度从暗到亮再到暗,如同呼吸一般均匀变化。难度等级适合初学者,特别是STEM教育场景下的学生。通过本教程,您可以了解PWM技术的基本原理,并学会使用analogWrite函数控制LED亮度。
【本篇课程内容于 2024年9月3日更新】

项目 - 呼吸灯


在前面几章中,我们知道了如何通过程序来控制LED亮灭。但Arduino还有个很强大的功能,就是通过程序来控制LED的明亮度。Arduino UNO数字引脚中有六个引脚标有“~”,这个符号就说明该口具有PWM功能。我们动手做一个呼吸灯,在做的过程中体会PWM的神奇力量!所谓呼吸灯,就是让灯有一个由亮到暗,再到亮的逐渐变化的过程,感觉像是在均匀的呼吸。

元件清单

Arduino教程 04 呼吸灯「DFR0100」图1

硬件连接

这个项目的硬件连接与项目【闪烁第一个LED】类似。但需要注意连接的引脚有所区别,请参考下面的连线图进行连接。

Arduino教程 04 呼吸灯「DFR0100」图2

图 1 呼吸灯连线图


示例代码
样例代码:

  1. //项目 – 呼吸灯
  2. int ledPin = 10;
  3. void setup() {
  4.       pinMode(ledPin,OUTPUT);
  5. }
  6. void loop(){
  7.       fadeOn(1000,5);
  8.       fadeOff(1000,5);
  9. }
  10. void fadeOn(unsigned int time,int increament){
  11.   for (byte value = 0 ; value < 255; value+=increament){
  12.     analogWrite(ledPin, value);
  13.     delay(time/(255/5));
  14.         }
  15. }
  16. void fadeOff(unsigned int time,int decreament){
  17.   for (byte value = 255; value >0; value-=decreament){
  18.     analogWrite(ledPin, value);
  19.     delay(time/(255/5));
  20.   }
  21. }
复制代码



代码上传完成后,我们可以看到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信号。

函数格式如下:

Arduino教程 04 呼吸灯「DFR0100」图3

analogWrite()函数用于给PWM口写入一个0~255的模拟值。特别注意的是,analogWrite()函数只能对具有PWM功能的数字引脚进行模拟写入。

PWM
PWM是一项通过数字方法来获得模拟量的技术。数字控制来形成一个方波,方波信号只有开关两种状态(也就是我们数字引脚的高低)。通过控制开与关所持续时间的比值就能模拟到一个0到5V之间变化的电压。开(学术上称为高电平)所占用的时间就叫做脉冲宽度,所以PWM也叫做脉冲宽度调制。
通过下面五个方波来更形象的了解一下PWM。

Arduino教程 04 呼吸灯「DFR0100」图4



上图绿色竖线代表方波的一个周期。每个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逐次变暗。


下载附件示例代码.rar


下一篇教程:Arduino教程 05 炫彩RGB LED

DFRobot版权所有,欢迎转载。
转载请务必标注来源: DF创客社区+作者姓名+原文网址。

创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(35)
zetacola
zetacola
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调太小
jfKprWpeUmyH
jfKprWpeUmyH
fadeOn(2000,50);
fadeOff(2000,50);
大手子们问一下,我的理解是time这个参数决定了led从灭到亮,或者亮到灭一共要多久,后面creament 决定了我以多大的间隔去决定灯亮度,那么creament应该越小led的亮度变化越均匀,但是我在wokwi模拟的时候led会缓慢的亮但是会突然灭是什么原因?
JOVI
JOVI
学习学习
耘想
耘想
评论内容
新来的
新来的
unsigned int不是整形吗
一休编程
一休编程
66666666666666666
DFHk-0ykaN8
DFHk-0ykaN8
感谢楼主的分享,学习中!!
DFHk-0ykaN8
DFHk-0ykaN8
感谢楼主的分享,学习中。
joone
joone
好东西,学习一下
373316737
373316737
6666666666666666666666666
绝地智者
绝地智者
厉害了,新手来顶一顶帖子,加油学习~
LeSoleil
LeSoleil
太好了!
救救我
救救我
请问现在要制作两个呼吸灯。如何使一个灯亮的时候另一个灯灭。就是两盏灯状态完全相反
非人哉
非人哉
求教,fadeon和fadeoff是两个内置函数,为什么前面需要加void呢,都什么时候需要加void呢。
林2
林2回复非人哉
函数没有返回值的时候就是void型
DFBypd0DaNN
DFBypd0DaNN
老师,请问
void loop(){
fadeOn(1000,5);
这句fadeOn后括号里的内容
和下句
void fadeOn(unsigned int time,int increament){
中fadeOn后括号里的内容
为什么不一样?为什么要这么写呢?
罗志宇
罗志宇回复DFBypd0DaNN
后面定义函数
WhXcjm
WhXcjm回复DFBypd0DaNN
建议入门下C++
54532541
54532541
人民邮电出版社出版社出版的《Arduino入门基础教程》的程序代码为
delay(time/(255/5)); 这是不是就是 delay(time/(time/25))呢 ?这里不是很懂

gada888
gada888
学一下子
海中月是天上月
海中月是天上月
为什么上传项目会出错的。
地狱满员
地狱满员
菜鸟我自己写的就几行代码。
int led=3;
void setup() {
pinMode(led,OUTPUT);
}
void loop() {
for(byte ATime=0;ATime<255;ATime++){
analogWrite(led,ATime/4);
delay(100);}
}
zuoyan
zuoyan
谢谢分享