فهرست مطالب:
- مرحله 1: مبدل AD چیست؟
- مرحله 2: منابع مورد استفاده
- مرحله 3: ESP32 ADC
- مرحله 4: مدار مورد استفاده
- مرحله 5: علامت استفاده شده
- مرحله 6: داده های بدست آمده از اسیلوسکوپ
- مرحله 7: داده های بدست آمده از اسیلوسکوپ (فایل csv در اکسل)
- مرحله 8: داده های به دست آمده توسط ADC
- مرحله 9: داده های به دست آمده توسط ADC - Excel
- مرحله دهم: مقایسه راهپیمایی های صعودی
- مرحله 11: برابر کردن تعداد نمونه ها
- مرحله 12: پر کردن شکاف - خط روند
- مرحله 13: پر کردن شکاف - منحنی چند جمله ای درجه 2
- مرحله 14: پر کردن شکاف - ارزیابی عملکرد
- مرحله 15: تبدیل ولتاژ اسیلوسکوپ به مقدار معادل برای مقایسه با ADC
- مرحله 16: مقایسه دو سطح شیب دار به دست آمده
- مرحله 17: رفتار تفاوت خواندن ADC (ERROR)
- مرحله 18: رفتار تفاوت خواندن ADC - یافتن یک تابع تصحیح
- مرحله 19: استفاده از نرم افزارهای دیگر
- مرحله 20: ثابت ها و راه اندازی ()
- مرحله 21: حلقه () و تابع تصحیح
- مرحله 22: استفاده از تابع اصلاح PolySolve
- مرحله 23: ضبط با تصحیح - سریال پلاتر
- مرحله 24: هزینه محاسبه
- مرحله 25: کد تست - راه اندازی () و شروع حلقه ()
- مرحله 26: کد تست - حلقه () و پردازش
- مرحله 27: کد تست - حلقه () - نتایج
- مرحله 28: کد تست - توابع مورد استفاده
- مرحله 29: فایل ها
تصویری: آیا در مورد ESP32 ADC Adjustment می دانید ؟: 29 مرحله
2024 نویسنده: John Day | [email protected]. آخرین اصلاح شده: 2024-01-30 08:55
امروز ، من قصد دارم در مورد یک مسئله فنی بیشتر صحبت کنم ، اما من فکر می کنم همه کسانی که با ESP32 کار می کنند باید بدانند: مسئله ADC (مبدل آنالوگ به دیجیتال) تنظیم خواندن. من این را مهم می دانم زیرا هنگام انجام "اندازه گیری" ، به ویژه با دستگاهی که خروجی آنالوگ دارد ، باید کاملاً مطمئن باشید که خواندن به درستی انجام می شود.
بنابراین ، در ویدئو امروز ، ما اندازه گیری ها را با استفاده از "مبدل آنالوگ-دیجیتال" ESP32 انجام می دهیم ، مغایرت های تبدیل را مشاهده کرده و یک روش تنظیم / کالیبراسیون ADC را اعمال می کنیم.
مرحله 1: مبدل AD چیست؟
مبدل AD مداری است که می تواند مقدار آنالوگ (پیوسته) را به مقادیر دیجیتال (گسسته) تبدیل کند. معنی آن چیست؟ این بدان معناست که در حالی که مقادیر دیجیتال فقط می توانند مقادیر گسسته ای را که از ترکیب صفر و یک تشکیل شده اند فرض کنند ، یک مقدار آنالوگ می تواند هر مقداری را در یک محدوده فرض کند. به عنوان مثال ، اگر ولتاژ یک سلول AA ایده آل را اندازه گیری کنیم ، می توانیم مقداری بین 0V تا 1.5V پیدا کنیم ، زیرا این مقدار آنالوگ است. حالت خروجی یک لامپ ایده آل باید فقط دو حالت (خاموش یا روشن) داشته باشد که قدر گسسته است. از آنجا که میکروکنترلرها با استفاده از این منطق گسسته کار می کنند ، ما به مداری نیاز داریم که بتواند مقدار آنالوگ را به دیجیتال (یا گسسته) تبدیل کند.
مرحله 2: منابع مورد استفاده
• یک کارت Lolin32 Lite v1.0.0
• اسیلوسکوپ Tektronix TDS1001C برای ضبط
• یک کابل USB برای ESP32
• اسیلوسکوپ Hantek DSO4102C به عنوان مولد سیگنال
مرحله 3: ESP32 ADC
بر اساس داده های Espressif ، تراشه های ESP32 ممکن است در نتایج اندازه گیری شده +/- 6٪ تفاوت از یک تراشه به تراشه دیگر نشان دهند.
علاوه بر این ، تبدیل پاسخ خطی برای هر محدوده موجود برای خواندن ندارد. Espressif روشی را برای کالیبراسیون ارائه می دهد و به کاربران پیشنهاد می کند که در صورت نیاز به دستیابی به دقت مورد نظر ، روشهای دیگری را نیز پیاده سازی کنند.
ما جمع آوری داده ها را انجام می دهیم و از این طریق ، پاسخ های ADC و نمونه ای از اعمال یک فرایند ریاضی برای خواندن تنظیم را نشان می دهیم.
چندین روش (ساده تر یا پیچیده تر) برای انجام این اصلاحات وجود دارد. این به شما بستگی دارد که مناسب ترین پروژه را برای پروژه خود ارزیابی کنید.
آنچه در اینجا نشان داده شده است ، دارای یک هدف گویا است و سعی می کند نکات جالبی را که در طول تعدیلات قابل مشاهده است ، مورد بررسی قرار دهد.
مرحله 4: مدار مورد استفاده
من از یک اسیلوسکوپ با ژنراتور سیگنال که تا 25 مگاهرتز می رود ، Hantek DSO4102C استفاده کردم. ما موجی ایجاد کردیم که توسط ESP A / D و اسیلوسکوپ خوانده شد. داده های جمع آوری شده در csv و در یک صفحه گسترده ثبت شده است ، که من آنها را در انتهای مقاله برای بارگذاری قرار می دهم.
مرحله 5: علامت استفاده شده
ما یک سیگنال ذوزنقه ای با فرکانس پایین را انتخاب کردیم که اجازه دسترسی به سطح شیب دار را که در تمام محدوده تبدیل اجرا می شود ، می دهد. این اجازه می دهد تا تعداد زیادی نمونه در این سطح شیب دار قرار گیرد.
مرحله 6: داده های بدست آمده از اسیلوسکوپ
تصویر ضبط توسط اسیلوسکوپ انجام شد. داده ها در یک فایل csv ذخیره شد. به انحنای جزئی در رمپ های بالا و پایین سیگنال توجه کنید.
مرحله 7: داده های بدست آمده از اسیلوسکوپ (فایل csv در اکسل)
ما نمونه برداری را در اینجا داریم.
مرحله 8: داده های به دست آمده توسط ADC
با تغییر سرعت انتقال سریال ، می توانیم داده های گرفته شده توسط ADC را مشاهده کنیم. تغییر شکل سیگنال ذوزنقه ای را مشاهده کنید.
داده های مشاهده شده در پلاتر سریال Arduino IDE
مرحله 9: داده های به دست آمده توسط ADC - Excel
با استفاده از نرخ بالاتر و ترمینال سریال ، می توانیم مقادیر را ضبط کرده و آنها را در Excel برای مقایسه های خود اعمال کنیم.
مرحله دهم: مقایسه راهپیمایی های صعودی
ما دو رمپ صعودی دو صید را با هم مقایسه می کنیم.
به انحنایی که در هر دو رمپ رخ می دهد توجه کنید.
همچنین توجه داشته باشید که برای همان سطح شیب دار ، نمونه های بسیار بیشتری از ESP32 نسبت به اسیلوسکوپ داریم.
مرحله 11: برابر کردن تعداد نمونه ها
از آنجا که ESP32 تعداد بیشتری نمونه از اسیلوسکوپ ارائه می دهد ، ما باید این مقادیر را برابر کنیم ، زیرا آنها به عنوان شاخصی برای مقایسه دو منحنی عمل می کنند.
برای این منظور ، ما یک مقایسه مستقیم انجام می دهیم.
ما 305 نمونه برای رمپ اسیلوسکوپ و 2365 نمونه برای رمپ ADC داریم.
از آنجا که رمپ ها در یک محدوده هستند ، می توانیم بگوییم که تقریباً 7.75 نمونه از ADC برای هر اسیلوسکوپ داریم.
ضرب شاخص هر نمونه اسیلوسکوپ منحنی یکسانی دارد ، اما دارای شاخص های معادل ADC و داده های توزیع شده مجدد است.
برای پر کردن داده های مفقود شده برای موقعیت های جدید ، ما یک منحنی را که از نظر آماری با داده های شناخته شده متناسب است ، اعمال می کنیم.
مرحله 12: پر کردن شکاف - خط روند
با انتخاب داده های شناخته شده (نقاط آبی) ، با کلیک و سپس کلیک با دکمه سمت راست ، "Add trend trend …" را انتخاب کنید.
در پنجره ای که ظاهر می شود ، نوع چند جمله ای را انتخاب می کنیم (سفارش 2 کافی خواهد بود).
ما همچنین گزینه های "مشاهده معادله در نمودار" و "نمایش مقدار مربع R در نمودار" را بررسی کردیم.
روی "بستن" کلیک می کنیم.
مرحله 13: پر کردن شکاف - منحنی چند جمله ای درجه 2
اکسل دو قطعه اطلاعات جدید به ما می دهد. معادله مرتبه دوم که بیشترین تناسب را با داده ها دارد و معادله مربع R که این کفایت را کمیت می کند.
فقط به یاد داشته باشید که هرچه به 1 نزدیکتر باشید ، معادله مناسب تر است.
بیایید وارد ریاضیات درگیر نشویم ، فقط از آن به عنوان یک ابزار استفاده کنیم.
مرحله 14: پر کردن شکاف - ارزیابی عملکرد
بیایید شکاف های نمونه گیری را با داده های ایجاد شده توسط معادله پر کنیم. و سپس ، آنها را نقطه به نقطه مقایسه کنید.
y = -9E -08x2 + 0 ، 0014x + 0 ، 1505
R² = 0 ، 9999
ولتاژ اسیلوسکوپ = -9E -08 * index2 + 0 ، 0014 * index + 0 ، 1505
مرحله 15: تبدیل ولتاژ اسیلوسکوپ به مقدار معادل برای مقایسه با ADC
بیایید از این مزیت استفاده کنیم تا مقدار ولتاژ اسیلوسکوپ را به یک مقدار ADC معادل تبدیل کنیم.
از آنجا که بالاترین مقدار به دست آمده در ADP ESP32 4095 بود ، که معادل خوانش 2.958V برای همان شاخص است ، می توان گفت که:
هر ولت در اندازه گیری های اسیلوسکوپ تقریباً برابر 1384.4 واحد بعد از میلاد است. بنابراین ، ما می توانیم همه اندازه گیری های اسیلوسکوپ را در این مقدار ضرب کنیم.
مرحله 16: مقایسه دو سطح شیب دار به دست آمده
تجسم تفاوتهای به دست آمده در دو قرائت.
مرحله 17: رفتار تفاوت خواندن ADC (ERROR)
منحنی زیر نشان می دهد که تفاوت در خواندن ADC به عنوان تابعی از اندازه گیری چگونه رفتار می کند. این مجموعه داده ها به ما امکان می دهد یک تابع تصحیح پیدا کنیم.
برای یافتن این منحنی ، ما فقط تفاوت موجود در هر اندازه را به عنوان تابعی از هر موقعیت احتمالی AD (0 تا 4095) ترسیم می کنیم.
مرحله 18: رفتار تفاوت خواندن ADC - یافتن یک تابع تصحیح
ما می توانیم در Excel با افزودن یک خط روند ، که در حال حاضر درجه بالاتری است ، یک تابع تصحیح را تعیین کنیم تا زمانی که به اندازه کافی با داده های ما مطابقت داشته باشد.
مرحله 19: استفاده از نرم افزارهای دیگر
نرم افزار جالب دیگر برای تعیین منحنی ها PolySolve است که می توانید مستقیماً در پیوند: https://arachnoid.com/polysolve/ استفاده کنید یا به عنوان یک برنامه جاوا بارگیری کنید.
این امکان استفاده از رگرسیون های چند جمله ای درجه بالاتر و ارائه عملکرد فرمت شده و همچنین سایر عملکردها را فراهم می آورد.
برای استفاده از آن ، کافی است داده ها را در اولین کادر متنی وارد کنید. داده ها باید از ترتیب X ، Y جدا شده با کاما یا زبانه پیروی کنند. در استفاده صحیح از نقطه به عنوان نقطه اعشار احتیاط کنید.
اگر داده های وارد شده به درستی قالب بندی شده باشند ، یک نمودار در کادر بعدی ظاهر می شود.
در اینجا نحوه منحنی خطای ADC ما پیش رفت.
این پنجره نتیجه رگرسیون را نشان می دهد ، از جمله داده های کفایت عملکرد ، که به نوبه خود می تواند خروجی خود را به چندین روش قالب بندی کند: به عنوان یک تابع C / C ++ ، یک لیست از ضرایب ، یک تابع نوشته شده در جاوا و غیره.
توجه: به جدا کننده های اعشاری توجه کنید
مرحله 20: ثابت ها و راه اندازی ()
من در اینجا به GPIO برای ضبط آنالوگ اشاره می کنم. من پورت سریال و همچنین پین تعیین شده برای ضبط آنالوگ را مقداردهی می کنم.
const int pin_leitura = 36؛ // GPIO usado para captura analógica void setup () {Serial.begin (1000000)؛ // به منظور رفع اشکال پین pinMode (pin_leitura، INPUT)؛ // Pino utilizado para captura analógica}
مرحله 21: حلقه () و تابع تصحیح
ما ضبط ولتاژ تنظیم شده را انجام می دهیم و مقادیر را با یا بدون اصلاحات صحیح چاپ می کنیم.
void loop () {int valor_analogico = analogRead (pin_leitura) ؛ // realiza a captura da tensão ajustada //Serial.print(valor_analogico + f (valor_analogico)) ؛ // imprime os valores para debug (COM CORREÇÃO) Serial.print (valor_analogico)؛ // imprimime os valores para debug (SEM CORREÇÃO) Serial.print ("،") ؛ Serial.print (4095) ؛ // cria uma linha para marcar o valor máximo de 4095 Serial.print ("،") ؛ Serial.println (0)؛ // cria uma linha para marcar o valor mínimo de 0}
در خط 12 توجه کنید که ما گزینه چاپ داده ها را با افزودن تابع تفاوت f (analog_value) داریم.
مرحله 22: استفاده از تابع اصلاح PolySolve
در اینجا ، ما از تابع PolySolve در داخل Arduino IDE استفاده می کنیم.
/* حالت: درجه چند جمله ای عادی 6 ، 2365 x ، y جفت داده ضریب همبستگی (r^2) = 9 ، 907187626418e-01 خطای استاندارد = 1 ، 353761109831e+01 فرم خروجی: تابع C ++ C: حق چاپ © 2012 ، P لوتوس - https://www.arachnoid.com. همه حقوق محفوظ است. */ double f (double x) {return 2.202196968876e + 02 + 3.561383996027e-01 * x + 1.276218788985e-04 * pow (x، 2) + -3.470360275448e-07 * pow (x، 3) + 2.082790802069e- قدرت 10 * (x ، 4) + -5.306931174991e-14 * توان (x ، 5) + 4.787659214703e-18 * توان (x ، 6) ؛ }
به علامت ویرگول نقطه به عنوان جدا کننده اعشاری توجه کنید.
مرحله 23: ضبط با تصحیح - سریال پلاتر
مرحله 24: هزینه محاسبه
برای انجام محاسبات چند جمله ای ، لازم است پردازنده این کار را انجام دهد. بسته به کد منبع و قدرت محاسباتی موجود ، این امر می تواند منجر به تاخیر در اجرا شود.
در اینجا ، جدول نتایج یک آزمایش را با استفاده از چند جمله ای چند درجه می بینیم. به تفاوت زمان استفاده از تابع pow () و زمان عدم استفاده توجه کنید.
مرحله 25: کد تست - راه اندازی () و شروع حلقه ()
در اینجا ، ما کد مورد استفاده در آزمون خود را داریم.
void setup () {Serial.begin (1000000)؛ // Iniciando a porta somente para debug} void loop () {float valor_analogico = 500.0؛ // um valor arbtrario float quantidade = 10000.0؛ // quantidade de chamadas float contador = 0.0؛ // contador de chamadas
مرحله 26: کد تست - حلقه () و پردازش
من از تابع micros () برای بدست آوردن مقدار بر حسب میکروثانیه استفاده کردم.
// ============= inicia o processo float agora = micros ()؛ // marca o instante inicial while (contador <quantidade) {// v (valor_analogico)؛ // função vazia // r (valor_analogico) ؛ // função com retorno // f0 (valor_analogico) ؛ // grau 0 // f1 (valor_analogico) ؛ // grau 1 // f2 (valor_analogico) ؛ // grau 2 // f3 (valor_analogico) ؛ // grau 3 // f4 (valor_analogico) ؛ // grau 4 // f5 (valor_analogico)؛ // grau 5 // f6 (valor_analogico)؛ // grau 6 // f13_semPow (valor_analogico) ؛ // grau 13º SEM a função POW // f13_comPow (valor_analogico) ؛ // grau 13º COM a função POW contador ++؛ } agora = (micros () - agora) / quantidade؛ // determina o intervalo que se passou para cada iteração // ============== finaliza o processo
مرحله 27: کد تست - حلقه () - نتایج
ما مقدار برگشتی از عملکرد درجه 13 را با و بدون POW برای مقایسه و فاصله پردازش چاپ می کنیم.
// imprime o valor retornado da função de grau 13 com e sem POW para comparação Serial.print (f13_semPow (valor_analogico))؛ // grau 13º SEM a função POW Serial.print (" -") ؛ Serial.print (f13_comPow (valor_analogico)) ؛ // grau 13º COM a função POW Serial.print (" -")؛ // imprime o intervalo do processamento Serial.println (agora، 6)؛ }
مرحله 28: کد تست - توابع مورد استفاده
توابع خالی (فقط با بازگشت) درجه 0 و 1.
// FUNÇÃO VAZIAdouble v (double x) {} // FUNÇÃO SOMENTE COM RETORNO double r (double x) {return x؛ } // FUNÇÃO DE GRAU 0 double f0 (double x) {return 2.202196968876e+02؛ } // FUNÇÃO DE GRAU 1 double f1 (double x) {return 2.202196968876e + 02 + 3.561383996027e-01 * x؛ }
توابع درجه 2 ، 3 و 4
// FUNÇÃO DE GRAU 2double f2 (double x) {return 2.202196968876e + 02 + 3.561383996027e-01 * x + 1.276218788985e-04 * pow (x، 2)؛ } // FUNÇÃO DE GRAU 3 double f3 (double x) {return 2.202196968876e + 02 + 3.561383996027e-01 * x + 1.276218788985e-04 * pow (x، 2) + -3.470360275448e-07 * pow (x، 3)؛ } // FUNÇÃO DE GRAU 4 double f4 (double x) {return 2.202196968876e + 02 + 3.561383996027e-01 * x + 1.276218788985e-04 * pow (x، 2) + -3.470360275448e-07 * pow (x، 3) + 2.082790802069e-10 * توان (x ، 4) ؛ }
توابع درجه 5 و 6
// FUNÇÃO DE GRAU 5double f5 (double x) {return 2.202196968876e + 02 + 3.561383996027e-01 * x + 1.276218788985e-04 * pow (x، 2) + -3.470360275448e-07 * pow (x، 3) + قدرت 2.082790802069e-10 * (x ، 4) + -5.306931174991e-14 * (x ، 5) ؛ } // FUNÇÃO DE GRAU 6 double f6 (double x) {return 2.202196968876e + 02 + 3.561383996027e-01 * x + 1.276218788985e-04 * pow (x، 2) + -3.470360275448e-07 * pow (x، 3) + 2.082790802069e-10 * توان (x ، 4) + -5.306931174991e-14 * قدرت (x ، 5) + 4.787659214703e-18 * توان (x ، 6) ؛ }
عملکرد درجه 13 با استفاده از POW.
// FUNÇÃO DE GRAU 13 USANDO O POWdouble f13_comPow (double x) {return 2، 161282383460e + 02 + 3، 944594843419e-01 * x + 5، 395439724295e-04 * pow (x، 2) + -3، 968558178426e-06 * pow (x، 3) + 1، 047910519933e-08 * pow (x، 4) + -1، 479271312313e-11 * pow (x، 5) + 1، 220894795714e-14 * pow (x، 6) + -6، 136200785076e-18 * pow (x، 7) + 1، 910015248179e-21 * pow (x، 8) + -3، 566607830903e-25 * pow (x، 9) + 5، 000280815521e-30 * pow (x، 10) + 3 ، 434515045670e-32 * توان (x ، 11) + -1 ، 407635444704e-35 * توان (x ، 12) + 9 ، 871816383223e-40 * پاور (x ، 13) ؛ }
عملکرد درجه 13 بدون استفاده از POW.
// FUNÇÃO DE GRAU SEM USAR O POWdouble f13_semPow (double x) {return 2، 161282383460e + 02 + 3، 944594843419e-01 * x + 5، 395439724295e-04 * x * x + -3، 968558178426e-06 * x * x * * x + 1 ، 047910519933e-08 * x * x * x * x + -1 ، 479271312313e-11 * x * x * x * x * x + 1 ، 220894795714e-14 * x * x * x * x * x * x * x + -6 ، 136200785076e-18 * x * x * x * x * x * x * x + 1 ، 910015248179e-21 * x * x * x * x * x * x * x * -3 + ، 566607830903e- 25 * x * x * x * x * x * x * x * x * x + 5 ، 000280815521e-30 * x * x * x * x * x * x * x * x * x * x + 3 ، 434515045670e- 32 * x * x * x * x * x * x * x * x * x * x * x + -1 ، 407635444704e -35 * x * x * x * x * x * x * x * x * x * x * x * x + 9 ، 871816383223e-40 * x * x * x * x * x * x * x * x * x * x * x * x * x * x ؛ }
مرحله 29: فایل ها
دانلود فایلها:
من نه
صفحه گسترده
توصیه شده:
آیا می دانید گیاهان شما چه احساسی دارند؟ [ذره+Ubidots]: 6 مرحله
آیا می دانید گیاهان شما چه احساسی دارند؟ [ذره+Ubidots]: هیچ چیز جایگزین بیرون رفتن و دست زدن به خاک برای شما نمی شود ، اما فناوری امروزه امکان نظارت از راه دور بر روی خاک و ردیابی پارامترهای غیرقابل اندازه گیری حواس انسان را فراهم کرده است. کاوشگرهای خاکی مانند SHT10 در حال حاضر بسیار دقیق هستند و
ESP32: آیا می دانید DAC چیست؟: 7 مرحله
ESP32: آیا می دانید DAC چیست ؟: امروز ، ما در مورد دو موضوع صحبت می کنیم. اولین مورد DAC (مبدل دیجیتال به آنالوگ) است. من آن را مهم می دانم ، زیرا به عنوان مثال ، از طریق آن ، ما یک خروجی صدا در ESP32 ایجاد می کنیم. دومین مسئله ای که امروز به آن می پردازیم ، oscil است
مورد جدید و بهبود یافته پنج مورد آدامس (برای NANO 3G): 5 مرحله
مورد جدید و بهبود یافته پنج عدد آدامس Ipod (FOR NANO 3G): Tomcat94 اخیراً یک مورد آیپاد ساخته شده از یک بسته بندی پنج آدامس ارسال کرده است. خوب ، من تصمیم گرفتم چیزی مشابه بسازم ، اما برای Ipod Nano
نحوه تهیه تقویم پدربزرگ و مادربزرگ & amp؛ دفترچه راهنما (حتی اگر نحوه چسباندن را نمی دانید): 8 مرحله (همراه با تصاویر)
نحوه تهیه تقویم پدربزرگ و مادربزرگ & amp؛ دفترچه یادداشت (حتی اگر نمی دانید چگونه دفترچه یادداشت کنید): این یک هدیه بسیار مقرون به صرفه (و بسیار قدردانی!) تعطیلات برای پدربزرگ و مادربزرگ است. من امسال 5 تقویم با هزینه کمتر از 7 دلار تهیه کردم. مواد: 12 عکس عالی از فرزند ، فرزندان ، خواهرزاده ها ، برادرزاده ها ، سگ ها ، گربه ها یا سایر اقوام شما 12 قطعه مختلف
مورد Duct Tape Zune مورد: 7 مرحله
مورد Duct Tape Zune Case: سلام به همه طرفداران سخت کوش من! من قصد دارم به شما نشان دهم که چگونه یک کیس zune بسیار ساده برای سایزهای کوچکتر 4-16 گیگ بسازید. من همچنین نحوه ایجاد برچسب های برچسب سفارشی برای این را نشان خواهم داد. مورد