Arduino入门

一、必要的安装

1.安装arduino开发软件

登录www.arduino.cc,在software菜单中下载Installer安装包,下载后直接下一步下一步安装即可。
注意:Install USB driver一定要勾选上,否则无法做开发。

2.安装CH340驱动

我们可以直接点击自带的CH341SER.EXE文件进行安装,也可以将arduino板子用USB线连上电脑,使用驱动精灵检测安装。

二、arduino开发软件介绍

1.面板介绍

(1)按钮

软件面板介绍-编译按钮.png

软件面板介绍-上传按钮.png

(2)选项

①板子的选择

软件介绍-板子的选择.png

Uno这款板子是最适合初学者学习的开发板。

②端口的选择

软件介绍-端口的选择.png

image.png

在链接板子之后,请选择后面括号标注Arduino的端口。如果是灰色的话,可能会是驱动程序没安装好。

三、arduino硬件介绍

1、最核心的元件——微控制器

image.png

微控制周围的这些金属片,叫做引脚:


image.png

引脚是往微控制器里传信号的通道,在开发板出现以前,都需要元器件和引脚做焊接,但是开发板出现后,只要把元器件插入两边的端口上即可,如下图所示:


image.png

2、端口

端口分三组。

(1)数字输入/输出端口

image.png

这里的输入和输出都是针对板子来说的,输入和输出的都是电位为0或1的电信号。最边上的第0号和第1号端口要注意,不到万不得已不要使用,因为RX<-0和TX->1这两个端口是象电脑传输数据用的,具体怎么传输请关注我后面的文章。


image.png

(2)模拟输入端口

image.png

如果要传输非二元性的信号则会用到这个输入端口。

(2)电源端口

image.png

接地端口是用来接地的:


image.png

5V和3.3V的端口是用来提供(即接收)5伏和3.3伏的电压:


image.png
image.png

四、Arduino编程介绍

1、C++语言基础

Arduino所使用的开发语言为C++,我们这里简单学习一下这种语言。
这部分内容可以参考我的领一篇文章——《C语言基础知识笔记》。传送门→ //www.greatytc.com/p/424549d88d46

2、Arduino程序运行流程

Arduino里面有有两个主要函数,一个是setup(),另一个是loop()。
在运行时,setup()函数只运行一次,然后就开始循环运行loop()函数。


image.png

3、Blink功能函数

该功能代码如下:

void setup() {
  //初始化LED_BUILTIN数字引脚为输出模式
  pinMode(LED_BUILTIN, OUTPUT);

}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH); //电量LED(高电平)
  delay(1000);                     //等待1秒
  digitalWrite(LED_BUILTIN, LOW);  //将电平设置为低来熄灭LED
  delay(1000);                     //等待1秒
}

Uno开发板上有个LED灯,这个灯被连接在引脚/端口13上,如下图所示:


image.png

我们可以看到在每个引脚/端口边都有数字和英文,这些就是他们的编号和名称:


image.png

现在这个端口13就是LED灯的电源,LED灯的开关就在板子里,我们可以通过程序来控制。Uno板子将LED_BUILTIN这个常量默认赋值为13(不同型号的板子赋值不同),所以setup()函数中,pinMode()函数就是将LED的电源初始化为13端口。
pinMode()的函数说明如下:


image.png

digitalWrite()函数,即对端口输出电流,HIGH就是有电流,LOW就是没有电流。
注意:一定要在setup()函数中初始化pinMode,否则digitalWrite无法给端口输出电平。

五、发光二极管简介

image.png

这种灯有个特性,给LED灯正向施加电流(约为20mA),其电阻约等于0,且等会发光,反向施加电流,电阻约等于无穷大,且不会发光。


image.png

刚才Blink功能的原理如下两张图所示:


image.png
image.png

六、面包板

图片.png

在没有面包板的时代,都是用绕线建立电路,很容易出错。

图片.png
图片.png
图片.png
图片.png
图片.png

blink实际电路图如下:


image.png
图片.png

然后我们修改一下Blink程序:

void setup() {
  //初始化5引脚为输出模式
  pinMode(5, OUTPUT);

}

void loop() {
  digitalWrite(5, HIGH); //电量LED(高电平)
  delay(1000);                     //等待1秒
  digitalWrite(5, LOW);  //将电平设置为低来熄灭LED
  delay(1000);                     //等待1秒
}

