Arduino#
当我们拿到Arduino开发板时,首先我们要安装Arduino IDE和驱动,相关文件我们可以在官网上找到,以下链接是包含各种系统、各种版本的Arduino IDE和驱动任你选择。
https://www.arduino.cc/en/Main/OldSoftwareReleases#1.5.x
下面我们介绍下Arduino-1.5.6 版本IDE在Windows系统的安装方法。
下载下来的文件是一个arduino-1.5.6-r2-windows.zip的压缩文件夹,解压出来到硬盘。
双击Arduino-1.5.6 .exe文件

然后

然后

等待安装完成.点击close,安装完成。

1.5.6版本安装后的样子。

接下来是开发板驱动的安装,这次我们安装的是Keyes UNO R3开发板的驱动,Keyes 2560 R3开发板安装驱动方法和这个类似,驱动文件可以用同一个文件。
不同的系统,安装驱动的方法也有一些细小的区别,下面我们介绍在WIN 7系统安装驱动的方法。
第一次Keyes UNO R3开发板连接电脑时,点击计算机–属性–设备管理器,显示如下图。

点击 Unknown device 安装驱动,如下图。

进入下图,选择

找到Arduino安装位置的drivers文件夹

点击“Next”,今天下图选择,开始安装驱动

安装驱动完成,出现下图点击Close。

这样驱动就装好了。点击计算机–属性–设备管理器,我们可看见如下图。

Arduino IDE的使用方法#
Keyes UNO R3 开发板的USB驱动安装成功之后,我们可以在Windows设备管理器中找到相应的串口。
下面示范第一个程序的烧写,串口监视器中显示“Hello World!”。
测试代码为:
int val; // 定义一个整型变量val,用于存储串口读取的值
int ledpin = 13; // 定义LED引脚为数字口13
void setup() // 初始化函数
{
Serial.begin(9600); // 初始化串口通信,波特率9600
pinMode(ledpin, OUTPUT); // 设置LED引脚为输出模式
}
void loop() // 主循环函数
{
val = Serial.read(); // 读取串口数据并赋值给val
if (val == 'R') // 如果接收到字符'R'
{
digitalWrite(ledpin, HIGH); // 点亮LED
delay(500); // 延时500ms
digitalWrite(ledpin, LOW); // 熄灭LED
delay(500); // 延时500ms
Serial.println("Hello World!"); // 串口打印"Hello World!"
}
}
我们打开Arduino 的软件,编写一段程序让Keyes UNO R3开发板接受到我们发的指令就显示“Hello World!”字符串;我们再借用一下Keyes UNO R3 开发板上的 D13的指示灯,让Keyes UNO R3开发板接受到指令时指示灯闪烁一下,再显示“Hello World!”。
打开Arduino 的软件,设置板,如下。

设置COM端口,如下

点击
编译程序,检查程序是否错误;点击
上传程序;Keyes UNO R3 开发板设置OK后右下脚显示如下图,和设备管理器中显示一致。

上传成功,输入R,点击发送,Keyes UNO R3 开发板上的 D13的指示灯闪烁一次,串口监视器中显示 Hello World! 如下图

