在之前的文章中,我们介绍了ESP32的数字信号。并介绍了用程序来控制引脚输出高或低的数字信号,本文,我们将介绍ESP32如何读取引脚接收到的数字信号。
数字信号只有两个值,1或0,当引脚接收到足够的电压信号时,引脚读取到的信号值为1。反之则为0。
在测试读取数值之前,我们先介绍引脚数字输出输入初始化函数:
pinMode(pin,mode);
参数:
pin - 引脚号码
mode - 初始化模式:
INPUT——输入模式
INPUT_PULLUP——输入上拉模式
INPUT_PULLDOWN--输入下拉模式
OUTPUT——输出模式
该函数的输入模式和输出模式很好理解,这里详细说一下上拉模式和下拉模式。在ESP32的内部电路中,部份的引脚内部自带有上拉或下拉电阻,当我们需要开机时该引脚默认为高电平时,我们需要选择INPUT_PULLUP模式,反之我们需要选择INPUT_PULLDOWN模式。
我们一步步来测试除了输出模式的各种情况下各个引脚的状态。
我们先不对引脚初始化,直接测试读取几个引脚的值。
void setup() {
Serial.begin(115200); //通信速率115200
}
void loop() {
bool data2 = digitalRead(2); //读取2号引脚的数字信号
bool data4 = digitalRead(4); //读取4号引脚的数字信号
bool data5 = digitalRead(5); //读取5号引脚的数字信号
bool data12 = digitalRead(12); //读取12号引脚的数字信号
bool data13 = digitalRead(13); //读取13号引脚的数字信号
bool data14 = digitalRead(14); //读取14号引脚的数字信号
bool data15 = digitalRead(15); //读取15号引脚的数字信号
bool data18 = digitalRead(18); //读取18号引脚的数字信号
Serial.print(data2); //串口输出数字信号的值
Serial.print(",");
Serial.print(data4); //串口输出数字信号的值
Serial.print(",");
Serial.print(data5); //串口输出数字信号的值
Serial.print(",");
Serial.print(data12); //串口输出数字信号的值
Serial.print(",");
Serial.print(data13); //串口输出数字信号的值
Serial.print(",");
Serial.print(data14); //串口输出数字信号的值
Serial.print(",");
Serial.print(data15); //串口输出数字信号的值
Serial.print(",");
Serial.println(data18); //串口输出数字信号的值
delay(1000); //暂停一秒
}
打开串口监视器,查看输出的值
我们可以看到,每个引脚在未经过初始化的情况下,当前引脚状态并非全都为低或高。
我们继续尝试给所有引脚加入初始化为输入模式。
void setup() {
Serial.begin(115200); //通信速率115200
pinMode(2,INPUT); //2号引脚设为输入模式
pinMode(4,INPUT); //4号引脚设为输入模式
pinMode(5,INPUT); //5号引脚设为输入模式
pinMode(12,INPUT); //12号引脚设为输入模式
pinMode(13,INPUT); //13号引脚设为输入模式
pinMode(14,INPUT); //14号引脚设为输入模式
pinMode(15,INPUT); //15号引脚设为输入模式
pinMode(18,INPUT); //18号引脚设为输入模式
}
void loop() {
bool data2 = digitalRead(2); //读取2号引脚的数字信号
bool data4 = digitalRead(4); //读取4号引脚的数字信号
bool data5 = digitalRead(5); //读取5号引脚的数字信号
bool data12 = digitalRead(12); //读取12号引脚的数字信号
bool data13 = digitalRead(13); //读取13号引脚的数字信号
bool data14 = digitalRead(14); //读取14号引脚的数字信号
bool data15 = digitalRead(15); //读取15号引脚的数字信号
bool data18 = digitalRead(18); //读取18号引脚的数字信号
Serial.print(data2); //串口输出数字信号的值
Serial.print(",");
Serial.print(data4); //串口输出数字信号的值
Serial.print(",");
Serial.print(data5); //串口输出数字信号的值
Serial.print(",");
Serial.print(data12); //串口输出数字信号的值
Serial.print(",");
Serial.print(data13); //串口输出数字信号的值
Serial.print(",");
Serial.print(data14); //串口输出数字信号的值
Serial.print(",");
Serial.print(data15); //串口输出数字信号的值
Serial.print(",");
Serial.println(data18); //串口输出数字信号的值
delay(1000); //暂停一秒
}
串口监视器清空之前的输出,查看加入了初始化的输出。
可以看到,在初始化后的输出同样有不同的输出状态。
我们再尝试给引脚设置上拉模式
void setup() {
Serial.begin(115200); //通信速率115200
pinMode(2,INPUT_PULLUP); //2号引脚设为输入上拉模式
pinMode(4,INPUT_PULLUP); //4号引脚设为输入上拉模式
pinMode(5,INPUT_PULLUP); //5号引脚设为输入上拉模式
pinMode(12,INPUT_PULLUP); //12号引脚设为输入上拉模式
pinMode(13,INPUT_PULLUP); //13号引脚设为输入上拉模式
pinMode(14,INPUT_PULLUP); //14号引脚设为输入上拉模式
pinMode(15,INPUT_PULLUP); //15号引脚设为输入上拉模式
pinMode(18,INPUT_PULLUP); //18号引脚设为输入上拉模式
}
void loop() {
bool data2 = digitalRead(2); //读取2号引脚的数字信号
bool data4 = digitalRead(4); //读取4号引脚的数字信号
bool data5 = digitalRead(5); //读取5号引脚的数字信号
bool data12 = digitalRead(12); //读取12号引脚的数字信号
bool data13 = digitalRead(13); //读取13号引脚的数字信号
bool data14 = digitalRead(14); //读取14号引脚的数字信号
bool data15 = digitalRead(15); //读取15号引脚的数字信号
bool data18 = digitalRead(18); //读取18号引脚的数字信号
Serial.print(data2); //串口输出数字信号的值
Serial.print(",");
Serial.print(data4); //串口输出数字信号的值
Serial.print(",");
Serial.print(data5); //串口输出数字信号的值
Serial.print(",");
Serial.print(data12); //串口输出数字信号的值
Serial.print(",");
Serial.print(data13); //串口输出数字信号的值
Serial.print(",");
Serial.print(data14); //串口输出数字信号的值
Serial.print(",");
Serial.print(data15); //串口输出数字信号的值
Serial.print(",");
Serial.println(data18); //串口输出数字信号的值
delay(1000); //暂停一秒
}
串口监视器清空之前的输出,查看加入了初始化的输出。
这时可以看到,除了2号引脚,加入了初始化代码的引脚已经全部的状态都为高电平。
我们再尝试给引脚设置下拉模式
void setup() {
Serial.begin(115200); //通信速率115200
pinMode(2,INPUT_PULLDOWN); //2号引脚设为输入下拉模式
pinMode(4,INPUT_PULLDOWN); //4号引脚设为输入下拉模式
pinMode(5,INPUT_PULLDOWN); //5号引脚设为输入下拉模式
pinMode(12,INPUT_PULLDOWN); //12号引脚设为输入下拉模式
pinMode(13,INPUT_PULLDOWN); //13号引脚设为输入下拉模式
pinMode(14,INPUT_PULLDOWN); //14号引脚设为输入下拉模式
pinMode(15,INPUT_PULLDOWN); //15号引脚设为输入下拉模式
pinMode(18,INPUT_PULLDOWN); //18号引脚设为输入下拉模式
}
void loop() {
bool data2 = digitalRead(2); //读取2号引脚的数字信号
bool data4 = digitalRead(4); //读取4号引脚的数字信号
bool data5 = digitalRead(5); //读取5号引脚的数字信号
bool data12 = digitalRead(12); //读取12号引脚的数字信号
bool data13 = digitalRead(13); //读取13号引脚的数字信号
bool data14 = digitalRead(14); //读取14号引脚的数字信号
bool data15 = digitalRead(15); //读取15号引脚的数字信号
bool data18 = digitalRead(18); //读取18号引脚的数字信号
Serial.print(data2); //串口输出数字信号的值
Serial.print(",");
Serial.print(data4); //串口输出数字信号的值
Serial.print(",");
Serial.print(data5); //串口输出数字信号的值
Serial.print(",");
Serial.print(data12); //串口输出数字信号的值
Serial.print(",");
Serial.print(data13); //串口输出数字信号的值
Serial.print(",");
Serial.print(data14); //串口输出数字信号的值
Serial.print(",");
Serial.print(data15); //串口输出数字信号的值
Serial.print(",");
Serial.println(data18); //串口输出数字信号的值
delay(1000); //暂停一秒
}
串口监视器清空之前的输出,查看加入了初始化的输出。
这时可以看到,除了5号引脚,加入了初始化代码的引脚已经全部的状态都为低电平。
这里产生了一个问题,为什么在各种模式中,2号引脚的状态永远为低电平。5号引脚的状态永远为高电平。其它的引脚都因不同模式产生了不同的变化。
我们可以在官方文档中找到相关的答案。
官方文档下载地址:技术文档 | 乐鑫科技
下载对应你的ESP32版本的文档,本文中的板子可以查到,GPIO2引脚的说明
文档中说明了2号引脚默认的状态为下拉状态,而5号引脚的说明默认状态为上拉状态。
也就是说,2号引脚默认是直接短接到GND引脚,而5号引脚默认是直接短接到3V3号引脚的。
所以,我们在选择引脚时,最好能对应官方文档,选择合适的引脚来实现你希望的功能。如果你并不确定该引脚的初始状态时,也可以用以上的方法来测试。
最后,我们用一个例子来实现读取一个引脚来控制另一个引脚实现高低电平的变换。
电路连接图:
实现代码:
void setup() {
Serial.begin(115200);
pinMode(4,INPUT_PULLUP); //4号引脚设为输入上拉模式
pinMode(13, OUTPUT); //13号引脚设为输出模式
}
void loop() {
bool data4 = digitalRead(4); //读取4号引脚的数字信号
if(data4 == LOW){ //如果4号引脚为低电平
digitalWrite(13, HIGH); //设置13号引脚为高电平
}else{ //如果4号引脚为高电平
digitalWrite(13, LOW); //设置13号引脚为低电平
}
}
该代码选择了4号引脚为输入引脚,4号引脚通过一个开关与GND连接,当开关按下时,4号引脚与GND发生短接,把4号引脚的电平下拉为低电平。当4号引脚的电平为低时,13号引脚的电平设置为高,点亮LED。当放开开关时,4号引脚与GND断开,4号引脚的电平恢复为高电平,当4号引脚的电平为高时,13号引脚的电平设置为低,关闭LED。
本文中,我们需要了解,并非所有的引脚都可以通过上拉或下拉模式来控制高低电平,因为各个版本不同,需要详细了解哪些引脚为特殊引脚,可以用上面的方法测试或下载官方文档了解更多。