ESP32-S3 GPIO 点灯

ESP32 S3 入门篇之《GPIO 点灯》,单色发光 LED,通常称为 LED,阳极到负极支持大于 0.6V 可导通,压差增大才会发光。三色发光LED,通常被称为RGB LED,是一种非常有趣的电子元件。它将红色(R)、绿色(G)、蓝色(B)三种颜色的发光芯片封装在同一个灯珠里,通过混合不同强度的三色光,可以模拟出几乎任何你想要的颜色,包括白色。

点击 牛瘪汤 主页可以了解更多。



开发环境

软件开发环境 Arduino IDE。
开发板选择 : ESP32 Arduino。
开发板库:Adafruit_NeoPixel。
板载 IO 控制 LED dengRGB 灯珠,灯珠采用8串联模式,8 数据,可以实现控制8颗灯珠。

1. GPIO 点灯

ESP32-S3 的 GPIO3 连接 LED 灯珠,外部有上拉电阻。LED 阳极接电源(通过上拉电阻),阴极接 GPIO3。当 GPIO3 为高电平时,LED 两端无压差,灯熄灭;当 GPIO3 为低电平时,电流经上拉电阻流向 GPIO3,灯点亮。

const int ledPin = 3; // 定义GPIO3为LED控制引脚

void setup() {
  pinMode(ledPin, INPUT); // 初始设置为输入模式(高阻态)
  digitalWrite(ledPin, HIGH); // 输出高电平,LED熄灭
}

void loop() {
  // 每秒切换LED状态
  digitalWrite(ledPin, LOW); // LED亮
  delay(500);
  digitalWrite(ledPin, HIGH); // LED灭
  delay(500);
}

输入模式与输出电平:ESP32 的 GPIO 在输入模式下仍可通过 digitalWrite 设置内部上拉/下拉电阻。此处设置为输入并输出高电平,实际为高阻态,依赖外部上拉维持高电平。
电平逻辑:HIGH 时 GPIO3 电压接近电源电压,LED 无电流;LOW 时 GPIO3 接地,电流形成回路。

2. GPIO 呼吸灯

ESP32-S3 的 GPIO3 连接 LED 灯珠,外部有上拉电阻。呼吸灯与 GPIO 亮灭灯实现逻辑大有不同。呼吸灯需要用到 PWM 模拟(脉冲宽度调制)控制LED亮度,通过改变占空比模拟呼吸效果。

PWM频率:5000Hz适合LED控制,过高可能超出LED响应能力
分辨率:8位提供256级亮度调节,12位可达4096级但视觉差异不明显
占空比计算:实际电压 = (占空比值/255) × 供电电压

LED限流电阻计算:R = (Vcc - VLed) / ILed
上拉电阻典型值:10KΩ(当GPIO内部无上拉时)。

const int ledPin = 3;
const int freq = 5000;      // PWM频率
const int channel = 0;      // PWM通道
const int resolution = 8;   // 8位分辨率(0-255)

void setup() {
  ledcSetup(channel, freq, resolution);
  ledcAttachPin(ledPin, channel);
}

void loop() {
  // 渐亮效果
  for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle++) {
    ledcWrite(channel, dutyCycle);
    delay(10);
  }
  
  // 渐暗效果
  for (int dutyCycle = 255; dutyCycle >= 0; dutyCycle--) {
    ledcWrite(channel, dutyCycle);
    delay(10);
  }
}

3. GPIO 跑马灯

串联 8 颗 RGB 灯珠,单颗 RGB LED 共用阳极,阳极分别与GPIO2-9;负极 R、G、B 并联8颗 LED。RGB三色交替闪烁。
RGB x 8

  • 阳极控制
    8颗LED的阳极分别独立连接至Arduino的GPIO2~GPIO9,每个GPIO控制一颗LED的阳极通断。
  • 阴极控制
    所有LED的红色阴极并联后串联限流电阻,接至PWM引脚GPIO10;绿色阴极并联接GPIO11,蓝色阴极并联接GPIO12。PWM引脚通过调节占空比控制颜色亮度。

限流电阻计算
RGB LED的限流电阻需根据LED正向压降(如红色2V,绿/蓝3V)和Arduino PWM引脚输出电流(通常20mA)计算:

红色阴极电阻: R = V c c − V f r e d I = 5 V − 2 V 0.02 A = 150 Ω R = \frac{V_{cc} - V_{f_red}}{I} = \frac{5V - 2V}{0.02A} = 150Ω R=IVccVfred=0.02A5V2V=150Ω
绿/蓝阴极电阻: R = 5 V − 3 V 0.02 A = 100 Ω R = \frac{5V - 3V}{0.02A} = 100Ω R=0.02A5V3V=100Ω

