Jane 发表于 2013-12-11 17:37:53

Arduino教程 01 LED灯闪烁「DFR0100」

【本篇课程内容于 2024年8月2日更新】>课程配套Arduino器材:Arduino入门套件 DFR0100


在这个项目中,我们将重复使用之前的测试代码中的Blink程序。
有所不同的是,这里我们需要外接一个LED到数字引脚,而不是使用焊在开发板上的LED(也就是“L”灯)。该项目能帮助我们能清晰的认识LED的工作原理及一些硬件电路的搭建。


## 所需元件


>*这里仅为示意图,具体阻值参看包装袋标示。阻值可能根据你使用的LED的不同而不同,后面会说明如何计算这个阻值。

## 硬件连接

首先,从套件中取出Prototype shield扩展板和面包板,将面包板背面的双面胶揭下,并按照下图将其粘贴到Prototype shield扩展板上。再取出UNO,把贴有面包板Prototype shield扩展板插到UNO上。
取出所需元件,按照下图进行连接。

> DF跳线颜色定义:
绿色连接数字口,蓝色连接模拟口,红色连接VCC(电源正极),黑色连接GND(电源负极),白色可随意搭配图 1LED闪烁连线图

*虽然跳线的本质功能是一样的,但标准化操作(通过规定跳线颜色的使用规律)能大大减少因个人习惯不同而导致的连接错误,还能帮助在排查错误时提高效率。

将LED和对应电阻连接在面包板上(按照上图),接着使用对应颜色的跳线进行连接。检查元件和线的连接位置,与上图保持一致即可。针对LED的连接需要注意:LED长脚为 + ,短脚为 - 。完成连接后,使用USB数据线将Arduino与计算机连接,准备编写和上传程序。

##示例代码

打开Arduino IDE,在编辑框中输入样下方例代码所示代码。(输入代码也是一种学习编程的过程,虽然提供代码的压缩包,但还是建议初学者自己输入代码,亲身体验一下。)

样例代码 1-1:
```
//项目一 —— 闪烁第一个LED闪烁
    /*
描述:LED每隔一秒交替亮灭一次
    */   
int ledPin = 13;
void setup() {
       pinMode(ledPin, OUTPUT);
}
void loop() {
       digitalWrite(ledPin,HIGH);
       delay(1000);
       digitalWrite(ledPin,LOW);
       delay(1000);
}
```

输入完毕后,点击IDE的“校验(Verify)”,查看输入代码是否通过编译。如果显示没有错误,单击“上传(UpLoad)”,给Arduino上传代码。以上每一步都完成了的话,你应该可以看到面包板上的红色LED每隔一秒交替亮灭一次。

现在让我们来回顾一下代码和硬件,看看它们是如何工作的。

### 代码回顾

代码的第一行如下所示:
`//项目一 —— 闪烁第一个LED`

这是代码中的说明文字,可以叫做注释。是以“//”开始,之后直到该行末尾的所有文字将不被编译器编译。注释在代码中是非常有用的,它可以帮助你理解代码,如果项目比较复杂,那么代码也会随之非常的长,而此时注释就会发挥很大作用,可以快速帮你回忆起这段代码的功能。同样,当把你的代码分享给别人的时候,别人也能很快理解你的代码。

又如以下文字:
`/* 在这两个符号之间的文字,都将被注释掉,编译器自动不进行编译,注释掉的文字将会呈现灰色 */`

这是另外一种写注释的方式,用“/*…*/”,这个符号的作用是可以注释多行,这也是与上一种注释方式的区别之处。在 /* 和 */ 中间的所有内容都将被编译器忽略,不进行编译。IDE会自动把注释的文字颜色变为灰色。

注释接下来的一行是:


这就是所谓的变量声明,变量是用来存储数据的。这个例子,我们用的类型是int型或者说是整型,可以表示一个在-32768到32767之间的数。变量的类型,是由你存储的内容来决定的。这里我们存储的10这个整数。ledPin是变量名。(变量名其实就是这个变量的一个名字,代表这个值。当然,也可以不叫ledPin,按你的喜好来取),变量名的选取最好根据变量的功能来定。ledPin这里说明,这个变量表示LED和Arduino的数字引脚10相连。

