مبدل آنالوگ به دیجیتال ADC برد ESP32 (آموزش جامع)

محتویات
این مقاله از سری مبانی ESP32 نحوه خواندن مقادیر آنالوگ با استفاده از ESP32 در محیط Arduino IDE را نشان میدهد. این قابلیت برای خواندن انواع سنسورها و قطعات متغیر، از جمله پتانسیومترها، جویاستیکها، اسلایدرها و مقاومتهای حساس به نیرو، مفید است.
آنالوگ به دیجیتال در ESP32
برد ESP32 شامل دو مبدل آنالوگ به دیجیتال (ADC) 12 بیتی از نوع SAR (ADC1 و ADC2) است و از اندازهگیری در 18 کانال (پینهای فعال آنالوگ) پشتیبانی میکند. ADC1 روی هشت پین GPIO (32 تا 39) و ADC2 روی ده پین GPIO (0، 2، 4، 12 تا 15 و 25 تا 27) در دسترس است.
با این حال، برد DEVKIT V1 DOIT (نسخهای با 30 پین GPIO) تنها 15 کانال ADC دارد، همانطور که در شکل زیر نشان داده شده است.
ADC در ESP32 شما دارای وضوح 12 بیت است ، به این معنی که می تواند سطح آنالوگ گسسته 4096 (2^12) را تشخیص دهد. به عبارت دیگر ، ولتاژهای ورودی از 0 تا 3.3 ولت (ولتاژ عملیاتی) را به مقادیر عدد صحیح از 0 تا 4095 تبدیل می کند. این منجر به وضوح 3.3 ولت / 4096 واحد یا 0.0008 ولت (0.8 میلی ولت) در واحد می شود.
علاوه بر این ، وضوح ADC و محدوده کانال را می توان به صورت برنامه ای تنظیم کرد.
محدودیتهای ADC در ESP32
واقعیت این است که ADC قویترین نقطه قوت ESP32 نیست. چندین محدودیت وجود دارد که باید از آنها آگاه باشید:
- غیرقابل استفاده هنگام فعالسازی وایفای: پینهای ADC2 زمانی که وایفای فعال است، قابل استفاده نیستند. از آنجا که احتمال استفاده از وایفای در میکروکنترلری که برای این منظور طراحی شده است زیاد است، تنها ADC1 قابل استفاده خواهد بود.
- محدوده ورودی ADC: ADC در ESP32 تنها میتواند ولتاژهای بین 0 تا 3.3 ولت را اندازهگیری کند. شما نمیتوانید ولتاژهای آنالوگ بین 0 تا 5 ولت را مستقیماً اندازهگیری کنید.
- دقت ADC: در حالت ایدهآل، شما انتظار دارید که ADC رفتار خطی داشته باشد، اما اینطور نیست. مبدلهای ADC در ESP32 ذاتاً غیرخطی هستند. اطلاعات بیشتر در این مورد را میتوانید در یک بحث روی GitHub پیدا کنید.
- نویز الکتریکی: نویز الکتریکی ADC به معنای نوسان جزئی در اندازهگیریها است. با این حال، این مشکل را میتوان با اضافه کردن یک خازن در خروجی و نمونهبرداری بیش از حد (oversampling) اصلاح کرد.
رزولوشن ADC در ESP32
ADC در ESP32 شما دارای رزولوشن 12 بیتی است، به این معنی که میتواند 4096 (2^12) سطح آنالوگ مجزا را تشخیص دهد. به عبارت دیگر، ولتاژهای ورودی در محدوده 0 تا 3.3 ولت (ولتاژ کاری) را به مقادیر عددی بین 0 تا 4095 تبدیل میکند. این موضوع منجر به رزولوشن 3.3 ولت / 4096 واحد، یا 0.0008 ولت (0.8 میلیولت) در هر واحد میشود.
علاوه بر این، رزولوشن ADC و محدوده کانال میتوانند به صورت برنامهای تنظیم شوند.
خواندن یک پتانسیومتر با برد ESP32
برای نشان دادن نحوه استفاده از ADC در ESP32، از یک مثال ساده استفاده میکنیم که مقدار آنالوگ یک پتانسیومتر را میخواند.
تابع analogRead()
خواندن مقادیر آنالوگ از یک پین GPIO بسیار ساده است. در Arduino IDE، از تابع analogRead()
استفاده میکنید که به عنوان آرگومان، شماره پین GPIO را که میخواهید بخوانید، میپذیرد.
analogRead(GPIO);
اتصالات سختافزاری
بیایید یک مدار ساده با پتانسیومتر برای این مثال راهاندازی کنیم.
- پتانسیومتر را روی برد بورد قرار دهید.
- پین وسط پتانسیومتر را به پین GPIO 34 روی ESP32 متصل کنید.
- یکی از پینهای بیرونی پتانسیومتر (فرقی نمیکند کدام یک) را به پین 3.3 ولت ESP32 و دیگری را به زمین (GND) وصل کنید.
کد نمونه آردوینو برای ADC ESP32
کد زیر را روی ESP32 خود آپلود کنید. این کد به سادگی پتانسیومتر را میخواند و نتایج را در Serial Monitor چاپ میکند.
// پتانسیومتر به پین GPIO 34 (کانال ADC1_CH6) متصل است const int potPin = 34; // متغیر برای ذخیره مقدار پتانسیومتر int potValue = 0; void setup() { Serial.begin(115200); delay(1000); } void loop() { // خواندن مقدار پتانسیومتر potValue = analogRead(potPin); Serial.print("Analog value: "); Serial.println(potValue); delay(500); }
پس از آپلود اسکچ، Serial Monitor را با نرخ باد 115200 باز کنید و دکمه EN روی ESP32 را فشار دهید.
شما باید مقداری بین 0 تا 4095 ببینید که بسته به چرخش دسته پتانسیومتر تغییر میکند. سعی کنید دسته پتانسیومتر را بچرخانید تا ببینید مقادیر چگونه تغییر میکنند.
توضیح کد
اسکچ با تعریف پین GPIO که پتانسیومتر به آن متصل است، شروع میشود. در این مورد، پین GPIO 34 است.
const int potPin = 34;
همچنین یک متغیر برای ذخیره مقادیر پتانسیومتر تعریف شده است.
int potValue = 0;
در بخش setup()
، ارتباط سریال با کامپیوتر راهاندازی میشود.
Serial.begin(115200);
در بخش loop()
، از تابع analogRead()
برای خواندن ولتاژ روی potPin
استفاده میشود. مقدار بازگشتی در متغیر potValue
ذخیره میشود.
potValue = analogRead(potPin);
در نهایت، مقادیر خوانده شده از پتانسیومتر در Serial Monitor چاپ میشوند.
Serial.print("Analog value: "); Serial.println(potValue);
توجه داشته باشید که potPin
نیازی به تنظیم به عنوان ورودی ندارد. این کار به طور خودکار هر بار که analogRead()
فراخوانی میشود، انجام میگیرد.
سایر توابع ADC
توابع دیگری نیز در رابطه با ADC وجود دارند که ممکن است در پروژههای دیگر مفید باشند:
analogReadMilliVolts(pin)
: مقدار ADC را برای یک پین/کانال مشخص بر حسب میلیولت بازمیگرداند.analogReadResolution(bits)
: وضوح نمونهبرداری و خواندن را تنظیم میکند. پیشفرض 12 بیت است. محدوده: 9 (0 تا 511) تا 12 بیت (0 تا 4095).analogSetWidth(bits)
: وضوح نمونهبرداری سختافزاری و خواندن را تنظیم میکند. پیشفرض 12 بیت است. محدوده: 9 تا 12 بیت.analogSetCycles(cycles)
: تعداد سیکلها در هر نمونه را تنظیم میکند. پیشفرض 8 است. محدوده: 1 تا 255.analogSetSamples(samples)
: تعداد نمونهها در محدوده را تنظیم میکند. پیشفرض 1 نمونه است. این کار باعث افزایش حساسیت میشود.analogSetClockDiv(clockDiv)
: تقسیمکننده ساعت ADC را تنظیم میکند. پیشفرض 1 است. محدوده: 1 تا 255.analogSetAttenuation(attenuation)
: تضعیف ورودی را برای همه پینهای ADC تنظیم میکند. پیشفرضADC_11db
است. مقادیر قابل قبول:ADC_0db
: بدون تضعیف (محدوده ولتاژ ورودی قابل اندازهگیری = 100 mV تا 950 mV).ADC_2_5db
: تضعیف 1.34 (محدوده ولتاژ ورودی قابل اندازهگیری = 100 mV تا 1250 mV).ADC_6db
: تضعیف 1.5 (محدوده ولتاژ ورودی قابل اندازهگیری = 150 mV تا 1750 mV).ADC_11db
: تضعیف 3.6 (محدوده ولتاژ ورودی قابل اندازهگیری = 150 mV تا 2450 mV).analogSetPinAttenuation(pin, attenuation)
: این تابع مشابه تابع قبلی است، اما تضعیف ورودی را برای پین مشخصشده تنظیم میکند.adcAttachPin(pin)
: یک پین را به ADC متصل میکند (و هر حالت آنالوگ دیگری که ممکن است فعال باشد را پاک میکند) و در صورت موفقیتآمیز بودن پیکربندی،true
و در غیر این صورتfalse
بازمیگرداند.adcStart(pin)
: یک تبدیل ADC را روی باس پین متصل شده شروع میکند.adcBusy(pin)
: بررسی میکند که آیا تبدیل روی باس ADC پین در حال اجرا است یا خیر (TRUE
یاFALSE
بازمیگرداند).adcEnd(pin)
: نتیجه تبدیل را دریافت میکند (اگر ADC هنوز تمام نشده باشد، منتظر میماند) و یک عدد صحیح 16 بیتی بازمیگرداند.
این توابع میتوانند برای تنظیم دقیقتر و بهبود عملکرد ADC در پروژههای مختلف استفاده شوند.