然后将其上传到arduino板子上即可看到LED的闪烁。

七、数字输入

1、pinMode()的输入模式

图片.png

2、按键开关

图片.png

图片.png

记住:相连不同侧,同侧不相连。
按下开关,电路中间的开关就相连了。
这种开和关提供给开发板的信号就是一种“0101”的数字信号。开表示1,关表示0。
图片.png

3、本节电路图

图片.png

图片.png

图片.png

图片.png

图片.png

(1)上拉电阻

图片.png

这个上拉电阻的作用就是为了让开关闭合之后,阻挡住电流的通过,所以我们在选择上拉电阻的时候通常都选择10k左右的大电阻。


图片.png

没有接上拉电阻,让5V高电平直接接地,会让开发板烧坏,很危险,所以必须配上上拉电阻。


图片.png

引脚悬空的状态,引脚会随机地接收到高电平或低电平,完全不确定。当你碰一碰开发板的时候,它的接收状态就会变得非常混乱。

3、程序代码

/*
 DigitalReadSerial
 Reads a digital input on pin 2, prints the result to the serial monitor
 读取引脚2的数字输入,将结果显示在串口监视器中
 
 This example code is in the public domain.
 */
 
// digital pin 2 has a pushbutton attached to it. Give it a name:
//引脚2连接有按键开关,给它一个名字:
int pushButton = 2;
 
// the setup routine runs once when you press reset:
//当你按下复位按钮后,setup流程运行一次:
void setup() {
  // initialize serial communication at 9600 bits per second:
  //串口通讯初始化,每秒9600位
  Serial.begin(9600);
  // make the pushbutton's pin an input:
  //设置按键引脚为输入
  pinMode(pushButton, INPUT);
}
 
// the loop routine runs over and over again forever:
// loop 流程会永远的反复运行
void loop() {
  // read the input pin:
  //读取输入引脚:
  int buttonState = digitalRead(pushButton);
  // print out the state of the button:
  // 显示按键状态
  Serial.println(buttonState);
  delay(1);        // delay in between reads for stability 为确保程序稳定运行进行短暂停止
}

4、电路组装

(1)开关的安装

图片.png

图片.png

图片.png

这个开关的安装很关键,如果装错了,后面的电路都不会成功。

(2)整体电路

图片.png

5、试验

电路搭建好之后,即可把本节的程序上传到开发板中,并在如下图所示的地方打开串口监视器,查看信号值。


图片.png

使用串口监视器的时候,一定要对右下角的波特率进行设置,


图片.png

打开波特率的选项,我们会看到很多选项值,
图片.png

因为我们程序中的数据传输速率为9600,所以这里我们也必须选择9600的波特率。

八、上拉模式

1、pinMode()的输入上拉模式

图片.png

也就是说,pinMode()的输入上拉模式,会启用板子中自带的上拉电阻,无需再配外接上拉电阻。
在本示例中,我们将通过pinMode()语句将Arduino引脚2配置为输入上拉模式。在此示例中,当开关闭合后,引脚2将获得低电平开关信号,引脚13旁的LED(如下照片红圈所示)将被点亮。反之,该LED为熄灭状态。

2、实验电路图

图片.png

3、程序

/*
设置Arduino引脚
为输入上拉(INPUT_PULLUP)
模式示例程序
 
v1.0
Created 2016
by 太极创客
www.taichi-maker.com
 
说明:
本程序旨在演示如何将Arduino引脚设置为
输入上拉(INPUT_PULLUP)模式。
当按钮被按下后,引脚13旁的LED将会点亮。
获得具体连接电路图,请参阅太极创客网站。
   
This example code is in the public domain.
*/
 
void setup() {
    //将引脚2设置为输入上拉(INPUT_PULLUP)模式
    pinMode(2, INPUT_PULLUP);
    //将引脚13设置为输出模式
    pinMode(13, OUTPUT);
 
}
 
void loop() {
    // 将开关状态数值读取到变量中
    int sensorVal = digitalRead(2);
    // 输出开关状态数值
    Serial.println(sensorVal);
    
    //请留意在上拉模式下,按钮的逻辑状态是反的。
    //即:开关断开时引脚读取到高电平。开关被按下后引脚读取到低电平。
    //按钮被按下后,引脚13连接的LED将被点亮。按钮没有按下时,LED熄灭。

    if (sensorVal == HIGH) {
        digitalWrite(13, LOW);
    } else {
        digitalWrite(13, HIGH);
    }
}