在声明的最后用一个“;”来表示这句语句的结束。分号必不可少!必须切换到英文输入法里的分号。

> ### 何为变量?

> 我们做个这样的比方,变量好比一个盒子,盒子的空间用来存放东西的,想要放的东西一定要比盒子小,那样才放的下,否则会溢出。变量也是一样,你存储的数据一定要在变量的范围内,否则会出现溢出。

> 之所以叫变量,是因为程序运行过程中,可以改变它的值。程序中,有时候会对变量值进行数字计算,变量的值也会随之发生变化。随着学习的深入,您将遇到更多关于变量、数据类型、作用域等高级概念,这些都将对您的编程技能产生重要影响。

> 在给变量起名字时,还需要强调的一点。在C语言中,变量名必须以一个字母开头,之后可以包含字母、数字、下划线。注意C语言认为大小写字母是不同的。C语言中还有一些特定的名称也是不能使用的,比如main,if,while等。为了避免这些特定名称作为变量名,所有这些名称在IDE程序中显示为橙色。

接下来是setup()函数:

在这个程序里有两个函数,一个叫做setup(),它的主要目的是在loop() 函数运行之前为程序做必要的设置。在Arduino中程序运行时将首先调用setup() 函数。用于初始化变量、设置针脚的输出/输入类型、配置串口等等。每次Arduino上电或重启后,setup() 函数只运行一次。函数内部被花括号括起来的部分将会被依次执行,从“ { ”开始,以“ } ”结束。两个符号之间的语句都属于这个函数。

setup()函数内只有一条语句,那就是pinMode函数。

`pinMode(ledPin, OUTPUT);`

> 这个函数是用来设置Arduino数字引脚的模式的,只用于数字引脚定义是输入(INPUT)还是输出 (OUTPUT)。在函数的括号内包含两个参数,引脚号以及引脚的模式。

函数格式如下:

pinMode就是一个函数的调用,只是这个函数已经在Arduino软件内部编写好了,所以我们也只需直接调用就可以了。在函数的括号内包含两个参数,就是需设定引脚号及引脚的模式,引脚号是ledPin,在我们程序的第一句话就声明过了, ledPin代表10,之后用到ledPin的地方,都可以理解为10的代名词。上述的语句表达什么意思呢?该语句想告诉Arduino,数字引脚10被设置为OUTPUT模式。

> ### 函数
>
> 函数通常为具有一个个功能的小模块,通过这些功能的整合,就组成了我们的整段代码,一个完整的功能实现。这些功能块也能被反复运用。这时,就体现函数的好处了。在程序运行过程中,有些功能可能会被重复使用,所以只需程序中调用一下函数名就可以了,无需重复编写。而setup()和loop()比较特殊,不能反复调用。
>
> 还有一个概念我们需要了解一下,就是函数的返回值,我们可以理解为是一种反馈。在函数中是如何体现有无返回值的呢?就是,函数的声明,比如“ void ”就是函数无返回值的信号,并且后面的括号内为空,我们之后会经常用到。带返回值的函数,我们先不做说明了,有兴趣的可以去网上了解一下。
>
> 你是否对函数有了一个简单的概念了呢?不明白也没关系,在我们之后的项目还会涉及到的。


> ### INPUT与 OUTPUT的区别
>
> INPUT是输入的信号,是外部给控制器的信号,根据外部环境变化给控制器不同的信号。比如像我们之后会用到的按钮,它就是典型的 INPUT模式,它需要我们按下按键后,控制器才能接收到外部给它的指令。
>
> OUTPUT是输出信号,你需要让控制器能反应出某些特征,向外界发出信号,典型的就是LED,它闪烁的过程就是向外部发出信号的过程。又比如我们后面会用到的蜂鸣器,一个会发出声音的玩意儿,发声的过程就是向外界发出信号的过程,所以它也是OUTPUT。


我们接着往下看,程序现在进行到我们的主函数loop():

