项目 Wiki>ESP32 开发板>ESP32 基础外设:GPIO、PWM 与 ADC

ESP32 基础外设:GPIO、PWM 与 ADC

摘要:掌握 ESP32 最常用的三类外设操作,用 Arduino 框架控制数字引脚、输出 PWM 调光调速、读取模拟电压,并了解各引脚的特殊限制。

数字输出与输入(GPIO)

ESP32 的通用输入输出引脚由 GPIO 矩阵统一管理,绝大多数引脚既可作输入也可作输出。Arduino 框架下使用 pinMode() 与 digitalWrite()、digitalRead() 控制,与经典 Arduino 用法一致。

const int LED = 2;

void setup() {
  pinMode(LED, OUTPUT);
}

void loop() {
  digitalWrite(LED, HIGH);
  delay(500);
  digitalWrite(LED, LOW);
  delay(500);
}

读取按键等外部信号时,把引脚设为 INPUT_PULLUP(内部上拉),按键另一端接地,按下读到 LOW,松开读到 HIGH。

哪些引脚不能随便用

ESP32 共有 34 个物理 GPIO,但一部分有特殊用途,做普通 IO 前要留心:

  • GPIO 34、35、36、39:仅输入,没有内部上拉下拉,适合接 ADC 或数字传感器,不能做输出
  • GPIO 6-11:连接内部 Flash,动了会直接崩溃,不要使用
  • GPIO 0、2、5、12、15:参与启动模式判断与上电电平检测,可用但外接电路不能影响上电时的默认电平,否则设备无法正常启动或进不了烧录模式
  • GPIO 1、3:默认串口 TX/RX,调试期间建议保留

PWM 输出(LEDC)

ESP32 的 PWM 由 LEDC 外设(原本为驱动 LED 设计,共 16 个通道)产生,可输出独立频率与占空比的方波,常用于 LED 调光、电机调速和驱动舵机。

Arduino-ESP32 3.x 对 API 做了重要简化:不再手动分配通道,直接把引脚、频率、分辨率一并交给 ledcAttach(),之后用 ledcWrite() 按引脚写占空比。2.x 时代的 ledcSetup() 与 ledcAttachPin() 已废弃,网上大量旧教程还在用,照抄会编译报错。

const int LED = 2;      // 任意支持输出的 GPIO
const int FREQ = 5000;  // 5 kHz
const int RES  = 8;     // 8 位分辨率

void setup() {
  ledcAttach(LED, FREQ, RES);  // 自动分配通道
}

void loop() {
  for (int duty = 0; duty <= 255; duty++) {
    ledcWrite(LED, duty);
    delay(5);
  }
  for (int duty = 255; duty >= 0; duty--) {
    ledcWrite(LED, duty);
    delay(5);
  }
}

频率与分辨率的权衡

LEDC 的时钟源固定,频率和分辨率此消彼长:频率越高,可用的分辨率位数越少。常用组合:

  • LED 调光:5 kHz、8 位(占空比 0-255)
  • 舵机控制:50 Hz、16 位(脉宽精度约 0.5 微秒)

如果只需要简单调光,也可以直接用 analogWrite(pin, value),它内部走 LEDC,取值 0-255,与 AVR Arduino 习惯一致。

模拟输入(ADC)

ESP32 内置两个 12 位逐次逼近型 ADC(ADC1、ADC2),共 18 个输入通道,读数范围默认 0-4095,对应约 0-3.3 V。使用 analogRead(pin) 即可读取:

const int POT = 34;  // 电位器接 GPIO34

void setup() {
  Serial.begin(115200);
}

void loop() {
  int raw = analogRead(POT);
  float voltage = raw * 3.3 / 4095.0;
  Serial.printf("raw=%d  voltage=%.2fV\n", raw, voltage);
  delay(200);
}

