【任务导航】

1.熟悉程序上传流程,掌握程序上传失败的解决办法。
2.理解示例程序Blink,并掌握Arduino程序开发的程序框架。
3.掌握pinMode(pin,val)函数、digitalWrite(pin,val)函数、delay()函数。
4.认识LED,并能动手连接简单的LED电路,编程控制LED点亮、熄灭。
5.理解I/O口。
6.掌握Mixly中“数字输出”模块和“延时模块”的使用。

【知识加油站】

1.LED

发光二极管灯即LED 灯(light emitting diode),它的基本结构是一块发光的半导体材料芯片,用银胶或白胶固化到支架上,然后用银线或金线连接芯片和电路板,然后四周用环氧树脂密封,起到保护内部芯线的作用,最后安装外壳,所以 LED 灯的抗震性能好。运用领域涉及到手机、台灯、家电等日常家电和机械生产方面。常见的LED发光二极管如图2.1.1所示。【1】百度百科
image.png
图2.1.1 常见的直插LED
LED的特点:
①耐压值:1.5V-50V。我们常见的LED发光二极管,一般耐压值都在5V以下,不同颜色的LED耐压值不同,所以在实际使用时需要接限流电阻。我们常用的LED能承受的电流在5-30mA左右,在设计电路时需要注意。
②大小:常见的LED一般在3-5mm的正方形大小,封装不同,大小不同。
③响应时间:其白炽灯的响应时间为毫秒级,LED灯的响应时间为纳秒级。
LED是半导体二极管的一种,可以把电能转化成光能。发光二极管与普通二极管一样是由一个PN结组成,也具有单向导电性。当给发光二极管加上正向电压后,它将会发光,常用的是发红光、绿光或黄光的二极管。常见的直插式封装的LED二极管有两个引脚,为了方便区分,在生产制造时,将两个引脚制造成一长一短,长的引脚叫阳极,短的引脚叫阴极,只有在阳极和阴极之间加正向电压LED才会发光,或者说电流从阳极流进阴极流出时二极管才会导通,LED才会发光,否则就算在两个引脚之间有电压也不会发光。

2. pinMode(pin,val)函数

pinMode(pin,val)函数是设置Arduino引脚的工作模式的函数,其中pin参数是需要设置的引脚,例如数字引脚的3号、5号引脚、模拟引脚的A0等等,使用范围包含了所有的数字引脚和部分模拟引脚;val参数是设置该引脚的工作模式(INPUT、OUTPUT、INPUT_PULLUP)模式,详细介绍请看语法手册相应部分。

3. digitalWrite(pin,val)函数

digitalWrite(pin,val)函数是数字输出函数,或者叫做数字方式写函数,这里的“写”表示的是Arduino输出。pin参数表示的是输出(写)的引脚编号;val表示的是输出(写)的状态(高或低),编写程序时写作(HIGHT或LOW)或者直接写(1或0)。高(HIGHT)对应1,低(LOW)对应0。

4.delay()函数

delay(val)函数是延时(等待)函数,可以让程序等待在此处一定的时间,括号内的参数val就是等待的时间,单位是ms。需要注意的是1s=1000ms。

【自己动手】

任务1:上传Blink示例程序,解决上传失败

1.任务要求:
在Arduino IDE中找到示例程序Blink并打开,完成上传程序前的必要设置后上传程序,遇到上传程序失败时,根据信息输出窗口中的提示信息,查找错误点,修改错误并完成程序上传,观察Arduino主板上的程序运行情况是否和程序一致。

2.所需器材:
Arduino NANO/UNO主板1块,主板对应USB连接线1根。

3.参考程序
3.1 Arduino IDE参考程序

  1. /* Blink
  2. Turns an LED on for one second, then off for one second, repeatedly.
  3. Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
  4. it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
  5. the correct LED pin independent of which board is used.
  6. If you want to know what pin the on-board LED is connected to on your Arduino
  7. model, check the Technical Specs of your board at:
  8. https://www.arduino.cc/en/Main/Products
  9. modified 8 May 2014
  10. by Scott Fitzgerald
  11. modified 2 Sep 2016
  12. by Arturo Guadalupi
  13. modified 8 Sep 2016
  14. by Colby Newman
  15. This example code is in the public domain.
  16. http://www.arduino.cc/en/Tutorial/Blink
  17. */
  18. void setup() {
  19. // initialize digital pin LED_BUILTIN as an output. 初始化数字引脚LED作为输出
  20. pinMode(LED_BUILTIN, OUTPUT);
  21. }
  22. void loop() {
  23. digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) 打开13号LED(高电平)
  24. delay(1000); // wait for a second 等待1秒钟
  25. digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW 用低电平来关闭LED
  26. delay(1000); // wait for a second 等待1秒钟
  27. }

