АЦП 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_CH0 | GPIO36 | ADC2_CH0 | GPIO4 |
| ADC1_CH1 | GPIO37 | ADC2_CH1 | GPIO0 |
| ADC1_CH2 | GPIO38 | ADC2_CH2 | GPIO2 |
| ADC1_CH3 | GPIO39 | ADC2_CH3 | GPIO15 |
| ADC1_CH4 | GPIO32 | ADC2_CH4 | GPIO13 |
| ADC1_CH5 | GPIO33 | ADC2_CH5 | GPIO12 |
| ADC1_CH6 | GPIO34 | ADC2_CH6 | GPIO14 |
| ADC1_CH7 | GPIO35 | ADC2_CH7 | GPIO27 |
| ADC2_CH8 | GPIO25 | ||
| ADC2_CH9 | GPIO26 |
Что учесть при выборе вывода:
- 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:
где 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 точность хуже. Большие напряжения подают через резистивный делитель.
Источники
- 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 В
- 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
- 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 отсчётов
- 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 — для отдельного вывода
Нашли ошибку?
Смотрите также
- ESP32ESP32, S2, S3, C2, C3, C5, C6, H2, P4: ядра, радио, USB, GPIO — сравнение и выбор
- Глубокий сон ESP32Режимы сна, токи, пробуждение по таймеру и выводам, RTC-память, расчёт батареи
- Strapping-выводы ESP32Какие GPIO читаются при сбросе: загрузка, напряжение флеш-памяти, JTAG — для ESP32, S2, S3, C2, C3, C5, C6, H2, P4
- ESP32-DevKitC V438 контактов, АЦП, сенсоры, обвязка загрузки, питание, прошивка
- АЦП последовательного приближенияВыборка и подбор кода бит за битом: такты, скорость, источник сигнала
- INL и DNLНелинейность АЦП: неравные ступени и изгиб характеристики, пропущенные коды
- Делитель напряженияВыход, ток, нагрузка, подбор пары резисторов