这段代码也可以使用布尔方式来写,具体如下:

/*
 * 布尔变量应用示例
 * 
 * 本示例程序演示如何使用布尔型数据变量。通过本程序,Arduino将利用
 * 布尔型变量存储引脚2的电平状态,并根据变量数值点亮或熄灭引脚13上
 * 连接的LED。
 * 
 * 电路:
 * 引脚2连接轻触开关,开关另一端接地
 * 引脚13上安装有开发板内置LED
 * 
 * 
 * This example code is in the public domain
 * 太极创客 
 * 2017-01-18
 * www.taichi-maker.com
*/
boolean pushButton; // 创建布尔型变量
 
void setup() {
  pinMode(2, INPUT_PULLUP); //将引脚2设置为输入上拉模式
  pinMode(13, OUTPUT);      //将引脚13设置为输出模式
}
 
void loop() {
  pushButton = digitalRead(2); //读取引脚2电平状态并将其赋值给布尔变量
  
  if (pushButton){          //根据布尔变量数值点亮或者熄灭LED
    digitalWrite(13, HIGH); //布尔变量数值为真(true)时点亮LED
  } else {
    digitalWrite(13, LOW);  //布尔变量数值为假(false)时熄灭LED
  }
}

刚这段代码,原本的电平HIGH和LOW被pushButton的TRUE(1)和FALSE(0)代替了,他们的效果是相同的。

2、逻辑与和逻辑或

如果电路是由两个按键来控制,我们就需要使用逻辑与的程序控制了。
电路图如下:


image.png

黑色的两根线都接入了板子中的接地插口。
我们把代码调整一下:

/*
 * 逻辑与布尔运算
 * 
 * 本示例程序演示逻辑与布尔运算。通过本程序,Arduino将对引脚2和引脚8的电平状态
 * 进行逻辑与布尔运算,并根据运算结果点亮或熄灭引脚13上连接的LED。
 * 
 * 电路:
 * 引脚2连接按键开关1,开关1另一端接地
 * 引脚8连接按键开关2,开关2另一端接地
 * 引脚13上安装有开发板内置LED
 * 
 * 
 * This example code is in the public domain
 * 太极创客 
 * 2017-01-18
 * www.taichi-maker.com
*/
 
boolean pushButton1; // 创建布尔型变量用来存储按键开关1的电平状态
boolean pushButton2; // 创建布尔型变量用来存储按键开关2的电平状态
 
void setup() {
  pinMode(2, INPUT_PULLUP); //将引脚2设置为输入上拉模式
  pinMode(8, INPUT_PULLUP); //将引脚8设置为输入上拉模式
  pinMode(13, OUTPUT);      //将引脚13设置为输出模式
}
 
void loop() {
  pushButton1 = digitalRead(2); //读取引脚2电平状态并将其赋值给布尔变量
  pushButton2 = digitalRead(8); //读取引脚8电平状态并将其赋值给布尔变量
  
  if (!pushButton1 && !pushButton2){  //根据逻辑与运算结果点亮或者熄灭LED
    digitalWrite(13, HIGH);           //两个布尔变量数值都为假(false)时点亮LED
  } else {
    digitalWrite(13, LOW);            //否则熄灭LED
  }
}
 
/*
逻辑与运算说明
!pushButton1 = 1, !pushButton2 = 1 --->  !pushButton1 && !pushButton2 = 1
!pushButton1 = 0, !pushButton2 = 1 --->  !pushButton1 && !pushButton2 = 0
!pushButton1 = 1, !pushButton2 = 0 --->  !pushButton1 && !pushButton2 = 0
!pushButton1 = 0, !pushButton2 = 0 --->  !pushButton1 && !pushButton2 = 0
*/

传到板子里之后,效果如下:


同时按下LED灯亮

按下左边一个按钮不亮

按下右边一个按钮不亮

试一下把代码逻辑与改成逻辑或,看看效果是什么样。

九、忙猜数字

1、电路图

image.png

实物搭建:


image.png

搭建好之后将测试程序上传上去:

/*
19 MC猜数字 - 1 电路搭建
太极创客
www.taichi-maker.com
 
此程序用于太极创客<<零基础入门学用Arduino教程>>中
MC猜数字电路测试使用。
 
2017-04-21
*/
void setup() {
  pinMode(2, INPUT_PULLUP);
  for (int i = 2; i <= 9; i++) {
    pinMode(i, OUTPUT);
  }
 
}
 