const int LED_PINS[] = {2, 3, 4, 5, 6, 7, 8, 9}; // 阳极引脚  
const int RED_PIN = 10;  // 红色阴极PWM  
const int GREEN_PIN = 11; // 绿色阴极PWM  
const int BLUE_PIN = 12;  // 蓝色阴极PWM  

void setup() {  
  for (int i = 0; i < 8; i++) {  
    pinMode(LED_PINS[i], OUTPUT);  
    digitalWrite(LED_PINS[i], LOW); // 初始关闭阳极  
  }  
  pinMode(RED_PIN, OUTPUT);  
  pinMode(GREEN_PIN, OUTPUT);  
  pinMode(BLUE_PIN, OUTPUT);  
}  

void setLED(int ledIndex, int r, int g, int b) {  
  digitalWrite(LED_PINS[ledIndex], HIGH); // 开启指定阳极  
  analogWrite(RED_PIN, 255 - r); // 共阳需反向PWM  
  analogWrite(GREEN_PIN, 255 - g);  
  analogWrite(BLUE_PIN, 255 - b);  
  delay(10); // 短暂点亮  
  digitalWrite(LED_PINS[ledIndex], LOW); // 关闭阳极  
}  

void loop() {  
  for (int i = 0; i < 8; i++) {  
    setLED(i, 255, 0, 0); // 红色  
    delay(100);  
    setLED(i, 0, 255, 0); // 绿色  
    delay(100);  
    setLED(i, 0, 0, 255); // 蓝色  
    delay(100);  
  }  
}  

共阳逻辑:PWM输出需反向(255 - value),因阴极电压越低亮度越高。
动态显示:快速轮询点亮LED可实现静态显示效果,类似矩阵扫描。
电流限制:确保并联LED总电流不超过 ESP32 S3 引脚最大驱动能力(单个PWM引脚约40mA)。

4. GPIO 流水灯

  • 硬件原理图
    8颗共阳RGB LED的阳极分别连接到Arduino的GPIO2-GPIO9,红色阴极并联后通过限流电阻连接到GPIO10(PWM),绿色阴极连接到GPIO11(PWM),蓝色阴极连接到GPIO12(PWM)。需确保限流电阻阻值合适(通常220Ω-1kΩ)。
    RGB x 8
  • 彩虹效果实现原理
    彩虹效果通过循环改变HSV色彩空间的H(色调)值实现,同时固定S(饱和度)和V(亮度)为最大值。HSV需转换为RGB值后输出到PWM引脚。颜色交替变化,类似彩虹流水灯。
const int redPin = 10;    // 红色阴极PWM引脚
const int greenPin = 11;  // 绿色阴极PWM引脚
const int bluePin = 12;   // 蓝色阴极PWM引脚
const int ledPins[] = {2,3,4,5,6,7,8,9}; // 阳极控制引脚

// HSV转RGB函数
void hsvToRgb(float h, float s, float v, int& r, int& g, int& b) {
  int i = int(h * 6);
  float f = h * 6 - i;
  float p = v * (1 - s);
  float q = v * (1 - f * s);
  float t = v * (1 - (1 - f) * s);
  
  switch(i % 6){
    case 0: r = v*255; g = t*255; b = p*255; break;
    case 1: r = q*255; g = v*255; b = p*255; break;
    case 2: r = p*255; g = v*255; b = t*255; break;
    case 3: r = p*255; g = q*255; b = v*255; break;
    case 4: r = t*255; g = p*255; b = v*255; break;
    case 5: r = v*255; g = p*255; b = q*255; break;
  }
}

void setup() {
  for(int i=0; i<8; i++){
    pinMode(ledPins[i], OUTPUT);
    digitalWrite(ledPins[i], HIGH); // 共阳LED初始点亮
  }
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
}

void loop() {
  static float hue = 0; // 色调值0-1.0
  
  // 计算当前RGB值
  int r, g, b;
  hsvToRgb(hue, 1.0, 1.0, r, g, b);
  
  // 输出到PWM引脚(共阳LED需反向输出)
  analogWrite(redPin, 255 - r);
  analogWrite(greenPin, 255 - g);
  analogWrite(bluePin, 255 - b);
  
  // 更新色调值
  hue += 0.001;
  if(hue >= 1.0) hue = 0;
  
  delay(10);
}

共阳LED需将阳极设为高电平才能工作,因此初始化时将GPIO2-GPIO9设为HIGH。PWM输出时需注意共阳LED是阴极控制,因此实际输出值为255减去计算得到的RGB值。

彩虹效果通过循环递增HSV的H值实现,每次增加0.001(可调整此值改变变化速度)。延时10ms可控制色彩变化平滑度。

结尾

文章都看到完了,就不点个关注吗,老铁!
欢迎关注博主–牛瘪汤

更多推荐