Arduino ESP32 ADC功能介绍以及模拟量信号读取示例

您所在的位置:网站首页 arduino模拟输入引脚电压 Arduino ESP32 ADC功能介绍以及模拟量信号读取示例

Arduino ESP32 ADC功能介绍以及模拟量信号读取示例

2024-07-03 07:40| 来源: 网络整理| 查看: 265

Arduino ESP32 ADC功能介绍以及模拟量信号读取示例

✨本篇文章展示如何使用Arduino IDE读取与ESP32模拟输入。模拟读数对于读出可变电阻(如电位器或模拟传感器)的值很有用。 在这里插入图片描述

📍关于ESP32 ADC功能英文介绍在参考手册:https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-reference/peripherals/adc.html 📗ADC引脚 ADC1:

8通道:GPIO32 - GPIO39

ADC2:

10个通道:GPIO0、GPIO2、GPIO4、GPIO12-GPIO15、GOIO25-GPIO27

typedef enum { ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO36 */ ADC1_CHANNEL_1, /*!< ADC1 channel 1 is GPIO37 */ ADC1_CHANNEL_2, /*!< ADC1 channel 2 is GPIO38 */ ADC1_CHANNEL_3, /*!< ADC1 channel 3 is GPIO39 */ ADC1_CHANNEL_4, /*!< ADC1 channel 4 is GPIO32 */ ADC1_CHANNEL_5, /*!< ADC1 channel 5 is GPIO33 */ ADC1_CHANNEL_6, /*!< ADC1 channel 6 is GPIO34 */ ADC1_CHANNEL_7, /*!< ADC1 channel 7 is GPIO35 */ ADC1_CHANNEL_MAX, } adc1_channel_t; typedef enum { ADC2_CHANNEL_0 = 0, /*!< ADC2 channel 0 is GPIO4 */ ADC2_CHANNEL_1, /*!< ADC2 channel 1 is GPIO0 */ ADC2_CHANNEL_2, /*!< ADC2 channel 2 is GPIO2 */ ADC2_CHANNEL_3, /*!< ADC2 channel 3 is GPIO15 */ ADC2_CHANNEL_4, /*!< ADC2 channel 4 is GPIO13 */ ADC2_CHANNEL_5, /*!< ADC2 channel 5 is GPIO12 */ ADC2_CHANNEL_6, /*!< ADC2 channel 6 is GPIO14 */ ADC2_CHANNEL_7, /*!< ADC2 channel 7 is GPIO27 */ ADC2_CHANNEL_8, /*!< ADC2 channel 8 is GPIO25 */ ADC2_CHANNEL_9, /*!< ADC2 channel 9 is GPIO26 */ ADC2_CHANNEL_MAX, } adc2_channel_t;

使用ESP32读取模拟输入就像使用analogRead(GPIO)函数一样简单,它接受要读取的GPIO作为参数。

📄ADC2使用限制说明 Wi-Fi 驱动程序使用了 ADC2。因此,应用程序只能在未启动 Wi-Fi 驱动程序时使用 ADC2。有些 ADC2 引脚作为Strapping 管脚引脚(GPIO 0,2,15),因此无法自由使用。ESP32 DevKitC型号 : 由于外部自动编程电路,无法使用 GPIO 0。ESP-WROVER-KIT型号 : GPIO 0, 2, 4 和 15 由于不同用途的外部连接而无法使用。 🎈管脚具体说明,可以参考说明:https://docs.espressif.com/projects/esp-idf/zh_CN/stable/esp32/api-reference/peripherals/gpio.html 📒ADC 采样模式

每个 ADC 单元支持两种工作模式,ADC 单次采样模式和ADC连续采样(DMA)模式。

ADC 单次采样模式适用于低频采样操作。ADC 连续采样(DMA)模式适用于高频连续采样动作。 📑衰减倍数 不同的衰减倍数对应不同的检测电压范围。

ADC的默认满量程电压为1.1V。要读取更高的电压(最高为引脚最大电压,通常为3.3V),则需要将该ADC通道的信号衰减设置为> 0dB。 在这里插入图片描述

👉针对不型号参数差异:可以参考:https://docs.espressif.com/projects/arduino-esp32/en/latest/api/adc.html?highlight=analogsetattenuation 在这里插入图片描述

当VDD_A为3.3V时:

