Перейти к содержанию

АЦП ESP32: как измерять напряжение и не ошибиться

У ESP32 два 12-разрядных АЦП на 18 входов, но измерять ими напряжение сложнее, чем на AVR: опорное напряжение у разных чипов отличается, ADC2 занят Wi-Fi, а у краёв диапазона растёт ошибка. Разбираем по даташиту Espressif и документации ESP-IDF и Arduino-ESP32, какие выводы брать, как выбрать ослабление и как получить милливольты с ошибкой в десятки, а не сотни милливольт.

Обновлено Редакция GAW

ESP32 содержит два 12-разрядных АЦП последовательного приближения (SAR) — ADC1 и ADC2 — и по даташиту Espressif измеряет напряжение на 18 выводах. Скорость — до 200 тысяч отсчётов в секунду через контроллер RTC и до 2 миллионов через цифровой контроллер в непрерывном режиме. Сопроцессор ULP умеет измерять напряжение и во сне, будя процессор по порогу. Но точность «из коробки» скромная, и почти все жалобы на АЦП ESP32 объясняются тремя причинами: разброс опорного напряжения, нелинейность у краёв и конфликт ADC2 с Wi-Fi.

Каналы и выводы

По даташиту ESP32:

КаналВыводКаналВывод
ADC1_CH0GPIO36ADC2_CH0GPIO4
ADC1_CH1GPIO37ADC2_CH1GPIO0
ADC1_CH2GPIO38ADC2_CH2GPIO2
ADC1_CH3GPIO39ADC2_CH3GPIO15
ADC1_CH4GPIO32ADC2_CH4GPIO13
ADC1_CH5GPIO33ADC2_CH5GPIO12
ADC1_CH6GPIO34ADC2_CH6GPIO14
ADC1_CH7GPIO35ADC2_CH7GPIO27
ADC2_CH8GPIO25
ADC2_CH9GPIO26

Что учесть при выборе вывода:

  • ADC2 и Wi-Fi. По документации ESP-IDF ADC2 использует и драйвер Wi-Fi. Функция чтения при занятом АЦП возвращает ошибку ESP_ERR_TIMEOUT, и результат недействителен. В проектах с Wi-Fi аналоговые сигналы подключают к ADC1.
  • Только вход. GPIO34–GPIO39 по даташиту работают лишь на вход — для АЦП это не помеха.
  • Strapping-выводы. GPIO0, 2, 12 и 15 из ADC2 влияют на загрузку чипа — подробно в статье о strapping-выводах. На плате ESP32-DevKitC GPIO0 по ESP-IDF вообще нельзя использовать для АЦП: он занят схемой автопрошивки.

Опорное напряжение и ослабление

АЦП сравнивает вход с опорным напряжением. По ESP-IDF у ESP32 оно 1100 мВ по проекту, но у конкретных чипов лежит в пределах 1000–1200 мВ — отсюда разброс результатов между чипами ±6 % по даташиту. Чтобы измерять напряжения выше опорного, вход ослабляют встроенным делителем. Напряжение по коду АЦП по ESP-IDF:

U=Vrefk⋅D2n−1,U = \frac{V_{ref}}{k} \cdot \frac{D}{2^{n} - 1},

где D — код, n — разрядность (12 по умолчанию), k — коэффициент ослабления.

Ослаблениеk по ESP-IDFРабочий диапазон по даташитуОшибка после калибровки по даташитуДиапазон по Arduino-ESP32
0 дБоколо 100 %100–950 мВ±23 мВ100–950 мВ
2,5 дБоколо 75 %100–1250 мВ±30 мВ100–1250 мВ
6 дБоколо 50 %150–1750 мВ±40 мВ150–1750 мВ
11–12 дБоколо 25 %150–2450 мВ±60 мВ150–3100 мВ

Обратите внимание на последнюю строку. Документация Arduino-ESP32 указывает для наибольшего ослабления диапазон до 3100 мВ, а даташит предупреждает: при коде выше 3000 — это около 2450 мВ — точность хуже табличной. Значит, измерять напряжения выше 2,45 В можно, но с гарантированной точностью — нет. И в любом случае на вход нельзя подавать больше напряжения питания плюс 0,3 В — это предел из таблицы 5-3 даташита.

Нелинейность и шум

По даташиту дифференциальная нелинейность — до ±7 МЗР, интегральная — до ±12 МЗР (INL и DNL). Эти цифры получены в щадящих условиях: при 25 °C, с конденсатором 100 нФ на входе, на постоянном сигнале и при выключенных Wi-Fi и Bluetooth. Стоит учесть и нижнюю границу: рабочие диапазоны начинаются со 100–150 мВ, так что совсем малые напряжения ESP32 измеряет плохо.

Против шума ESP-IDF советует то же, что учтено в даташите: керамический конденсатор 100 нФ на входе АЦП и усреднение нескольких отсчётов, например 64. Если сигнал идёт через высокоомный делитель, конденсатор особенно важен — он даёт АЦП заряд на время выборки.

Калибровка

Разброс опорного напряжения компенсируют калибровкой. В eFuse чипа бывают записаны параметры калибровки: по ESP-IDF это либо две точки (Two Point), либо измеренное опорное напряжение (Vref). Драйвер калибровки ESP-IDF для ESP32 использует схему Line Fitting: по этим данным он переводит код в милливольты. Если в eFuse ничего не записано, драйвер берёт опорное напряжение, заданное программистом. После калибровки по eFuse Vref ошибка по даташиту — от ±23 мВ при ослаблении 0 дБ до ±60 мВ при 11–12 дБ. Для большей точности Espressif допускает собственную калибровку.

Arduino и ESP-IDF