```
void loop() {

       digitalWrite(ledPin,HIGH);

       delay(1000);

       digitalWrite(ledPin,LOW);

       delay(1000);

}
```

* Arduino程序必须包含setup()和loop()两个函数,否则不能正常工作。*

在 setup() 函数中初始化和定义了变量后,就开始执行 loop() 函数。顾名思义,该函数在程序运行过程中不断的循环,loop()函数中的每条语句都逐次进行,直到函数的最后,然后再从loop函数的第一条语句再次开始,三次、四次......一直这样循环下去,直到关闭Arduino或者按下重启按钮。

在这个项目中,我们希望LED灯亮,保持1秒,然后关闭,保持1 秒,然后一直重复上面的动作。那么在Arduino的语句中,该怎么实现呢?

先看loop()函数内的第一条语句,这里我们涉及到了另外一个函数就是digitalWrite()。

`digitalWrite(ledPin,HIGH);`

函数格式如下:


这个函数的意义是:引脚pin在 pinMode()的中被设置为OUTPUT模式时,其电压将被设置为相应的值,HIGH为5V(3.3V控制板上为 3.3V),LOW为0V。我们这里就是给引脚10(ledPin)一个5V的高电平,点亮了引脚10这个LED。

我们这里强调了,pinMode()被设置为OUTPUT时,才用到 digitalWrite()。这是为什么呢?看一下下面这段话。

> ### pinMode()digitalWrite()digitalRead()的关系
>
> 前面说了pinMode()中的INPUT与OUTPUT设置是有讲究的,是由元件本身的功能决定的。
>
> 然而,前面设置INPUT和OUTPUT与之后程序需要如何执行也有着紧密关系的。既然pin是OUTPUT的话,那势必是控制器Arduino要给外界信号,所以需要Arduino给引脚先写入信号——digitalWrite()。我们这里还没用到digitalRead(),就先说了吧!如果pin是INPUT的话,是外界给了控制器Arduino信号,所以需要Arduino读取引脚信号——digitalRead()。
>
> 对于初学者来说,可以先学着用,再慢慢弄明白里面的原由。pinMode()设置为OUTPUT,对应使用digitalWrite()。INPUT对应使用digitalRead()。下表是一张对应表:

| 比如:LED、蜂鸣器 | 比如:按键控制 |
| -------- | -------- | -------- |
| pinMode(pin,OUTPUT)   | pinMode(pin,INPUT)    |
| digitalWrite(pin,HIGH/LOW) | digitalRead(pin) |

接着的一句语句:

               delay(1000);

delay()函数,用于延时等待。等待1000毫秒(1000毫秒也就是1秒,以此类推吧!)。我们举一反三一下,如果我们需要延时2秒呢?
答案:delay(2000);

接着看下一句是:

`digitalWrite(ledPin,LOW);`

有了上面的引导,这句话是不是很容易理解了呢?这句话意思为,为引脚10一个0V的低电平,也就是熄灭LED。

然后再延时1秒。之后回到loop()函数开始部分,循环运行。

现在我们知道代码是如何运作的了,让我们来个小小的改动吧!让LED保持关闭5秒,然后快速闪烁 一下(250毫秒),就像汽车报警器上的LED指示灯那样。试着写一 下:

答案:

```
int ledPin = 10;void setup() {pinMode(ledPin, OUTPUT);}void loop() {digitalWrite(ledPin, HIGH);delay(250);digitalWrite(ledPin, LOW);delay(5000);}```

通过改变LED开和关的时间,可以产生不同的效果,开关时间短,则闪烁快,开关时间长,则闪烁慢。外面的灯光效果都是基于这样的原理。让我们再来看下硬件。看看硬件又是如何工作的。

## 硬件回顾

### 面包板

面包板是一种可重复使用的非焊接的元件,用于制作电子线路原型或者线路设计。简单的说,面包板是一种电子实验元件,表面是打孔的塑料,底部有金属条,可以实现插上即可导通,无需焊接的作用。面包板该怎么使用?其实很简单,就是把电子元件和跳线插到板子上的洞洞里,具体该怎么插,我们就要从面包板的内部结构上说了。