// the loop function runs over and over again forever
void loop() {
  int myNumber = 0;
  while(myNumber <= 9){
    displayNumber(myNumber);
    delay(500);
    displayClear();
    myNumber++;
    while(!digitalRead(2)){
      digitalWrite(5, HIGH); 
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      digitalWrite(9, HIGH); 
    }
    delay(500);
  }
}
void displayClear(){
  // 清理显示内容
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW); 
  digitalWrite(6, LOW); 
  digitalWrite(7, LOW); 
  digitalWrite(8, LOW); 
  digitalWrite(9, LOW); 
}
 
void displayNumber(int number){
  switch(number){
    case 1:
      digitalWrite(4, HIGH);
      digitalWrite(7, HIGH); 
      break;   
    case 2:
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH); 
      digitalWrite(5, HIGH); 
      digitalWrite(8, HIGH); 
      digitalWrite(9, HIGH); 
      break;   
    case 3:
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH); 
      digitalWrite(5, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      break;   
    case 4:
      digitalWrite(4, HIGH); 
      digitalWrite(5, HIGH); 
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      break;  
    case 5:
      digitalWrite(3, HIGH);
      digitalWrite(5, HIGH); 
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      break;
    case 6:
      digitalWrite(3, HIGH);
      digitalWrite(5, HIGH); 
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      digitalWrite(9, HIGH); 
      break;    
    case 7:
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH); 
      digitalWrite(7, HIGH);  
      break;
    case 8:
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH); 
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      digitalWrite(9, HIGH); 
      break;
    case 9:
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH); 
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      break;
    case 0:
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      digitalWrite(9, HIGH); 
      break;
    default:
      digitalWrite(5, HIGH);    
    }
}

2、数码管

我们用的数码管学名叫做1位8段共阴极数码管。


image.png

实际上是有8个LED灯组成:


image.png

要点亮数字实际上是7个LED的组合:
1679979327437.png

image.png

之所以叫共阴极,是因为它所有的阴极(负极)都接在一起了。

image.png

中间的cc端就是共阴极。
我们使用digitalWrite(引脚号, HIGH);即可点亮引脚连接的LED灯:
image.png

使用digitalWrite(引脚号, LOW);即可点亮引脚连接的LED灯。

3、random()

说明

random函数可用来产生随机数。

语法

random(max)
random(min, max)

参数

min: 产生随机数的下限(包含此数值)
max: 产生随机数的上限(不包含此数值)

返回值

在最小值(min)和最大值减一(max-1)之间的随机数值

注意

单独使用random()函数。每次程序运行所产生的随机数字都是同一系列数字。并非真实的随机数,而是所谓的伪随机数。如果希望每次程序运行时产生不同的随机数值。应配合使用randomseed()函数。具体操作请参见本站randomseed()函数的具体说明。

示例

long randNumber;
 
void setup(){
  Serial.begin(9600);
}
 
void loop(){
  randNumber = random(0, 300);  //产生0-300间的随机数
  Serial.println(randNumber);
  delay(50);
}

4、 While循环

while循环将会连续地无限地循环,直到圆括号()中的表达式变为假。被测试的表达式变量必须被改变,否则while循环将永远不会中止。可以在代码改变测试变量,比如让该变量递增,或者通过外部条件改变测试变量,比如将一个传感器的读数赋值给测试变量。

while语句的意思是:先计算表达式的值,当值为真(非0)时, 执行循环体语句;执行完循环体语句,再次计算表达式的值,如果为真,继续执行循环体……这个过程会一直重复,直到表达式的值为假(0)才退出循环。其执行过程如下图所示:

int pinNumber = 3;
while(pinNumber<=9)
{
pinMode(pinNumber,OUTPUT);
pinNumber = pinNumber + 1;
}
 
//这与下面的代码是等效的
/*
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
*/

5、if...else

通过if…else语句,用户可以让Arduino判断某一个条件是否达到,并且根据这一判断结果执行相应的程序。


if( 表达式1 ) {

    语句块1

} else {

    语句块2

}

上述结构表示:如果 “表达式1” 的条件得到满足则执行”语句块1″。否则Arduino将执行”语句块2″。(如下图所示)

6、switch case语句

