В этой статье из серии «Основы ESP32» показано, как считывать аналоговые значения с помощью ESP32 с использованием Arduino IDE.
Это полезно для считывания данных с самых разных датчиков и переменных компонентов, включая, помимо прочего, подстроечные резисторы, джойстики, ползунки и чувствительные к силе резисторы.
Выводы АЦП ESP32
ESP32 включает в себя два 12-битных АЦП SAR – АЦП1 и АЦП2 – и поддерживает измерения по 18 каналам (аналоговые контакты). ADC1 доступен на восьми GPIO (от 32 до 39), а ADC2 доступен на десяти GPIO (0, 2, 4, с 12 по 15 и с 25 по 27).
Однако плата DEVKIT V1 DOIT (версия с 30 GPIO) имеет всего 15 каналов АЦП, как показано на рисунке ниже.
АЦП вашего ESP32 имеет разрешение 12 бит, что означает, что он может обнаруживать 4096 (2 ^ 12) дискретных аналоговых уровней. Другими словами, он преобразует входные напряжения в диапазоне от 0 до 3,3 В (рабочее напряжение) в целочисленные значения от 0 до 4095. В результате разрешение составляет 3,3 В/4096 единиц, или 0,0008 В (0,8 мВ) на единицу.
Более того, разрешение АЦП и диапазон каналов можно задавать программно.
Ограничения АЦП ESP32
По правде говоря, АЦП — не самая сильная сторона ESP32. Есть несколько ограничений, о которых вам следует знать.
Невозможно использовать, когда Wi-Fi включен.
Контакты ADC2 нельзя использовать, когда включен Wi-Fi. Поскольку существует большая вероятность использования Wi-Fi на микроконтроллере, предназначенном для его использования, можно использовать только ADC1.
Входной диапазон АЦП
АЦП ESP32 может измерять напряжение только в диапазоне от 0 до 3,3 В. Вы не можете напрямую измерить аналоговое напряжение от 0 до 5 В.
Точность АЦП
В идеале при использовании АЦП можно было бы ожидать линейного поведения, но это не так. Преобразователи АЦП на ESP32 имеют нелинейный характер. Более подробную информацию об этом вы можете найти в обсуждении на GitHub .
На графике ниже хорошо видны нелинейности на нижнем и верхнем концах входного напряжения.
По сути, это означает, что ESP32 не может отличить 3,2 В от 3,3 В; измеренное значение будет таким же (4095). Точно так же он не может различать сигналы 0 В и 0,13 В; измеренное значение будет таким же (0).
Электрический шум
Электрический шум АЦП предполагает небольшие колебания результатов измерений.
Однако это можно исправить добавлением конденсатора на выходе и передискретизацией.
Функция AnalogRead()
Считать аналоговые значения с вывода GPIO очень просто. В Arduino IDE вы используете analogRead()
функцию, которая принимает в качестве аргумента номер контакта GPIO, который вы хотите прочитать.
analogRead(GPIO);
Чтение потенциометра
Чтобы продемонстрировать, как использовать АЦП на ESP32, мы будем использовать простой пример, который считывает аналоговое значение с потенциометра.
Подключение оборудования
Давайте создадим простую схему потенциометра для этого примера.
Начните с вставки потенциометра в макет. Подключите средний контакт к контакту GPIO 34 на вашем ESP32. Наконец, соедините один из внешних контактов потенциометра (неважно какой) с контактом 3V3 ESP32, а другой — с землей.
Пример кода
Загрузите следующий эскиз на свой ESP32. Этот скетч просто считывает показания потенциометра и выводит результаты на последовательный монитор.
// Potentiometer is connected to GPIO 34 (Analog ADC1_CH6)
34;
// variable for storing the potentiometer value
0;
setup() {
Serial.115200);
1000);
}
loop() {
// Reading potentiometer value
potValue = analogRead(potPin);
Serial.<span);
Serial.println(potValue);
500);
}
После загрузки эскиза откройте последовательный монитор на скорости 115200 бод и нажмите кнопку EN на ESP32.
Вы должны увидеть значение от 0 до 4095, в зависимости от текущего поворота ручки, которое будет распечатано на последовательном мониторе. Попробуйте повернуть ручку потенциометра и посмотреть, как изменяются значения.
Объяснение кода:
Эскиз начинается с определения контакта GPIO, к которому подключен потенциометр, в данном случае это GPIO 34.
34;
Также определена переменная для хранения значений потенциометра.
0;
В setup() мы инициализируем последовательную связь с ПК.
Serial.115200);
В цикле функция analogRead()
используется для считывания напряжения на potPin
. Возвращаемое значение сохраняется в переменной potValue
.
potValue = analogRead(potPin);
Наконец, значения, считанные с потенциометра, выводятся на последовательный монитор.
Serial.<span);
Serial.println(potValue);
potPin
не нужно устанавливать в качестве входных данных. Это делается автоматически каждый раз, когда вы звоните analogRead()
.
Другие функции АЦП
Есть и другие функции АЦП, которые могут быть полезны в других проектах:
analogReadMilliVolts(pin)
: получить значение АЦП для данного вывода/канала АЦП в милливольтах.analogReadResolution(bits)
: устанавливает биты выборки и разрешение чтения. По умолчанию установлено разрешение 12 бит. Диапазон: от 9 (0–511) до 12 бит (0–4095).analogSetWidth(bits)
: устанавливает аппаратные биты выборки и разрешение чтения. По умолчанию установлено разрешение 12 бит. Диапазон: от 9 до 12 бит. 9 бит = 0–511, 10 бит = 0–1023, 11 бит = 0–2047 и 12 бит = 0–4095.analogSetCycles(cycles)
: устанавливает количество циклов на выборку. По умолчанию — 8. Диапазон: от 1 до 255.analogSetSamples(samples)
: устанавливает количество выборок в диапазоне. По умолчанию — 1 образец. Оказывает эффект повышения чувствительности.analogSetClockp(clockp)
: устанавливает делитель тактовой частоты АЦП. По умолчанию — 1. Диапазон: от 1 до 255.analogSetAttenuation(attenuation)
: устанавливает входное затухание для всех выводов АЦП. По умолчаниюADC_11db
. Принятые значения:ADC_0db
: затухание не устанавливается (диапазон измеряемого входного напряжения = 100 мВ ~ 950 мВ).ADC_2_5db
: устанавливает затухание 1,34 (диапазон измеряемого входного напряжения = 100 мВ ~ 1250 мВ)ADC_6db
: устанавливает затухание 1,5 (диапазон измеряемого входного напряжения = 150 мВ ~ 1750 мВ)ADC_11db
: устанавливает затухание 3,6 (диапазон измеряемого входного напряжения = 150 мВ ~ 2450 мВ)analogSetPinAttenuation(pin, attenuation)
: Эта функция аналогична предыдущей, за исключением того, что она устанавливает входное затухание для указанного контакта.adcAttachPin(pin)
: подключает вывод к АЦП (также отключает любой другой аналоговый режим, который может быть включен) и возвращает true, если конфигурация прошла успешно, в противном случае возвращает false.adcStart(pin)
: запускает преобразование АЦП на шине подключенного контакта.adcBusy(pin)
: проверяет, выполняется ли в данный момент преобразование на шине АЦП вывода (возвращает ИСТИНА или ЛОЖЬ).resultadcEnd(pin)
: получает результат преобразования (ждет, если АЦП не завершился), возвращает 16-битное целое число.
Более подробную информацию можно найти на readthedocs .