从上图我们可以看到,面包板分为上下两个部分,蓝线指出的纵向每5个孔是相通的。那有人问,为什么上下两个部分不全通呢?其实面包板中间这个凹槽设计是有讲究的。凹槽两面孔间距刚好是7.62mm,这个间距正好可以插入标准窄体的DIP引脚的IC(如下图)。


IC插上后,因为引脚多,一般很难取下,硬来很容易弄弯引脚,这个槽刚好可以用镊子之类的东西将IC慢慢取下。(这里引入DIP引脚的IC的目的是为了解释面包板凹槽的作用,后续课程如果用到该元件会有更详细的说明。)

### 电阻

下一个要说的元件是电阻。电阻的单位是 Ω(欧姆)。电阻会对电流产生一定的阻力,引起它两端电压的下降。可以将电阻想象成一个水管,它比连接它的管子细一点,当水(电流)流入电阻,因管子变细,水流(电流)虽然从另一端出来,但水流减小了。电阻也是一样的道理,所以电阻可以用来给其他元件减流或减压。

电阻有很多用处,对应名称也不同,上拉电阻,下拉电阻,限流电阻等。我们这里用作限流电阻。在这个例子里,数字引脚10的输出电压为5V,输入电流为40mA(毫安)直流电。普通的LED需要2V的电压和35mA左右的电流。因此如果想以LED的最大亮度点亮它,需要一个电阻将电压从5V降到2V,电流从40mA减到35mA。这个电阻起限流的作用。

如果不连电阻会怎样呢?流过LED的电流过过大(可以理解为水流过大,水管爆破了!),会使LED烧掉,就会看到一缕青烟并伴随着糊味儿~

这里具体对电阻值选取的计算就不做说明了,只要知道在接LED时需要用到一个100Ω左右的电阻就可以了。大一点也没关系,但不能小于100Ω。如果电阻值选的过大的话,LED不会有什么影响,就是会显的比较暗。很容易理解,电阻越大,减流或减压效果更明显了。LED随电流减小而变暗。

### 电阻色环读值
我们元器件的包装袋上已经明确标明了各个元件的名称。但不排除有时候不小心标签掉了,可是手头又没有可以测量的工具,那该怎么办 呢?有个方法就是从电阻上的色环来读取电阻值。我们这里就不做详细说明了。感兴趣的可以读读看阻值。

提供一个五色坏电阻阻值在线计算器:
HTTP://WWW.eechina.com/tools/five_color_ring_resistance.html(如果链接失效,请使用阻值计算器作为关键词搜索可用的网页或软件。)
### LED
最后要说就是LED,标准的发光二极管,是二极管中的一种。二极管是一种只允许电流从一个方向流进的电子器件。它就像一个水流系统的中的阀门,但是只允许一个方向通过。如果电流试图改变流动方向,那么二极管就将阻止它这么干。所以,二极管在电路中的作用通常是用来防止电路中意外地电源与地连接,避免造成损坏其他元件。
LED也是一种二极管,会发光的二极管。LED能发出不同颜色和亮度的光线,包括光谱中的紫外线和红外线。(比如我们经常使用的各类遥控器上面的LED也是其中一种,与普通的发光二极管长的一样,只是发出的光我们人眼看不到,我们也称之为红外发射管。)

如果仔细观察LED,你会注意到,LED引脚长度不同,长引脚为+,短引脚为-。那如果正负接反会怎么样呢?下面这张图就说明问题了,接反就不亮了呗。下图是不是还缺个电阻呀,细心的你发现了吗?

在我们的套件中,还有一种LED,是4个脚的,不要以为我们发错了噢。这个LED功能可大着呢,它能呈现不同颜色,也称之为RGB LED。我们都知道红色、绿色、蓝色是三原色,通过这三种颜色的暗弱变换的组合可以呈现出任何你想要的颜色。把三种颜色放在同一个外壳里就能达到这样的效果。在我们之后的项目中还会介绍到。

现在你知道了各元件的功能及整个项目中软硬件是如何工作的,让我们尝试做其他好玩儿的东西吧!

## 动手试一试