就像if语句,switch…case允许Arduino根据不同的条件运行不同的的程序代码。switch语句通过对一个变量的值与case语句中指定的值进行比较。当一个case语句中的指定值与switch语句中的变量相匹配。就会运行这个case语句下的代码。

通过break关键字,Arduino可以中止并跳出switch语句段,break关键字常常用于每个case语句的最后面。如果没有break语句,switch语句将继续执行下面的表达式(“持续下降”)直到遇到break,或者是到达switch语句的末尾。

Arduino编程语言虽然没有限制 if else 能够处理的分支数量,但当分支过多时,用 if else 处理会不太方便,而且容易出现 if else 配对出错的情况。

switch (var) {
    case 1:
        //当var等于1时执行这里的程序
        break;
    case 2:
        //当var等于2时执行这里的程序
        break;
    default:
        // 如果var的值与以上case中的值都不匹配
        // 则执行这里的程序
        break;
}

需要注意的几点内容:
① 在以上结构示例代码中,当变量var和某个case后面的数值匹配成功后,如果没有break, Arduino会执行该分支以及后面所有分支的语句。
②case 后面必须是一个整数,或者是结果为整数的表达式,但不能包含任何变量。
③ case 后面不能使用字符串,但可以使用字符,使用字符时需要用单引号把字符括起来,如: case: 'b'。
④default 不是必须的。当没有 default 时,如果所有 case 都匹配失败,那么就什么都不执行。

7、自定义函数

定义函数:

void displayClear(){
  // 清理显示内容
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW); 
  digitalWrite(6, LOW); 
  digitalWrite(7, LOW); 
  digitalWrite(8, LOW); 
  digitalWrite(9, LOW); 
}

调用:

void loop() {
  int myNumber = 0;
  while(myNumber <= 9){
    displayNumber(myNumber);
    delay(500);
 
 
    displayClear();
 
 
 
    myNumber++;
    while(!digitalRead(2)){
      digitalWrite(5, HIGH); 
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      digitalWrite(9, HIGH); 
    }
    delay(500);
  }
}

8、完成制作

(1)串口监视器的特性

每次打开串口监视器的时候,板子都会复位,就是重新执行你所上传的程序。

(2)randomSeed()

randomSeed()函数可用来产生随机种子。单独使用random()函数所产生的随机数,在每一次程序重新启动后,总是重复同一组随机数字。如果希望程序重新启动后产生的随机数值与上一次程序运行时的随机数不同,则需要使用randomSeed()函数。

在实际应用时,可以通过调用analogRead()函数读取一个空引脚,作为随机种子数值。具体操作,本页面后续示例程序将进行说明。

语法
randomSeed(seedVal);

参数
seedVal: 随机种子数值

例子
randomSeed(analogRead(A0));//读取A0端的一个模拟数值

/*
 * MC猜数字 (Ver. 1.0)
 * 
 * 本程序用于太极创客制作的《零基础入门学用Arduino教程》中
 * MC猜数字小制作。通过学习和搭建这个小装置,我们希望您能够
 * 学会以下内容:
 * 
 *  - LED数码管的原理和使用
 *  - if...else if的概念和应用
 *  - while循环的概念和应用
 *  - switch case控制语句
 *  - random函数的使用
 *  - 建立和使用自定义函数(三种形式:无参数无返回值,有参数无返回值,有参数有返回值)
 *  - 通过串口监视器观察调试程序运行状况
 *  
 *  电路连接:
 *  有关本制作的详细电路连接资料,请参阅太极创客网站的《零基础入门学用Arduino教程》相关网页。
 *  
 *  
 *  太极创客网站地址:
 *  www.taichi-maker.com
 *  
 *  如您对我们有任何建议或意见,请发邮件至:
 *  taichimaker@163.com
 *  
 *  同时您也可以通过我们的微信公众号以及微博获得更多太极创客的最新信息。
 *  
 *  This example code is in the public domain.
 *  
 *  2017-04-23
 *
 *  注:
 *  目前科学技术尚无法实现意念控制。
 *  科技可以改变世界,但也有心怀不轨的人会利用科技制作
 *  我们不宜察觉的装置。而这些装置会被用于赌博或诈骗。
 *  我们一定要远离赌博,相信科学。:)
*/
 
 
int thisResult;  //存储按键按下以后显示在数码管的数字。
int nextResult;  //存储作弊数字,也就是下一次按键按下后即将显示的数字。
 