0dB衰减(ADC_ATTEN_0db)表示参考电压为1.1V 2.5dB衰减(ADC_ATTEN_2_5db)表示参考电压为1.5V 6dB衰减(ADC_ATTEN_6db)表示参考电压为2.2V 11dB衰减(ADC_ATTEN_11db)表示参考电压为3.9V

Arduino ESP32 核心库有关ADC库函数

在这里插入图片描述

esp32-hal-adc.h #ifndef MAIN_ESP32_HAL_ADC_H_ #define MAIN_ESP32_HAL_ADC_H_ #ifdef __cplusplus extern "C" { #endif #include "esp32-hal.h" /* 衰减倍数 0dB衰减(ADC_ATTEN_0db)表示参考电压为1.1V 2.5dB衰减(ADC_ATTEN_2_5db)表示参考电压为1.5V 6dB衰减(ADC_ATTEN_6db)表示参考电压为2.2V 11dB衰减(ADC_ATTEN_11db)表示参考电压为3.9V */ typedef enum { ADC_0db, ADC_2_5db, ADC_6db, ADC_11db } adc_attenuation_t; /* * 获取引脚的ADC值 * */ uint16_t analogRead(uint8_t pin); /* *设置analogRead返回值的分辨率。缺省值是12位(0 ~ 4096)。 *如果在9和12之间,它将等于设置的硬件分辨率,否则值将被移动。 *范围为1 - 16 * * 注:兼容Arduino SAM */ void analogReadResolution(uint8_t bits); /* *设置示例位和读取分辨率 *默认为12bit (0 - 4095) *范围是9 - 12 * */ void analogSetWidth(uint8_t bits); /* *设置ADC时钟的分压器。 *默认值为1 *取值范围为1 - 255 * */ void analogSetClockDiv(uint8_t clockDiv); /* * Set the attenuation for all channels * Default is 11db * */ void analogSetAttenuation(adc_attenuation_t attenuation); /* *设置所有通道的衰减 *默认为11db * */ void analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation); /* * 获取霍尔传感器的值(无LNA) * 连接到引脚36(SVP)和引脚39(SVN) * */ int hallRead(); /* *将引脚连接到ADC(也将清除任何其他模拟模式,可以打开) * */ bool adcAttachPin(uint8_t pin); /*设置引脚用于ADC校准,如果esp还没有校准(25、26或27) * Set pin to use for ADC calibration if the esp is not already calibrated (25, 26 or 27) * */ void analogSetVRefPin(uint8_t pin); /*获取引脚的毫伏值 * Get MilliVolts value for pin * */ uint32_t analogReadMilliVolts(uint8_t pin); #ifdef __cplusplus } #endif #endif /* MAIN_ESP32_HAL_ADC_H_ */ 📘ESP32模拟输入(ADC)

用ESP32读取模拟值意味着你可以测量0 V到3.3 V之间的变化电压等级。然后将测量的电压赋给0到4095之间的一个值,其中0 V对应0,3.3 V对应4095。0 V到3.3 V之间的任何电压都将给出两者之间的相应值。

在这里插入图片描述

📙ADC是非线性的值

理想情况下,当使用ESP32 ADC引脚时,你会期望线性行为。然而,这并没有发生。你会得到如下图所示的行为:

在这里插入图片描述

这种行为意味着你的ESP32无法区分3.3 V和3.2 V。你会得到相同的电压值:4095。 同样的情况发生在非常低的电压值:对于0 V和0.1 V,你将得到相同的值:0。 在使用ESP32 ADC引脚时,您需要记住这一点。

🌿 analogRead()

使用Arduino IDE读取ESP32模拟输入就像使用analogRead()函数一样简单。它接受你想要读取的GPIO作为参数:

analogRead(GPIO); ESP32支持18个不同通道的测量。在DEVKIT V1 DOIT板(30 gpio版本)中只有15个可用。 在这里插入图片描述 📓其他相关的功能 analogReadResolution(resolution):设置样本位和分辨率。它可以是一个介于9(0 - 511)和12位(0 - 4095)之间的值。默认是12位分辨率。analogSetWidth(width):设置样本位和分辨率。它可以是一个介于9(0 - 511)和12位(0 - 4095)之间的值。默认是12位分辨率。analogSetCycles(cycles):设置每个样本的循环次数。默认是8。取值范围:1 ~ 255。analogSetSamples(samples):设置范围内的样本数量。默认为1个样本。它有增加灵敏度的作用。analogSetClockDiv(attenuation):设置ADC时钟的分压器。默认值为1。取值范围:1 ~ 255。analogSetAttenuation(attenuation):设置所有ADC引脚的输入衰减。默认是ADC_11db。其他取值:

