ADC در آردوینو – آموزش آردوینو جلسه ششم
خیلی از سیگنال ها توی دنیای واقعی پیوسته و آنالوگ هستند اما ما از قطعات دیجیتال استفاده میکنیم و به طبع دوسداریم سیگنال های پیوسته رو به دیجیتال تبدیل کنیم !برای تبدیل این سیگنال ها از مبدل های انالوگ به دیجیتال یا ADC استفاده میکنیم.ADC آی سی هم داره ، ولی توی میکروکنترلر ها این واحد وجود داره و درنتیجه ADC در آردوینو هم وجود داره و لازم به استفاده از آی سی دیگه ای نداریم.
کاربرد ADC در آردوینو – مبدل آنالوگ به دیجیتال
بعنوان مثال یک سری از سنسور های دما مثل سری LM و به طور خاص LM35 که خیلی پر مصرفه توی پروژه ها ، خروجی ای با ولتاژ آنالوگ دارن و با تغییر دما ، ولتاژ پایه های خروجیشون تغییر میکنه و ما نیاز داریم برای خوندنشون خروجی رو تبدیل به دیجیتال کنیم.
استفاده و راه اندازی واحد ADC در آردوینو یا مبدل آنالوگ به دیجیتال
توی مبدل های آنالوگ به دیجیتال 2 مشخصه داریم که خیلی مهم
- دقت
- سرعت
دقت تراشه برای اندازه گیری کمترین مقدار سیگنال آنالوگ مهمه . این مقدار تناسب داره با تعداد بیت های خروجی داده های دیجیتال (زمانی که تبدیل انجام شده)
و سرعت که به فرکانس نمونه برداری مربوط میشه و هرچقدر فاصله زمانی بین نمونه برداری کمتر باشه(همون دوره تناوب) سرعت هم بیشتر میشه.مقدار داده ی دیجیتالی خروجی هم با فرمول زیر حساب میشه:
VIN: ولتاژ ورودیمونه که قراره تبدیل بشه.
VREF : ولتاز رفرنسه که جلوتر توضیح میدم . ولی درحالت دیفالت و معمول 5 ولته.
طبق قانون نایکوئیست فرکانس نمونه برداری باید حداقل 2 برابر بیشترین فرکانس موجود سیگنال باشه. باید حواسمون باشه به اینکه بالا بودن فرکانس نمونه برداری باعث بالارفتن توان مصرفی میشه و این برای سیستم هایی که قراره با باتری کار کنن خیلی مهمه. مثلا وقتی داریم از یک سنسور دما یا رطوبت استفاده میکنیم زیاد سرعت نمونه برداری ی بالا مهم نیست چون دما و رطوبت توی زمان پایین تغییر وضعیت نمیدن.(برای هر سنسوری میشه زمان بین تغییرات خروجیش رو توی دیتاشیت نگاه کرد)
میکورکنترلر های avr حداکثر 10 بیت دقت دارن و بازه ی نمونه برداری از 0 تا ولتاژ مرجع (فرض میکنیم 5ولت) رو به 1024 قسمت تقسیم می کنند.بنابراین با اضافه شدن حدود 5 میلی ولت به سیگنال آنالوگ یک بیت به مقدار دیجیتال اضافه میشه!(توی فرمول بالا خودتون حساب کنید به این نتیجه میرسین)
ADC در آردوینو UNO و بقیه ی آردوینو ها هم 10 بیتی ای هست چون هسته avr دارن ، در سری هایی که هسته ARM دارن هم ای مقدار 12 بیته.
فک کنم بهتره بقیه توضیح رو با یک مثال ادامه بدم :
مثلا میخوایم با یک LM35 کار کنیم که یک سنسور دماست، توی دیتاشیت این آی سی که نگاه میکنیم میبینیم که گفته 10 میلی ولت به ازای هر درجه سانتی گراد به خروجیش اضافه میشه.دقت آی سی هم تغریبا 0.5 درجه هست ، یعنی توانایی اندازه گیری 0.5 درجه سانتیگراد رو با دقت خوبی داره، پس به ازای هر 0.5 درجه 5 میلی ولت در خروجی افزایش داریم که برابر افزایش یک بیت در مقدار دیجیتال هست.بنابراین ، مبدل کاملا سیگنال آنالوگ رو ردیابی میکنه و دقت خوبی داره.البته اگه قرار باشه دما رو بدون اعشار نشون بدیم دقت حتی بیش از نیاز ما هم هست
برای انتخاب ولتاژ مرجع هم باید اینو بدونیم که ولتاژ مرجع به دامنه سیگنال آنالوگ ورودی وابسته هستش، آردوینو ، 2 ولتاژ مرجع 5 ولت و داخلی رو بدون نیاز به قطعه خارجی فراهم کرده(دمش گرم 😀 )
برای استفاده از ولتاژ های مرجع باید از تابع زیر استفاده کنیم:
تابع ()analogReference
که ورودی اون شامل متغیرهای زیره:
DEFAULT: ولتاژ 5 (3.3)
INTERNAL: ولتاژ 1.1 ولت در تراشه های ATMEGA168 & ATMEGA328
INTERNAL1V1: ولتاژ 1.1 ولت تنها در بردهای مگا
INTERNAL3V56: ولتاژ 2.56 ولت تنها در بردهای مگا
EXTERNAL: ولتاژ مرجع دلخواه بین صفر تا 5 ولت در پایهAREF
تابع analogRead()
برای تبدیل و خوندن داده، تابع analogRead رو استفاده میکنیم ومتغیر ورودی تابع ، شماره پایه ی ورودی هستش و خروجی تابع یک عدد ده بیتی صفر تا 1023 هستش که مقدار دیجیتال و متناظر سیگنال آنالوگ در لحظه نمونه برداری هست.
(یک نکته هم اینکه هر تبدیل در مبدل آنالوگ به دیجیتال به جز تبدیل اول ، سیزده پالس ساعت طول میکشه)
تابع analogReadResolution()
(مخصوص برد های DUE و ZERO (M0 PRO))
یک تابع هم مخصوص برد های DUE و ZERO (M0 PRO)وجود داره ، اول مطلب گفتم که میکروهای AVR دقت 10 بیتی دارن ، اما این برد ها چون هسته ARM دارن دارای دقت بالاتری و 12 بیتی هستند وخروجی بین 0 تا 4095 دارن.البته با این کد میشه دقتی 16 بیتی هم داشت و درکل وظیفه این تابع اینه که دقت خوندن ورودی آنالوگ رو تنظیم میکنه.
اینم یک مثال برای این تابع:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
void setup() { // open a serial connection Serial.begin(9600); } void loop() { // read the input on A0 at default resolution (10 bits) // and send it out the serial connection analogReadResolution(10); Serial.print("ADC 10-bit (default) : "); Serial.print(analogRead(A0)); // change the resolution to 12 bits and read A0 analogReadResolution(12); Serial.print(", 12-bit : "); Serial.print(analogRead(A0)); // change the resolution to 16 bits and read A0 analogReadResolution(16); Serial.print(", 16-bit : "); Serial.print(analogRead(A0)); // change the resolution to 8 bits and read A0 analogReadResolution(8); Serial.print(", 8-bit : "); Serial.println(analogRead(A0)); // a little delay to not hog serial monitor delay(100); } |
توضیح بسه دیگه !بریم سراغ چند تا مثال! سوال داشیتن اول توی گوگل بگردین (اینطوری بهتر یاد میگیرین)و اگر به جواب نرسیدین بپرسین ، حتما سعی میکنم کمک کنم 🙂
یک برنامه بنویسید که از پایه ی A0 سیگنال آنالوگ رو بخونه و مقدار اون رو به شکل سریال بفرسته : (ارتباط سریال در آردوینو – آموزش برنامه نویسی آردوینو – جلسه چهارم رو اگر یادتون رفته میتونید نگاه بندازین)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
void setup() { Serial.begin(9600); analogReference(DEFAULT); } void loop() { int sensorValue = analogRead(A0);//"int sensorValue" ro mishod balaye void setup ham nevesht . Serial.println(sensorValue); } |
برنامه ای بنویسید که یک led رو با توجه با مقدار خوانده شده از حسگری که به پایه ی صفر آنالوگ وصل شده روشن و خاموش کنه.
با این مشخصات که اگر مقدار خوانده شده از پایه ی انالوگ کمتر از 800 بود پایه روشن بشه و اگر نبود خاموش بشه. (مقدار 800 معادل 3.9 ولت میشه)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
int pininput=A0; int ledpin=9; void setup() { pinMode(ledpin,OUTPUT); analogReference(DEFAULT); } void loop() { int val=analogRead(pininput); if(val<800) { digitalWrite(ledpin,HIGH); } else { digitalWrite(ledpin,LOW); } } |
در برد موجو ( که میکروکنترلرش هم atmega32 هست) برای استفاده از واحد ADC باید باز هم کدی بنویسیم؟ یا فقط کد برنامه ی موردنظرمون رو روی fpgaلود کنیم؟
سلام.
atmega32 روی موجو برای برقراری ارتباط سریاله ،متاسفانه با fpga آشنا نیستم.
سلام وقت بخیر
اگه مثلا با کمک AREF یک ولت وصل کنیم بعد از سنسور بخونیم از صفر ولت تا یک ولت رو به 1024 قسمت تبدیل میکنه؟
سلام، بله دقیقا.
فقط باید حواست به نویز باشه و یک ولت دقیق اعمال بشه به میکرو
سلام وقت بخیر
برای پروژه ای مشغول هستم و سوالهای زیادی دارم اگر تمایل دارید در این پروژه با من همکاری کنید خوشحال میشم اینم شماره تماس بندست
************
سلام.
متاسفانه الان فرصت انجام پروژه ندارم
سوالاتتون رو داخل کامنت ها بپرسین، اگر بلد بودم حتما سعی میکنم کمکتون کنم.
موفق باشید
سلام ببخشید یه سوال مقدار INTERNAL تو آنالوگ رفرنس Atmega8 چند ولت هست؟
سلام
بردهایی که مگا۸ دارن 2.56
تابع adcReference()
هست نه adcRefrence()
ن ببخشید analogReference()
سلام
آره توی عنوان اشتباه تایپی بود مرسی که اطلاع دادین،البته توی مثالها صحیح نوشته شده..