void setup() {
  pinMode(2, INPUT_PULLUP); //2号引脚上连接有按键开关,将2号引脚设置为输入上拉模式
  int pinNumber = 3;        //设置3-9号引脚为输出模式
  while(pinNumber <= 9){
    pinMode(pinNumber, OUTPUT);
    pinNumber = pinNumber + 1;
  }
  randomSeed(analogRead(A0)); //为了每一次复位或断电后产生不同顺序的随机数字
}
 
// the loop function runs over and over again forever
void loop() {
  if (!digitalRead(2)){      //读取2号引脚电平状态
    getRandomNumber(0,10);   //用户按下按键后,开始新一次猜数字游戏
  }
  displayNumber(thisResult); //将猜数字游戏"结果"显示在数码管中
}
 
/*
用户在每一次按下按键后,随机产生的数字将存储于nextResult变量中。
而实际显示在数码管上的数字是thisResult变量。
当thisResult即将显示在数码管前,程序会将下一次显示的数字通过
图形暗示的形式显示在数码管上。具体程序如何显示暗示图形,
请参阅displayCheat()函数说明。
*/
void getRandomNumber(int minNumber, int maxNumber){
  thisResult = nextResult; 
  int i; 
  while(i < 15){
    i = i + 1;
    nextResult = random(0, 10);
    displayRandom();         //显示随机图案,混淆注意力
    delay(50 + i * 10);      //让随机图案显示时间由快到慢,增加混淆
    displayClear();
  }
  displayCheat(nextResult);  //显示作弊图案,用户可通过此函数所显示的图案
                             //获知下次按键后将要出现在LED数码管上的数字。  
                             //此图案是在用户每次按下按键后显示新的数字
                             //前的最后一次图案显示
  delay(500);
  displayClear();
}
 
//根据参数数值在LED数码管上显示数字
void displayNumber(int ledNumber){     
  switch(ledNumber){
    case 1:  //显示1
      digitalWrite(4, HIGH);
      digitalWrite(7, HIGH); 
      break;   
    case 2:  //显示2
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH); 
      digitalWrite(5, HIGH); 
      digitalWrite(8, HIGH); 
      digitalWrite(9, HIGH); 
      break;   
    case 3:   //显示3
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH); 
      digitalWrite(5, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      break;   
    case 4:  //显示4
      digitalWrite(4, HIGH); 
      digitalWrite(5, HIGH); 
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      break;  
    case 5:  //显示5
      digitalWrite(3, HIGH);
      digitalWrite(5, HIGH); 
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      break;
    case 6:  //显示6
      digitalWrite(3, HIGH);
      digitalWrite(5, HIGH); 
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      digitalWrite(9, HIGH); 
      break;    
    case 7:  //显示7
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH); 
      digitalWrite(7, HIGH);  
      break;
    case 8:  //显示8
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH); 
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      digitalWrite(9, HIGH); 
      break;
    case 9:  //显示9
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH); 
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      break;
    case 0:  //显示默认
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      digitalWrite(9, HIGH); 
      break;
    default:
        digitalWrite(4, HIGH); 
        digitalWrite(5, HIGH); 
        digitalWrite(7, HIGH); 
        digitalWrite(8, HIGH);  
        digitalWrite(9, HIGH);   
    }
}
 
//清理显示内容
void displayClear(){
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW); 
  digitalWrite(6, LOW); 
  digitalWrite(7, LOW); 
  digitalWrite(8, LOW); 
  digitalWrite(9, LOW); 
}
 
//显示随机图案以混淆注意力
//使作弊图案显示时不易察觉。
void displayRandom(){
  int randomPin = random(3,9);
  digitalWrite(randomPin, HIGH);  
}
 
//显示作弊图案。
void displayCheat(int number){
  switch(number){
    case 1:  // 显示数字1作弊图案
      digitalWrite(3, HIGH);
      break;   
    case 2:  // 显示数字2作弊图案
      digitalWrite(6, HIGH); 
      break;   
    case 3:  // 显示数字3作弊图案
      digitalWrite(4, HIGH); ;
      break;   
    case 4:  // 显示数字4作弊图案
      digitalWrite(5, HIGH); 
      break;  
    case 5:  // 显示数字5作弊图案
      digitalWrite(9, HIGH); 
      break;
    case 6:  // 显示数字6作弊图案
      digitalWrite(7, HIGH);   
      break;    
    case 7: // 显示数字7作弊图案
      digitalWrite(8, HIGH);
      break;
    case 8: // 显示数字8作弊图案
      digitalWrite(6, HIGH);
      digitalWrite(4, HIGH);
      break;
    case 9: // 显示数字9作弊图案
      digitalWrite(9, HIGH);
      digitalWrite(7, HIGH);
      break;
    case 0: // 显示数字0作弊图案
      digitalWrite(3, HIGH);
      digitalWrite(8, HIGH); 
      break;
    }
}