使用注意

  • ADC2 与 WiFi 冲突:ADC2 的所有引脚在 WiFi 开启时不可用,WiFi 项目中的模拟输入一律选 ADC1 引脚(GPIO 32-39)
  • 满量程并非精确 3.3 V:ESP32 的 ADC 非线性较明显,绝对精度约 ±3%,适合趋势判断(如电位器、光敏电阻),做精确电压测量需校准或外接 ADC
  • 衰减设置:默认量程约 1.1 V,需用 analogSetPinAttenuation(pin, ADC_11db) 把量程扩到约 3.3 V(新版核心多数引脚默认已是 11 dB,读满量程前建议显式设置一次)

动手实验:呼吸灯 + 旋钮调光

把前面内容串起来:电位器接 GPIO34(ADC1),LED 接 GPIO2,转动旋钮实时改变 LED 亮度。

const int POT = 34;
const int LED = 2;

void setup() {
  ledcAttach(LED, 5000, 8);
}

void loop() {
  int raw = analogRead(POT);          // 0-4095
  int duty = map(raw, 0, 4095, 0, 255);
  ledcWrite(LED, duty);
  delay(20);
}

烧录后转动电位器,LED 亮度应平滑跟随。若 LED 不亮,先检查引脚是否误用了 GPIO 6-11;若读数始终为 0 或 4095,检查电位器接线与衰减设置。

常见坑速查

  • 编译报 ledcSetup was not declared:在用 2.x 旧 API,改用 ledcAttach / ledcWrite
  • 引脚无输出:确认不是 GPIO 34-39(仅输入)或 GPIO 6-11(Flash 专用)
  • 上电反复重启或进不了烧录模式:GPIO 0、2、12、15 上外接了影响启动电平的电路
  • 开了 WiFi 后模拟读数异常:用了 ADC2 引脚,换 GPIO 32-39

资料来源

  • Espressif 官方文档
  • Arduino-ESP32 官方仓库
  • Random Nerd Tutorials
  • iotwithesp

相关内容

