ESP32-Arduino(三)GPIO输入操作,去抖,ADC多按键

GPIO除了输入输出,一般还有很丰富的复用功能,以ESP32为例:

我们在上次开关量输出(HIGH/LOW)先来看输入信号一般的用法:

1. 读取外部接口状态--开关信号量,比如按键

2. 模拟输入, 读取外部信号的电压值

3. 用作中断触发,当状态改变时触发中断,进入预设的处理程序

GPIO其他的输出功能:

1. DAC/PWM

然后就是组合的高速串口接口了,SPI/I2C最为典型,和通用串口的差异就在于支持高速的数据传输,而且主要以同步传输为主(带时钟信号)。

我们这一节主要来看输入的应用,主要三个案例:

1. 读取状态;

2. 增加去抖动处理,提高可靠性

3. 通过模拟输入实现一个IO处理多个按键

4.*触发外部中断

案例1,读取光电开关状态,并控制LED

初级,直接控制状态

/*
  GPIO digital input. 
  P12 connected to an optical switch.
  
*/
#define LED_ON LOW
#define LED_OFF HIGH

#define SWITCH_ON HIGH
#define SWITCH_OFF LOW

// These constants won't change. They're used to give names to the pins used:
const int switchInput=12;
const int led=22;


int switchState ;        // value read from the pot



void setup() {
  // initialize serial communications at 9600 bps:
 
  pinMode(switchInput,INPUT);
  pinMode(led,OUTPUT);
}

void loop() {
  // read the analog in value:
  switchState=digitalRead(switchInput);
  if(switchState==SWITCH_ON) digitalWrite(led,LED_ON);
  
  else digitalWrite(led,LED_OFF);
    

  delay(2);
}

案例2  .升级,加入去抖

/*
  GPIO digital input. 
  P12 connected to an optical switch.
  
*/
#define LED_ON LOW
#define LED_OFF HIGH


#define SWITCH_ON HIGH
#define SWITCH_OFF LOW

// These constants won't change. They're used to give names to the pins used:
const int switchInput=12;
const int led=22;


int switchState = SWITCH_OFF;        // value read from the pot

int lastState=SWITCH_OFF;
int ledState=LED_OFF;

unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers


void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600);
  pinMode(switchInput,INPUT);
  pinMode(led,OUTPUT);
  digitalWrite(led,ledState);
}

void loop() {
  // read the analog in value:
  int readValue=digitalRead(switchInput);
  if(readValue!=lastState){
    // reset the debounce timer
    lastDebounceTime=millis();
    }
   if((millis()-lastDebounceTime)>debounceDelay){
    // longer than limit,set the actual state
    if(readValue!=switchState){
      
      switchState=readValue;
    
      if(switchState==SWITCH_ON){
        ledState=!ledState;
        Serial.println("led stat changed.");
      }
    }
  }
  digitalWrite(led,ledState);
  // save the read value.
   lastState=readValue;
}

关键Arduino库函数: millis(), digitalRead()

millis() - Arduino Reference

digitalRead() - Arduino Reference

案例3, 一个GPIO通过读取模拟信号量来获取多个控制按键

电路连接的原理

代码

// These constants won't change. They're used to give names to the pins used:
const int analogInPin = 12;  // Analog input pin that the potentiometer is attached to
const int led = 22; // Analog output pin that the LED is attached to

int sensorValue = 0;        // value read from the pot


void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600);
}

void loop() {
  // read the analog in value:
  sensorValue = analogRead(analogInPin);

  // print the results to the Serial Monitor:
  Serial.print("sensor = ");
  Serial.print(sensorValue);
  Serial.print("\n ");
 

  // wait 2 milliseconds before the next loop for the analog-to-digital
  // converter to settle after the last reading:
  delay(2);
}

时间关系, 留给大家思考的题目: 

1. 怎么分辨多按键? 

2. 怎么进行滤波处理? 

3. 能否处理组合键? 

4. 如何处理按下和释放? 

Micropython的示例代码:

import machine
from machine import ADC,Pin
import time

led=machine.Pin(22,machine.Pin.OUT)

adc=ADC(Pin(33))

while True:
    
    adcValue=adc.read()
    
    print("voltage: %d mv \r\n"%(adcValue))
    time.sleep(0.1)
    

### ESP32-S3 Arduino LED 控制教程 #### 使用ESP32-S3控制LED的基础方法 对于ESP32-S3而言,其能够利用Arduino IDE编写程序来控制不同类型的LED。无论是简单的单色LED还是复杂的RGB LED以及WS2812B灯带,都可以通过特定的方式进行有效的管理。 当涉及到调整LED亮度时,PWM(脉宽调制)技术被广泛应用。该技术允许改变输出到LED的电压水平从而达到调节亮度的效果[^1]。 针对更高级的应用场景,比如使用光敏电阻根据周围光线强度动态调整LED亮度的情况,在ESP32-S3上可以通过读取模拟输入引脚上的值并将其转换成合适的PWM信号发送给连接的LED实现这一功能。 另外,如果目标是操作像WS2812这样的地址able LED,则需要依赖专门设计用于处理这些设备的数据传输协议的库函数。例如`Adafruit_NeoPixel`或`FastLED`库可以帮助开发者简化对这类复杂灯光系统的编程工作[^2]。 下面给出一段基于上述原理编写的简单示例代码: ```cpp // 导入必要的库文件 #include "esp_wifi.h" #include <WiFi.h> #include <Wire.h> #define LED_PIN 2 // 定义LED所连GPIO编号 int sensorValue; // 存储来自光敏电阻或其他传感器的数值变量 float outputValue; // 经过映射后的最终输出值 void setup() { pinMode(LED_PIN, OUTPUT); // 设置LED针脚模式为输出 Serial.begin(9600); } void loop() { // 假设我们有一个连接至A0口的光敏电阻或者其他形式的模拟量采集装置 sensorValue = analogRead(A0); // 将获取到的最大范围内的ADC值缩放到适合于PWM使用的区间内 (假设最大占空比为255) outputValue = map(sensorValue, 0, 4095, 0, 255); // 输出计算所得的结果作为PWM波形 ledcWrite(CHANNEL_0, outputValue); delay(100); // 短暂延时以便观察效果变化 } ``` 此段代码展示了如何从一个模拟输入端子读数,并据此设置LED的亮度级别。值得注意的是实际应用中可能还需要考虑更因素如噪声过滤等以提高稳定性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海里的鱼2022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值