十、模拟输出

1、analogWrite

(1)演示电路:

image.png

image.png

(2)相关函数及原理

image.png

说明

将一个模拟数值写进Arduino引脚。这个操作可以用来控制LED的亮度, 或者控制电机的转速。Arduino每一次对引脚执行analogWrite()指令,都会给该引脚一个固定频率的PWM信号。PWM信号的频率大约为490Hz.

在Arduino UNO控制器中,5号引脚和6号引脚的PWM频率为980Hz。在一些基于ATmega168和ATmega328的Arduino控制器中,analogWrite()函数支持以下引脚: 3, 5, 6, 9, 10, 11。

在Arduino Mega控制其中,该函数支持引脚 2 – 13 和 44 – 46。使用ATmega8的Arduino控制器中,该函数只支持引脚 9, 10, 11.

在调用analogWrite()函数前,不是必须使用pinMode()函数来设置该引脚,当然设置也是可以的。

语法

analogWrite(pin, value)

参数

pin:被读取的模拟引脚号码
value:0到255之间的PWM频率值, 0对应off, 255对应on

返回值

(3)示例程序

/*
25 模拟输出1 - analogWrite
太极创客
www.taichi-maker.com

此程序用于太极创客<<零基础入门学用Arduino教程>> 
25 模拟输出1 - analogWrite

演示如何通过两个按键开关通过analogWrite指令
进行模拟输出操作。具体电路和其它信息请参考
太极创客网站本教程相关页面。

2017-04-28
*/
boolean pushButton1;   // 创建布尔型变量用来存储按键开关1的电平状态
boolean pushButton2;   // 创建布尔型变量用来存储按键开关2的电平状态
int ledPin = 9;        //LED引脚号
int brightness = 128;  //LED亮度参数

void setup() {
  // put your setup code here, to run once:
  pinMode(2, INPUT_PULLUP); //将引脚2设置为输入上拉模式
  pinMode(8, INPUT_PULLUP); //将引脚8设置为输入上拉模式
  pinMode(ledPin, OUTPUT);  //将LED引脚设置为输出模式
  Serial.begin(9600);      //启动串口通讯
}

void loop() {
  // put your main code here, to run repeatedly:
  pushButton1 = digitalRead(2); //读取引脚2电平状态并将其赋值给布尔变量
  pushButton2 = digitalRead(8); //读取引脚8电平状态并将其赋值给布尔变量
  
  if (!pushButton1 && brightness > 0){     // 当按下按键开关1并且LED亮度参数大于0
    brightness--;                          // 减低LED亮度参数
                                           //(brightness-- 相当于  brightness = brightness - 1;)
  } else if (!pushButton2 && brightness < 255) {  //当按下按键开关2并且LED亮度参数小于255
    brightness++;                                 //增加LED亮度参数
                                                  //(brightness++ 相当于  brightness = brightness + 1;)
  }
  analogWrite(ledPin, brightness);         //模拟输出控制LED亮度
  Serial.println(brightness);              //将LED亮度参数显示在串口监视器上
  delay(10);
}

2、PWM

(1)LED灯的亮度

image.png

这个就是我们之前Blink程序的效果。如果我们把时间单位改成毫秒会怎样?


image.png

image.png

image.png

image.png

image.png

(2)analogWrite函数与亮灭时间比的关系

image.png

image.png

不同开发板的亮度时间周期单位是不同的,不一定是2毫秒。

3、呼吸灯

电路图:


image.png

程序:

/*
27 模拟输出3 - for
太极创客
www.taichi-maker.com

此程序用于太极创客<<零基础入门学用Arduino教程>> 
27 模拟输出3 - for

演示如何通过for循环语句实现LED明暗交替(呼吸灯)效果。

2017-04-28
*/
void setup() {
  pinMode(9, OUTPUT);      //设置9号引脚为输出模式
  Serial.begin(9600);     //启动串口通讯
}

