02_ESP32 数字信号控制

02_ESP32 数字信号控制

1、数字信号

数字信号是用离散的数值来表示信息的信号。最简单、最常见的数字信号是二进制数字信号,它只有两种状态。

在 ESP32 的 GPIO 控制中,主要使用这种二进制数字信号,二进制数字信号在任何时刻都处于两种明确状态之一:

  • 高电平 (HIGH): 代表逻辑上的 "1" 或 "真"。在 ESP32 开发板上,这通常意味着引脚输出接近 3.3V 的电压。
  • 低电平 (LOW): 代表逻辑上的 "0" 或 "假"。在 ESP32 开发板上,这通常意味着引脚输出大约 0 伏特的电压,也就是连接到地 (GND)。

image-20260519141459972

简单来说,数字信号就是用这两种电压状态来传递是 (HIGH) / 否 (LOW) 或者 1 / 0 这样的信息。

  • 当 ESP32 输出一个数字信号时,它控制一个引脚变成高电平或低电平,就像是在“说话”,比如控制 LED 的开关。
  • 当 ESP32 输入一个数字信号时,它检测一个引脚上是高电平还是低电平,就像是在“倾听”,比如检测按钮是否被按下。

2、输出代码示例

const int ledPin = 7;   // LED 连接的引脚号

// setup 函数在开发板上电或复位后运行一次
void setup(){
  // 将引脚初始化为输出模式
  pinMode(ledPin,OUTPUT);
}

// loop 函数会永远反复执行
void loop(){
  digitalWrite(ledPin,HIGH);  // 点亮 LED (HIGH 表示高电平)
  delay(1000);
  digitalWrite(ledPin,LOW);   // 引脚输出低电平,关闭 LED
  delay(1000);
}

上传代码后,与 ESP32 开发板连接的 LED 将会亮起一秒,熄灭一秒,如此循环往复。

image-20260519142944387

代码解析:

  1. const int ledPin = 7;
    • 使用 const int 定义一个常量,这样如果要换引脚,只需修改这一处。
    • const 表示这个值在程序运行期间不会改变。
  2. pinMode(ledPin, OUTPUT);
    • pinMode()函数的作用: 配置指定引脚的工作模式,需要在使用数字引脚前调用。
    • 第一个参数: 引脚编号
    • 第二个参数:模式类型
      • OUTPUT:输出模式,ESP32 可以控制这个引脚输出高电平或低电平。
  3. digitalWrite(ledPin, HIGH)
    • digitalWrite()函数的作用: 向输出引脚输出值
    • 第一个参数: 引脚编号
    • 第二个参数:要输出的电平
      • HIGH:输出高电平(3.3V),LED 点亮。
      • LOW:输出低电平(0V),LED 熄灭。
  4. delay(1000);
    • delay()函数的作用: 暂停程序执行指定的毫秒数
    • 1000 毫秒 = 1 秒。
    • delay() 期间,程序不执行其他操作。这意味着在 delay() 期间,ESP32 不能响应其他事件,例如读取传感器或按钮。在更复杂的项目中,需要使用非阻塞的延时方法。

3、输入代码示例

image-20260519143110748

image-20260519143206336

示例 1:读取按钮状态

const int buttonPin = 8;            // 定义按钮连接的引脚

void setup(){
  Serial.begin(9600);               // 初始化串口通信,波特率 9600
  while(!Serial){}                  // 等待串口建立连接

  pinMode(buttonPin,INPUT_PULLUP);  // 设置按钮引脚为上拉输入模式
}

void loop(){
  int buttonState = digitalRead(buttonPin);  // 读取按钮当前状态
  Serial.println(buttonState);               // 串口输出按钮状态值
}