DIY机器人想听懂人话,离线语音模块怎么选?问答DIY机器车,主控用ESP32够不够打?问答NRF24L01双Arduino通信实操:接线收发与供电坑实践ESP32-C6-DevKitC-1深拆:Wi-Fi6双协议实践OLED、TFT彩屏、电子墨水屏横评:创客项目怎么选实践Wemos D1 mini深拆:4MB闪存为何仍是入门首选实践ESP32 Web服务器实操:局域网网页按钮控制LED实践HC-SR501 人体感应接 Arduino 自动点灯实操实践DHT11/DHT22接ESP32实操:读温湿度、校准与显示实践公交到站信息显示器 · 基于ESP32和墨水屏实践麦克纳姆轮全向小车运动学解算与电机控制实践Nano 33 BLE Sense深拆:9轴IMU全能板实践光照检测怎么选:光敏电阻、光敏模块与BH1750实践M5Stack AtomS3深拆:240MHz双核拇指控制器实践TM1637四位数码管接Arduino:时钟显示到计数器实践ESP32-C6-DevKitC-1深拆:WiFi6双栈入门实践DHT11/DHT22接ESP32:读温湿度到OLED显示实践ESP32接DS3231时钟模块:设置时间到读时间实践ESP32-S3-DevKitC-1深拆:3种内存版本怎么挑实践Mega 2560深拆:54路I/O、4路串口的5V老将实践机械蝴蝶、游泳机器人、智能鸡舍实践校园卫生间冲水提醒器:28元语音提示器全制作实践Firebeetle 2 C5做PT100温度计:宽范围测温实践ESP-Mosaico AI开发平台:从硬件到Agent闭环实践ESP-Mosaico智能套件上手:AI编码与模块化扩展实践WS2812B接ESP32:一根GPIO点亮幻彩灯条实践继电器模块接Arduino控制台灯,新手一次点亮实践XIAO ESP32S3 Sense:8MB+OV5640实践CH340、CP2102与PL2303串口芯片怎么选实践ESP32-P4深拆:双核RISC-V跑400MHz的旗舰实践TM1637 数码管接ESP32:四根线点亮四位数字实践Firebeetle 2 ESP32 C5驱动OLED实测实践拇指盖摄像头小板:XIAO ESP32-S3 Sense深拆实践HX711称重传感器接ESP32:接线校准与读重实操实践行空板K10变身AI PassPort:语音问答与猜谜互动实践基于小龟板与行空板联动的机械臂小车实践乐鑫ESP32、S3、C3三款芯片怎么选实践Uno R4 WiFi深拆:48MHz双芯+12x8矩阵实践PCA9685舵机驱动板:接线、I2C地址、驱动代码全流程实践DS18B20接ESP32教程:单总线接线与读取温度实操实践CoreS3深拆:ESP32-S3双核240MHz触摸屏实践Romeo ESP32-S3深拆:四路2.5A电机驱动实践ESP32-CAM 拍照实操:烧录接线、网页预览与取流实践行空板K10小智AI聊天机器人:固件烧录与配置实践游泳池水质怎么检测?从余氯、pH到DIY监测系统实践DFRobot气体传感器选型指南实践Firebeetle 2 ESP32 C5评测:点亮OLED实践测距方案怎么选:HC-SR04、VL53L0X与红外对比实践SSD1306 OLED配ESP32:I2C接线与显示实操实践STEM教育 · K10对讲机项目实践智能蓝联防遗忘雨伞 · ESP32 创客项目实践Nano ESP32深拆:240MHz双核+16MB闪存实践MPU6050接ESP32教程:读加速度、角速度与姿态角实践AS5600磁编码器配ESP32:机械臂关节角度测量实操实践STEM教育 · 可调机翼观测站:用数据解密飞机升空实践传送带键盘与战损版S23游戏机实践ESP32配网别再写死密码:WiFiManager双路线实操实践Petoi Bittle深拆:9关节舵机,掌心开源机器狗实践ESP-NOW入门:两块ESP32免路由器无线通信实践myArm 300 Pi深拆:7轴桌面臂1499美元值不值实践HC-SR501人体红外PIR接ESP32:接线调参避坑实践降压模块怎么选:LM2596、TPS5430与1117横评实践RC522 RFID读卡接ESP32:接线、读UID与避坑实践电钻电池供电的 Cyberdeck、能捡垃圾的履带车实践ST3215总线舵机机械臂:从激光切割到双向数字孪生实践语音指挥农夫自动寻路!行空板K10+MCP打造AI 3D农场实践ESP-Mosaico 入门:乐鑫模块化 AI 套件上手实践ESP32接VS1838B:红外NEC解码与按键控制实践红米 Note 10 Pro 成功跑起 iOS 16实践灵眸小智:基于自研扩展板的桌面AI交互机器人实践掌控板+AI:低成本多通道高中物理超重失重实验实践AI健身助手 · 行空板K10+姿势识别实践智居中枢:基于行空板M10的触摸式智能家居终端实践声光律动灯 · 基于 ESP32 的 RGB 音量可视化装置实践HC-SR04超声波测距接ESP32:接线代码与精度实践myCobot 280 深拆:六轴开源桌面机械臂值不值实践机器人显示模块横评:OLED、TFT、墨水屏怎么选实践AS5600磁编码器接ESP32,四根线读出0到360度实践透明 OLED 蓝牙歌词显示及音乐控制器实践当我把K10做成音乐播放器,再加入小智后是这样!实践ESP32-CAM实操:烧录固件、拍照上传与局域网图传实践HuskyLens/Grove V2/MaixCAM怎么选实践ESP32 DS18B20温度传感器接线与读数教程实践PiDog/MechDog/PuppyPi三款机器狗怎么选实践心率监测仪项目:ESP32+MicroPython实战实践ESP32 双 I2C 总线:21/22 引脚与多设备接法实践ESP-Mosaico V1.2 硬件手册电源与管脚详解实践ESP32-C3方盒水动力灯用点阵模拟真实液体流动实践执行器与模块怎么选:从电机、继电器到通信模块实践桌面机械臂怎么选:越疆、幻尔、大象三款横评实践Bittle X四足机器狗深拆:ESP32主控+9自由度实践ESP32配DWM3000自制UWB定位:3基站精度10厘米实践行空板K10人脸检测:自动给脸加马赛克遮挡实践行空板K10显示楷体彩色汉字:点阵取模加画布实践三款ROS开源小车横评:90美元底盘到659美元整机实践NeoPixel 灯环做机器人眼睛:16灯接线与眨眼代码实践ESP32数字消消乐小游戏:按键灯带加LCD实践VCNL4040接Arduino:20cm测距与照度二合一实践ESP32驱动28BYJ-48:2048步一圈的接线与代码实践Arduino、ESP32驱动BMV080 PM2.5空气质量传感器实践会议麦克风如何同时处理USB音频与蓝牙回声消除实践Arduino、ESP32驱动STCC4二氧化碳传感器实践Arduino、ESP32驱动PAV3015空气流速传感器实践Arduino、ESP32驱动BMP585气压温度传感器实践Arduino、ESP32驱动BMP581气压温度传感器实践3款200美元级LeRobot桌面臂横评:参数和选型实践3款200美元级LeRobot桌面臂横评:参数和选型实践3款200美元LeRobot桌面臂横评:参数和选型实践Arduino、ESP32驱动PAV3015空气流速传感器(实践Arduino、ESP32驱动BMV080实践Arduino、ESP32驱动BMP585气压温度传感器(压实践Arduino、ESP32驱动BMP581气压温度传感器(压实践基于物联网SIOT的便携式学生用气象监测胶囊实践BTS7960 电机驱动模块 43A大功率 H桥马达电子智实践基于物联网SIOT的便携式学生用气象监测胶囊实践3款入门激光测距传感器横评:小车避障选哪颗实践Petoi Quaddle深拆:99美元四舵机机器狗硬件账实践Arduino、ESP32驱动BMP581气压温度传感器实践Mind+V2 通信扩展库|经典蓝牙:手机遥控就这么简单实践【造点好玩的】我做了一个能说会道实践我用行空板K10做了一个南京博物院的AI讲解器实践K10行空板,走出课堂,走近煤炭生产环境实践开源飞行雷达桌面摆件实践超解压的弹珠迷宫游戏实践XGO-mini2SW深拆:399美元起的桌面轮腿AI机器人实践PCA9685接Arduino:2个引脚控制16路舵机实操实践开源飞行雷达桌面摆件——移植Dask Rader到M5D实践给机器人加WS2812B状态灯带:Arduino接线实操实践桌面机器狗横评:Quaddle到Gogobot D1三款实践ESP32四足蜘蛛机器人搭建:8舵机蓝牙遥控,3小时完工实践FluidBox流体模拟移植到ESP32实录实践行空板K10国庆升旗模拟项目实践行空板K10像素电子宠物制作教程实践行空板K10弹珠迷宫Python版教程实践三款LeRobot机械臂横评:入门到研究怎么选实践Hexapod开源六足家族深拆:三款体型一套固件的设计逻辑实践WiFi蜘蛛机器人搭建教程:12舵机+ESP32网页遥控实践Agent友好开发范式:行空板K10工程实践实践EDGE101开箱:ESP32工业控制器点灯教程实践ESP32-CAM WiFi小车:浏览器实时遥控实践RIG-Hover自平衡搭建教程:ESP32加LQR控制实践标准舵机核心功能与原理详解实践4款入门桌面机械臂横评:60到230美元怎么选实践Petoi Quaddle深拆:4个舵机怎么走出四足步态实践60美元四足机器人Sesame实操指南实践ESP32-C5管道流体脉动采集实践ESP32-C5弹簧振子阻尼实验实践Q8botOne掌中四足:零布线组装与ESP32控制入门实践ESP32四足狗入门:BiBoard接线与步态调试实践TCS34725接Arduino:颜色识别从接线到分拣实战实践ESP32-CAM 图传入门:30 块钱给机器人装个第一视角实践VL53L0X激光测距实战:接线、装库到双传感器改地址实践旧安卓手机塞进人形机器人:UCLA这个开源方案成本400美元实践从零学硬件第三篇:传感器就是硬件的五官实践告别红外误判:毫米波传感器打造工位感知系统实践给独居老人装毫米波跌倒告警:隐私与通知取舍实践从零学硬件第二篇:主板就像大脑与神经中枢实践从零学硬件:主板就是机器的大脑和神经中枢实践ESP32+MPU6050自制双足自平衡机器人入门实践OmArm One开源7DOF机械臂:3D打印+ROS2教程实践四足机器狗步态控制:从Trot到MPC方案怎么选实践SO-ARM102开源机械臂BOM公开:404美元造一对手臂实践2026年3款入门级开源四足机器狗方案横评实践Petoi Quaddle:109美元的开源迷你机器狗都能做什么实践12舵机DIY四足机器狗:3D打印+蓝牙遥控从零搭建实践ESP32-S3驱动CAN总线伺服教程:给你的机器狗升级关节实践myCobot 280拆解:250g负载桌面臂的软硬件架构全解析实践2026年5款众筹爆款机器人:从轮足到软体都有哪些新物种实践ESP32+PCA9685搭6DOF桌面机械臂:从接线到控制全攻略实践掌控板物理实验玻意尔定律探究装置实践六足螃蟹机逆运动学入门:ESP32实时解算不卡顿实践42闭环步进电机驱动:智能小车精密定位不再靠开环实践IBT-4电机驱动模块50A:大电流H桥驱动实测实践36GP全金属555行星减速电机:14.4V427rpm实践WPM20L5G步进减速电机:20mm行星带霍尔反馈实践ESP32-C3+LIS2DW12做方盒水动力灯:模拟真实液体晃动实践电动轮椅底盘加ESP32和ROS2:给机器人做移动平台的改装思路实践ESP32做Web蓝牙控制轮式机器人:手机浏览器直接操控不用装App实践SO-ARM101和NexArm横评:130美元入门款和600元性能款差在哪实践12自由度四足蜘蛛机器人DIY:3D打印件加Arduino从零搭建全流程实践MAX7219 LED点阵屏接ESP32:给机器人做表情显示模块实践3D打印六足机器人开源方案:MG996R舵机+Arduino步态控制实践WS2812灯带接ESP32:用FastLED库做机器人状态指示灯实践ESP32+超声波避障小车:HC-SR04+舵机扫描做自动避障实践ESP32桌面表情互动机器人DIY:OLED表情+触摸反馈+舵机转头实践Q8botOne开源掌上机器狗:199美元套件ESP32-C3+DYNAMIXEL全解析实践旧物重生:刮胡刀变AI语音警报器实践小智AI语音打靶机器人制作教程实践ESP32C6小智AI情绪小车制作教程实践ESP32-C3+小智MCP自然语言控制彩灯实践5V继电器模块接ESP32:多路设备电源时序控制与隔离驱动实践红外避障传感器做AGV循迹小车:5路红外阵列加PID调速实践NEO-6M GPS模块接ESP32:户外机器人轨迹追踪与电子围栏实现实践TCA9548A I2C多路复用器接ESP32:解决传感器地址冲突,8通道挂满不撞车实践乐高EV3接入小智AI:语音控制小车实践ESP32-C6+旧手机:语音控制小车实战实践桌面级机械臂3款盘点:myCobot 280/320与Dobot MG400怎么选实践消费级机器狗3款横评:宇树Go2、小米铁蛋2、幻尔MechDog怎么选实践ESP32-CAM怎么搭WiFi摄像头:OV2640接线+CameraWebServer一步到位实践Arduino 6自由度机械臂怎么做?从舵机选型到逆运动学,一套能落地的小白方案实践六足机器人怎么做?Arduino+18个舵机,从3D打印到步态调好的完整教程实践MG996R舵机抖动、无力、不回中?供电和信号排查一次讲清实践HC-05/HC-06蓝牙模块接Arduino做手机无线控制:接线、配对与代码实践ESP32驱动BMV080 PM2.5传感器,静音无风扇I2C/SPI测实践ESP32驱动BMP585工业级气压温度传感器,双协议与FIFO实践ESP32驱动BMP581气压温度传感器,I2C/UART与FIFO读取实践ESP32驱动STCC4二氧化碳传感器,I2C读取与校准实践RC522 RFID射频模块怎么接线?Arduino刷门禁卡+读卡号教程实践桌面机械臂怎么选?新手入门看这4个参数不踩坑实践ESP32和ATmega328P功耗实测对比!电池供电项目怎么选实践ATmega328P引脚功能详解!数字模拟PWM串口SPI一张图讲清实践ESP32和ATMega328P怎么选?机器人主控芯片对比避坑指南实践ESP32-CAM摄像头怎么接线?FTDI烧录+WiFi拍照串流完整教程实践ESP32-S2 T12温控先别调PID:先让每一帧ADC读数可信实践量产级硬件原理图设计指南:138个已量产模块原理图全拆解实践ESP32-C3短信终端AT接收链路优化:解决串口漏信问题实践Maixduino声源定位听声转头平台:双舵机云台DIY实践AHT20温湿度传感器怎么接线?Arduino I2C读地址0x38避坑实践HC-SR04超声波测距模块怎么接线?Arduino避障小车触发和回波预置详解实践BH1750光照传感器怎么接线?GY-302模块采集勒克斯教程实践nRF24L01无线模块怎么接线?Arduino双机透传做2.4G遥控收发实践低成本双足机器人盘点 400美元PhoneBot用旧手机驱动 还有谁在卷价格实践RC522射频模块Arduino怎么读卡?RFID接线地址和卡号避坑实践AS5600磁编码器怎么给舵机加360度角度反馈?接线校准实践ST7735 1.8寸TFT彩屏怎么接线?Arduino SPI初始化避坑实践INA219模块怎么测电流?I2C接线与校准方法实测实践ESP32-CAM怎么玩?几十块钱做个手机能看的局域网图传小车实践ESP-NOW不连WiFi也能无线遥控?两个ESP32点对点直传小车教程实践SSD1306 OLED屏是怎么接的?给Arduino小车加显示的I2C避坑实践TFmini激光雷达给小车避障怎么做?Arduino串口接线避坑实践ESP32做DIY机器人怎么入门?开发板和供电避坑实践ESP32六足机器人怎么走稳?18舵机开源方案组装和步态实践镜头见人脸,马赛克就登场:用行空板K10做一台隐私摄像头实践六足机器人怎么自制?18舵机开源方案从装机到校准跑通实践MPU6050姿态解算怎么入门?DMP和卡尔曼该怎么选实践总线舵机串行通信怎么接线?DIY机械臂供电避坑三步实践EPS32-S3开源四足机器狗TNY-360,单芯片200Hz闭环跑通实践SimpleFOC无刷电机控制:DIY机械臂关节怎么调更顺实践给DIY机械臂加PS2无线手柄:三点示教让关节听话实践ESP32做DIY机械臂主控:PWM舵机接线与供电避坑实践atmega328能干啥:三个自攒机器人项目从Arduino UNO跑通实践atmega328为什么是DIY机器人第一颗主控芯片:AVR架构拆解实践千元自己攒全向底盘机器人:4个麦克纳姆轮从选型到跑通实践花200元给DIY机器人装'耳朵':麦克风阵列从接线到离线语音跑通实践TRAE大赛3.7万人参赛:前保安、初中生、退休老人都在用AI编程了实践