У ESP32 два 12-разрядных АЦП, но шкала у них не задана опорным напряжением, как у AVR: перед преобразователем стоит ослабитель на 0, 2,5, 6 или 12 дБ, и рабочий диапазон зависит от выбранной ступени. Калькулятор подбирает ступень под ваше напряжение и пересчитывает погрешность из даташита на вход с учётом делителя. Подробно об устройстве АЦП, каналах ADC2 и Wi-Fi — в статье «АЦП ESP32».
Рабочие диапазоны
Таблица 4-4 даташита ESP32 приводит диапазоны, в которых нормирована погрешность после калибровки по опорному напряжению из eFuse:
| Ослабление | ESP-IDF | Arduino | Рабочий диапазон | Погрешность |
|---|---|---|---|---|
| 0 дБ | ADC_ATTEN_DB_0 | ADC_0db | 100–950 мВ | ±23 мВ |
| 2,5 дБ | ADC_ATTEN_DB_2_5 | ADC_2_5db | 100–1250 мВ | ±30 мВ |
| 6 дБ | ADC_ATTEN_DB_6 | ADC_6db | 150–1750 мВ | ±40 мВ |
| 12 дБ | ADC_ATTEN_DB_12 | ADC_11db | 150–2450 мВ | ±60 мВ |
Калькулятор берёт наименьшее ослабление, в диапазон которого помещается наибольшее напряжение на выводе: чем меньше ступень, тем меньше погрешность. Ниже нижней границы — 100 или 150 мВ — показания недостоверны, это тоже стоит учесть: при делителе граница на входе растёт.
В документации Arduino-ESP32 для ступени ADC_11db указан диапазон до 3100 мВ. Даташит оговаривает, что выше кода 3000 — около 2450 мВ — точность хуже, чем в таблице. Калькулятор допускает этот участок, но предупреждает о нём и погрешность не называет.
Делитель и погрешность на входе
Напряжение больше 2,45 В подают через делитель: R1 — от источника к выводу, R2 — от вывода к земле. На выводе получается
а погрешность после калибровки на входе — во столько же раз больше, чем на выводе: ±60 мВ при делителе пополам дают ±120 мВ. К ней добавляется допуск резисторов. Делитель делают высокоомным, чтобы он не разряжал источник, а ESP-IDF советует конденсатор 100 нФ от входа на землю против шума.
Калибровка
Опорное напряжение АЦП ESP32 по ESP-IDF — 1100 мВ по проекту, но у разных чипов от 1000 до 1200 мВ, и без калибровки результаты различаются на ±6 %. Идеальная формула из руководства ESP-IDF
с k ≈ 25 % для 12 дБ даёт для кода 3000 около 3223 мВ, тогда как по даташиту код 3000 — примерно 2450 мВ. Поэтому напряжение берут не из формулы, а из драйвера калибровки: analogReadMilliVolts() в Arduino или adc_cali_raw_to_voltage() со схемой Line Fitting в ESP-IDF, как в коде, который выдаёт калькулятор. Каналы — только ADC1, GPIO32–GPIO39: ADC2 по ESP-IDF использует и Wi-Fi.
Частые вопросы
Какое ослабление АЦП ESP32 выбрать?
Наименьшее, при котором наибольшее напряжение на выводе попадает в рабочий диапазон из таблицы 4-4 даташита: до 950 мВ — 0 дБ, до 1250 мВ — 2,5 дБ, до 1750 мВ — 6 дБ, до 2450 мВ — 12 дБ (в Arduino — ADC_11db). Чем меньше ослабление, тем меньше погрешность: после калибровки ±23 мВ при 0 дБ против ±60 мВ при 12 дБ.
Как измерить напряжение аккумулятора 4,2 В на ESP32?
Через делитель из двух резисторов, например 100 кОм и 100 кОм: на вывод придёт до 2,1 В — это диапазон ослабления 12 дБ. Результат analogReadMilliVolts умножают на 2. Погрешность ±60 мВ на выводе превратится в ±120 мВ на входе, плюс допуск резисторов; делитель при этом потребляет около 21 мкА.
Можно ли подать на АЦП ESP32 3,3 В?
Arduino-ESP32 указывает для ESP32 при ADC_11db диапазон до 3100 мВ, а даташит нормирует точность только до 2450 мВ: выше кода 3000 она хуже, чем в таблице. Поэтому 3,3 В лучше подавать через делитель, например 47 и 100 кОм: на выводе будет около 2,24 В.
Зачем калибровка, если есть формула из ESP-IDF?
Формула ESP-IDF с опорным напряжением 1100 мВ и k ≈ 25 % для 12 дБ даёт для кода 3000 около 3223 мВ, а по даташиту код 3000 — примерно 2450 мВ. Коэффициенты ослабления приблизительные, а опорное напряжение у чипов разное, поэтому милливольты берут из драйвера калибровки: analogReadMilliVolts в Arduino или adc_cali_raw_to_voltage в ESP-IDF.
Источники
- Espressif. ESP32 Series Datasheet, v5.3 — разд. 4.9.1 — два 12-разрядных SAR АЦП; табл. 4-3 — DNL ±7 LSB, INL ±12 LSB; при atten = 3 выше кода 3000 (около 2450 мВ) точность хуже; без калибровки результаты разных чипов различаются на ±6 %; табл. 4-4 — после калибровки по eFuse Vref рабочие диапазоны и полная погрешность: atten 0 — 100–950 мВ, ±23 мВ; 1 — 100–1250 мВ, ±30 мВ; 2 — 150–1750 мВ, ±40 мВ; 3 — 150–2450 мВ, ±60 мВ (эталон тестов)
- Espressif. ESP-IDF Programming Guide (stable), ESP32: ADC, ADC Oneshot Mode Driver, ADC Calibration Driver — 12 бит по умолчанию; Vref 1100 мВ по проекту, 1000–1200 мВ у разных чипов; ослабление 0, 2,5, 6 и 12 дБ — k около 100, 75, 50 и 25 %, V = Vref / k · код / (2^разрядность − 1) (второй источник тестов); каналы ADC1 — GPIO36, 37, 38, 39, 32, 33, 34, 35 (каналы 0–7); adc_oneshot_new_unit, adc_oneshot_config_channel, adc_oneshot_read; схема калибровки Line Fitting — adc_cali_create_scheme_line_fitting, adc_cali_raw_to_voltage; ADC2 используется и Wi-Fi; конденсатор 100 нФ на входе от шума
- Espressif. Arduino-ESP32 Documentation: ADC — analogReadMilliVolts — калиброванные милливольты; analogSetPinAttenuation; ослабления ADC_0db, ADC_2_5db, ADC_6db, ADC_11db, для ESP32 измеримые диапазоны 100–950, 100–1250, 150–1750 и 150–3100 мВ
Где пригодится
Встроить калькулятор на свой сайт
Скопируйте код и вставьте его в HTML страницы, статьи или вики. Виджет бесплатный, без рекламы, счётчиков и cookie. Условие одно — ссылка на GAW под рамкой остаётся на месте. Подробнее о виджетах
<iframe src="https://gaw.ru/embed/esp32-adc/" title="АЦП ESP32: ослабление, делитель и погрешность измерения" width="100%" height="640" style="border:1px solid #e3e5e9;border-radius:8px" loading="lazy" allow="clipboard-write"></iframe>
<p style="margin:6px 0 0;font-size:14px">Калькулятор: <a href="https://gaw.ru/tools/esp32-adc/">АЦП ESP32: ослабление, делитель и погрешность измерения</a> — GAW.ru</p>Автоподстройка высоты рамки
Если сайт разрешает скрипты, добавьте этот код один раз в любом месте страницы: рамка будет менять высоту вместе с результатом расчёта.
<script>window.addEventListener("message",function(e){if(e.origin!=="https://gaw.ru"||!e.data||e.data.type!=="gaw:embed-height")return;var f=document.querySelectorAll('iframe[src^="https://gaw.ru/embed/"]');for(var i=0;i<f.length;i++)if(f[i].contentWindow===e.source)f[i].style.height=e.data.height+"px"})</script>Обновлено .
Нашли ошибку в расчёте?