В Arduino-ESP32 по документации Espressif:

  • analogRead(pin) возвращает необработанный код без калибровки;
  • analogReadMilliVolts(pin) — калиброванное значение в милливольтах, его и стоит использовать для измерения напряжения;
  • разрешение по умолчанию — 12 бит (0–4095), у ESP32 аппаратно можно задать 9–12 бит;
  • ослабление по умолчанию — 11 дБ; для отдельного вывода его меняет analogSetPinAttenuation.

В ESP-IDF канал настраивают драйвером oneshot (adc_oneshot_config_channel, ослабление ADC_ATTEN_DB_12 в примере Espressif), а в милливольты код переводит драйвер калибровки. ESP-IDF предупреждает, что АЦП служит и источником для генератора случайных чисел: пока идёт чтение, случайные числа становятся менее случайными.

Пример: напряжение до 4,8 В

Чтобы измерить сигнал до 4,8 В, его делят пополам делителем из двух одинаковых резисторов: на вход ADC1 придёт до 2,4 В — внутри рабочего диапазона 150–2450 мВ при ослаблении 12 дБ. Результат analogReadMilliVolts умножают на 2. Делитель берут высокоомным, чтобы не нагружать источник, и ставят конденсатор 100 нФ от входа на землю, как советует ESP-IDF. Ошибка в верхней части диапазона — до ±60 мВ на входе АЦП, то есть до ±120 мВ после умножения, плюс допуск резисторов.

Другие чипы Espressif и их отличия — в разделе ESP32, плата для опытов — ESP32-DevKitC.

Частые вопросы

Какие выводы ESP32 можно использовать как аналоговые входы?

По даташиту Espressif — 18: восемь каналов ADC1 на GPIO32–GPIO39 и десять каналов ADC2 на GPIO0, 2, 4, 12–15, 25–27. Для проектов с Wi-Fi берите ADC1: ADC2 использует и сам Wi-Fi, и чтение в это время может завершиться ошибкой. Выводы GPIO34–GPIO39 работают только на вход.

Почему ESP32 показывает неточное напряжение?

Опорное напряжение 1100 мВ у разных чипов по ESP-IDF лежит в пределах 1000–1200 мВ, и без калибровки результаты различаются на ±6 %. Кроме того, у краёв диапазона растёт нелинейность. Используйте калибровку: в Arduino — функцию analogReadMilliVolts, в ESP-IDF — драйвер калибровки. По даташиту после калибровки ошибка — ±23…±60 мВ в рабочем диапазоне.

Можно ли использовать ADC2 вместе с Wi-Fi?

Ненадёжно. В документации ESP-IDF сказано, что ADC2 использует и Wi-Fi, а функция чтения при занятом АЦП возвращает ошибку ESP_ERR_TIMEOUT, и результат при этом недействителен. Поэтому аналоговые сигналы в проектах с Wi-Fi подключают к выводам ADC1 — GPIO32–GPIO39.

Какое напряжение можно подать на аналоговый вход ESP32?

Не больше напряжения питания плюс 0,3 В — таков предел входа по таблице 5-3 даташита. Измерять при ослаблении 12 дБ даташит рекомендует в диапазоне 150–2450 мВ: выше кода 3000 точность хуже. Большие напряжения подают через резистивный делитель.

Источники

  1. Espressif. ESP32 Series Datasheet, v5.3 — разд. 1 — два 12-разрядных SAR АЦП, до 18 каналов; разд. 4.9.1, табл. 4-3 — DNL ±7 LSB, INL ±12 LSB при 25 °C с конденсатором 100 нФ на входе, постоянном сигнале и выключенных Wi-Fi и Bluetooth; 200 тыс. отсчётов/с (контроллер RTC) и 2 млн (DIG); при atten = 3 и коде выше 3000 (около 2450 мВ) точность хуже; ULP-сопроцессор измеряет во сне; разброс результатов между чипами ±6 % без калибровки; табл. 4-4 — после калибровки по eFuse Vref ошибка ±23, ±30, ±40 и ±60 мВ в диапазонах 100–950, 100–1250, 150–1750 и 150–2450 мВ; разд. 4.10 — каналы ADC1_CH0–CH7 и ADC2_CH0–CH9 и их выводы; табл. 5-3 — вход не выше VDD + 0,3 В
  2. Espressif. ESP-IDF Programming Guide (stable), ESP32: Analog to Digital Converter (ADC) — результат 12 бит по умолчанию; опорное напряжение 1100 мВ по проекту, у разных чипов 1000–1200 мВ; ослабление 0, 2,5, 6 и 12 дБ — k около 100, 75, 50 и 25 %; формула напряжения через код, разрядность, Vref и k; режимы oneshot и continuous
  3. Espressif. ESP-IDF Programming Guide (stable), ESP32: ADC Oneshot Mode Driver и ADC Calibration Driver — ADC2 используется и Wi-Fi; adc_oneshot_read может вернуть ESP_ERR_TIMEOUT, если АЦП занят другим драйвером, результат тогда недействителен; на ESP32-DevKitC GPIO0 нельзя использовать — он занят автопрошивкой; АЦП — источник для генератора случайных чисел; калибровка ESP32 — схема Line Fitting по eFuse Two Point или eFuse Vref, иначе по заданному default_vref; против шума — конденсатор 100 нФ на входе и усреднение, например 64 отсчётов
  4. Espressif. Arduino-ESP32 Documentation: ADC — analogRead — необработанный код без калибровки, analogReadMilliVolts — калиброванные милливольты; разрешение по умолчанию 12 бит, у ESP32 аппаратно 9–12 бит; ослабление по умолчанию 11 дБ; диапазоны ESP32: 100–950, 100–1250, 150–1750 и 150–3100 мВ для 0, 2,5, 6 и 11 дБ; analogSetPinAttenuation — для отдельного вывода

Нашли ошибку?