ADC_0db: 集没有衰减。ADC可以测量大约800mv (1V输入= ADC读数1088)。 ADC_2_5db: ADC的输入电压将被衰减,扩展测量范围至约。1100 mV。(1V输入= ADC读数3722)。 ADC_6db: ADC的输入电压将被衰减,扩展测量范围至约。1350 mV。(1V输入= ADC读数3033)。 ADC_11db: ADC的输入电压将被衰减,扩展测量范围至约。2600 mV。(1V输入= ADC读数1575)。

analogSetPinAttenuation(pin, attenuation):设置指定引脚的输入衰减。默认是ADC_11db。衰减值与前一个函数相同。adcAttachPin(pin):附加一个引脚到ADC(也清除任何其他模拟模式可能是on)。返回TRUE或FALSE结果。adcStart(pin), adcBusy(pin) 和 resultadcEnd(pin):在附加引脚的总线上启动ADC转换。检查引脚的ADC总线上的转换是否正在运行(返回TRUE或FALSE)。获取转换的结果:返回16位整数。 接线图

在这里插入图片描述

在这里插入图片描述

📝测试代码 // 电位器连接到GPIO 34(模拟ADC1_CH6) const int PotPin = 34; // 用于存储电位器值的变量 int PotValue = 0; void setup() { Serial.begin(115200); delay(1000); } void loop() { // 读取电位计值 potValue = analogRead(PotPin); Serial.println(PotValue); delay(500); } 📄例程二:

OneShot模式下使用ADC的示例,或者您可以运行Arduino 自带例程:basic->AnalogReadSerial。

void setup() { // initialize serial communication at 115200 bits per second: Serial.begin(115200); //set the resolution to 12 bits (0-4095) analogReadResolution(12); } void loop() { // read the analog / millivolts value for pin 2: int analogValue = analogRead(2); int analogVolts = analogReadMilliVolts(2); // print out the values you read: Serial.printf("ADC analog value = %d\n",analogValue); Serial.printf("ADC millivolts value = %d\n",analogVolts); delay(800); // delay in between reads for clear read from serial } 🌿例程三:ADC连续转换模式 🔖此例程来源:https://docs.espressif.com/projects/arduino-esp32/en/latest/api/adc.html?highlight=analogsetattenuation#example-applications(需要安装Development release 版本) // Define how many conversion per pin will happen and reading the data will be and average of all conversions #define CONVERSIONS_PER_PIN 5 // Declare array of ADC pins that will be used for ADC Continuous mode - ONLY ADC1 pins are supported // Number of selected pins can be from 1 to ALL ADC1 pins. #ifdef CONFIG_IDF_TARGET_ESP32 uint8_t adc_pins[] = {36, 39, 34, 35}; //some of ADC1 pins for ESP32 #else uint8_t adc_pins[] = {1, 2, 3, 4}; //ADC1 common pins for ESP32S2/S3 + ESP32C3/C6 + ESP32H2 #endif // Calculate how many pins are declared in the array - needed as input for the setup function of ADC Continuous uint8_t adc_pins_count = sizeof(adc_pins) / sizeof(uint8_t); // Flag which will be set in ISR when conversion is done volatile bool adc_coversion_done = false; // Result structure for ADC Continuous reading adc_continuos_data_t * result = NULL; // ISR Function that will be triggered when ADC conversion is done void ARDUINO_ISR_ATTR adcComplete() { adc_coversion_done = true; } void setup() { // Initialize serial communication at 115200 bits per second: Serial.begin(115200); // Optional for ESP32: Set the resolution to 9-12 bits (default is 12 bits) analogContinuousSetWidth(12); // Optional: Set different attenaution (default is ADC_11db) analogContinuousSetAtten(ADC_11db); // Setup ADC Continuous with following input: // array of pins, count of the pins, how many conversions per pin in one cycle will happen, sampling frequency, callback function analogContinuous(adc_pins, adc_pins_count, CONVERSIONS_PER_PIN, 20000, &adcComplete); // Start ADC Continuous conversions analogContinuousStart(); } void loop() { // Check if conversion is done and try to read data if (adc_coversion_done == true) { // Set ISR flag back to false adc_coversion_done = false; // Read data from ADC if (analogContinuousRead(&result, 0)) { // Optional: Stop ADC Continuous conversions to have more time to process (print) the data analogContinuousStop(); for (int i = 0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3