3.2 Mixly 参考程序
image.png
图2.1.2 mixly图形化编程的Blink程序

关于使用Arduino IDE和Mixly打开本例程的方法、开发环境的基本操作以及上传程序失败的解决办法,已在第一章第四节中做了详细的叙述,请参看相关章节内容,在此不重复叙述。个别特例的上传原因以及程序编译错误,需要具体参照信息输出区的错误提示信息具体分析。所以强烈建议开启Arduino IDE的编译和上传的详细信息输出功能。

任务2:理解Blink/闪灯示例程序

1.任务要求
本任务是对Blink程序的解读,从中认识Arduino的程序框架;会用本例程中用到的三个函数;知道程序中的注释语句。会使用Mixly中的数字输出功能。

2.所需器材
无,本例程为程序理论解读,不需要硬件电路支持。

3.参考程序
同任务1程序。

4.程序解读
4.1 Arduino IDE程序
①注释:在程序中给编程者或程序使用者看的一些说明性字符。
注释有两种形式,一种形式是注释程序中连续的多行字符或代码,叫做多行注释,用“/被注释的多行字符或代码/”表示(不含引号),也就是用“斜杠加星号”开始,“星号加斜杠”结束,中间包含需要注释的多行或一行注释性字符。另一种形式是注释程序中一行字符和代码,叫做单行注释,用“//”表示(不含引号),也就是用“双斜杠”表示。在“双斜杠”后紧跟着需要被注释掉的文字或代码,只对“双斜杠”所在行有效,换行后需要在新的一行前加上“双斜杠”作为新行的注释标识。
②Arduino 程序框架
Arduino程序包含一个固定的程序框架,在新建一个程序草图的时候,Arduino IDE会自动填写这个程序框架,不需要编程者手动编写,Arduino程序框架如图2.1.3所示。
image.png
图2.1.3 Arduino的程序框架

程序框架中包含两个函数,setup()函数和loop()函数。setup()函数在Arduino程序启动时会被调用。使用它来初始化变量,引脚模式,启用库等。setup函数只会在Arduino主板的每次上电或复位后运行一次。Arduino程序在执行完setup()函数后,将会连续循环的执行loop()函数中的代码,可以使用它来控制Arduino主板完成相应的动作。
③语句结束标识符“;”
在C语言中,分号表示语句的结束,意思是一个分号表示着一句具有完整意义的C语言语句的完结。而什么是“具有完整意义的C语句”呢?即是意思明确,说完了一件事情,完成了一个操作的C语句。在初学编程时,时长会写成中文分号“;”,验证程序时Arduino会提示错误。所以一定记得切换为英文输入模式时再输入分号“;”。如下两个程序片段中就有“;”分号使用错误的地方。

  1. //程序段1,在定义变量和赋值时少了分号
  2. int a,b
  3. a= 20;
  4. b= 30
  5. //程序段2,分支结构中多了分号
  6. if(a>b);
  7. printf( "%d",a);

如程序段1中的“b=30”,表示将30赋值给变量b,意思完整,操作完成,因此需要加上分号。而第一行代码表示创建两个int型的变量a和b,意思表达完整,操作完整且结束,同样需要添加分号,此处没加分号,在编译程序时Arduino IDE将会提示错误。而程序段2本意是想表达如果a大于b,那么打印a,而示例的写法却告诉计算机“ if (a> b)”是一个完整意义的C语句了,完成了一个操作了。这在语法上是没有错,而却与程序设计者的初衷相去甚远,此时的含义已经变成了如果a大于b,那么什么都不做(因为分号前没有任何操作)。像程序段2中这个的写法在语法上是没错的,所以Arduino IDE在编译时不会提示错误,但是程序运行后肯定得不到编程者想要的结果。
④本例程所用函数
pinMode(pin, mode)—> pinMode(LED_BUILTIN, OUTPUT);
将13号引脚设置为输出模式。
此处的pin被设置为LED_BUILTIN,是因为在Arduino函数库中定义了LED_BUILTIN为常量13,所以可以简单理解为在Arduino程序中写13和写LED_BUILTIN是一样的效果。此处的mode设置为OUTPUT,表示把13号引脚的工作模式设为输出模式。

