众所周知,掌控板在创客教育中用的非常广泛,它是一块基于 ESP32 的学习开发板。大家对掌控板编程,用的比较多的都是图形化编程的方式,比如 mPython、Mind+ 等。但是,既然掌控板是基于 ESP32 芯片的,所以我们也可以用 Arduino 软件对其编程。所以,有时间的话,我准备给大家分享一系列用 Arduino 代码对掌控板(ESP32)编程的教程:用 Arduino 玩转掌控板(ESP32)系列。
本系列历史文章目录:
ESP32概述与Arduino软件准备
蓝牙翻页笔(PPT控制器)
新冠肺炎疫情数据实时显示器
B站粉丝计数器
Siri 语音识别控制 LED 灯
Siri 语音识别获取传感器数据
本期给大家带来的是:掌控板IO接口编程入门,教你用 Arduino IDE 学会掌控板 IO 接口的简单编程操作。IO 就是 INPUT 与 OUTPUT 的缩写,即输入与输出。
其实本篇是这个系列的入门篇之一,但是由于我一直偷懒,这篇一直放着没写,先写了一些进阶的内容。本篇比较简单,所以就不放案例演示视频了。
# 概述
掌控板的 IO 接口主要是用来连接外部传感器、执行器等相关外设的。平时我们使用最多最常见的一些外设,一般都是数字量或模拟量的,传感器一般都是输入设备、执行器一般都是输出设备。所以,一般情况下学习一个主控板的 IO 接口基本操作,我们都是从数字输入、数字输出、模拟输入、模拟输出这个 4 个方面来进行学习的,本篇也不例外。
这里需要注意的是,输入和输出是相对主控板来说的:当信号是由主控板向外设发送时,相应的外设就是主控板的输出设备;当信号是由外设向主控板发送时,也就是主控板去读取外设的信号时,相应的外设就是主控板的输入设备。所以:大部分传感器都是输入设备,因为他们的功能是测量数据,然后主控板去读取他们的数据;大部分执行器都是输出设备,因为是主控板向他们发送信号、控制他们完成相应的操作。
# 数字输入
数字输入(或数字量输入)设备是生活中最常见的设备,比如房间里的开关、按钮、楼道里的人体感应设备,这些设备有一个共同的特点,即只有 2 种情况:有或无、开或关、1 或 0,这些只有 2 种情况的设备,一般称为数字量设备。相应地,如果他们是传感器,则称为数字输入设备,或数字输入传感器。
掌控板上的按键 A 和 B,其实就是数字输入传感器。所以本节就以读取掌控板上的按键 A 和 B 为例,教你对数字输入设备编程。
先来看一下完整的程序:
// 设置掌控板按键 A 的引脚编号constintbuttonAPin=P5;// 设置按键 A 的状态值变量int buttonAState = 0;void setup() {// 初始化串口监视器Serial.begin(9600); // 初始化按键 A 对应的引脚为输入模式 pinMode(buttonAPin, INPUT);}void loop() {// 读取按键 A 的值buttonAState=digitalRead(buttonAPin); // 如果按键 A 被按下了,串口监视器输出信息 if (buttonAState == LOW) {Serial.println("ButtonApressed"); } delay(100);}
这个程序很简单,程序中也有相应的注释了,我们简单来讲解一下。
首先在程序开头定义了两个变量,buttonAPin 用来定义按键 A 对应的引脚,buttonAState 用来存储按键 A 的状态。
// 设置掌控板按键 A 的引脚编号constintbuttonAPin=P5;// 设置按键 A 的状态值变量int buttonAState = 0;
这里讲一下命名变量的小技巧,变量一般要命名成方便用户辨别、并且有一定实际字面意义的名称,这样当程序比较长的时候更加容易读懂。尽量不要命名成 a、b 这些没有太多实际字面意义的名称,当然特殊情况除外。
那么我们是如何知道按键 A 对应的引脚编号是 P5 呢?
实际上掌控板官方 Wiki 上提供了非常详细的说明和电路图,我们阅读相应的文档,就可以知道掌控板上的板载资源对应的引脚了。我们可以直接点击下方链接,查看掌控板官方 Wiki 资料。
https://mpython.readthedocs.io/zh/master/board/hardware.html
在上面的网页中,我们可以查到一张表格,上面记录了掌控板上所有板载资源对应的引脚。从这里我们可以查到按键 A 对应的引脚编号为 P5。
接下来在初始化程序 setup() 中,我们可以看到下面两句代码,分别用来对串口监视器进行初始化、以及设定按键 A 引脚的模式。对串口监视器初始化时,我们要设定串口波特率,常用的波特率是 9600 和 115200,设置波特率的作用是让电脑和掌控板保持相同的通信速率,以便可以互相收发信息。引脚模式,最常用的一般为输入模式 INPUT 和输出模式 OUTPUT,我们知道按键是数字输入传感器,所以要设置为输入模式 INPUT。
// 初始化串口监视器Serial.begin(9600);// 初始化按键 A 对应的引脚为输入模式pinMode(buttonAPin,INPUT);
这里顺便再提一下,在 Arduino IDE 中编程,一般会有两个自带的函数,分别为初始化函数 setup() 和循环函数 loop()。setup() 函数的功能是在程序开始前做相应的设置,设备上电后(或者按下 RESET 按键之后)只执行一次;loop() 函数是在 setup() 运行完成之后开始运行的,它的功能是不断重复执行其中的代码,因此需要重复运行的代码或任务,一般放在 loop() 函数中,比如不断读取按键的状态。当然也有一些特殊情况,比如中断的设置等,是不用放在 loop() 中的,这部分等讲到相应内容的时候再来展开。
接下来在 loop() 函数中,首先读取按键 A 的状态值,并且赋值给变量 buttonAState。读取数字量输入的程序为 digitalRead(),跟变量命名一样,程序中函数命名也是带有一定的意义、简单易读的。
// 读取按键 A 的值buttonAState = digitalRead(buttonAPin);
然后根据按键 A 的状态值,通过串口监视器打印出相应的信息。这里需要注意的是,一般情况下,按键弹起时的默认值为 LOW(或 0),当按键被按下时,按键的值变为 HIGH(或 1)。但是这不是绝对的,跟电路设计有关,掌控板的按键值与按键状态,就正好相反。所以当掌控板的按键 A 被按下时,它的状态值为 LOW。为了防止程序运行太快,导致串口监视器一下子输出太多信息,我们这里加了一个延时函数:delay(100),让程序每次都延时 100 毫秒再去运行下一次循环任务。
// 如果按键 A 被按下了,串口监视器输出信息if (buttonAState == LOW) {Serial.println("ButtonApressed");}delay(100);
在工具菜单中,将主控板选为掌控板,并选择正确的串口号,上传程序。然后打开串口监视器,我们看看程序运行的效果。在串口监视器中将波特率设置为 9600,然后按下掌控板上的按键 A。每按下一次按键 A,串口监视器中就会输出相应的信息,说明程序编写成功!
试一试:改写程序,让程序同时也可以读取按键 B 的状态,并在串口监视器输出相应的信息。你会了么?
# 数字输出
学会了数字输入,我们再来学一学数字输出。我们生活中最常见的电灯,一般情况下,都是数字输出设备。数字输出也是只有 2 种控制状态的设备,高或低、1 或 0。这里以控制 LED 灯为例,来学习一下数字输出的程序编写。我们现在掌控板的 P0 端口外接一个 LED 灯,这里你可以选择自己喜欢的任意扩展板。电路比较简单,所以这里不放电路图了。
来看一下完整的程序:
// 设置掌控板按键 A 的引脚编号constintbuttonAPin=P5;// 设置 LED 灯的引脚编号constintledPin=P0;// 设置按键 A 的状态值变量int buttonAState = 0;void setup() {// 初始化串口监视器Serial.begin(9600); // 初始化按键 A 对应的引脚为输入模式pinMode(buttonAPin,INPUT); // 初始化 LED 对应的引脚为输出模式 pinMode(ledPin, OUTPUT);}void loop() {// 读取按键 A 的值buttonAState=digitalRead(buttonAPin); // 如果按键 A 被按下了,点亮 LED 灯,否则熄灭 LED 灯 if (buttonAState == LOW) {Serial.println("ButtonApressed"); digitalWrite(ledPin,HIGH); } else {digitalWrite(ledPin,LOW);} delay(100);}
仔细观察,我们发现这个程序跟上一节数字输入中的程序非常类似,我们只是在这基础之上加了几行代码。这里只讲差异部分。
首先在程序开头,定义了 LED 灯的引脚编号,我们将 LED 灯通过扩展板接在掌控板的 P0 引脚,这个与定义按键 A 引脚编号的方法一致。
// 设置 LED 灯的引脚编号const int ledPin = P0;
然后在 setup() 初始化函数中设置了 LED 连接的引脚为输出模式 OUTPUT,这个与设置按键 A 的方法也一样,只不过一个是 LED 设置为输出模式、按键 A 设置为输入模式。
// 初始化 LED 对应的引脚为输出模式pinMode(ledPin, OUTPUT);
然后在 loop() 函数中,当检测到按键 A 被按下时,点亮 LED,否则熄灭 LED 灯。点亮 LED 灯的代码为:
digitalWrite(ledPin, HIGH);
熄灭 LED 灯的代码为:
digitalWrite(ledPin, LOW);
将程序上传到掌控板,按下按键 A,看看 LED 灯是否点亮了呢?松开按键 A 呢?
试一试:改写程序,实现:按下按键 A,点亮 LED 灯;按下按键 B,熄灭 LED 灯。
# 模拟输入
讲完数字输入、数字输出,我们再来看一看模拟输入。模拟输入是相对数字输入来说的,数字输入只要 2 种状态,但是模拟输入有很多种连续的状态,比如各种旋钮、温度值等。
在掌控板上也有 2 个模拟输入传感器:声音传感器与光线传感器。下面我们以声音传感器为例,讲一讲模拟输入的程序编写方法。
// 设置掌控板声音传感器引脚编号constintsoundPin=P10;// 设置声音大小值变量int soundValue = 0;void setup() {// 初始化串口监视器Serial.begin(9600); // 初始化声音传感器引脚为输入模式 pinMode(soundPin, INPUT);}void loop() {// 读取声音传感器的值soundValue=analogRead(soundPin); // 串口监视器中打印声音传感器的值 Serial.println(soundValue); delay(10);}
这个程序与数字输入部分的程序也是非常类似的。
在程序开头,定义了两个变量,用来设置声音传感器的引脚编号、声音传感器的值。
// 设置掌控板声音传感器引脚编号constintsoundPin=P10;// 设置声音大小值变量int soundValue = 0;
接着在 setup() 初始化函数中,初始化串口监视器和声音传感器的引脚模式:
// 初始化串口监视器Serial.begin(9600);// 初始化声音传感器引脚为输入模式pinMode(soundPin, INPUT);
接着在 loop() 函数中读取声音的值,并且在串口监视器中打印出来。读取模拟量的函数为 analogRead()。
// 读取声音传感器的值soundValue=analogRead(soundPin);// 串口监视器中打印声音传感器的值Serial.println(soundValue);delay(10);
将程序上传到掌控板中,打开串口监视器,对着声音传感器说话,我们看看效果。
我们还可以以曲线图的形式,将声音传感器数据的变化展现出来。在 Arduino IDE 菜单栏中,依次点击:工具 → 串口绘图器,打开串口绘图器,对着声音传感器说话,看看曲线图变化吧。
试一试:改写程序,让程序同时也可以读取光线传感器的值,看看串口绘图器会输出什么信息呢?
# 模拟输出
你有没有注意到,有些人家里的电灯,亮度是可以调节的?这个其实就是模拟输出。相比于数字输出只有两种状态,模拟输出可以有连续的多种状态。
由于在 Arduino IDE 中,用掌控板自带的函数功能实现模拟输出比较复杂。因此我们这里调用别人做好的适用于掌控板 ESP32 的模拟输出函数库。函数库下载地址为:
/ERROPiX/ESP32_AnalogWrite
我们要先将这个库导入到 Arduino IDE 中。这个库的功能是可以让掌控板像 Arduino 一样,方便的使用模拟输出功能,有个这个库,掌控板模拟输出的语法,就跟 Arduino 完全一样了。
这里以控制 LED 灯实现呼吸灯效果为例,完整的程序如下:
#include #include // 设置 LED 灯引脚编号const int ledPin = P0;void setup() {// 初始化 LED 灯引脚为输出模式 pinMode(ledPin, OUTPUT);}void loop() {for (int brightness = 0; brightness <= 255; brightness++) {analogWrite(ledPin,brightness); delay(5); } for (int brightness = 255; brightness >= 0; brightness--) {analogWrite(ledPin,brightness); delay(5); }}
在程序最开始,我们先引入两个头文件,在头文件中定义了实现模拟输出相关的功能函数。然后定义了 LED 灯的引脚编号。
#include #include // 设置 LED 灯引脚编号const int ledPin = P0;
接着在 setup() 函数中设置 LED 灯引脚为输出模式。
然后在 loop() 函数中,通过 for 循环结构,控制 LED 灯由暗变亮,再由亮变暗。亮度通过局部变量 brightness 来设置。
for (int brightness = 0; brightness <= 255; brightness++) {analogWrite(ledPin,brightness);delay(5);}for (int brightness = 255; brightness >= 0; brightness--) {analogWrite(ledPin, brightness);delay(5);}
将程序上传到掌控板中,LED 灯是不是呈现呼吸灯闪烁变化的样子?说明程序编程成功了。
# 总结
在本章中,我们学习了:
如何查阅掌控板各引脚相应的资源配置;
数字量与模拟量的区别;
简单的数字输入、数字输出、模拟输入、模拟输出的程序编写;
Arduino IDE 的基本使用方法。
学习了这些基础内容之后,就可以学习后面更加进阶的内容啦,其实进阶内容与入门内容类似,都是由一个个小功能组成的,有了这些基础功能的组合,通过不同的排列组合和逻辑设置,就可以实现各种好玩的创意啦!
我们下期见!如果本文对你有帮助的话,点个“在看”支持一下喽。
欢迎转发朋友圈。如需转载,请注明出处和原作者。
我知道你在看呦
如果觉得《arduino nano 蓝牙_掌控板IO接口编程入门 | 用Arduino玩转掌控板(ESP32)系列》对你有帮助,请点赞、收藏,并留下你的观点哦!