那么恭喜你,你的第一个程序已经成功了!!!
实验课程#
实验一 LED 闪烁实验#
实验说明
LED 闪烁实验是比较基础的实验之一,上一个“ Hello World!”实验里已经利用到了Arduino 自带的LED,这次我们利用其他I/O口和外接直插LED 灯来完成这个实验。
实验器材
开发板*1
USB线*1
LED*1
220Ω 电阻*1
面包板*1
正标线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
int led = 2; // 定义数字口2为LED控制引脚
void setup() // 初始化函数
{
pinMode(led, OUTPUT); // 设置LED引脚为输出模式
}
void loop() // 主循环函数
{
digitalWrite(led, HIGH); // 点亮LED
delay(2000); // 延时2000ms(2秒)
digitalWrite(led, LOW); // 熄灭LED
delay(2000); // 延时2000ms(2秒)
}
测试结果
下载完程序就可以看到我们的IO口外接小灯在闪烁了,这样我们的实验现象为LED不停闪烁,间隔大约为两秒。
实验二 呼吸灯实验#
实验说明
上一课程中我们只是控制LED的亮和灭,那么我们可以怎么控制LED的亮度呢?本课程中我们把LED接到PWM口中,然后通过改变PWM数值,调节LED亮度,使LED逐渐变亮,和逐渐变暗,从而达到呼吸灯的效果。
实验器材
开发板*1
USB线*1
LED*1
220Ω 电阻*1
面包板*1
正标线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
int ledPin = 3; // 定义数字口3为LED控制引脚(支持PWM调光)
void setup() // 初始化函数
{
pinMode(ledPin, OUTPUT); // 设置LED引脚为输出模式
}
void loop() // 主循环函数
{
// LED逐渐变亮(0 → 255)
for (int a = 0; a <= 255; a++)
{
analogWrite(ledPin, a); // PWM输出亮度值(0最暗,255最亮)
delay(10); // 延时10ms,控制渐变速度
}
// LED逐渐变暗(255 → 0)
for (int a = 255; a >= 0; a--)
{
analogWrite(ledPin, a); // PWM输出亮度值
delay(10); // 延时10ms,控制渐变速度
}
delay(1000); // 循环间隔1秒
}
测试结果
下载完程序就可以看到我们的IO口外接小灯显示出呼吸灯的效果,小灯先逐渐变亮,后逐渐变暗,循环交替。
实验三 广告灯实验#
实验说明
在生活中我们经常会看到一些由各种颜色的led灯组成的广告牌,广告牌上各个位置上癿led灯不断的变话,形成各种效果。本节实验就是利用led灯编程模拟广告灯效果。
实验器材
开发板*1
USB线*1
LED*5
220Ω 电阻*5
面包板*1
正标线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
int BASE = 2; //第一个 LED 接的 I/O 口
int NUM = 5; //LED 的总数
void setup()
{
for (int i = BASE; i < BASE + NUM; i ++)
{
pinMode(i, OUTPUT); //设定数字I/O口为输出
}
}
void loop()
{
for (int i = BASE; i < BASE + NUM; i ++)
{
digitalWrite(i, HIGH); //设定数字I/O口输出为"高",即逐渐开灯
delay(200); //延迟
}
for (int i = BASE; i < BASE + NUM; i ++)
{
digitalWrite(i, LOW); //设定数字I/O口输出为"低",即逐渐关灯
delay(200); //延迟
}
}
测试结果
下载完程序就可以看到我们的IO口外接小灯先逐渐变亮,然后逐渐变暗,循环交替。
实验四 按键控制LED实验#
实验说明
I/O 口的意思即为INPUT 接口和OUTPUT接口,到目前为止我们设计的小灯实验都还只是应用到Arduino 的I/O口的输出功能,这个实验我们来尝试一下使用Arduino的I/O口的输入功能即为读取外接设备的输出值,我们用一个按键和一个LED小灯完成一个输入输出结合使用的实验,让大家能简单了解I/O 的作用。
实验器材
开发板 *1
USB线*1
LED*1
轻触按键*1
220Ω 电阻*1
10KΩ 电阻*1
面包板*1
正标线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
int ledPin = 11; //定义数字口11
int inputPin = 3; //定义数字口3
void setup()
{
pinMode(ledPin, OUTPUT); //将ledPin设置为输出
pinMode(inputPin, INPUT); //将inputPin设置为输入
}
void loop()
{
int val = digitalRead(inputPin);
//设置数字变量val,读取到数字口3的数值,并赋值给 val
if (val == LOW) //当val为低电平时,LED变暗
{
digitalWrite(ledPin, LOW); // LED变暗
}
else
{
digitalWrite(ledPin, HIGH); // LED亮起
}
}
测试结果
下载完程序,上电后,当按键按下时小灯亮起,否则小灯不亮。
实验五 抢答器实验#
实验说明
完成上面的实验以后相信已经有很多朋友可以独立完成这个实验了,我们可以模拟抢答器实验。实验中我们利用4个按键控制3个小灯,一个按键用做复位按键;另外3个按键对应3个小灯,用于抢答。
实验器材
开发板*1
USB线*1
keyes 插件RGB模块*1
轻触按键*4
10KΩ 电阻*4
面包板*1
正标线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
int redled = 8; //红色LED 输出
int yellowled = 7; //黄色LED输出
int greenled = 6; //绿色LED输出
int redpin = 5; //红色按键引脚
int yellowpin = 4; //黄色按键引脚
int greenpin = 3; //绿色按键引脚
int restpin = 2; //复位按键引脚定义
int red;
int yellow;
int green;
void setup()
{
pinMode(redled, OUTPUT);
pinMode(yellowled, OUTPUT);
pinMode(greenled, OUTPUT);
pinMode(redpin, INPUT);
pinMode(yellowpin, INPUT);
pinMode(greenpin, INPUT);
}
void loop() //按键循环扫描。
{
red = digitalRead(redpin);
yellow = digitalRead(yellowpin);
green = digitalRead(greenpin);
if(red == LOW)
RED_YES();
if(yellow == LOW)
YELLOW_YES();
if(green == LOW)
GREEN_YES();
}
void RED_YES() //一直执行红灯亮,直到复位键按下,结束循环
{
while(digitalRead(restpin) == 1)
{
digitalWrite(redled, HIGH);
digitalWrite(greenled, LOW);
digitalWrite(yellowled, LOW);
}
clear_led();
}
void YELLOW_YES() //一直执行黄灯亮,直到复位键按下,结束循环
{
while(digitalRead(restpin) == 1)
{
digitalWrite(redled, LOW);
digitalWrite(greenled, LOW);
digitalWrite(yellowled, HIGH);
}
clear_led();
}
void GREEN_YES() //一直执行绿灯亮,直到复位键按下,结束循环
{
while(digitalRead(restpin) == 1)
{
digitalWrite(redled, LOW);
digitalWrite(greenled, HIGH);
digitalWrite(yellowled, LOW);
}
clear_led();
}
void clear_led() //清除LED
{
digitalWrite(redled, LOW);
digitalWrite(greenled, LOW);
digitalWrite(yellowled, LOW);
}
测试结果
下载完程序,上电后,一个简单的抢答器就做好了。
实验六 电位器调控灯光亮度实验#
实验说明
在第二课程中我们直接通过PWM口控制灯的亮度,从而达到呼吸灯的效果。在这课程中我们通过一个电位器,利用电位器调节PWM值,从而控制灯的亮度。
实验器材
开发板*1
USB线*1
LED*1
220Ω 电阻*1
可调电位器*1
面包板*1
正标线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
int ledpin = 11; //定义数字接口11(PWM 输出)
void setup()
{
pinMode(ledpin, OUTPUT); //定义数字接口11 为输出
Serial.begin(9600); //设置波特率为9600
}
void loop()
{
int val = analogRead(0); //读取模拟口A0口的值
val = map(val, 0, 1023, 0, 255); //从0-1023映射到0-255
Serial.println(val); //显示val 变量
analogWrite(ledpin, val); // 打开LED 并设置亮度
delay(100); //延时0.1 秒
}
测试结果
下载完程序后。我们可以通过旋转可调电位器控制小灯的亮度,打开串口监视器,设置波特率为9600,就可看到调节LED亮度的PWM值。
实验七 感光灯实验#
实验说明
完成以上的各种实验后,我们对Arduino的应用也应该有一些认识和了解了,在基本的数字量输入输出和模拟量输入以及PWM的产生都掌握以后,我们就可以开始进行一些传感器的应用了。
本次实验我们先进行一个较为简单的光敏电阻的使用实验。光敏电阻既然是可以根据光强改变阻值的元件,自然也需要模拟口读取模拟值了,本实验可以借鉴电位器调控灯光亮度实验,将电位计换做光敏电阻实现当光强不同时LED小灯的亮度也会有相应的变化。
实验器材
开发板*1
USB线*1
LED*
220Ω 电阻*1
10KΩ 电阻*1
光敏电阻*1
面包板*1
正标线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
int ledpin = 11; //定义数字接口11(PWM 输出)
void setup()
{
pinMode(ledpin, OUTPUT); //定义数字接口11 为输出
Serial.begin(9600); //设置波特率为9600
}
void loop()
{
int val = analogRead(0); //读取模拟口A0口的值
Serial.println(val); //显示val 变量
val = map(val, 0, 1023, 0, 255); //从0-1023映射到0-255
analogWrite(ledpin, 255 - val); // 打开LED 并设置亮度
delay(10); //延时0.01 秒
}
测试结果
下载完程序后,光敏电阻感应到灯光越亮,小灯越暗;光敏电阻感应到灯光越暗,小灯越亮。打开串口监视器,设置波特率为9600,就可看到光敏电阻感应到外界光强所得的模拟值。
实验八 有源蜂鸣器实验#
实验说明
蜂鸣器可分为有源蜂鸣器和无源蜂鸣器两种。本课程中主要用到了有源蜂鸣器,有源蜂鸣器内部有一简单的振荡电路,能将恒定的直流电转化成一定频率的脉冲信号。实验中中我们只需要给蜂鸣器输入一个高电平信号,蜂鸣器响起。
实验器材
开发板*1
USB线*1
有源蜂鸣器*1
面包板*1
正标线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
int buzzer = 2; //定义数字口2
void setup()
{
pinMode(buzzer, OUTPUT); //设置buzzer为输出
}
void loop()
{
digitalWrite(buzzer, HIGH); //开启buzzer
delay(1000); //延迟1S
digitalWrite(buzzer, LOW); //关闭buzzer
delay(1000); //延迟1S
}
测试结果
下载完程序后,我们可以听到蜂鸣器响1秒,停止响起1秒,循环交替。
实验九 无源蜂鸣器实验#
实验说明
蜂鸣器可分为有源蜂鸣器和无源蜂鸣器两种。本课程中主要用到了无源蜂鸣器,无源蜂鸣器内部不带振荡源,直流信号无法令其鸣叫,须用方波驱动。
实验器材
开发板 *1
USB线*1
无源蜂鸣器*1
面包板*1
正标线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
code 1:
int buzzer = 3; //定义数字口3
void setup()
{
pinMode(buzzer, OUTPUT); //将buzzer设置为输出
}
void loop()
{
unsigned char i, j; //定义变量i,j
while(1)
{
for(i = 0; i < 80; i++) // 输出一个频率的声音
{
digitalWrite(buzzer, HIGH);
delay(1); //延迟1ms
digitalWrite(buzzer, LOW);
delay(1); //延迟1ms
}
for(i = 0; i < 100; i++) // 输出另一个频率的声音
{
digitalWrite(buzzer, HIGH);
delay(2); //延迟2ms
digitalWrite(buzzer, LOW);
delay(2); //延迟2ms
}
}
}
code 2:
#define D0 -1
#define D1 262
#define D2 293
#define D3 329
#define D4 349
#define D5 392
#define D6 440
#define D7 494
#define M1 523
#define M2 586
#define M3 658
#define M4 697
#define M5 783
#define M6 879
#define M7 987
#define H1 1045
#define H2 1171
#define H3 1316
#define H4 1393
#define H5 1563
#define H6 1755
#define H7 1971
// 列出全部D调的频率
#define WHOLE 1
#define HALF 0.5
#define QUARTER 0.25
#define EIGHTH 0.25
#define SIXTEENTH 0.625
// 列出所有节拍
int tune[] = // 根据简谱列出各频率
{
M3,M3,M4,M5,
M5,M4,M3,M2,
M1,M1,M2,M3,
M3,M2,M2,
M3,M3,M4,M5,
M5,M4,M3,M2,
M1,M1,M2,M3,
M2,M1,M1,
M2,M2,M3,M1,
M2,M3,M4,M3,M1,
M2,M3,M4,M3,M2,
M1,M2,D5,D0,
M3,M3,M4,M5,
M5,M4,M3,M4,M2,
M1,M1,M2,M3,
M2,M1,M1
};
float durt[] = // 根据简谱列出各节拍
{
1,1,1,1,
1,1,1,1,
1,1,1,1,
1+0.5,0.5,1+1,
1,1,1,1,
1,1,1,1,
1,1,1,1,
1+0.5,0.5,1+1,
1,1,1,1,
1,0.5,0.5,1,1,
1,0.5,0.5,1,1,
1,1,1,1,
1,1,1,1,
1,1,1,0.5,0.5,
1,1,1,1,
1+0.5,0.5,1+1,
};
int length;
int tonepin = 3; // 使用3号接口
void setup()
{
pinMode(tonepin, OUTPUT);
length = sizeof(tune) / sizeof(tune[0]); // 计算长度
}
void loop()
{
for(int x = 0; x < length; x++)
{
tone(tonepin, tune[x]);
delay(500 * durt[x]); // 根据节拍调节延时
noTone(tonepin);
}
delay(2000); // 每遍播放完后暂停2秒
}
测试结果
实验中我们提供了两个例程,上传例程1代码后,蜂鸣器会发出两种不同的声音,实验中,两种声音循环交替。上传例程2中代码后,蜂鸣器会想响起《欢乐颂》的曲子。
实验十 火焰报警实验#
实验说明
火焰传感器是机器人专门用来搜寻火源的传感器,本传感器对火焰特别灵敏。火焰传感器利用红外线对火焰非常敏感的特点,使用特制的红外线接收管来检测火焰,然后把火焰的亮度转化为高低变化的电平信号。
实验中,我们把火焰的亮度转化为高低变化的电平信号输入到UNO板中,然后控制蜂鸣器的响起。
实验器材
开发板*1
USB线*1
有源蜂鸣器*1
火焰传感器*1
10KΩ 电阻*1
面包板*1
正标线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
int flame = 7; // 定义火焰传感器接口为数字7接口
int Beep = 9; // 定义蜂鸣器接口为数字9接口
void setup()
{
pinMode(Beep, OUTPUT); // 定义Beep为输出接口
pinMode(flame, INPUT); // 定义flame为输入接口
}
void loop()
{
int val = digitalRead(flame); // 读取火焰传感器
if(val == HIGH) // 当检测到火焰时(数字口7为高电平)
{
digitalWrite(Beep, HIGH); // 蜂鸣器鸣响
}
else
{
digitalWrite(Beep, LOW); // 关闭蜂鸣器
}
delay(500); // 检测间隔500ms
}
测试结果
下载完程序后,我们可以模拟在有火焰时报警的情况,在没有火焰时一切正常,当有火焰时立刻报警做出提示。
实验十一 温馨水杯实验#
实验说明
LM35 是很常用且易用的温度传感器元件,将LM35温度传感器接到开发板上,通过算法可将读取的模拟值转换为实际的温度。
本实验中我们还外接了3个指示灯,在代码中我没设置在不同的温度范围,亮起不同颜色的指示灯。根据这个,我们完全可以做个温馨水杯,通过指示灯,我们就可以知道杯子里的水的冷热情况。
实验器材
开发板 *1
USB线*1
LM35DZ*1
LED*3
220Ω 电阻*3
面包板*1
正标线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
void setup()
{
Serial.begin(9600); // 初始化串口通信,波特率9600
pinMode(12, OUTPUT); // 设置12号引脚为输出模式
pinMode(11, OUTPUT); // 设置11号引脚为输出模式
pinMode(10, OUTPUT); // 设置10号引脚为输出模式
}
void loop()
{
int vol = analogRead(A0) * (5.0 / 1023.0*100); // 读取A0模拟值并转换为温度值
Serial.print("Tep:"); // 串口打印温度标签(注意原代码拼写为"Tep")
Serial.print(vol); // 输出温度数值
Serial.println("C"); // 输出温度单位(摄氏度)
// 温度状态判断
if (vol<28) // 当温度低于28度时
{
digitalWrite(12, HIGH); // 开启12号引脚(低温指示灯)
digitalWrite(11, LOW); // 关闭11号引脚
digitalWrite(10, LOW); // 关闭10号引脚
}
else if (vol>=28 && vol<=30) // 当温度在28-30度之间时
{
digitalWrite(12, LOW); // 关闭12号引脚
digitalWrite(11, HIGH); // 开启11号引脚(正常温度指示灯)
digitalWrite(10, LOW); // 关闭10号引脚
}
else if (vol>30) // 当温度高于30度时
{
digitalWrite(12, LOW); // 关闭12号引脚
digitalWrite(11, LOW); // 关闭11号引脚
digitalWrite(10, HIGH); // 开启10号引脚(高温指示灯)
}
}
测试结果
下载完程序后,打开串口监视器,设置波特率为9600,就可看到当前的温度。当温度大于30摄氏度时,红色指示灯亮起,其他指示灯熄灭;当温度大于等于28摄氏度且小于等于30摄氏度时,红色指示灯熄灭,黄色指示灯亮起;当温度小于28摄氏度时,黄色指示灯熄灭,蓝色指示灯亮起。
实验十二 魔术光杯实验#
实验说明
倾斜开关的工作原理是当开关一端低于水平位置倾斜,开关寻通;当另一端低于水平位置倾斜,开关停止。魔术光杯实验原理是利用 PWM调光的原理,两个LED的亮度发生变化。
这个实验中倾斜开关提供数字信号,触发 PWM的调节,通过程序的设计,我们就能看到类似于两组装满光的杯子倒来倒去的效果了。
实验器材
开发板*1
USB线*1
LED*2
倾斜开关*2
220Ω 电阻*2
10KΩ 电阻*2
面包板*1
正标线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
int LedPinA = 5; // 定义数字口5(PWM输出控制LED)
int LedPinB = 6; // 定义数字口6(PWM输出控制LED)
int ButtonPinA = 7; // 定义数字口7(按钮A输入)
int ButtonPinB = 4; // 定义数字口4(按钮B输入)
int buttonStateA = 0; // 存储按钮A的状态
int buttonStateB = 0; // 存储按钮B的状态
int brightnessA = 0; // LEDA亮度初始值(0-255)
int brightnessB = 255; // LEDB亮度初始值(0-255)
void setup() // 初始化函数
{
Serial.begin(9600); // 初始化串口通信(波特率9600)
pinMode(LedPinA, OUTPUT); // 设置数字口5为输出模式
pinMode(LedPinB, OUTPUT); // 设置数字口6为输出模式
pinMode(ButtonPinA, INPUT); // 设置数字口7为输入模式
pinMode(ButtonPinB, INPUT); // 设置数字口4为输入模式
}
void loop() // 主循环函数
{
// 按钮A控制LEDB亮度
buttonStateA = digitalRead(ButtonPinA); // 读取按钮A状态
if (buttonStateA == HIGH && brightnessA != 255) // 按下按钮A且亮度未达最大值
{
brightnessA++; // 亮度增加
delay(10); // 延时10ms(防抖+渐变效果)
}
if (buttonStateA == LOW && brightnessA != 0) // 松开按钮A且亮度未达最小值
{
brightnessA--; // 亮度减少
delay(10); // 延时10ms
}
analogWrite(LedPinB, brightnessA); // 输出PWM信号控制LEDB亮度
Serial.print(brightnessA); // 串口打印LEDB亮度值
Serial.print(" "); // 打印空格分隔数据
// 按钮B控制LEDA亮度
buttonStateB = digitalRead(ButtonPinB); // 读取按钮B状态
if (buttonStateB == HIGH && brightnessB != 0) // 按下按钮B且亮度未达最小值
{
brightnessB--; // 亮度减少
delay(10); // 延时10ms
}
if (buttonStateB == LOW && brightnessB != 255) // 松开按钮B且亮度未达最大值
{
brightnessB++; // 亮度增加
delay(10); // 延时10ms
}
analogWrite(LedPinA, brightnessB); // 输出PWM信号控制LEDA亮度
Serial.println(brightnessB); // 串口打印LEDA亮度值并换行
delay(5); // 主循环延时5ms(降低CPU占用)
测试结果
按照上图接好线,烧录好代码,上电后,将两个倾斜开关同时倾斜一边,一个LED逐渐变暗,同时另一个逐渐变亮,最终一个LED完全熄灭,一个LED最亮;在串口监视器中看到对应具体数值变化,如下图。当倾斜另一边中,现象一样,方向相反。

实验十三 红外遥控解码实验#
实验说明
通用红外遥控系统由发射和接收两大部分组成。本实验中发射部分就是遥控器,接收部分就是红外接收 VS1838B。红外接收 VS1838B是集接收、放大、解调一体的器件,它内部IC就已经完成了解调,输出的就是数字信号。

实验器材
开发板*1
USB线*1
红外遥控*1
红外接收 VS1838B*1
面包板*1
正标线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
#include <IRremote.h> // 引入红外遥控库
int RECV_PIN = 11; // 定义红外接收器连接的数字口11
IRrecv irrecv(RECV_PIN); // 创建红外接收对象
decode_results results; // 存储解码结果的结构体
void setup() // 初始化函数
{
Serial.begin(9600); // 初始化串口通信(波特率9600)
irrecv.enableIRIn(); // 启动红外接收功能
}
void loop() // 主循环函数
{
if (irrecv.decode(&results)) // 检测是否接收到红外信号
{
Serial.println(results.value, HEX); // 以16进制格式输出红外编码
irrecv.resume(); // 准备接收下一个红外信号
}
}
测试结果
下载完程序,上电后,红外遥控对准红外接收传感器发送信号,我们可以在串口监视器总看到相应按键的编码,如下图。


实验十四 一位数码管显示实验#
实验说明
数码管是一种半导体发光器件,其基本单元是发光二极管。数码管按段数分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元(多一个小数点显示),本实验所使用的是八段数码管。数码管共有七段显示数字的段,还有一个显示小数点的段。当让数码管显示数字时,只要将相应的段点亮即可。
实验器材
开发板 *1
USB线*1
一位数码管*1
220Ω 电阻*8
面包板*1
正标线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
//设置控制各段的数字IO 脚
int a=7;//定义数字接口7 连接a 段数码管
int b=6;// 定义数字接口6 连接b 段数码管
int c=5;// 定义数字接口5 连接c 段数码管
int d=10;// 定义数字接口11 连接d 段数码管
int e=11;// 定义数字接口10 连接e 段数码管
int f=8;// 定义数字接口8 连接f 段数码管
int g=9;// 定义数字接口9 连接g 段数码管
int dp=4;// 定义数字接口4 连接dp 段数码管
void digital_1(void) //显示数字1
{
unsigned char j;
digitalWrite(c,HIGH);//给数字接口5 引脚高电平,点亮c 段
digitalWrite(b,HIGH);//点亮b 段
for(j=7;j<=11;j++)//熄灭其余段
digitalWrite(j,LOW);
digitalWrite(dp,LOW);//熄灭小数点DP 段
}
void digital_2(void) //显示数字2
{
unsigned char j;
digitalWrite(b,HIGH);
digitalWrite(a,HIGH);
for(j=9;j<=11;j++)
digitalWrite(j,HIGH);
digitalWrite(dp,LOW);
digitalWrite(c,LOW);
digitalWrite(f,LOW);
}
void digital_3(void) //显示数字3
{
unsigned char j;
digitalWrite(g,HIGH);
digitalWrite(d,HIGH);
for(j=5;j<=7;j++)
digitalWrite(j,HIGH);
digitalWrite(dp,LOW);
digitalWrite(f,LOW);
digitalWrite(e,LOW);
}
void digital_4(void) //显示数字4
{
digitalWrite(c,HIGH);
digitalWrite(b,HIGH);
digitalWrite(f,HIGH);
digitalWrite(g,HIGH);
digitalWrite(dp,LOW);
digitalWrite(a,LOW);
digitalWrite(e,LOW);
digitalWrite(d,LOW);
}
void digital_5(void) //显示数字5
{
unsigned char j;
for(j=7;j<=9;j++)
digitalWrite(j,HIGH);
digitalWrite(c,HIGH);
digitalWrite(d,HIGH);
digitalWrite(dp,LOW);
digitalWrite(b,LOW);
digitalWrite(e,LOW);
}
void digital_6(void) //显示数字6
{
unsigned char j;
for(j=7;j<=11;j++)
digitalWrite(j,HIGH);
digitalWrite(c,HIGH);
digitalWrite(dp,LOW);
digitalWrite(b,LOW);
}
void digital_7(void) //显示数字7
{
unsigned char j;
for(j=5;j<=7;j++)
digitalWrite(j,HIGH);
digitalWrite(dp,LOW);
for(j=8;j<=11;j++)
digitalWrite(j,LOW);
}
void digital_8(void) //显示数字8
{
unsigned char j;
for(j=5;j<=11;j++)
digitalWrite(j,HIGH);
digitalWrite(dp,LOW);
}
void setup()
{
int i;//定义变量
for(i=4;i<=11;i++)
pinMode(i,OUTPUT);//设置4~11 引脚为输出模式
}
void loop()
{
while(1)
{
digital_1();//显示数字1
delay(2000);//延时2s
digital_2();//显示数字2
delay(1000); //延时1s
digital_3();//显示数字3
delay(1000); //延时1s
digital_4();//显示数字4
delay(1000); //延时1s
digital_5();//显示数字5
delay(1000); //延时1s
digital_6();//显示数字6
delay(1000); //延时1s
digital_7();//显示数字7
delay(1000); //延时1s
digital_8();//显示数字8
delay(1000); //延时1s
}
}
测试结果
下载完程序后,数码管循环显示1~8 数字。
实验十五 74HC595驱动一位数码管实验#
实验说明
上一个实验中我们直接把用开发板控制一位数码管,需要占用了较多的数字口,本实验中我们添加了一个74HC595芯片控制一位数码管,只需要用3个数字口就可以控制8个LED灯,具体设置方法可以参照以下表格。
Q7 |
Q6 |
Q5 |
Q4 |
Q3 |
Q2 |
Q1 |
Q0 |
||
|---|---|---|---|---|---|---|---|---|---|
a |
b |
c |
d |
e |
f |
g |
dp |
||
0 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
252 |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
96 |
2 |
1 |
1 |
0 |
1 |
1 |
0 |
1 |
0 |
218 |
3 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
0 |
242 |
4 |
0 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
102 |
5 |
1 |
0 |
1 |
1 |
0 |
1 |
1 |
0 |
182 |
6 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
0 |
190 |
7 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
224 |
8 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
254 |
9 |
1 |
1 |
1 |
1 |
0 |
1 |
1 |
0 |
246 |
实验器材
开发板*1
USB线*1
74HC595*1
一位数码管*1
220Ω 电阻*8
面包板*1
正标接线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
int latchPin = 4;
int clockPin = 5;
int dataPin = 2; //这里定义了那三个脚
void setup ()
{
pinMode(latchPin,OUTPUT);
pinMode(clockPin,OUTPUT);
pinMode(dataPin,OUTPUT); //让三个脚都是输出状态
}
void loop()
{
int a[10]={
246,254,224,190,182,102,242,218,96,252};
//定义功能数组,数组依次为数码管得定义
for(int x=9; x>-1 ;x-- ) //倒数功能循环
{
digitalWrite(latchPin,LOW);
shiftOut(dataPin,clockPin,MSBFIRST,a[x]); //显示数组a[x]
digitalWrite(latchPin,HIGH);
delay(1000);
}
}
测试结果
下载完程序后,数码管循环显示0~9 数字。
实验十六 舵机控制实验#
实验说明
舵机是一种位置伺服的驱动器,主要是由外壳、电路板、无核心马达、齿轮与位置检测
器所构成。舵机有很多规格,但所有的舵机都有外接三根线,分别用棕、红、橙三种颜
色进行区分,由于舵机品牌不同,颜色也会有所差异,棕色为接地线,红色为电源正极
线,橙色为信号线。
舵机的转动的角度是通过调节PWM(脉冲宽度调制)信号的占空比来实现的,标准PWM
(脉冲宽度调制)信号的周期固定为20ms(50Hz),理论上脉宽分布应在1ms到2ms
之间,但是,事实上脉宽可由0.5ms 到2.5ms 之间,脉宽和舵机的转角0°~180°相
对应。有一点值得注意的地方,由于舵机牌子不同,对于同一信号,不同牌子的舵机旋
转的角度也会有所不同。
实验器材
开发板*1
USB线*1
舵机*1
正标线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
程序A:
int servopin=9; //定义数字接口9 连接伺服舵机信号线
int myangle; //定义角度变量
int pulsewidth; //定义脉宽变量
int val;
void servopulse(int servopin,int myangle) //定义一个脉冲函数
{
pulsewidth=(myangle*11)+500; //将角度转化为500-2480 的脉宽值
digitalWrite(servopin,HIGH); //将舵机接口电平至高
delayMicroseconds(pulsewidth); //延时脉宽值的微秒数
digitalWrite(servopin,LOW); //将舵机接口电平至低
delay(20-pulsewidth/1000);
}
void setup()
{
pinMode(servopin,OUTPUT); //设定舵机接口为输出接口
Serial.begin(9600); //连接到串行端口,波特率为9600
Serial.println("servo=o_seral_simple ready");
}
void loop() //将0 到9 的数转化为0 到180 角度,并让LED 闪烁相应数的次数
{
val=Serial.read(); //读取串行端口的值
if(val>='0'&&val<='9')
{
val=val-'0'; //将特征量转化为数值变量
val=val*(180/9); //将数字转化为角度
Serial.print("moving servo to ");
Serial.print(val,DEC);
Serial.println();
for(int i=0;i<=50;i++) //给予舵机足够的时间让它转到指定角度
{
servopulse(servopin,val); //引用脉冲函数
}
}
}
程序B:
#include <Servo.h>
Servo myservo; //定义舵机变量名
void setup()
{
myservo.attach(9); //定义舵机接口(9、10 都可以,缺点只能控制2 个)
}
void loop()
{
myservo.write(90); //设置舵机旋转的角度
}
测试结果
程序A 结果:
在串口监视器中输入数字点击发送,舵机转动到所对应的角度数的位置,并将角度打印显示到屏幕上。
程序B结果:
舵机自己转动到90度位置。
实验十七 四位数码管显示数字实验#
实验说明
在实验十五中我们使用开发板驱动一个一位数码管,本实验我们使用开发板驱动一个共阴四位数码管。驱动数码管限流电阻肯定是必不可少的,限流电阻有两种接法,一种是在d1-d4阴极接,总共接4颗。这种接法好处是需求电阻比较少,但是会产生每一位上显示不同数字亮度会不一样,1最亮,8最暗。另外一种接法就是在其他8个引脚上接,这种接法亮度显示均匀,但是用电阻较多。本次实验使用8颗220Ω电阻。
四位数码管总共有12个引脚,小数点朝下正放在面前时,左下角为1,其他管脚顺序为逆时针旋转。左上角为最大的12号管脚。

四位数码管原理图如下

实验器材
开发板*1
USB线*1
四位数码管*1
220Ω 电阻*8
面包板*1
正标线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
// 数码管段选引脚定义(a-g, dp)
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 5;
int f = 6;
int g = 7;
int dp = 8;
// 数码管位选引脚定义(4位数码管)
int d4 = 9;
int d3 = 10;
int d2 = 11;
int d1 = 12;
// 全局变量定义
long n = 1230; // 初始显示值(未使用)
int x = 100; // 变量(未使用)
int del = 55; // 时钟微调参数(未使用)
void setup()
{
// 初始化所有引脚为输出模式
pinMode(d1, OUTPUT);
pinMode(d2, OUTPUT);
pinMode(d3, OUTPUT);
pinMode(d4, OUTPUT);
pinMode(a, OUTPUT);
pinMode(b, OUTPUT);
pinMode(c, OUTPUT);
pinMode(d, OUTPUT);
pinMode(e, OUTPUT);
pinMode(f, OUTPUT);
pinMode(g, OUTPUT);
pinMode(dp, OUTPUT);
}
/////////////////////////////////////////////////////////////
void loop()
{
// 计数器变量初始化
int a=0; // 千位
int b=0; // 百位
int c=0; // 十位
int d=0; // 个位
unsigned long currentMillis = millis();
// 主计数循环
while(d>=0)
{
// 每秒更新一次显示
while(millis()-currentMillis<1000)
{
// 动态扫描显示4位数码管
Display(1,a); // 显示千位
Display(2,b); // 显示百位
Display(3,c); // 显示十位
Display(4,d); // 显示个位
}
currentMillis = millis();
// 数字递增逻辑
d++;
if (d>9) // 个位进位
{
c++;
d=0;
}
if (c>9) // 十位进位
{
b++;
c=0;
}
if (b>9) // 百位进位
{
a++;
b=0;
}
if (a>9) // 千位归零
{
a=0;
b=0;
c=0;
d=0;
}
}
}
///////////////////////////////////////////////////////////////
// 位选函数(选择要显示的数码管位)
void WeiXuan(unsigned char n)
{
switch (n)
{
case 1: // 选择第1位
digitalWrite(d1, LOW);
digitalWrite(d2, HIGH);
digitalWrite(d3, HIGH);
digitalWrite(d4, HIGH);
break;
case 2: // 选择第2位
digitalWrite(d1, HIGH);
digitalWrite(d2, LOW);
digitalWrite(d3, HIGH);
digitalWrite(d4, HIGH);
break;
case 3: // 选择第3位
digitalWrite(d1, HIGH);
digitalWrite(d2, HIGH);
digitalWrite(d3, LOW);
digitalWrite(d4, HIGH);
break;
case 4: // 选择第4位
digitalWrite(d1, HIGH);
digitalWrite(d2, HIGH);
digitalWrite(d3, HIGH);
digitalWrite(d4, LOW);
break;
default: // 默认关闭所有位选
digitalWrite(d1, HIGH);
digitalWrite(d2, HIGH);
digitalWrite(d3, HIGH);
digitalWrite(d4, HIGH);
break;
}
}
// 数字0-9的显示函数(共阴极数码管)
void Num_0() // 显示数字0
{
digitalWrite(a, HIGH);
digitalWrite(b, HIGH);
digitalWrite(c, HIGH);
digitalWrite(d, HIGH);
digitalWrite(e, HIGH);
digitalWrite(f, HIGH);
digitalWrite(g, LOW);
digitalWrite(dp, LOW);
}
void Num_1() // 显示数字1
{
digitalWrite(a, LOW);
digitalWrite(b, HIGH);
digitalWrite(c, HIGH);
digitalWrite(d, LOW);
digitalWrite(e, LOW);
digitalWrite(f, LOW);
digitalWrite(g, LOW);
digitalWrite(dp, LOW);
}
void Num_2() // 显示数字2
{
digitalWrite(a, HIGH);
digitalWrite(b, HIGH);
digitalWrite(c, LOW);
digitalWrite(d, HIGH);
digitalWrite(e, HIGH);
digitalWrite(f, LOW);
digitalWrite(g, HIGH);
digitalWrite(dp, LOW);
}
void Num_3() // 显示数字3
{
digitalWrite(a, HIGH);
digitalWrite(b, HIGH);
digitalWrite(c, HIGH);
digitalWrite(d, HIGH);
digitalWrite(e, LOW);
digitalWrite(f, LOW);
digitalWrite(g, HIGH);
digitalWrite(dp, LOW);
}
void Num_4() // 显示数字4
{
digitalWrite(a, LOW);
digitalWrite(b, HIGH);
digitalWrite(c, HIGH);
digitalWrite(d, LOW);
digitalWrite(e, LOW);
digitalWrite(f, HIGH);
digitalWrite(g, HIGH);
digitalWrite(dp, LOW);
}
void Num_5() // 显示数字5
{
digitalWrite(a, HIGH);
digitalWrite(b, LOW);
digitalWrite(c, HIGH);
digitalWrite(d, HIGH);
digitalWrite(e, LOW);
digitalWrite(f, HIGH);
digitalWrite(g, HIGH);
digitalWrite(dp, LOW);
}
void Num_6() // 显示数字6
{
digitalWrite(a, HIGH);
digitalWrite(b, LOW);
digitalWrite(c, HIGH);
digitalWrite(d, HIGH);
digitalWrite(e, HIGH);
digitalWrite(f, HIGH);
digitalWrite(g, HIGH);
digitalWrite(dp, LOW);
}
void Num_7() // 显示数字7
{
digitalWrite(a, HIGH);
digitalWrite(b, HIGH);
digitalWrite(c, HIGH);
digitalWrite(d, LOW);
digitalWrite(e, LOW);
digitalWrite(f, LOW);
digitalWrite(g, LOW);
digitalWrite(dp, LOW);
}
void Num_8() // 显示数字8
{
digitalWrite(a, HIGH);
digitalWrite(b, HIGH);
digitalWrite(c, HIGH);
digitalWrite(d, HIGH);
digitalWrite(e, HIGH);
digitalWrite(f, HIGH);
digitalWrite(g, HIGH);
digitalWrite(dp, LOW);
}
void Num_9() // 显示数字9
{
digitalWrite(a, HIGH);
digitalWrite(b, HIGH);
digitalWrite(c, HIGH);
digitalWrite(d, HIGH);
digitalWrite(e, LOW);
digitalWrite(f, HIGH);
digitalWrite(g, HIGH);
digitalWrite(dp, LOW);
}
void Clear() // 清空数码管显示
{
digitalWrite(a, LOW);
digitalWrite(b, LOW);
digitalWrite(c, LOW);
digitalWrite(d, LOW);
digitalWrite(e, LOW);
digitalWrite(f, LOW);
digitalWrite(g, LOW);
digitalWrite(dp, LOW);
}
// 数字选择函数
void pickNumber(unsigned char n)
{
switch (n)
{
case 0: Num_0(); break;
case 1: Num_1(); break;
case 2: Num_2(); break;
case 3: Num_3(); break;
case 4: Num_4(); break;
case 5: Num_5(); break;
case 6: Num_6(); break;
case 7: Num_7(); break;
case 8: Num_8(); break;
case 9: Num_9(); break;
default: Clear(); break;
}
}
// 数码管显示函数
void Display(unsigned char x, unsigned char Number)
{
WeiXuan(x); // 选择显示位
pickNumber(Number); // 显示数字
delay(1); // 短暂延时
Clear(); // 清除显示(消隐)
}
测试结果
下载完程序后,数码管首先显示“0000”数值,显示跳动,每跳动一下数码管显示数值加1。当显示数值为超过“9999”后,显示数值再次变为“0000”,循环显示。
实验十八 1602液晶显示实验#
实验说明
本次试验使用keyes UNO R3 直接驱动1602液晶显示文字。1602液晶在应用中非常广泛,它的显示容量为16×2个字符,芯片工作电压为4.5~5.5V。1602液晶在接keyes UNO R3 控制板显示文字时有两种接线法,分别为4位接法和8位接法,本实验中都会有相关说明介绍。
实验器材
开发板*1
USB线*1
1602 LCD*1
可调电位器*1
面包板*1
正标线若干
接线图
连接Keyes UNO R3
四位接法

八位接法

连接Keyes 2560 R3
四位接法

八位接法

测试代码
四位接法
/*
LiquidCrystal Library - Hello World
演示16x2 LCD显示器的使用。LiquidCrystal库适用于所有兼容
Hitachi HD44780驱动器的LCD显示器。这类显示器通常具有16针接口
本示例在LCD上显示"Hello World!"和"Hello keyes!"
电路连接:
* LCD RS引脚 -> 数字引脚2
* LCD Enable引脚 -> 数字引脚3
* LCD D4引脚 -> 数字引脚4
* LCD D5引脚 -> 数字引脚5
* LCD D6引脚 -> 数字引脚6
* LCD D7引脚 -> 数字引脚7
* LCD R/W引脚 -> 接地
* LCD VSS引脚 -> 接地
* LCD VCC引脚 -> 5V
* 10K电位器:
- 两端分别接+5V和地
- 中间引脚接LCD VO引脚
*/
// 包含LCD库
#include <LiquidCrystal.h>
// 初始化库,指定接口引脚
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
void setup() {
// 设置LCD的列数和行数(16列2行)
lcd.begin(16, 2);
// 在LCD上打印消息
lcd.setCursor(2,0); // 设置光标位置(列,行)
lcd.print("Hello, world!");
lcd.setCursor(2,1);
lcd.print("Hello, keyes!");
}
void loop() {
// 空循环
}
/* 以下是八位接法的实现代码 */
// 定义引脚(八位并行接口)
int DI = 12; // 数据/指令选择
int RW = 11; // 读/写选择
int DB[] = {3, 4, 5, 6, 7, 8, 9, 10}; // 使用数组定义数据总线引脚
int Enable = 2; // 使能引脚
// 写命令函数
void LcdCommandWrite(int value) {
int i = 0;
digitalWrite(DI, LOW); // 写命令模式
digitalWrite(RW, LOW); // 写模式
// 向数据总线写入值(注意信号顺序反转)
for (i=DB[0]; i <= DI; i++) {
digitalWrite(i,value & 0x01);
value >>= 1;
}
// 产生使能脉冲
digitalWrite(Enable,LOW);
delayMicroseconds(1);
digitalWrite(Enable,HIGH);
delayMicroseconds(1);
digitalWrite(Enable,LOW);
delayMicroseconds(1);
}
// 写数据函数
void LcdDataWrite(int value) {
int i = 0;
digitalWrite(DI, HIGH); // 写数据模式
digitalWrite(RW, LOW);
for (i=DB[0]; i <= DB[7]; i++) {
digitalWrite(i,value & 0x01);
value >>= 1;
}
// 产生使能脉冲
digitalWrite(Enable,LOW);
delayMicroseconds(1);
digitalWrite(Enable,HIGH);
delayMicroseconds(1);
digitalWrite(Enable,LOW);
delayMicroseconds(1);
}
// 初始化函数(八位接口)
void setup(void) {
int i = 0;
// 设置所有引脚为输出模式
for (i=Enable; i <= DI; i++) {
pinMode(i,OUTPUT);
}
delay(100); // 短暂延时等待LCD上电
// LCD初始化序列
LcdCommandWrite(0x38); // 8位接口,2行显示,5x7点阵
delay(64);
LcdCommandWrite(0x38);
delay(50);
LcdCommandWrite(0x38);
delay(20);
LcdCommandWrite(0x06); // 输入模式设置:增量,不移位
delay(20);
LcdCommandWrite(0x0E); // 显示控制:开显示,显示光标,不闪烁
delay(20);
LcdCommandWrite(0x01); // 清屏,光标归位
delay(100);
LcdCommandWrite(0x80); // 设置DDRAM地址
delay(20);
}
// 主循环(八位接口)
void loop(void) {
LcdCommandWrite(0x01); // 清屏
delay(10);
LcdCommandWrite(0x80+2); // 设置光标位置第一行第3列
delay(10);
// 逐字符写入"Hello, world!"
LcdDataWrite('H');
LcdDataWrite('e');
LcdDataWrite('l');
LcdDataWrite('l');
LcdDataWrite('o');
LcdDataWrite(',');
LcdDataWrite(' ');
LcdDataWrite('w');
LcdDataWrite('o');
LcdDataWrite('r');
LcdDataWrite('l');
LcdDataWrite('d');
LcdDataWrite('!');
delay(10);
LcdCommandWrite(0xc0+2); // 设置光标位置第二行第3列
delay(10);
// 逐字符写入"Hello, keyes!"
LcdDataWrite('H');
LcdDataWrite('e');
LcdDataWrite('l');
LcdDataWrite('l');
LcdDataWrite('o');
LcdDataWrite(',');
LcdDataWrite(' ');
LcdDataWrite('k');
LcdDataWrite('e');
LcdDataWrite('y');
LcdDataWrite('e');
LcdDataWrite('s');
LcdDataWrite('!');
LcdDataWrite(' ');
delay(5000); // 显示5秒
}
测试结果
无论是四位接法还是八位接法,接好线,烧录程序上电后,通过旋转电位器调节背光,即可在1602 LCD上看到设置的显示字符。四位接法和八位接法显示一样,第一行显示 "Hello, world!"字符,第二行显示"Hello, keyes!"字符。
实验十九 超声波测距显示实验#
实验说明
本实验中我们主要用到了超声波传感器和1602 LCD。实验中我们通过超声波测到超声波与前方障碍物的距离,然后在1602 LCD上显示测试结果。
实验器材
开发板 *1
USB线*1
1602 LCD*1
可调电位器*1
超声波传感器*1
面包板*1
正标线若干
杜邦线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
#include <LiquidCrystal.h>
// 超声波传感器引脚定义
#define echoPin 3 // 回声信号接收引脚
#define trigPin 2 // 触发信号输出引脚
#define LEDPin 13 // 板载LED指示灯引脚
// 初始化LCD对象(RS, E, D4, D5, D6, D7)
LiquidCrystal lcd(4, 5, 6, 7, 8, 9);
// 距离测量范围设置
int maximumRange = 200; // 最大测量距离(厘米)
int minimumRange = 0; // 最小测量距离(厘米)
// 测量变量
long duration, distance; // 持续时间和计算得到的距离
void setup()
{
// 初始化各引脚模式
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(LEDPin, OUTPUT); // 用于距离超出范围指示
// LCD显示屏初始化
lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.print("The distance is:");
}
void loop()
{
/* 超声波测距过程 */
// 发送10μs的触发脉冲
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// 测量回声脉冲宽度
duration = pulseIn(echoPin, HIGH);
// 计算距离(声速340m/s,换算为58.2μs/cm)
distance = duration/58.2;
// 距离有效性判断
if (distance >= maximumRange || distance <= minimumRange)
{
/* 超出有效范围时的处理 */
lcd.setCursor(0,1);
lcd.print("-1 "); // 显示-1表示超出范围
digitalWrite(LEDPin, HIGH); // 点亮LED指示异常
}
else
{
/* 正常距离显示处理 */
Serial.println(distance); // 串口输出距离值
// 根据距离值位数调整LCD显示格式
if(distance<10)
{
lcd.setCursor(0,1);
lcd.print(distance);
lcd.setCursor(1,1);
lcd.print(" "); // 清空后两位
}
if((distance >=10)&&(distance<100))
{
lcd.setCursor(0,1);
lcd.print(distance);
lcd.setCursor(2,1);
lcd.print(" "); // 清空最后一位
}
if(distance>100)
{
lcd.setCursor(0,1);
lcd.print(distance); // 三位数完整显示
}
digitalWrite(LEDPin, LOW); // 关闭LED指示
}
// 每次测量间隔50ms
delay(50);
}
测试结果
按照上图接好线,烧录好代码,旋转电位器调节好背光后,1602 LCD显示"The distance is:"字符;测试超声波与前方障碍物的距离,测试到数据,则在1602 LCD上显示该数据,若没测试到数据,那么就在1602 LCD上显示”-1”字符。
实验二十 1302时钟显示实验#
实验说明
上一实验中我们在1602 LCD上显示超声波距离,这一实验程也是将1602 LCD做显示器。这个实验相当于我们自制一个时钟,时钟上包含年、月、日、星期、小时、分钟、秒。初始时间在代码中设置,时钟自动行走,在1602 LCD显示。
实验器材
开发板*1
USB线*1
1602 LCD*1
可调电位器*1
1302时钟传感器*1
面包板*1
正标线若干
杜邦线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
#include <stdio.h> // 标准输入输出头文件
#include <string.h> // 字符串操作头文件
#include <DS1302.h> // DS1302实时时钟库
#include <Wire.h> // I2C通信库
#include <LiquidCrystal.h> // LCD液晶显示屏库
LiquidCrystal lcd(5, 6, 7, 8, 9, 10); // 初始化LCD引脚(RS,EN,D4,D5,D6,D7)
/* 设置数字I/O引脚连接 */
uint8_t CE_PIN = 4; // RST复位引脚
uint8_t IO_PIN = 3; // DAT数据引脚
uint8_t SCLK_PIN = 2; // CLK时钟引脚
/* 创建缓冲区 */
char buf[50]; // 完整日期时间缓冲区
char bf[50]; // 星期和年份缓冲区
char bu[50]; // 时间缓冲区
char uf[50]; // 月份和日期缓冲区
char day[10]; // 星期名称缓冲区
/* 创建DS1302对象 */
DS1302 rtc(CE_PIN, IO_PIN, SCLK_PIN); // 实例化DS1302对象
void print_time()
{
/* 从芯片获取当前时间和日期 */
Time t = rtc.time(); // 获取当前时间结构体
/* 设置星期名称 */
memset(day, 0, sizeof(day)); // 清空星期缓冲区
switch (t.day)
{
case 1:
strcpy(day, "Sunday "); // 星期日
break;
case 2:
strcpy(day, "Monday "); // 星期一
break;
case 3:
strcpy(day, "Tuesday "); // 星期二
break;
case 4:
strcpy(day, "Wednesday"); // 星期三
break;
case 5:
strcpy(day, "Thursday "); // 星期四
break;
case 6:
strcpy(day, "Friday "); // 星期五
break;
case 7:
strcpy(day, "Saturday "); // 星期六
break;
}
/* 格式化日期时间并存入缓冲区 */
snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d",
day,
t.yr, t.mon, t.date,
t.hr, t.min, t.sec);
snprintf(bf, sizeof(bf), "%s %04d",
day, t.yr);
lcd.setCursor(0,0); // 设置光标位置(第一行开头)
lcd.print(bf); // 显示星期和年份
snprintf(bu, sizeof(bu), "%02d:%02d:%02d",
t.hr, t.min, t.sec);
lcd.setCursor(0,1); // 设置光标位置(第二行开头)
lcd.print(bu); // 显示时分秒
snprintf(uf, sizeof(uf), "%02d-%02d",
t.mon, t.date);
lcd.setCursor(11,1); // 设置光标位置(第二行第11列)
lcd.print(uf); // 显示月-日
}
void setup()
{
lcd.begin(16, 2); // 初始化16x2 LCD显示屏
/* 通过关闭写保护和清除时钟停止标志初始化芯片 */
rtc.write_protect(false); // 禁用写保护
rtc.halt(false); // 清除时钟停止标志
/* 创建时间对象设置日期时间 */
Time t(2017,7,24,10,12,22,2); // 创建时间对象(年,月,日,时,分,秒,星期)
/* 设置芯片日期时间 */
rtc.time(t); // 写入RTC时间
}
/* 循环每秒打印时间 */
void loop()
{
print_time(); // 调用时间显示函数
delay(1000); // 延时1秒
}
测试结果
按照上图接好线,烧录好代码,旋转电位器调节好背光后,1602 LCD显示当前初始时间,然后时钟开始走动。
实验二十一 人体红外感应实验#
实验说明
和上面两个实验一样,这个实验也是用1602 LCD做显示器。实验中,我们用到了人体红外热释电传感器,当检测到有人有附近移动时,在1602 LCD显示对应字符,当没有检测到人体在附件移动时,1602 LCD显示另一对应字符。
实验器材
开发板*1
USB线*1
1602 LCD*1
可调电位器*1
人台红外热释电传感器*1
面包板*1
正标线若干
杜邦线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
#include <LiquidCrystal.h>
LiquidCrystal lcd(3, 4, 5, 6, 7, 8);
byte sensorPin = 2; //定义数字口2
byte indicator = 13; //定义数字口13
void setup()
{
pinMode(sensorPin, INPUT); //设置数字口2位输入
pinMode(indicator, OUTPUT); //设置数字口13为输出
lcd.begin(16, 2);
}
void loop()
{
byte state = digitalRead(sensorPin); //读取到数字口2的数值赋值给state
digitalWrite(indicator, state); //控制数值口13的状态
if(state == 1) //当数值口2位高电平时,串口监视器输出对应字符,并自动换行
{
lcd.setCursor(0, 0);
lcd.print("Somebody is ");
lcd.setCursor(0, 1);
lcd.print("in this area! ");
}
else if(state == 0)
{
lcd.setCursor(0, 0);
lcd.print("No one! ");
lcd.setCursor(0, 1);
lcd.print("No one! ");
}
}
按照上图接好线,烧录好代码,旋转电位器调节好背光后,当检测到有人有附近移动时,在1602 LCD第一行显示显示"Somebody is "字符,第二行显示"in this area!"字符;当没有检测到人体在附件移动时,1602 LCD两行都显示"No one!"字符。
实验二十二 温湿度显示实验#
实验说明
和上面实验一样,这个实验也是用1602 LCD做显示器。这个实验中我们主要用到了DHT11温湿度传感器和1602 LCD。DHT11温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。
实验中我们DHT11温湿度传感器测试出当前环境中的温度和湿度,然后在1602 LCD 显示测试结果。
实验器材
开发板*1
USB线*1
1602 LCD*1
可调电位器*1
DHT11温湿度传感器*1
面包板*1
正标线若干
杜邦线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
#include <dht11.h> // DHT11温湿度传感器库
#include <LiquidCrystal.h> // LCD液晶显示屏库
// 初始化LCD引脚(RS,EN,D4,D5,D6,D7)
LiquidCrystal lcd(3, 4, 5, 6, 7, 8);
dht11 DHT; // 创建DHT11对象
#define DHT11_PIN 2 // DHT11数据引脚定义
void setup()
{
lcd.begin(16, 2); // 初始化16x2 LCD显示屏
// 在LCD上打印固定信息
lcd.setCursor(0,0); // 设置光标位置(第一行开头)
lcd.print("Humidity (%):"); // 显示"湿度(%)"
lcd.setCursor(0,1); // 设置光标位置(第二行开头)
lcd.print("Temp (C):"); // 显示"温度(℃)"
}
void loop()
{
int chk; // 传感器状态检查变量
chk = DHT.read(DHT11_PIN); // 读取DHT11传感器数据
// 检查传感器状态
switch (chk)
{
case DHTLIB_OK: // 读取成功
break;
case DHTLIB_ERROR_CHECKSUM: // 校验和错误
break;
case DHTLIB_ERROR_TIMEOUT: // 读取超时
break;
default: // 其他错误
break;
}
// 显示传感器数据
lcd.setCursor(13,0); // 设置湿度显示位置(第一行第13列)
lcd.print(DHT.humidity); // 显示湿度值
lcd.setCursor(9,1); // 设置温度显示位置(第二行第9列)
lcd.print(DHT.temperature); // 显示温度值
delay(1000); // 延时1秒
}
测试结果
按照上图接好线,烧录好代码,旋转电位器调节好背光后,1602 LCD显示当前环境中的温度和湿度值。
实验二十三 摇杆模块数据显示实验#
实验说明
和上面实验一样,这个实验也是用1602 LCD做显示器。这个实验中我们主要用到了摇杆模块和1602 LCD。摇杆模块5V供电,信号端X,Y接模拟口,原始状态下读出电压为2.5V左右,当随箭头方向按下,读出电压值随着增加,最大到5V,箭头相反方向按下,读出电压值减少,最小为0V;信号端B接数字口,原始状态下输出0,按下输出1。
实验中我们读取摇杆模块X、Y、B三个接口数值,然后在1602 LCD显示测试结果。
实验器材
开发板*1
USB线*1
1602 LCD*1
可调电位器*1
摇杆模块*1
面包板*1
正标线若干
杜邦线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
#include <LiquidCrystal.h> // LCD液晶显示屏库
// 初始化LCD引脚(RS,EN,D4,D5,D6,D7)
LiquidCrystal lcd(3, 4, 5, 6, 7, 8);
int JoyStick_X = 1; // 定义摇杆X轴模拟口A1
int JoyStick_Y = 0; // 定义摇杆Y轴模拟口A0
int JoyStick_Z = 2; // 定义摇杆Z轴数字口2
void setup()
{
pinMode(JoyStick_Z, INPUT); // 将JoyStick_Z设置为输入模式
lcd.begin(16, 2); // 初始化16x2 LCD显示屏
// 在LCD上打印固定标签
lcd.setCursor(0,0); // 设置光标位置(第一行开头)
lcd.print("X:"); // 显示X轴标签
lcd.setCursor(8,0); // 设置光标位置(第一行第8列)
lcd.print("Y:"); // 显示Y轴标签
lcd.setCursor(0,1); // 设置光标位置(第二行开头)
lcd.print("Z:"); // 显示Z轴标签
}
void loop()
{
int x,y,z; // 定义摇杆值变量
// 读取并显示X轴数值
x = analogRead(JoyStick_X); // 读取A1模拟口数值
if(x < 10)
{
lcd.setCursor(2,0); // 设置光标位置(第一行第2列)
lcd.print(x); // 显示个位数
lcd.setCursor(3,0); // 设置光标清除位置
lcd.print(" "); // 清除多余数字
}
else if((x >= 10) && (x < 100))
{
lcd.setCursor(2,0);
lcd.print(x); // 显示两位数
lcd.setCursor(4,0);
lcd.print(" ");
}
else if((x >= 100) && (x < 1000))
{
lcd.setCursor(2,0);
lcd.print(x); // 显示三位数
lcd.setCursor(5,0);
lcd.print(" ");
}
else if(x >= 1000)
{
lcd.setCursor(2,0);
lcd.print(x); // 显示四位数
}
delay(100); // 延时100ms
// 读取并显示Y轴数值
y = analogRead(JoyStick_Y); // 读取A0模拟口数值
if(y < 10)
{
lcd.setCursor(10,0); // 设置光标位置(第一行第10列)
lcd.print(y);
lcd.setCursor(11,0);
lcd.print(" ");
}
else if((y >= 10) && (y < 100))
{
lcd.setCursor(10,0);
lcd.print(y);
lcd.setCursor(12,0);
lcd.print(" ");
}
else if((y >= 100) && (y < 1000))
{
lcd.setCursor(10,0);
lcd.print(y);
lcd.setCursor(13,0);
lcd.print(" ");
}
else if(y >= 1000)
{
lcd.setCursor(2,0);
lcd.print(y);
}
delay(100);
// 读取并显示Z轴数值
z = digitalRead(JoyStick_Z); // 读取数字口2数值
lcd.setCursor(2,1); // 设置光标位置(第二行第2列)
lcd.print(z); // 显示开关状态(0/1)
delay(100); // 延时100ms
}
测试结果
下载完程序后,上电后,通过电位器调节1602 LCD背光后,我们可以在1602 LCD上看、
到摇杆模块X、Y、Z方向对应的的数值。
实验二十四 继电器控灯实验#
实验说明
继电器模块是一种用于低电控制高电,保护电路的模块。本实验用到的5V单路继电器模块高电平有效,它有控制指示灯,吸合亮,断开不亮。实验中我们通过控制继电器从而控制一个LED的亮灭。
实验器材
开发板*1
USB线*1
5V 单路继电器模块*1
LED*1
220Ω 电阻*1
面包板*1
正标线若干
杜邦线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
int Relay = 3; //定义数字口3
void setup()
{
pinMode(Relay, OUTPUT); //将Relay设置为输出
}
void loop()
{
digitalWrite(Relay, HIGH); //打开继电器
delay(2000); //延时2S
digitalWrite(Relay, LOW); //关闭继电器
delay(2000); //延时2S
}
实验二十五 水蒸气检测显示实验#
实验说明
和上面实验一样,这个实验也是用1602 LCD做显示器。这个实验中我们主要用到了水滴水蒸气传感器和1602 LCD。水滴水蒸气传感器是一个模拟传感器,可以制作简单的雨水探测器与液位开关。当传感器表面的湿度上升,输出电压将增大。
实验中我们读取水滴水蒸气传感器信号端的模拟值,然后在1602 LCD显示测试结果。
实验器材
开发板*1
USB线*1
1602 LCD*1
可调电位器*1
水滴水蒸气传感器*1
面包板*1
正标线若干
杜邦线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
#include <LiquidCrystal.h> // LCD液晶显示屏库头文件
// 初始化LCD引脚(RS,EN,D4,D5,D6,D7)
LiquidCrystal lcd(3, 4, 5, 6, 7, 8);
void setup()
{
lcd.begin(16, 2); // 初始化16列2行的LCD显示屏
// 在LCD第一行打印标题
lcd.setCursor(0,0); // 设置光标位置(第一行开头)
lcd.print("Sensor value:"); // 显示"传感器值:"
}
void loop()
{
int value = analogRead(A0); // 读取A0模拟口的数值
// 根据数值位数调整显示位置
if(value < 10) // 数值小于10的情况
{
lcd.setCursor(0,1); // 设置光标位置(第二行开头)
lcd.print(value); // 显示数值
lcd.setCursor(1,1); // 设置清除位置
lcd.print(" "); // 清除多余数字
}
if((value >= 10) && (value < 100)) // 数值在10-99之间
{
lcd.setCursor(0,1);
lcd.print(value);
lcd.setCursor(2,1);
lcd.print(" ");
}
if((value >= 100) && (value < 1000)) // 数值在100-999之间
{
lcd.setCursor(0,1);
lcd.print(value);
lcd.setCursor(3,1);
lcd.print(" ");
}
if(value >= 1000) // 数值大于等于1000
{
lcd.setCursor(2,0); // 注意:这里显示在第一行第2列
lcd.print(value);
}
delay(100); // 延时100毫秒
}
测试结果
下载完程序后,上电后,通过电位器调节1602 LCD背光后,我们可以在1602 LCD上看
到水滴水蒸气传感器信号端的模拟值。
实验二十六 声控灯实验#
实验说明
麦克风声音传感器是专门用来检测声音的传感器。传感器有S端是模拟输出,是麦克风的电压信号实时输出,通过电位器可调节信号增益。实验中,我通过传感器检测声音大小,从而控制一个LED亮灭。
实验器材
开发板*1
USB线*1
麦克风声音传感器*1
LED*1
220Ω 电阻*1
面包板*1
正标线若干
杜邦线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
int MIC = 0; //定义声音传感器为模拟0 接口
int LED = 9; //定义LED接口为数字9 接口
int val = 0; //定义数字变量
void setup()
{
pinMode(LED, OUTPUT); //定义LED 为输出接口
pinMode(MIC, INPUT); //定义声音传感器为输入接口
Serial.begin(9600); //设定波特率为9600
}
void loop()
{
val = analogRead(MIC); //读取声音传感器的模拟值
Serial.println(val); //输出模拟值,并将其打印出来
if(val >= 300) //当模拟值大于300 时LED亮起
{
digitalWrite(LED, HIGH);
}
else
{
digitalWrite(LED, LOW);
}
delay(500);
}
测试结果
下载完程序后,我们可以检测声音大小,输出模拟值,声音越大,输出越大。当声音大小到达一定数值时,LED亮起,否则LED熄灭。
实验二十七 步进电机实验#
实验说明
步进电机是一种将电脉冲转化为角位移的执行机构。通俗一点讲:当步进驱动器接收到
一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(及步进角)。你
可以通过控制脉冲个数来控制角位移量,从而达到准确定位的目的;同时你也可以通过
控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。
下面这个就是本次实验使用的步进电机

