第7章:ADC与传感器
ESP32内置12位逐次逼近型模数转换器(ADC),可用于将模拟信号转换为数字信号。ESP32的ADC特性包括:
光敏电阻通常与固定电阻组成分压电路连接到ESP32的ADC引脚:
// 包含必要的头文件
#include "driver/adc.h"
#include "esp_adc_cal.h"
// 配置ADC
void setup_adc() {
adc1_config_width(ADC_WIDTH_BIT_12); // 设置12位分辨率
adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11); // 设置衰减
}
// 读取ADC原始值
int read_light_sensor() {
return adc1_get_raw(ADC1_CHANNEL_0); // 读取ADC1通道0的值
}
由于ESP32的ADC存在非线性特性,特别是接近电压极限时,需要进行校准以提高测量精度。
使用已知的两个输入电压点进行线性校准:
// 两点校准函数
float two_point_calibration(int raw, int raw_min, int raw_max, float volt_min, float volt_max) {
return volt_min + (volt_max - volt_min) * (raw - raw_min) / (float)(raw_max - raw_min);
}
对于更高精度的要求,可以使用多项式拟合:
// 多项式拟合校准
float poly_calibration(int raw) {
// 这些系数需要通过实际测量数据拟合得到
const float a = 0.0001;
const float b = -0.012;
const float c = 0.5;
const float d = 0.0;
return a * pow(raw, 3) + b * pow(raw, 2) + c * raw + d;
}
#include "driver/adc.h"
#include "esp_adc_cal.h"
// 定义ADC通道
#define LIGHT_SENSOR ADC1_CHANNEL_0
// 初始化ADC
void setup_adc() {
adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(LIGHT_SENSOR, ADC_ATTEN_DB_11);
}
// 读取ADC原始值(多次采样取平均)
int read_light_sensor_raw() {
int samples = 10;
int sum = 0;
for(int i = 0; i < samples; i++) {
sum += adc1_get_raw(LIGHT_SENSOR);
ets_delay_us(100);
}
return sum / samples;
}
// 校准函数(示例使用二次多项式)
float calibrate_light(int raw) {
// 这些系数需要根据实际校准数据确定
const float a = 0.00002;
const float b = -0.015;
const float c = 4.2;
return a * raw * raw + b * raw + c; // 返回校准后的光照强度(单位:lux)
}
void app_main() {
setup_adc();
while(1) {
int raw = read_light_sensor_raw();
float lux = calibrate_light(raw);
printf("原始值: %d, 校准后光照强度: %.2f lux\n", raw, lux);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
客服小姐姐(优先添加)
讲师微信(备用)