void loop() {
  // LED由暗到明
  for (int brightness = 0; brightness <= 255; brightness++){
    analogWrite(9, brightness);   
    Serial.println(brightness);
    delay(10);
  }
  
  // LED由明到暗  
  for (int brightness = 255; brightness >=0 ; brightness--){
    analogWrite(9, brightness);
    Serial.println(brightness);
    delay(10);
  }
}

3、电位器

(1)什么是电位器

image.png
电位器的电路符号图

电位器的旋钮是可以调节的,旋钮向那个方向旋转,那个引脚的电阻值就减小,但是整个电位器的电阻值并不会变。

(2)电位器的应用

分压电路

通常来说电位器的接入如下图所示,不过你反过来接也可以。


image.png

(2)analogRead函数

说明

本指令用于从Arduino的模拟输入引脚读取数值。Arduino控制器有多个10位数模转换通道。这意味着Arduino可以将0-5伏特的电压输入信号映射到数值0-1023。

换句话说,我们可以将5伏特等分成1024份。0伏特的输入信号对应着数值0,而5伏特的输入信号对应着1023。

例:
当模拟输入引脚的输入电压为2.5伏特的时候,该引脚的数值为512。
(2.5伏特 / 5伏特 = 0.5, 1024 X 0.5 ?=512)

引脚的输入范围以及解析度可以使用analogReference()指令进行调整。

Arduino控制器读取一次模拟输入需要消耗100微秒的时间(0.0001秒)。控制器读取模拟输入的最大频率是每秒10,000次。

注意:在模拟输入引脚没有任何连接的情况下,用analogRead()指令读取该引脚,这时获得的返回值为不固定的数值。这个数值可能受到多种因素影响,如将手靠近引脚也可能使得该返回值产生变化。

语法

analogRead(pin)

参数

pin:被读取的模拟引脚号码

返回值

0到1023之间的值

本节要用到的电路图

image.png

image.png

本节课的程序代码:

/*
  模拟输入
 
  本程序旨在演示如何使用analogRead()读取Arduino的引脚电平。
  通过调节电位器, A0引脚的输入电压将在0V-5V之间。
  该输入电压将被映射到数值0-1023之间,并显示在串口监视器中。
  
 电路连接:
   电位器中间引脚连接到模拟输入A0引脚
   电位器两端引脚分别连接在Arduino +5V和接地引脚
 
 太极创客 www.taichi-maker.com
 2017-01-08
 
 This example code is in the public domain.
 
 */
 
void setup() {
  // 串口通讯初始化(9600 bps):
  Serial.begin(9600);
}
 
void loop() {
  // 读取模拟输入值:
  int analogInputVal = analogRead(A0);
 
  // 将结果通过串口监视器显示:
  Serial.println(analogInputVal);
}

(3)电位器控制光的亮度

本节电路

image.png

image.png

image.png

示例程序

/*
  电位器模拟输出
 
 读取模拟输入引脚,并将读取到的数值映射到0 - 255之间。然后用该映射结果设置
 引脚9的LED亮度,同时通过串口监视器显示这一映射结果。
 
 电路连接:
     电位器中间引脚连接到模拟输入A0引脚
     电位器两端引脚分别连接在Arduino +5V和接地引脚
   * LED正极通过 限流电阻连接在Arduino的9号引脚
     LED负极接地
 
 太极创客
 2017-01-08
 http://www.taichi-maker.com
 
 This example code is in the public domain.
 
 */
 
void setup() {
  
  Serial.begin(9600);  // 串口通讯初始化(9600 bps)
  pinMode(9, OUTPUT);  // 设置9号引脚为输出模式
}
 
void loop() {
  int analogInputVal = analogRead(A0);  // 读取模拟输入值
 
  int brightness = map(analogInputVal, 0, 1023, 0, 255); //将模拟输入数值(0 - 1023)等比映射到模拟输出数值区间(0-255)内
  
  analogWrite(9, brightness);  //根据模拟输入值调节LED亮度
 
  // 将结果通过串口监视器显示:
  Serial.print("analogInputVal = ");
  Serial.println(analogInputVal);
  
  Serial.print("brightness = ");
  Serial.println(brightness);
  
  Serial.println("");
}
image.png
image.png
image.png
image.png
image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容