ESP32 ADC |
![]() |
Добавил(а) microsin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
На кристалле ESP32 MCU интегрировано 2 блока АЦП (ADC), работающих по принципу последовательного приближения (Successive Approximation Register, SAR). Эти два АЦП поддерживают до 18 каналов, которые могут быть направлены на определенные ножки MCU. Примечание: в этой статье приведен перевод главы, посвященной ADC из документации [1]. Незнакомые термины и сокращения см. в Словарике, в конце статьи. [Основные возможности ADC] ADC1: поддерживает 8 каналов (GPIO32 - GPIO39). Таблица 1. Характеристики ADC.
Примечание (1): вес младшего разряда. Когда аттенюация == 3 (ADC_ATTEN_DB_11), и результат чтения АЦП больше 3000 (напряжение достигло 2450 mV), точность ADC будет хуже, чем представлено в таблице 1. Чтобы получить лучшие параметры DNL, пользователь может произвести несколько измерений сигнала, пропущенных через входной фильтр, либо вычислить среднее значение от нескольких выборок сигнала. Диапазон входного напряжения ножек GPIO в домене VDD3P3_RTC должно строго соответствовать уровням напряжения питания (например, от 0 до 3.3V). Иначе будут наблюдаться ошибки измерений, и может ухудшиться производительность чипа. По умолчанию между разными экземплярами чипа могут быть ±6% различий в результатах чтения АЦП. Библиотеки ESP-IDF предоставляют набор методов калибровки для ADC1. В качестве примера в таблице 2 приведены результаты измерения с использованием коэффициентов калибровки eFuse Vref. Для повышения точности пользователи могут применить другие методы калибровки, предоставленные в ESP-IDF, либо реализовать собственные методы калибровки. Таблица 2. Результаты калибровки ADC. В столбце "Ошибка" приведено значение отклонения в милливольтах результата измерения от действительного значения.
Ослабление по входу ADC. Входные уровни напряжений оцифровываются по отношению к внутреннему опорному напряжению Vref. Таким образом, диапазон входных измеряемых уровней напряжения составляет от 0V до Vref. На разных экземплярах кристаллов Vref может варьироваться, среднее значение Vref составляет 1.1V. Чтобы можно было преобразовывать входные напряжения, превышающие Vref, уровни на входе должны быть уменьшены. Существует 4 опции уменьшения уровней (attenuation), чем больше ослабление, тем больше может быть уровень измеряемого напряжения на входе АЦП. Таблица 3. Опции ослабления (аттенюации) уровней на входе АЦП.
Преобразование ADC. Это процесс преобразования уровня сигнала в цифровое значение. Результаты преобразования предоставляются API-функциями драйвера ADC в виде сырых данных. Разрешающая способность ESP32 ADC в режиме Single Read составляет 12 бит. Для преобразования используются функции adc1_get_raw и adc2_get_raw. Для вычисления реального напряжения на основе сырого результата, предоставленного ADC, можно использовать формулу: Vout = Dout * Vmax / Dmax (Формула 1) Здесь Vout это результат измерения напряжения (в милливольтах), Dout сырой цифровой результат преобразования АЦП, Vmax максимальное измеряемое напряжение на входе (см. выше секцию "Ослабление по входу ADC"). Dmax максимальный сырой результат преобразования АЦП (который в режима Single Read и Continuous Read равен 212 - 1 = 4095). Для плат, у которых есть биты калибровки eFuse ADC, может использоваться функция esp_adc_cal_raw_to_voltage для получения калиброванных результатов преобразования. Это результаты будут реальным напряжением (в mV). Нет необходимости преобразовывать эти данные по формуле 1. Если API-функции калибровки используются на платах, где нет бит калибровки eFuse ADC, будут генерироваться предупреждения, см. секцию "Калибровка ADC". Дополнительную информацию по использованию АЦП см. в главе "On-Chip Sensors and Analog Signal Processing" технического руководства ESP32 (ESP32 Technical Reference Manual, esp32_technical_reference_manual_en.pdf). [Ограничения ADC] Не могут свободно использоваться некоторые ножки ADC2, на которых совмещена функция управления загрузкой (strapping pins GPIO0, GPIO2, GPIO15). Такой случай имеет место на следующих официальных платах разработчика (Development Kits): ESP32 DevKitC: GPIO0 не может использоваться из-за внешних схем автоматического программирования. Поскольку модуль ADC2 также используется для Wi-Fi, одновременно можно использовать только одну из этих функций. Т. е. функция adc2_get_raw может блокировать выполнение до тех пор, пока не остановится использование Wi-Fi, и наоборот. [Использование драйвера ADC] Оба блока ADC поддерживают одиночный режим чтения (Single Read mode), который подойдет для низкочастотных оцифровок сигнала. Примечание: чтение никуда не подключенных (висящих) входов ADC будут давать случайные результаты. Single Read. Это режим одиночного чтения АЦП. Перед тем, как можно будет считывать результаты измерений, ADC должно быть сконфигурировано. ● Для ADC1 конфигурируется желаемая точность (precision) и ослабление (attenuation) с помощью вызова функций adc1_config_width и adc1_config_channel_atten. Конфигурация ослабления осуществляется для каждого канала отдельно с помощью типов adc1_channel_t и adc2_channel_t, эти значения устанавливаются в качестве параметров для вышеупомянутых функций настройки ослабления. Результаты преобразования считываются вызовами функций adc1_get_raw и adc2_get_raw. Ширина результата ADC2 должна быть установлена в параметре adc2_get_raw, вместо того, чтобы это настраивать функцией конфигурации. Пример режима Single Read можно найти в папке peripherals/adc/single_read среди примеров ESP-IDF [4]. С помощью ADC1 также можно считывать внутренний датчик Холла (hall effect sensor) путем вызова специальной функции hall_sensor_read. Обратите внимание, что несмотря на то, чт датчик Холла внутренний для кристалла ESP32, для его чтения используются каналы 0 и 3 ADC1 (GPIO36 и GPIO39). Ничего не подключайте к этим выводам, и не меняйте их конфигурацию, иначе это может повлиять на измерение слабого сигнала от сенсора. API предоставляет удобный способ конфигурирования ADC1 для чтения из режима ULP [5]. Для этого вызовите функцию adc1_ulp_enable, и затем установите точность (precision) и ослабление (attenuation), как обсуждалось выше. Есть еще одна специальная функция adc_vref_to_gpio, которая используется для перенаправления внутреннего опорного напряжения Vref на ножку GPIO. Это удобно для калибровки ADC, и обсуждается в секции "Калибровка ADC". Минимизация шума. ESP32 ADC может быть чувствителен к шуму, что приводит к большим расхождениям между отдельными результатами чтения ADC. В зависимости от сценария использования можно подключить на входную ножку ADC блокирующий конденсатор (например керамический конденсатор на 100 нФ). Кроме того, для уменьшения эффектов от шума может использоваться техника передискретизации и усреднения (multisampling, также см. [6]). Рис. 1. График, иллюстрирующий уменьшение шума с помощью конденсатора на входе и усреднения 64 выборок. [Калибровка ADC] Заголовок esp_adc_cal/include/esp_adc_cal.h представляет API-функции для корректировки ошибок измерения из-за разброса уровня опорного напряжения (Vref) на разных кристаллах ESP32. Источник опорного напряжения был разработан на напряжение 1100 mV, однако в действительности этот уровень может быть в диапазоне от 1000 mV до 1200 mV. Рис. 2. График, показывающий эффект влияния различного напряжения Vref на результат оцифровки АЦП. Коррекция результатов чтения ADC с помощью этого API включает в себя один из ADC на определенной аттенюации, с целью получить кривую характеристики (зависимость результат ADC - напряжение), которая учитывает неточность опорного напряжения. Кривая характеристики представляется в форме y = coeff_a * x + coeff_b, и она используется для преобразования сырых результатов чтения ADC в напряжения в mV. Вычисление кривой характеристики основано на значениях калибровки, которые можно сохранить в энергонезависимую память eFuse [9], или они могут быть предоставлены пользователем. Значения калибровки. Эти значения используются для генерации кривой характеристики ADC, которая учитывает погрешность опорного напряжения каждого конкретного кристалла ESP32. На ESP32 существует 3 источника значений калибровки. Доступность этих значений калибровки зависит от типа чипа/модуля ESP32 и даты его производства. ● Two Point. Это 2 значения (точки калибровки), каждое представляет собой результат чтения ADC для входных уровней 150 mV и 850 mV. Чтобы получить точные результаты калибровки, эти значения должны быть измерены пользователем и прошиты в eFuse BLOCK3. Индивидуальное измерение и прошивка eFuse Vref было применено для чипов ESP32-D0WD и ESP32-D0WDQ6, которые произведены начиная с 1 недели 2018 года. Такие чипы можно распознать по кодам даты, которая равна или больше 012018, см. рис. 3. Здесь WW это код недели, YYYY код года изготовления. Рис. 3. Маркировка чипа ESP32. Если Вы хотите купить чипы или модули с калибровкой, свяжитесь с дистрибьютором или напрямую с Espressif (sales@espressif.com). Если Вы не можете проверить код даты (например, когда чип закрыт крышкой модуля), то все еще можете проверить наличие eFuse Vref путем запуска espefuse.py с параметром adc_info. Пример командной строки запуска espefuse.py в среде Linux (замените /dev/ttyUSB0 реальным именем последовательного порта подключенной через USB платы ESP32): $IDF_PATH/components/esptool_py/esptool/espefuse.py --port /dev/ttyUSB0 adc_info Примечание: как запускать скрипты администрирования на языке Python *.py в операционной системе Windows см. врезку "Как запустить idf.py menuconfig" из статьи [10]. Скрипт espefuse.py и другие скрипты запускаются аналогично. Чип, у которого есть запрограммированное значение eFuse Vref (в этом примере 1093 mV) покажет следующее сообщение: ADC VRef calibration: 1093 mV Другой пример сообщения, когда значение eFuse Vref не запрограммировано: ADC VRef calibration: None (1100 mV nominal) Для чипа, у которого есть 2 точки калибровки, сообщение будет выглядеть примерно так: ADC VRef calibration: 1149 mV ADC readings stored in efuse BLK3: ADC1 Low reading (150 mV): 306 ADC1 High reading (850 mV): 3153 ADC2 Low reading (150 mV): 389 ADC2 High reading (850 mV): 3206 Пример целиком см. в каталоге peripherals/adc/single_read установки среды разработки ESP-IDF [4]. Характеристика АЦП при определенной аттенюации: #include "driver/adc.h"
#include "esp_adc_cal.h"
... esp_adc_cal_characteristics_t *adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t)); esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_chars); // Проверка типа значения калибровки, используемого для характеристики ADC:
if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) printf("eFuse Vref"); else if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) printf("Two Point"); else printf("Default"); Чтение ADC, затем преобразование результата чтения в напряжение: #include "driver/adc.h"
#include "esp_adc_cal.h"
... uint32_t reading = adc1_get_raw(ADC1_CHANNEL_5); uint32_t voltage = esp_adc_cal_raw_to_voltage(reading, adc_chars); Направление опорного напряжения ADC на ножку GPIO, после чего оно может быть измерено вручную (для Default Vref): #include "driver/adc.h"
... esp_err_t status = adc_vref_to_gpio(ADC_UNIT_1, GPIO_NUM_25); if (status == ESP_OK) printf("v_ref routed to GPIO\n"); else printf("failed to route v_ref\n"); Макросы назначения GPIO. Доступны макросы, предназначенные для указания номера GPIO канала ADC, или наоборот, например: ADC1_CHANNEL_0_GPIO_NUM это номер ножки GPIO канала 0 ADC1. [Справочник по API-функциям ADC] API-функции ADC разделены на 3 категории: ● Драйвер ADC (заголовочный файл components/driver/include/driver/adc.h) Типы, используемые в API-функциях ADC, определены в заголовочном файле components/hal/include/hal/adc_types.h. Таблица 4. Общее описание API-функций ADC.
Полный справочник по API-функциям, макросам и структурам ADC см. в документации [1]. [Словарик] ADC Analog to Digital Converter, аналого-цифровой преобразователь (АЦП). DIG DIGital, цифровой. В контексте ADC имеется в виду специальный контроллер для управления АЦП (Digital ADC). DNL Differential Non-Linearity, дифференциальная нелинейность. INL Integral Non-Linearity, общая нелинейность. LSB Least Significant Bit, самый младший бит. MCU MicroController Unit, микроконтроллер. RTC Real Time Clock, блок часов реального времени. SAR Successive Approximation Register, принцип работы АЦП - регистр последовательного приближения ULP Ultra Low Power, сверхнизкое энергопотребление. [Ссылки] 1. ESP32 Analog to Digital Converter (ADC) site:docs.espressif.com. |