- 机器人等级考试
ESP32 for Arduino 模拟信号学习笔记
- 2025-8-2 19:34:22 @
ESP32 for Arduino 模拟信号学习笔记
一、模拟信号输入
1. 读取函数 analogRead()
- 功能:从指定引脚读取模拟信号,并获取其返回值。
- 返回值:ESP32 的 ADC 模块分辨率默认为 12 位,这意味着
analogRead()
函数返回值的范围是 0 ~ 4095 ,对应输入电压 0 ~ 3.3v 。比如返回值为 4095 时,输入电压就是 3.3v ;返回值为 0 ,输入电压为 0v 。不过,ESP32 的 ADC 模块返回值线性度不是很好。 - 可用引脚:一共有 15 个可用引脚 ,当打开 WiFi 功能时,其中 9 个引脚不能使用,建议优先使用 A0、A3、A4、A5、A6、A7 引脚。
2. 设置取样精度函数 analogSetWidth(bits)
- 功能:用于设置
analogRead()
函数的取样精度。 - 参数:
bits
取值范围在 9 ~ 12 之间。当设为 9 时,analogRead()
函数返回值为 0 ~ 511 ;设为 12 时返回 0 - 4095 。
3. 示例代码
const int potPin = A0; // 定义模拟输入引脚为A0,一般可接电位器等模拟信号源
void setup() {
pinMode(potPin,INPUT); // 将A0引脚设置为输入模式
Serial.begin(115200); // 初始化串口通信,波特率为115200,方便查看读取的数据
analogSetWidth(10); // 设置模拟输入精度为10位,此时返回值范围是0 - 1023
}
int val; // 定义变量用于存储读取到的模拟值
void loop() {
val = analogRead(potPin); // 从A0引脚读取模拟值
Serial.println(val); // 通过串口打印读取到的模拟值
delay(10); // 延迟10毫秒,避免读取过于频繁
}
二、模拟信号输出
1. 输出方式概述
Arduino 模拟输出通过 PWM 实现,对应的函数是 analogWrite()
,但在 ESP32 中没有这个函数。ESP32 提供了 3 种模拟输出方式:
- LEDC:基于 PWM 调制的 16 通道模拟输出,是我们常用的方式。
- SigmaDelta:基于 SigmaDelta 调制的 8 通道模拟输出。
- DAC:硬件(DAC)实现的 2 个通道的模拟输出 。
2. LEDC 输出相关函数
(1)ledcSetup(channel,freq,bit_num)
- 功能:设置指定 LEDC 通道的参数。
- 参数:
channel
:PWM 通道,总共有 16 个通道,编号为 0 ~ 15 。freq
:设置 PWM 的频率。bit_num
:占空比的分辨率,范围是 1 ~ 16 。比如设置为 8 ,则控制 LED 的亮度可以在 0 ~ 255 之间变化。
(2)ledcAttachPin(pin,channel)
- 功能:将指定通道上产生的 PWM 信号输出到指定引脚。
- 参数:
pin
:开发板上除 34 、 35 、 36 、 39 以外的 19 个引脚。channel
:PWM 通道,编号 0 ~ 15 。
(3)ledcWrite(channel,Value)
- 功能:设置指定通道的占空比数值,进而控制输出信号。
- 参数:
channel
:PWM 通道,0 ~ 15 。Value
:指定占空比数值,具体范围取决于ledcSetup
中设置的占空比分辨率。
3. 示例代码
(1)简单 LED 亮灭示例
const int ledPin = 27; // 定义LED连接引脚为27
void setup() {
pinMode(ledPin,OUTPUT); // 将引脚27设置为输出模式
ledcSetup(0,5000,10); // 设置通道0,频率为5000Hz,占空比分辨率为10位(0 - 1023)
ledcAttachPin(ledPin,0); // 将引脚27与通道0关联
}
void loop() {
ledcWrite(0,1023); // 设置通道0的占空比为最大值,LED最亮
delay(1000); // 延迟1秒
ledcWrite(0,0); // 设置通道0的占空比为0,LED熄灭
delay(1000); // 延迟1秒
}
(2)模拟输入控制模拟输出示例
const int ledPin = 27; // 定义LED连接引脚为27
const int potPin = A0; // 定义模拟输入引脚为A0
void setup() {
pinMode(ledPin,OUTPUT); // 将引脚27设置为输出模式
pinMode(potPin,INPUT); // 将A0引脚设置为输入模式
ledcSetup(0,5000,10); // 设置通道0,频率为5000Hz,占空比分辨率为10位(0 - 1023)
ledcAttachPin(ledPin,0); // 将引脚27与通道0关联
Serial.begin(115200); // 初始化串口通信,
2 条评论
-
admin SU @ 2025-8-2 19:36:54
ESP32 for Arduino 模拟信号开发学习笔记
一、基础概念与核心函数
(一)模拟输入
ESP32 可通过
analogRead(pin)
读取模拟信号,默认 ADC 分辨率 12 位,返回值范围 0~4095,对应电压 0~3.3V 。若需调整精度,用analogSetWidth(bits)
,bits
取 9~12 ,如设为 10 ,返回值范围变为 0~1023 。(二)模拟输出
ESP32 无 Arduino 传统
analogWrite()
,改用 LEDC、SigmaDelta、DAC 三种方式。常用 LEDC(基于 PWM ,16 通道),需三步配置:ledcSetup(channel, freq, bit_num)
:设通道参数(通道 0~15 、频率、占空比分辨率 1~16 )。ledcAttachPin(pin, channel)
:关联引脚与通道。ledcWrite(channel, value)
:输出占空比,控制设备(如 LED 亮度)。
二、代码实践与解析
(一)基础模拟输入(读取电位器值)
const int potPin = A0; // 定义模拟输入引脚(接电位器) void setup() { pinMode(potPin, INPUT); // 设为输入模式 Serial.begin(115200); // 初始化串口,波特率115200 analogSetWidth(10); // 设ADC精度为10位,返回值0~1023 } int val; void loop() { val = analogRead(potPin); // 读模拟值 Serial.println(val); // 串口打印 delay(10); // 延时防抖 }
说明:通过电位器改变电压,
analogRead
读取后串口输出,analogSetWidth
灵活调整精度适配场景。(二)基础模拟输出(LED 亮灭控制)
const int ledPin = 27; // 定义LED引脚 void setup() { pinMode(ledPin, OUTPUT); // 设为输出 ledcSetup(0, 5000, 10); // 通道0,频率5000Hz,占空比分辨率10位(0~1023) ledcAttachPin(ledPin, 0); // 引脚27关联通道0 } void loop() { ledcWrite(0, 1023); // 占空比最大,LED最亮 delay(1000); ledcWrite(0, 0); // 占空比0,LED灭 delay(1000); }
说明:
ledcSetup
配置通道,ledcAttachPin
绑定引脚,ledcWrite
控制占空比实现亮灭循环。(三)模拟输入控制输出(电位器调 LED 亮度)
const int ledPin = 27; const int potPin = A0; void setup() { pinMode(ledPin, OUTPUT); pinMode(potPin, INPUT); ledcSetup(0, 5000, 10); // 通道0,频率5000Hz,分辨率10位 ledcAttachPin(ledPin, 0); Serial.begin(115200); analogSetWidth(10); // ADC精度10位 } int val; void loop() { val = analogRead(potPin); // 读电位器值 Serial.println(val); ledcWrite(0, val); // 直接用读取值控制占空比 delay(10); }
说明:电位器值实时改变
ledcWrite
占空比,实现 LED 亮度随电位器转动渐变,体现“输入 - 处理 - 输出”闭环。(四)进阶:映射函数适配范围(精准调亮度)
const int ledPin = 27; const int potPin = A0; void setup() { pinMode(ledPin, OUTPUT); pinMode(potPin, INPUT); ledcSetup(0, 5000, 8); // 通道0,分辨率8位(0~255) ledcAttachPin(ledPin, 0); Serial.begin(115200); analogSetWidth(12); // ADC精度12位(0~4095) } int val; void loop() { val = analogRead(potPin); // 读12位值(0~4095) Serial.println(val); val = map(val, 0, 4095, 0, 255); // 映射到8位范围(0~255) ledcWrite(0, val); // 控制LED delay(10); }
说明:
map
函数将 12 位输入(0~4095)映射到 8 位占空比范围(0~255),解决输入输出分辨率不匹配问题,让亮度调节更线性、精准。(五)双 LED 渐变控制(循环亮暗)
const int ledPin1 = 27; const int ledPin2 = 26; void setup() { pinMode(ledPin1, OUTPUT); pinMode(ledPin2, OUTPUT); ledcSetup(0, 5000, 8); // 通道0,分辨率8位(0~255) ledcSetup(1, 5000, 8); // 通道1,参数同通道0 ledcAttachPin(ledPin1, 0); // 引脚27-通道0 ledcAttachPin(ledPin2, 1); // 引脚26-通道1 } void loop() { // 从暗到亮 for (int light = 0; light <= 255; light++) { ledcWrite(0, light); // 通道0占空比递增 ledcWrite(1, light); // 通道1占空比递增 delay(10); // 延时控制渐变速度 } // 从亮到暗 for (int light = 255; light >= 0; light--) { ledcWrite(0, light); // 通道0占空比递减 ledcWrite(1, light); // 通道1占空比递减 delay(10); } }
说明:用
for
循环实现双 LED 同步渐变,ledcWrite
按循环变量调整占空比,delay
控制渐变节奏,打造灯光呼吸效果。三、总结与扩展
通过上述代码,可掌握 ESP32 模拟信号 输入读取、输出控制、分辨率适配 核心逻辑。实际开发中,可结合传感器(如光敏、温度)拓展应用:
- 光敏电阻接模拟输入,实时调节 LED 亮度模拟“环境光感应”;
- 温度传感器(模拟型)读取值映射为 PWM 占空比,驱动风扇调速。
多尝试不同函数组合、引脚配置,就能用 ESP32 玩转模拟信号,搭建创意硬件项目啦!
-
2025-8-2 19:36:22@
ESP32 for Arduino 模拟信号入门教程
一、模拟信号基础概念
在电子设备中,信号分为数字信号和模拟信号:
- 数字信号:只有0和1两种状态(高低电平)
- 模拟信号:可以是连续变化的数值(如声音、光线、温度等)
ESP32作为一款功能强大的单片机,支持模拟信号的输入和输出,这为我们制作调光、调速、传感器数据采集等项目提供了可能。
二、ESP32模拟信号输入
1. 核心函数:
analogRead()
用于从指定引脚读取模拟信号,基本语法:
int value = analogRead(pin); // pin为指定的模拟输入引脚
2. 输入特性
- 默认精度为12位,返回值范围:
0~4095
- 对应电压范围:
0~3.3V
(4095对应3.3V,0对应0V) - 可用引脚:共15个,推荐使用A0、A3、A4、A5、A6、A7(尤其开启WiFi时)
3. 精度设置:
analogSetWidth()
可以通过该函数修改模拟输入的精度,语法:
analogSetWidth(bits); // bits取值范围9~12
不同精度对应的返回值范围:
- 9位:
0~511
- 10位:
0~1023
- 11位:
0~2047
- 12位:
0~4095
(默认)
4. 基础示例:读取电位器值
const int potPin = A0; // 定义电位器连接的引脚 int val; // 存储读取到的数值 void setup() { pinMode(potPin, INPUT); // 设置引脚为输入模式 Serial.begin(115200); // 初始化串口通信 // 可选:设置精度 // analogSetWidth(10); // 设置为10位精度,返回值0-1023 } void loop() { val = analogRead(potPin); // 读取模拟值 Serial.print("电位器值:"); Serial.println(val); // 串口打印数值 delay(100); // 延时100ms }
三、ESP32模拟信号输出
ESP32没有Arduino UNO的
analogWrite()
函数,而是提供了三种模拟输出方式:LEDC
:基于PWM的16通道输出(最常用)SigmaDelta
:8通道输出DAC
:硬件2通道输出
我们主要学习最常用的
LEDC
方式。1. LEDC输出三步骤
步骤1:设置通道参数
ledcSetup()
ledcSetup(channel, freq, bit_num);
channel
:通道编号(0~15)freq
:PWM频率(如5000Hz)bit_num
:占空比分辨率(1~16),决定输出值范围- 8位:
0~255
- 10位:
0~1023
- 8位:
步骤2:绑定引脚
ledcAttachPin()
ledcAttachPin(pin, channel);
pin
:输出引脚(除34、35、36、39外的大多数引脚)channel
:要绑定的通道(与步骤1设置的通道一致)
步骤3:输出PWM信号
ledcWrite()
ledcWrite(channel, value);
channel
:通道编号value
:输出值(范围由步骤1的bit_num
决定)
2. 基础示例:LED闪烁
const int ledPin = 27; // LED连接的引脚 void setup() { pinMode(ledPin, OUTPUT); // 步骤1:设置通道0,频率5000Hz,8位分辨率(0-255) ledcSetup(0, 5000, 8); // 步骤2:将引脚27绑定到通道0 ledcAttachPin(ledPin, 0); } void loop() { ledcWrite(0, 255); // 最大亮度(8位分辨率的最大值) delay(1000); // 亮1秒 ledcWrite(0, 0); // 熄灭 delay(1000); // 灭1秒 }
四、综合应用:模拟输入控制模拟输出
1. 电位器控制LED亮度(同范围)
const int ledPin = 27; // LED引脚 const int potPin = A0; // 电位器引脚 int val; // 存储读取值 void setup() { pinMode(ledPin, OUTPUT); pinMode(potPin, INPUT); // 设置LED输出通道:通道0,5000Hz,10位分辨率(0-1023) ledcSetup(0, 5000, 10); ledcAttachPin(ledPin, 0); Serial.begin(115200); analogSetWidth(10); // 输入也设为10位(0-1023),与输出范围匹配 } void loop() { val = analogRead(potPin); // 读取电位器值(0-1023) Serial.println(val); // 打印数值 ledcWrite(0, val); // 直接用于控制LED亮度 delay(10); }
2. 范围映射:
map()
函数的使用当输入和输出范围不同时,使用
map()
函数进行转换:val = map(原数值, 原最小值, 原最大值, 目标最小值, 目标最大值);
示例:12位输入控制8位输出
const int ledPin = 27; const int potPin = A0; int val; void setup() { pinMode(ledPin, OUTPUT); pinMode(potPin, INPUT); // 输出:8位分辨率(0-255) ledcSetup(0, 5000, 8); ledcAttachPin(ledPin, 0); Serial.begin(115200); analogSetWidth(12); // 输入:12位(0-4095) } void loop() { val = analogRead(potPin); // 读取0-4095 Serial.print("原始值:"); Serial.print(val); // 将0-4095映射到0-255 val = map(val, 0, 4095, 0, 255); Serial.print(",映射后:"); Serial.println(val); ledcWrite(0, val); // 控制LED delay(10); }
3. 高级应用:LED渐变效果
使用循环实现LED从暗到亮再到暗的渐变:
const int ledPin1 = 27; const int ledPin2 = 26; void setup() { pinMode(ledPin1, OUTPUT); pinMode(ledPin2, OUTPUT); // 设置两个通道,都用8位分辨率(0-255) ledcSetup(0, 5000, 8); ledcSetup(1, 5000, 8); // 绑定引脚到通道 ledcAttachPin(ledPin1, 0); ledcAttachPin(ledPin2, 1); } void loop() { // 从暗到亮(for循环版) for(int i = 0; i <= 255; i++){ ledcWrite(0, i); // 控制第一个LED ledcWrite(1, i); // 控制第二个LED delay(15); // 控制渐变速度 } // 从亮到暗(while循环版) int light = 255; while(light >= 0){ ledcWrite(0, light); ledcWrite(1, light); delay(15); light--; // 递减 } }
五、ESP32与Arduino UNO的区别
特性 ESP32 Arduino UNO 模拟输入范围 0~4095(12位) 0~1023(10位) 模拟输出函数 无 analogWrite()
,用LEDC
系列函数有 analogWrite()
输出通道数 16个(LEDC) 6个PWM引脚 工作电压 3.3V 5V 六、常见问题解决
-
读取值不稳定:
- 确保接线牢固
- 增加
delay()
时间 - 尝试软件滤波(如取多次平均值)
-
引脚冲突:
- 开启WiFi时,避免使用特定引脚
- 推荐使用A0、A3-A7作为模拟输入
-
范围不匹配:
- 始终注意输入输出的范围是否一致
- 不同范围时务必使用
map()
函数转换
通过本教程,你已经掌握了ESP32模拟信号的基本用法。尝试将这些知识应用到实际项目中,比如制作一个光线感应灯、温度控制器或音乐可视化装置吧!
- 1