digitalWrite(pin, val) —> digitalWrite(LED_BUILTIN, HIGH);
将13号引脚设置为高输出。
此处的HIGH必须为大写方式,表示在该引脚上输出高电压,也就是Arduino主板的供电电压5V,同理,把这条语句中的HIGH换成LOW就表示在该引脚上输出低电压,也就是0V电压,就是GND。在编程时写HIGH和写数字1是一样的效果,写LOW和写数字0是一样的效果。同样是因为Arduino函数库中定义了HIGH是常数1,LOW是常数0。

delay(ms)—> delay(1000);
使程序暂停1000ms,也就是让程序在这儿等着,什么也不做,等到1000ms时间到后再往下执行。(1s=1000ms)

通过以上基础知识的学习,相信我们已经能看懂本例程了,在此我们对程序进行简单的分析,在这个示例程序中,前面的大段的英文字符属于注释部分,第26行的setup()函数和第32行的loop()函数是Arduino程序的两个主要函数,setup()函数里包含的语句第28将会设置Arduino的13数字引脚为输出模式;loop()函数里包含的语句第33行程序将会在13数字引脚输出一个高电平;第34行和36行程序是延时程序,第35行程序将会在13号数字引脚上输出一个低电平。将会在Arduino有正常供电的情况下不断的重复循环执行以上4行代码,直到Arduino断电或复位。
根据以上分析,Arduino执行示例程序Blink后,将会把数字引脚13设置为输出模式,然后在13号数字引脚上循环输出高低电平,循环周期是2秒钟。表现在Arduino主板上的现象是标注为L的LED发光二极管将会以2秒的周期进行闪烁。因为Arduino输出高电压可以点亮LED小灯,输出低电压可以关闭LED小灯。

4.2 Mixly程序解读
如图2.1.2所示,Mixly的闪灯程序只有5个程序块,下面将对每一个程序块作详细说明。
①第一个灰色的程序块是程序的注释,注释块里面可以写一些对程序的解释和标注的文字信息,是给编程者或者程序使用者阅读的,Mixly在编译程序时会跳过注释块,准确的说注释块不是程序块,因为Arduino核心处理器并没有执行注释块。
②第2个和第4个棕色的程序块是Arduino数字输出程序模块,此程序块有两个可以供用户设置的选项,分别是数字输出的管脚号和输出的信号(高/低)。输出管脚号就是我们所需要在Arduino的哪个引脚上上进行信号的输出,输出的信号就是输出是高电压5V(HIGH)还是低电压(LOW),在数字方式输出时,引脚上的电压只能是高或者是低,只有这两种状态。在闪灯程序中,第2个程序块是输出高,在Arduino引脚上表现出的就是5V电压,第4程序块是输出低,在Arduino引脚上表现出的就是0V电压。
③第3个和第5个绿色的程序块是一模一样的,其意思是让程序在此等待1000毫秒,在这等待的时间内,Arduino不再处理其他程序。其中这里的时间单位可以选择毫秒和微妙(1秒=1000毫秒;1毫秒=1000微秒),后面的数值只能是正整数。

综合以上的介绍说明,其实Arduino IDE代码编程个Mixly图形化编程是大同小异的,一个是以字母、单词或文本的形式编程,另一个是以积木块的形式编写,如图2.1.4所示。IDE中的注释符号“//”和“/,,,,/”就等同于Mixly中的注释块;IDE中的digitalWrite(pin, val)函数就等同于Mixly中的棕色的数字输出程序块;IDE中的delay(1000)函数就等同于Mixly中的绿色的等待程序块。只是在Mixly编程中,使用数字输出程序块时,不需要再设置引脚为输出模式,Mixly软件会自动设置为输出模式。
image.png
图2.1.4 代码编程和图形化编程图

任务3:点亮自己的LED