减速步进电机
直径:28mm
电压:5V
步进角度:5.625 x 1/64
减速比:1/64
5线4相 可以用普通uln2003芯片驱动,也可以接成2相使用
该步进电机空载耗电在50mA以下,带64倍减速器,输出力矩比较大,可以驱动重负
载,极适合开发板使用。注意:此款步进电机带有64倍减速器,与不带减速器的步进
电机相比,转速显得较慢,为方便观察,可在输出轴处粘上一片小纸板。

步进电机(五线四相)驱动板(UL2003)试验板

实验器材
开发板*1
USB线*1
减速步进电机*1
UL2003*1
杜邦线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
#include <Stepper.h>
// 这里设置步进电机旋转一圈是多少步
#define STEPS 100
// 设置步进电机的步数和引脚
Stepper stepper(STEPS, 11, 10, 9, 8);
// 定义变量用来存储历史读数
int previous = 0;
void setup()
{
// 设置电机每分钟的转速为90步
stepper.setSpeed(90);
}
void loop()
{
// 获取传感器读数
int val = analogRead(0);
// 移动步数为当前读数减去历史读数
stepper.step(val - previous);
// 保存历史读数
previous = val;
}
测试结果
按照上图接好线,烧录好代码,上电后,5V步进电机转动,转动速度很慢。
实验二十八 姿态传感器实验#
实验说明
APDS-9930 在单个 8 引脚封装内提供 I2C 接口兼容的环境亮度传感器 (ALS, Ambient Light Sensor) 和带有红外 LED的接近传感器,其中环境亮度传感器使用双光二极管来近似 0.01 lux照度下低流明性能的人眼视觉反应,提供的高灵敏度使得器件可以在深色玻璃后运作。接近传感器经过完全调校可进行100毫米物体检测,免除终端设备和次组件的工厂校准需求。从明亮的阳光照射到黑暗的房间,接近检测功能都能运作良好。模块中加入微光学透镜提供红外能量的高效率传送和接收,可降低总体功耗。另外,内部状态机可使器件进入低功耗模式,带来极低的平均功耗。
本实验只是简单的测试下这个传感器的基本功能。
实验器材
开发板*1
USB线*1
keyes 9930 接近和非接触式手势检测RGB和姿态传感器*1
杜邦线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
#define DUMP_REGS // 定义寄存器调试模式
#include <Wire.h> // I2C通信库
#include <APDS9930.h> // APDS-9930传感器库
// 引脚定义
#define APDS9930_INT 2 // 中断引脚(必须使用中断引脚)
#define LED_PIN 13 // LED指示灯引脚
// 常量定义
#define PROX_INT_HIGH 600 // 接近中断高阈值
#define PROX_INT_LOW 0 // 接近中断低阈值
// 全局变量
APDS9930 apds = APDS9930(); // 创建APDS-9930对象
float ambient_light = 0; // 环境光强度值
uint16_t ch0 = 0; // 通道0光强度
uint16_t ch1 = 1; // 通道1光强度
uint16_t proximity_data = 0; // 接近检测数据
volatile bool isr_flag = false; // 中断标志位
void setup()
{
// 初始化LED引脚
pinMode(LED_PIN, OUTPUT); // 设置LED为输出模式
pinMode(APDS9930_INT, INPUT); // 设置中断引脚为输入模式
// 初始化串口通信
Serial.begin(9600); // 设置串口波特率9600
Serial.println();
Serial.println(F("------------------------------"));
Serial.println(F("APDS-9930 - ProximityInterrupt"));
Serial.println(F("------------------------------"));
// 初始化中断服务程序
attachInterrupt(digitalPinToInterrupt(APDS9930_INT), interruptRoutine, FALLING);
// 初始化APDS-9930传感器
if (apds.init())
{
Serial.println(F("APDS-9930 initialization complete"));
}
else
{
Serial.println(F("Something went wrong during APDS-9930 init!"));
}
// 设置接近传感器增益
if (!apds.setProximityGain(PGAIN_2X))
{
Serial.println(F("Something went wrong trying to set PGAIN"));
}
// 设置接近中断阈值
if (!apds.setProximityIntLowThreshold(PROX_INT_LOW))
{
Serial.println(F("Error writing low threshold"));
}
if (!apds.setProximityIntHighThreshold(PROX_INT_HIGH))
{
Serial.println(F("Error writing high threshold"));
}
// 启动接近传感器(启用中断)
if (apds.enableProximitySensor(true))
{
Serial.println(F("Proximity sensor is now running"));
}
else
{
Serial.println(F("Something went wrong during sensor init!"));
}
// 启动光传感器(不启用中断)
if (apds.enableLightSensor(false))
{
Serial.println(F("Light sensor is now running"));
}
else
{
Serial.println(F("Something went wrong during light sensor init!"));
}
#ifdef DUMP_REGS
/* 寄存器调试输出 */
uint8_t reg;
uint8_t val;
for (reg = 0x00; reg <= 0x19; reg++)
{
if ((reg != 0x10) && (reg != 0x11))
{
apds.wireReadDataByte(reg, val);
Serial.print(reg, HEX);
Serial.print(": 0x");
Serial.println(val, HEX);
}
}
apds.wireReadDataByte(0x1E, val);
Serial.print(0x1E, HEX);
Serial.print(": 0x");
Serial.println(val, HEX);
#endif
}
void loop()
{
// 检测中断标志
if (isr_flag)
{
// 读取接近值并输出
if (!apds.readProximity(proximity_data))
{
Serial.println("Error reading proximity value");
}
else
{
Serial.print("Proximity detected! Level: ");
Serial.print(proximity_data);
Serial.print(" ");
}
// 读取光强度值(环境光,通道0,通道1)
if (!apds.readAmbientLightLux(ambient_light) || !apds.readCh0Light(ch0) || !apds.readCh1Light(ch1))
{
Serial.println(F("Error reading light values"));
}
else
{
Serial.print(F("Ambient: "));
Serial.print(ambient_light);
Serial.print(F(" Ch0: "));
Serial.print(ch0);
Serial.print(F(" Ch1: "));
Serial.println(ch1);
}
// LED指示灯闪烁
digitalWrite(LED_PIN, HIGH); // 点亮LED
delay(300); // 保持300ms
digitalWrite(LED_PIN, LOW); // 关闭LED
// 清除中断标志和中断状态
isr_flag = false;
if (!apds.clearProximityInt())
{
Serial.println("Error clearing interrupt");
}
}
}
// 中断服务程序
void interruptRoutine()
{
isr_flag = true; // 设置中断标志
}
测试结果
打开串口监视器,显示如下图。

