

检测GPIO高低电平
1. 中断
2. 轮询
gpio.ino

// ============ GPIO按键输入 ============// 监听高电平接线图
// ESP8266 NodeMCU
// ┌───────────┐
// │   D1(GPIO5)  │──────┤按键一端
// │           │      │
// │   3V3     │──────┤按键另一端
// └───────────┘// 监听低电平接线图
// ESP8266 NodeMCU
// ┌───────────┐
// │   D1(GPIO5)  │──────┤按键一端
// │           │      │
// │   GND     │──────┤按键另一端
// └───────────┘#include "button.h"  // 添加按钮头文件
#include "gpioinput.h"  #define ISR_PREFIX ICACHE_RAM_ATTR
Button button1(D1); // 中断模式,监听高电平信号
GPIOInput button2(D2, 20, 5);// 轮询模式void setup() {Serial.begin(9600);  // 先初始化串口Serial.println("MCU RUN");  // 再输出信息button1.setCallback([](){ if (HIGH == digitalRead(D1)) {Serial.printf("Button1 Pressed,%d\n", digitalRead(D1));} });button1.begin();  
}void loop() {  int val = button2.read();if (val == LOW) {  // LOW HIGHSerial.println("按钮按下!");  } delay(100);  
} 
 

button.h

#ifndef Button_H
#define Button_H#include <Arduino.h>
#include <functional>class Button {
public:typedef std::function<void()> Callback;Button(uint8_t pin);void begin();void setCallback(Callback cb);private:uint8_t pin;Callback pressedCallback;static Button* instance;static void IRAM_ATTR isrHandler();
};#endif  
 

button.cpp

#include "Button.h"Button* Button::instance = nullptr;Button::Button(uint8_t pin)  : pin(pin) {instance = this;
}void Button::setCallback(Callback cb) {pressedCallback = cb;
}void Button::begin() {pinMode(pin, INPUT_PULLUP);// INPUT(输入) OUTPUT(输出) INPUT_PULLUP(上拉输入) INPUT_PULLDOWN(下拉输入)attachInterrupt(digitalPinToInterrupt(pin), isrHandler, CHANGE);// RISING(上升沿L->H) FALLING(下降沿H->L) CHANGE(改变时)
}void IRAM_ATTR Button::isrHandler() { Serial.printf("Current Value,%d\n", digitalRead(D1));// 硬件去抖处理(通过使用电容器和电阻器电路来进行去抖动)  if (instance->pressedCallback) {instance->pressedCallback();} 
}  
 

gpioinput.h

#ifndef GPIOINPUT_H  
#define GPIOINPUT_H  #include <Arduino.h>  class GPIOInput {  
public:  // 构造函数  GPIOInput(int pin, int checkInterval, int checkCount);// 轮询方法, 返回当前状态  int read();  private:int pin = 0;int checkInterval = 0;int checkIndex = -1;int checkCount = 0;long checkTime = 0; int stateOld = 0;int stateTemp = 0; 
};  #endif // GPIOINPUT_H 
 

gpioinput.cpp

#include "gpioinput.h"  // 构造函数  
GPIOInput::GPIOInput(int pin, int checkInterval, int checkCount) : pin(pin), checkInterval(checkInterval), checkCount(checkCount) {pinMode(pin, INPUT);  stateOld = stateTemp = digitalRead(pin);Serial.println("pin input:" + String(pin));
}  // 轮询读取引脚状态  
int GPIOInput::read() {  if ((0 != checkIndex) && (millis() - checkTime) <= checkInterval) return -1;// 过滤中间时段的数据int state = digitalRead(pin); if (state != stateTemp){checkIndex = 0;stateOld = stateTemp;}else{if (state != stateOld){checkIndex++;checkTime = millis();}}stateTemp = state;int ret = -1; if (checkIndex == checkCount) {checkIndex = 0;if (stateOld != state) {stateOld = state;ret = state;}}return ret;  
} 
 