1.任务要求
通过杜邦线,连接一个自己的LED灯到Arduino的2号数字引脚,并编写程序点亮它。
①LED灯的阳极通过杜邦线连接到Arduino的2号数字引脚,LED灯的阴极通过杜邦线连接到Arduino主板的GND。编写程序点亮这个LED灯。
②在不改变①中的电路的情况下,编写程序程序让LED灯实现亮1S,灭0.5S。
③在不改变②中程序的情况下,实现让LED灯亮0.5S,灭1S。

2.所需硬件
Arduino UNO/NANO 主板一块、直插式LED灯一个、杜邦线2根。

3.参考电路
image.png
图2.1.5 点亮LED电路

4.参考程序

  1. void setup() {
  2. // put your setup code here, to run once:
  3. pinMode(2,OUTPUT); //2号引脚设置为输出模式
  4. }
  5. void loop() {
  6. // put your main code here, to run repeatedly:
  7. digitalWrita(2,HIGH); //2号引脚输出高电平
  8. }

image.png
图2.1.6 点亮D2引脚上的LED灯

  1. void setup() {
  2. // put your setup code here, to run once:
  3. pinMode(2,OUTPUT); //2号引脚设置为输出模式
  4. }
  5. void loop() {
  6. // put your main code here, to run repeatedly:
  7. digitalWrita(2,HIGH); //2号引脚输出高电平
  8. delay(1000); //等待1秒钟
  9. digitalWrita(2,LOW); //2号引脚输出低电平
  10. delay(500); //等待0.5秒钟
  11. }

image.png
图2.1.7 D2引脚上LED不等时长闪烁

本步骤要求不改变程序,所以程序和②需要保持一致。在任务3中,我们点亮了自己连接电路的LED灯,Arduino主板上的L小灯并没有点亮,所以,Arduino编程是与硬件电路相关的,通过不同的硬件电路加上不同的程序可以实现我们不同的创意。换句话说,Arduino编程需要硬件电路和软件编程一一对应。在要求③中,要不改变程序,要实现LED灯的亮灭时长刚好交替,那我们只能从硬件电路入手,在修改电路连接时需要注意LED灯的单向导电性。

【拓展学习】

前面我们已经介绍了LED的一些见特点,其中的耐压值和承受电流大小是LED灯的两个重要的参数。在Arduino设计中常用的LED灯都是低耐压值和低电流的电子元件,耐压值通常在3V以下,承受电流在25mA以下。而Arduino的数字口在输出模式时,能输出20mA电流,几乎到了LED的最大承受电流,所以细心的读者会发现,在完成本节的任务时,LED灯会非常亮,或者说亮度很高,就是因为流过LED灯的电流很大。这样的电路是不安全的,或者说不符合设计规范的,那如何解决这个问题呢?
通过以前的知识学习我们知道,电阻可以阻碍电子的移动,也就是可以减小电流的大小,那我们是不是可以在LED灯的这个支路中串联一个电阻来减小电流呢?答案是肯定的,实际的电路设计就是这样的,仔细观察Arduino主板上L小灯的旁边,你会发现确实有一颗外形很小的电阻。关于电阻的知识,可以自行阅读附录1中的电阻部分。
在任务3的电路中,加入电阻后的电路图如图2.1.8所示。那这个电阻的阻值多大合适呢?
image.png
图2.1.8 加入限流电阻的LED电路
在实际的电路运用中,点亮LED灯的电流只需要5-10mA就够了,在此处我们选取电流I=10mA计算,LED承受的电压我们取2.5V计算。Arduino的数字输出高电平时候的电压是U=5V,新加入的限流电阻和LED灯是串联关系,串联电路中电流处处相等,所以流过电阻的电流也是10mA。通过以上数据就可以计算出新加入的限流电阻的阻值R=(U-2.5V)/10mA=250Ω。也就是说,需要至少接入一个250欧姆的电阻LED才能工作在正常的亮度下,因为耐压值和承受的电流值我们在计算时都是取的偏高,所以计算出的电流就偏小。在实际的电路运用中,限流电阻的大小在470Ω-2.2K都可以正常点亮LED灯。实际运用中不同颜色的LED的耐压值不同,在自己设计电路时需要查看厂家的数据手册中具体的参数来计算限流电阻的大小。

【思考与讨论】

1.能否用LED灯来模拟摩斯电码的发送,尝试用LED发送“SOS”的摩斯电码。
2.需要单独控制多个LED灯时,该如何连接电路,又该如何编程呢?