实验二十九 震动检测传感器实验#
实验说明
震动检测传感器是基于压电陶瓷片的模拟震动传感器,是利用压电陶瓷给电信号产生震动的反变换过程,当压电陶瓷片震动时就会产生电信号。它可与Arduino专用传感器扩展板结合使用,Arduino模拟口能感知微弱的震动电信号,可实现与震动有相关的互动作品,比如电子鼓互动作品。
这个实验中,我们将模拟电压陶瓷震动传感器依照程序接入Arduino UNO控制器模拟口A0,观察当震动程度不同时,串口的输出值。
实验器材
开发板*1
USB线*1
震动检测传感器*1
杜邦线若干
接线图
连接Keyes UNO R3

连接Keyes 2560 R3

测试代码
void setup()
{
Serial.begin(9600); //打开串口,设置串口波特率为 9600bps
}
void loop()
{
int val;
val = analogRead(0); //将模拟压电陶瓷震动传感器连接到模拟接口 0
Serial.print("Vibration is ");
Serial.println(val, DEC); //通过串口打印读取到的模拟值
delay(100);
}
测试结果
当你检测到不同程度震动时,反馈回此时的测量值。如下图所示,此图是当将震动传
感器贴到 A4 纸中央上,绷直 A4 纸,敲击 A4一边,串口反馈回来的数据示意图。