代码解释:

  1. const int buttonPin = 8;:定义按钮连接的引脚。
  2. Serial.begin(9600);:初始化串口通信,波特率设置为 9600。
  3. pinMode(buttonPin, INPUT_PULLUP);
    • buttonPin 设置为 INPUT_PULLUP 模式。
    • INPUT_PULLUP 是一个特殊的输入模式,它会启用 ESP32 GPIO 引脚内部的上拉电阻。这样,当按钮未按下时,引脚会被拉到高电平;当按钮按下将引脚连接到 GND 时,引脚变为低电平。这避免了连接外部上拉电阻的需要。
  4. int buttonState = digitalRead(buttonPin);
    • digitalRead() 函数用于读取指定数字引脚的电平状态。
    • 它返回 HIGH (通常是整数 1) 或 LOW (通常是整数 0)。
    • 由于使用了INPUT_PULLUP
      • 按钮未按下:buttonStateHIGH
      • 按钮按下:buttonStateLOW
  5. Serial.println():将括号内的内容打印到串口监视器,并换行。

运行结果:

将代码烧录到 ESP32 开发板后,打开串口监视器。按钮未按下时,串口监视器会持续显示"1";按下按钮时,显示"0"。你可以通过按压和释放按钮来观察这些状态的变化。

示例 2:记录按钮按下的次数

const int buttonPin = 8;

int lastButtonState = 1;            // 上一次按钮状态
int currentButtonState;             // 当前按钮状态
int count = 0;                      // 计数器

void setup(){
  Serial.begin(9600);               // 初始化串口波特率
  while(!Serial){}                  // 等待串口连接

  pinMode(buttonPin,INPUT_PULLUP);  // 设置按钮引脚为上拉输入
}

void loop(){
  currentButtonState = digitalRead(buttonPin);  // 读取当前按钮状态

  if(lastButtonState == HIGH && currentButtonState == LOW){
    // 按钮被按下
  } else if(lastButtonState == LOW && currentButtonState == HIGH){
    // 按钮被释放
    count = count + 1;          // 计数器加 1
    Serial.println(count);      // 串口输出当前计数值
  }

  lastButtonState = currentButtonState;   // 保存当前按钮状态
}

代码解释:

  1. int lastButtonState = HIGH;:由于我们使用 INPUT_PULLUP 模式,按钮未按下时引脚为高电平,所以初始值设为 HIGH
  2. 状态检测逻辑
    • lastButtonState == HIGH && currentButtonState == LOW:引脚由高电平到低电平,检测按钮刚被按下的瞬间
    • lastButtonState == LOW && currentButtonState == HIGH:引脚由低电平到高电平,检测按钮刚被释放的瞬间
    • 我们选择在按钮释放时计数
  3. lastButtonState = currentButtonState;:在每次循环结束时更新状态,为下一次比较做准备。

运行结果:

烧录代码后打开串口监视器。尝试多次按下按钮,你可能会发现计数器有时会增加 1,但有时会突然增加 2、3 或者更多。这就是按钮抖动 (Button Bouncing)。

示例 3:简单的防抖算法

一种简单的消除抖动的方法是在检测到一次按键后,加入一个短暂的延时,忽略掉后续的抖动信号。

image-20260519145836472

const int buttonPin = 8;

int lastButtonState = 1;            // 上一次按钮状态
int currentButtonState;             // 当前按钮状态
int count = 0;                      // 计数器

void setup(){
  Serial.begin(9600);               // 初始化串口波特率
  while(!Serial){}                  // 等待串口连接

  pinMode(buttonPin,INPUT_PULLUP);  // 设置按钮引脚为上拉输入
}

void loop(){
  currentButtonState = digitalRead(buttonPin);  // 读取当前按钮状态

  if(lastButtonState == HIGH && currentButtonState == LOW){
    // 按钮被按下
  } else if(lastButtonState == LOW && currentButtonState == HIGH){
    // 按钮被释放
    count = count + 1;          // 计数器加 1
    Serial.println(count);      // 串口输出当前计数值
    delay(100);                 // 延时 100 毫秒防抖
  }

  lastButtonState = currentButtonState;   // 保存当前按钮状态
}

运行结果:

和上面一样,每松开按钮一次,计数器加 1,并且因为加了 delay(100),每次按钮弹起只会计数一次,有效减少了误触发数量。你可以尝试快速多次按按钮,留意计数器增量是否与实际按动匹配。

posted @ 2026-05-19 15:02  Q&25  阅读(17)  评论(0)    收藏  举报