尝试换不同阻值的电阻,看看LED灯的变化。





下一篇教程:Arduino教程 02 做一个S.O.S求救信号灯

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

Youyou 发表于 2014-3-21 23:59:07

Grey 发表于 2014-3-19 18:34
楼主好细心,一步步都列出来了
32个赞

亲,32个赞怎么够呢,必须怒赞啊

心平气和 发表于 2017-5-16 20:22:40


为什么我的没有反应呢?全部安图做的

lbsun77 发表于 2018-5-27 10:12:43

你好,为什么总是显示上传出错(程序上的上传按钮就是教程的下载按钮),错误提示:Arduino:1.8.5 (Windows 7), 开发板:"Arduino/Genuino Uno"

项目使用了 940 字节,占用了 (2%) 程序存储空间。最大为 32256 字节。
全局变量使用了9字节,(0%)的动态内存,余留2039字节局部变量。最大为2048字节。
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0xd9
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0xd9
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0xd9
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0xd9
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0xd9
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0xd9
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0xd9
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0xd9
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0xd9
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0xd9
上传出错。

在文件 -> 首选项开启
“编译过程中显示详细输出”选项
这份报告会包含更多信息。

社区活动向导 发表于 2013-12-12 10:05:27

不错,配件和连线图,看着超舒服的。。。。。:loveliness:

Grey 发表于 2014-3-19 18:34:53

楼主好细心,一步步都列出来了
32个赞

zyj2007at 发表于 2015-8-7 14:01:33

已经学会了,我又加上了一盏灯,也亮了,挺有意思。

zyj2007at 发表于 2015-8-7 14:01:37

已经学会了,我又加上了一盏灯,也亮了,挺有意思。

Jane 发表于 2015-8-8 09:39:30

zyj2007at 发表于 2015-8-7 14:01
已经学会了,我又加上了一盏灯,也亮了,挺有意思。

:victory::victory:

powera 发表于 2015-12-1 10:42:27

哇,怎么可能这么详细
楼主威武!!!

OLDSTUDENT 发表于 2016-1-24 11:00:19

对于初学者不怕细只怕粗。谢谢楼主!

murongshaogong 发表于 2016-4-17 10:49:40

第一次接触这样的板子 好好学习下

z1033969032 发表于 2016-5-22 10:56:52

已经学会了

maoweiyong 发表于 2016-9-12 16:27:01

为什么我的没有反应呢?全部安图做的

maoweiyong 发表于 2016-9-13 08:07:10

maoweiyong 发表于 2016-9-12 16:27
为什么我的没有反应呢?全部安图做的

板子不一样,GND的位置和教程不同,自己解决了!!!

ElleryQueen 发表于 2016-11-3 07:58:49

感谢楼主,初学者真的是受益了

Jane 发表于 2016-11-3 11:27:30

ElleryQueen 发表于 2016-11-3 07:58
感谢楼主,初学者真的是受益了

哈哈哈 不客气哒

chengshuwan 发表于 2017-1-6 15:40:08

学习的路上第二章已拜读。。。

talesman 发表于 2017-1-20 08:59:12

我按照教程一模一样做的可是led等就是不亮(如图),求指点

talesman 发表于 2017-1-20 09:01:45

maoweiyong 发表于 2016-9-13 08:07
板子不一样,GND的位置和教程不同,自己解决了!!!

你好,请问你是怎么解决的?我也是按照图上做的但是led有任何反应

Jane 发表于 2017-1-21 18:36:35

talesman 发表于 2017-1-20 09:01
你好,请问你是怎么解决的?我也是按照图上做的但是led有任何反应

LED长短脚有没有接反呀?

samon2017 发表于 2017-1-30 14:15:25

talesman 发表于 2017-1-20 09:01
你好,请问你是怎么解决的?我也是按照图上做的但是led有任何反应

多彩线插错,GND从左往右第4个孔。

jiashe2011 发表于 2017-2-21 23:02:10

不错,配件和连线图都有。
页: [1] 2 3 4
查看完整版本: Arduino教程 01 LED灯闪烁「DFR0100」