منتظر آموزش بعدی ما باشید
معرفی آردینو
Arduino

معرفی آردینو

اردینو یک بستر متن باز بسیار ساده است که با استفاده از آن می توانید پروژه ها و ایده های الکترونیکی خود را با سرعت زیاد و هزینه بسیار پایین پیاده نمایید. برد آردینو را می توانید به انواع مختلف سنسورها، درایورها، نمایشکرها و… متصل کنید و با استفاده از یک نرم افزار بیسار ساده و توابع کاملا آماده، به سرعت پروژه نهایی خود را بدون نگرانی از دسترس بودن توابع ارتباطی با ماژولها به انجام برسانید.بیش از 250000 برد آردینو در سراسر دنیا به فروش رفته که نشان از محبوبیت این برد دارد طوری که نسخه های نرم افزاری و سخت افزاری و توابع بیشماری برای آن تولید شده و به رایگان در دسترس علاقه مندان قرار دارد.

 

محیط برنامه نویسی Arduino

محیط برنامه نویسی Arduino بسیار ساده بوده و از قسمتهای زیر تشکیل می شود:

الف) محیط ویرایشگر متن که برنامه در این قسمت نوشته می شود.

برد

محیط برنامه نویسی اردینو

در قسمت منو ابزار چند گزینه وجود دارند که به شرح آنها می پردازیم:

: این گزینه برنامه را کامپایل نموده و کد هگز ایجاد می کند که این کد توسط پروگرامر به میکرو منتقل میشود. چنانچه برنامه خطا نداشته باشد اندازه کد برنامه در قسمت پیامها همانند بالا نشان داده میشود.

: این گزینه ابتدا برنامه را کامپایل نموده و سپس آن را توسط پروگرمری که انتخاب کردیم به میکرو منتقل می کند.

: این گزینه یک برنامه جدید ایجاد می کند.

: برای باز کردن برنامه های قبلی و مثالها به کار می رود.

: برای ذخیره برنامه به کار می رود.

: برای باز کردن محیط ارتباط سریال به کار می رود.

سایر منوها عبارتند از: FileEditSketchToolsHelp که در زیر به شرح آنها می پردازیم.

منوی EDIT:

Copy for Forum: این گزینه برنامه را برای انتشار در انجمن گفتگو (forum) کپی می کند. برای خوانایی بیشتر برنامه، رنگهای کد برنامه حفظ می شوند.

Copy as HTML: این گزینه برنامه را به منظور انتشار در اینترنت کپی می کند.

منوی Sketch:

Verify/Compile: این گزینه برنامه را کامپایل کرده و چنانچه برنامه خطا داشته باشد آن را در قسمت پیامها نمایش می دهد.

Show Sketch Folder: این گزینه پوشه حاوی برنامه را باز می کند.

Add Fileبا زدن این گزینه یک برنامه جدید به پوشه برنامه کپی می شود و در یک صفحه جدید باز می شود.

Import Libraryاین گزینه یک تابع کتابخانه ای را به برنامه اضافه می کند.

منوی Tools:

Auto Format: این گزینه برنامه را مرتب می کند و در نتیجه خوانایی برنامه بیشتر می شود.

Archive Sketch: این گزینه یک نسخه فشرده از برنامه در پوشه برنامه قرار می دهد.

Board: این گزینه بورد مورد استفاده را انتخاب می کند.

Serial Port: این گزینه تمامی وسایل سریال که به کامپیوتر متصلند اعم از حقیقی و یا مجازی را نشان میدهد.

Programmer: چنانچه بخواهیم از یک پروگرمر به غیر از پروگرمی که بر روی برد تعبیه شده استفاده کنیم، گزینه مناسب را انتخاب کرده و سپس برنامه را به میکرو منتقل می کنیم. چنانچه بخواهیم بر روی یک میکروی جدید Bootloader را منتقل کنیم بایستی از پروگرمر خارجی استفاده می کنیم.

Burn Bootloader: این گزینه Bootloader را به روی یک بورد Arduino انتقال می دهد. توجه داشته باشید که قبل از انتخاب این گزینه بورد مناسب را از منوی مربوطه انتخاب کنید.

Arduino گزینه ای با نام Sketchbook در اختیار کاربر قرار می دهد که شامل کلیه برنامه های نوشته شده می باشد. هنگامی که نرم افزار باز می شود یک پوشه با نام برنامه در آدرسی که در منوی Preferences قرار دارد ایجاد می شود و برنامه کاربر در آن قرار داده می شود. برنامه های Arduino با پسوند .ino ذخیره می شوند.

 

کتابخانه ها

کتابخانه ها قابلیت های زیادی را به برنامه کاربر اضافه می کنند. با انتخاب منوی Sketch > Import Libraryفایل سرآمد کتابخانه با نوشتن #include به برنامه پیوست می شود و می توان از توابع آن استفاده نمود. هنگام پروگرم کردن بورد،چون کتابخانه همراه با برنامه کامپایل شده و به بورد منتقل می شود حجم بیشتری از فضای حافظه برنامه در میکرو را اشغال می کند بنابراین اگر نیازی به توابع کتابخانه ای ندارید خط #include را از برنامه حذف کنید.

معماری و ساختار AVR

معماری کلی هسته AVR در شکل زیر  نشان داده شده است. در این شکل واحد پردازشگر مرکزی توسط باس داده به تمامی قسمتها دسترسی دارد .

1

میکروکنترلر AVR از معماری هاروارد تبعیت می کند و دارای حافظه و باس مجزا برای برنامه و داده می باشد. دستورات داخل حافظه برنامه ذر یک مرحله اجرا می شوند بدین معنا که در هر لحظه ای که یک دستور در حال اجراست، دستور بعدی در همان لحظه از حافظه خوانده می شود. این روش به میکروکنترلر اجازه می دهد که در هر سیکل زمان یک دستور را اجرا نماید. برنامه را می توان به روش برنامه ریزی در حین کار (ISP) به ذاخل حافظه منتقل نمود و نیازی به برداشتن تراشه از روی مدار نمی باشد. وجود 32 رجیستر سریع همه منظوره که قابل دسترسی با یک سیکل ساعت می باشند یکی از مهمترین ویژگیهای AVR به شمار می رود که باعث انجام محاسبات ریاضی و منطق در یک سیکل ساعت می شود. به عبلرت دیگر، در یک دستور معمولی، در یک سیکل ساعت دو مقدار از رجیسترها خوانده شده، عملیات لازم در واحد محاسبه و منطق (ALU) بر روی آنها صورت گرفته و سپس نتیجه در رجیسترهای مربوطه نوشته می شود.

در تراشه ATMEGA328P سه نوع حافطه وجود دارد که عبارتند از حافظه داده یا SRAM، حافظه برنامه یا FLASH و حافظه EEPROM که برای ذخیره دائم داده به کار می رود. حافظه داده به چهار قسمت تقسیم می شود که عبارتند از: رجیسترهای همه منظوره، رجیسترهای ورودی/خروجی، رجیسترهای ورودی/خروجی توسعه یافته و فضای SRAM که برای دخیره موقت داده به کار میرود. نقشه فضای حافظه در شکل 1-1 نشان داده شده است.

آدرس

نقشه فضای حافظه داده

0x0000-0x001F

رجیسترهای همه منظوره R0-R31

0x0020-0x005F

64 رجیستر ورودی/خروجی

0x0060-0x00FF

160 رجیستر ورودی/خروجی خارجی

0x0100-0x08FF

SRAM داخلی

فضای حافظه برنامه یا حافظه FLASH به دو قسمت کاربردی و Boot تقسیم می شود. در قسمت کاربردی کد ماشین برنامه نوشته می شود و در قسمت Boot اظلاعات مربوط به نحوه برنامه ریزی فضای حافظه برنامه قرار داده می شود. فضای حافظه EEPROMنیز توسط توابعی که بعدا شرح داده خواهند شد قابل دسترسی می باشد.

تراشه ATMEGA328P دارای امکانات زیر می باشد:

–        8 کیلوبایت حافظه برنامه قابل برنامه ریزی حین کار

–        1 کیلو بایت فضای حافظه EEPROM

–        2 کیلو بایت فضای حافظه SRAM

–        23 پایه ورودی/خروجی همه منظوره

–        3 تایمر/شمارنده با قابلیتهای مقایسه ای

–        وقفه های داخلی و خارجی

–        ماژول قابل برنامه ریزی ارتباط سریال

–        ماژول قابل برنامه ریزی دو سیمه سازگار با پروتکلI2C شرکت فیلیپس

–        ماژول برنامه ریزی سریال SPI

–        مبدل آنالوگ به دیجیتال 10 بیتی 6 کاناله

–        ماژول تایمر Watchdog با نوسانساز داخلی

–        5 حالت قابل برنامه ریزی به منظور صرفه جویی در مصرف توان

در Arduino برای دسترسی به ماژولها توابع از پیش آماده شده وجود دارد که سرعت برنامه نویسی را افزایش می دهد و دیگر نیازی به دانستن جزئیات عملکرد آنها وجود ندارد.

 دستورات برنامه نویسی

ساختار:
{}آکولاد
آکولادها ابتدا و انتهای توابع وبلوک های جملات رامشخص می کند.

void setup()
{
statements;
}
void loop()
{
statements;

;نقطه ویرگول
نقطه ویرگول برای خاتمه یک جمله وهمچنین جداکردن المانهای مختلف برنامه به کارمی رود. فراموش کردن نقطه ویرگول درانتهای یک خط منجربه خطای کامپایلرمی شود.
توضیحات بلوکی/*……*/
این عبارت نوشتن چندخط توضیح دربرنامه مورداستفاده قرارمی گیرد.توضیحات با*/شروع شده وبا/*خاتمه می یابد بهتر است برای هرقسمت ازبرنامه توضیحات لازم رابنویسیم تا هنگام رجوع به برنامه ازعملکرد آن آگاه شویم. بدیهی است که توضیحات دربرنامه کامپایل نمی شود. ازتوضیحات می توان برای غیرفعال کردن موقت قسمتی ازبرنامه به منظورعیب یابی نیز استفاده نمود.
توضیحات خطی //
توضیحات خطی با//شروع شده وتمام قسمت های جلوی آن به عنوان توضیح درنظرگرفته می شود.توضیح خطی معمولابرای دادن اطلاعات بیشتردرموردعملکردیک خط ازبرنامه به کارمی رود همچنین می توان ازآن برای غیرفعال کردن یک خط به منظورعیب یابی برنامه استفاده نمود.
متغیرها
یک متغیر راهی برای نام گذاری وذخیره یک مقدارعددی برای استفاده بعدی دربرنامه می باشد .ابتدا نوع یک متغیر در برنامه تعریف شده و سپس در برنامه با توجه به نوع آن مقداردهی شود. انواع متغیرها و بازه مقداردهی آنها درجدول زیرآمده است.

کاربرد بازه تغییرات تعداد بایت نوع متغیر
نمایش دهنده مقادیرمثبت ومنفی اعدادصحیح می باشد. 32768- تا 32767 2 int
برای نمایش مقادیرمنحصرامثبت اعدادصحیح به کارمی رود. 0 تا 65535 2 unsigned int
برای نمایش مقادیر بسیاربزرگ اعدادصحیح مثبت ومنفی به کار می رود. 2147483648-تا21474483647 4 long
برای نمایش مقادیر بسیاربزرگ اعدادصحیح مثبت به کار می رود. 0 تا 4294967295 4 unsigned long
برای نمایش اعداداعشاری به کارمی رود. -3.4028235E+38تا 3.4028235E+38 4 float
در Arduino double همانند float به کارمی رود. مانند float 4 double
نمایش دهنده مقادیر صحیح(true)، غلط(false) می باشد. غلط(0)یاصحیح(1) 1 boolean
برای نمایش دهنده یک کاراکتر به کارمی رود.همچنین می تواند نمایش دهنده یک عددصحیح بین 128-تا127باشد. 128-تا127 1 char
همانند char بوده ولی فقط برای اعداد مثبت به کارمی رود. 0 تا 255 1 byte
انواع دیگر:
string: نمایش دهنده ی آرایه ای از کاراکترها بوده که معمولا برای نمایش متن به کارمی رود
void: تنها در تعریف تابع هنگامی که هیچگونه خروجی نداریم به کارمی رود.
به طورمثال اگربخواهیم یک متغیرازنوع 16بیتی بامقداراولیه صفرتعریف کنیم به صورت زیرمی نویسیم:
int var = 0 ;
کلمات byte، char، int، float و long به صورت تابع نیز عمل می کنند و نوع متغیر ورودی خود را به ترتیب به هشت بیتی بدون علامت، هشت بیتی با علامت، 16 بیتی، اعشاری و 32 بیتی تبدیل می کنند.
– حوزه عملکردمتغیرها
حوزه ی عملکرد هر متغیر بستگی به مکانی داردکه آن متغیر تعریف می شود. یک متغیرعمومی می تواند توسط هرتابع یاجمله ای درون یک برنامه مورد استفاده قرارگیرد این متغیردرابتدای برنامه قبل ازتابع setup() تعریف می شود یک متغیرمحلی درون یک تابع و یا یک حلقه تعریف می شود و تنها درون تابع و یا حلقه ای که تعریف شده قابل استفاده است. بنابراین می توان متغیرهای محلی با نامهای یکسان ومقادیرمتفاوت درقسمت های مختلف برنامه تعریف نمود. مثال زیرتعریف دونوع متغیر عمومی و محلی را نشان می دهد.

int value; // ‘value’ is visible
// to any function
void setup()
{
// no setup needed
}
void loop()
{
for (int i=0; i<20;) // ‘i’ is only visible
{ // inside the for-loop
i++;
}
float f; // ‘f’ is only visible
} // inside loop

– آرایه ها
آرایه ها مجموعه ای ازمقادیر هستندکه بایک اندیس می توان به المانهای آن دسترسی پیدا کرد. اندیس آرایه ازصفرشروع شده تا n-1ادامه می یابدکه n بعدآرایه می باشد.
مثال:یک آرایه ازنوع 16بیتی با بعد 5 تعریف کنید که مقادیرآن از0 تا 4 باشد.
int myArray[] = {0,1,2,3,4}
همچنین می توان مقادیر اندیس های مختلف آرایه رابه صورت مجزا مقداردهی نمود به طور مثال اگر بخواهیم مقدار اندیس دوم آرایه را به 5 تغییر دهیم باید به صورت زیرعمل کنیم:
myArray[2]=5;
– آرایه چند بعدی
آرایه های چندبعدی درزبان C آرایه ای ازآرایه ها درنظر گرفته می شوند آرایه دو بعدی به صورت زیر تعریف می شود:
array [x] [y];
اولین آرگومان سمت راست تعداد سطر ها و دومین آرگومان تعداد ستون ها را نمایش می دهد المان هایی که توسط اولین آرگومان از سمت راست مشخص می شوند درخانه های حافظه مجاورقرار می گیرند به طور مثال آرایه زیر را در نظر بگیرید که دارای سه سطر و چهار ستون می باشد
int array [3][4] = { {10,11,12,13},
{14,15,16,17},
{18,19,20,21} };
دراین مثال آرگومان از سمت راست 4 بوده و بنابراین می توان آرایه ی بالا را به صورت زیر نیز نوشت

int array [3][4]={10,11,12,13,14,15,16,17,18,19,20,21};

– عملیات ریاضی
عملگرهای ریاضی شامل جمع، تفریق، ضرب وتقسیم و باقیمانده می باشند. این عملگرها بر روی دو متغیرعمل نموده وحاصل آن رابه متغیر دیگر نسبت می دهند.

 

y = y + 3;
x = x – 7;
i = j * 6;
r = r / 5;
z = x % y;

توجه داشته باشید که متغیری که حاصل عملیات ریاضی درآن قرارمی گیرد باید به اندازه کافی بزرگ باشد بطور مثال دو عدد 8 بیتی را با هم جمع کنیم باید متغیری که برای نتیجه تعریف می کنیم از نوع 16بیتی باشد برای خلاصه نویسی در عملیات ریاضی می توانیم ازعبارات زیراستفاده کنیم:

 

 

به طورمثال:x%=2 باقیمانده x به 2 را محاسبه نموده و حاصل آن را دوباره در xقرارمی دهد.
عملگرهای مقایسه ای
عملگرهای مقایسه ای برای مقایسه بین دومتغیر به کارمی رود که معمولا در یک عبارت شرطی به کارمی رود حاصل این مقایسه صحیح (true) ویاغلط(false) که نتیجه شرط را بیان می کند. درمثال های زیر عبارت های مقایسه ای آورده شده اند:
مفایسه برابری x با y x == y
مقایسه نابرابری x با y x != y
مقایسه کوچکتربودن xازy x < y
مقایسه بزرگتربودن x ازy x > y
مقایسه کوچکتریامساویx ازy x <= y
مقایسه بزرگتریامساوی xازy x >= y

 

 

عملگرهای بیتی
عملگرهای برای صفر یا یک کردن بیت ها مورد استفاده قرارمی گیرد. جداول سه عملگر AND، OR و XOR درزیرآمده است.

حاصل XOR دوبیت بیت2 بیت1 حاصل OR دوبیت بیت2 بیت1 حاصل AND دوبیت بیت2 بیت1
0 0 0 0 0 0 0 0 0
1 1 0 1 1 0 0 1 0
1 0 1 1 0 1 0 0 1
0 1 1 1 1 1 1 1 1

همانطور که ازدو سطر آخر جدول OR مشخص است عدد صفر و یا یک که با یک OR شود حاصل یک می شود بنابراین برای یک کردن یک بیت آن را باید با یک OR کنیم. همچنین اگر بخواهیم عددی تغیر نکند آن را باید با صفر OR کنیم که این موضوع از دو سطر اول جدول مشخص است. همانطور که از دو سطر اول جدول AND مشخص است هر عددی که با صفر AND شود حاصل آن صفر می شود بنابراین برای صفر کردن یک بیت آن را باید با صفر AND کنیم. هر عددی که با یک AND شود تغییری نمی کند بنابراین اگر بخواهیم بیتی تغییر نکند باید آن را با یک AND کنیم. برای مکمل کردن یک بیت باید آن را با یک XOR کنیم که دو سطر آخر جدول XOR نیز این موضوع را تایید می کند. همچنین اگر عددی با صفر XOR شود بدون تغییر باقی می ماند که دو سطر اول جدول گویای این مساله می باشد. نمایش عملگرهای AND، OR و XOR در زبان C به ترتیب به صورت &، | و ^ می باشد.
مثال: بیت هفتم عدد a را یک و بیت پنجم آن را صفر نمایید.
برای اینکه بیت هفتم عدد a را یک کنیم باید آن را باعدد 10000000 باینری OR کنیم که این کار را به صورت زیر انجام می دهیم:

 

a = a | 0b10000000 ;

 

برای اینکه بیت پنجم a را صفر کنیم آن را باید با عدد 11011111 باینری AND کنیم که این کار را به صورت زیر انجام میدهیم:

a = a & 0b11011111;

عملگر شیفت منطقی: این عملگر به دو صورت شیفت چپ (>>) و شیفت راست (<<) راست وجود دارد که به صورت زیر تعریف می شوند:

c = a << b ;عملگر شیفت به چپ
c = a << b ;عملگر شیفت به راست

در مثال بالا عدد a به اندازه b به سمت چپ شیفت داده می شود. به عبارت دیگر b بیت از سمت راست صفر وارد عدد شده و b بیت از سمت حذف می شود و حاصل در متغیر c قرار داده میشود. به طور مثال چنانچه عدد 00000011 باینری 5 بیت به سمت چپ شیفت داده شود حاصل عدد 01100000 بدست می آید.
اگر بخواهیم از عملگرهای شیفت منطقی استفاده کنیم روابط بالا به صورت زیر نوشته می شوند.
مثال: بیت چهارم عدد a را را با استفاده از عملگر شیفت پیاده کنید.

a = a | ( 1<<4) ;

x x x x x x x x aمتغیر

0 0 0 1 0 0 0 0 1<<4

x x x 1 x x x x a|(1<<4)

 

مثال: بیت دوم عدد a را با استفاده از عملگر شیفت صفر کنید.

a = a & ~( 1<<2) ;

عملگر~ به معنای مکمل یک بیتی است که صفر را به یک و یک را به صفر تبدیل می کند.

 

x x x x x x x x aمتغیر

0 0 0 0 0 1 0 0 1<<2

1 1 1 1 1 0 1 1 ~(1<<2)

x x x x x 0 x x a&~(1<<2)

– عملگرهای منطقی
عملگرهای منطقی برای مقایسه دو عبارت بکار می روند و نتیجه آن صحیح (TRUE) و یا غلط(FALSE) می باشد. سه نوع عملگر منطقی AND، OR و NOTوجود دارد که درشرط ها به کارمی رود به طور مثال اگر بخواهیم شرط 0<X<5 را پیاده کنیم از AND منطقی به صورت زیر استفاده می کنیم:

(X > 0 ) && (X<5)

در عملگر OR منطقی اگر یکی از شرطها درست باشد حاصل عملگر صحیح است. به طور مثال اگر بخواهیم X یا Y هرکدام مثبت باشندحاصل شرط صحیح باشدبه صورت زیرمی نویسیم:

)X>0) || (Y>0)

عملگرNOT منطقی صحیح را به غلط وغلط رابه صحیح تبدیل می کند به طورمثال اگربخواهیم شرط مثبت بودن یک عدد را بنویسیم داریم:
!(X<0)
اگر بخواهیم مقدار یک متغیر در طول برنامه ثابت باقی بماند ازعبارتconst قبل ازنوع متغیر استفاده می کنیم. به طور مثال عدد π را در برنامه به صورت زیر تعریف می کنیم:

const double PI = 3.14159265 ;

– عملگر volatile:
درمیکرو کنترلر که مقدار متغیرها علاوه براینکه درنرم افزارمقداردهی می شوند توسط ماژورهای مختلف تغییر می کنند ممکن است کامپایلر دربهینه سازی برنامه تغییرات ناشی از سخت افزار را نادیده گرفته و این تغییرات در برنامه اعمال نشوند. به طور مثال فرض کنید که یک متغیر عمومی تعریف شده که هم در برنامه اصلی و هم در زیرروال سرویس وقفه استفاده می شود. کامپایلر هنگام تبدیل برنامه به کد ماشین تغییرات متغیردر زیر برنامه وقفه را نادیده گرفته و متغیر تنها در برنامه اصلی تغییر خواهد کرد. برای جلوگیری از این مشکل باید از کلمه volatile قبل از تعریف نوع متغیر استفاده کنیم و به کامپایلر یادآوری کنیم که مقدار متغیر را در حافظه RAM و نه در یک رجیستر ذخیره کند و مقدار این متغیر می تواند خارج از برنامه (زیربرنامه وقفه یا سایر زیربرنامه ها) تغییر نماید.
– عملگر #define:
این عملگر یک نام را به یک متغیر ثابت اختصاص می دهد و فضای حافظه را اشغال نمی کند. در هنگام کامپایل برنامه، متغیرهای تعریف شده به جای اسامی قرار می گیرند. به طور مثال با تعریف پایه ای که LED به آن متصل است در تمامی برنامه به جای نام ledPin متغیر 13 قرار می گیرد.
#define ledPin 13
– عملگر static:
این عملگر برای تعریف متغیرهایی بکار می رود که تنها در یک تابع قابل تغییر هستند و توابع دیگر به این متغیر دسترسی ندارند. متغیرهای استاتیک برخلاف متغیرهای محلی که در هر بار فراخوانی تابع تعریف شده و از بین می روند مقدار خود را در فراخوان های بعدی تابع حفظ می کنند. چنانچه این عملگر بر روی تابع در یک فایل بکار رود تنها توابع موجود در همان فایل می توانند تابع را فراخوانی کنند و نمی توان تابع را از فایل دیگر فراخوانی نمود.
– عملگر const:
این عملگر یک متغیر را به صورت فقط خواندنی تبدیل می نماید و در طول برنامه نمی توان مقدار آن را تغییر داد. کاربرد آن برای تعریف متغیرها بخ صورت ثابت می باشد. به طور مثال مقدار عدد را می توان به صورت زیر تعریف نمود:
const float pi = 3.14;
توجه داشته باشید که عملگر #define نیز کارکردی مشابه const دارد ولی عملگر const به خاطر مشکلاتی که بعضا #define بوجود می آورد کاربرد بیشتری دارد. نکته دیگر اینکه برای تعریف یک آرایه به صورت ثابت بایستی از const استفاده نمود و عملگر #define تنها برای تعریف رشته ها و متغیرهای عددی به صورت ثابت کاربرد دارد.
– عملگر sizeof():
این عملگر تعداد بایتهای موجود در یک متغیر و یا آرایه را بدست می دهد. برنامه زیر اندیس هر حرف در یک متن را به صورت سریال نمایش می دهد.

char myStr[] = “this is a test”;
int i;

void setup(){
Serial.begin(9600);
}

void loop() {
for (i = 0; i < sizeof(myStr) – 1; i++){
Serial.print(i, DEC);
Serial.print(” = “);
Serial.write(myStr[i]);
Serial.println();
}
delay(5000); // slow down the program
}

خروجی پورت سریال به صورت زیر است:

چنانچه متغیر از نوع int و یا بالاتر باشد حلقه for نیز باید برای این نوع متغیر تغییر کند:

for (i = 0; i < (sizeof(myInts)/sizeof(int)) – 1; i++) {
// do something with myInts[i] }

 

– عملگر PROGMEM:
چنانچه بخواهیم داده را به جای حافظه SRAM در حافظه FLASH ذخیره کنیم از این عملگر استفاده می کنیم. برای استفاده از توابعی که داده را در حافظه FLASH ذخیره می کنند ابتدا باید فایل سرآمد توابع کتابخانه ای حافظه FLASH را به صورت زیر پیوست برنامه کنیم:
#include <avr/pgmspace.h>
برای تعریف یک متغیر در حافظه FLASH از کلمه کلیدی PROGMEM به صورت زیر استفاده می کنیم:

dataType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3…};

کلمه PROGMEM را می توان به یکی از صورتهای زیر نیز بکار برد که البته ممکن است در برخی از نسخه های AVR-GCC تنها حالت اول کار کند:

dataType variableName[] PROGMEM = {};
dataType PROGMEM variableName[] = {};
PROGMEM dataType variableName[] = {};

 

برای ذخیره متغیرها در فضای حافظه بایستی نوع آن را طبق جدول زیر تعریف نمود:
عدد 8 بیتی با علامت از 128- تا 127 prog_char
عدد 8 بیتی بدون علامت از 0 تا 255 prog_uchar
عدد 16 بیتی با علامت از 32768- تا 32767 prog_int16_t
عدد 16 بیتی بدون علامت از 0 تا 65535 prog_uint16_t
عدد 32 بیتی با علامت از -2,147,483,648 تا 2,147,483,647 prog_int32_t
عدد 32 بیتی بدون علامت از 0 تا 4,294,967,295 prog_uint32_t

مثالهای زیر تعریف چندین متغیر با انواع مختلف را نشان می دهند:

PROGMEM prog_uint16_t charSet[] = { 65000, 32796, 16843, 10, 11234};
prog_uchar signMessage[] PROGMEM = {“This is a test message”};

 

توابع خواندن و نوشتن داده در فضای حافظه برنامه به شرح زیر می باشند:
– تابع pgm_read_byte_near (address_short):
این تابع یک بایت را از 64 کیلو بایت اول فضای حافظه می خواند و آدرس آن از نوع prog_uint16_t می باشد.
– تابع pgm_read_byte_far (address_long):
این تابع یک بایت را از 4 گیگا بایت اول فضای حافظه می خواند و آدرس آن از نوع prog_uint32_t می باشد.
– تابع pgm_read_word_near (address_short):
این تابع یک دوبایتی را از 64 کیلو بایت اول فضای حافظه می خواند و آدرس آن از نوع prog_uint16_t می باشد.
– تابع pgm_read_word_far (address_long):
این تابع یک دوبایتی را از 4 گیگا بایت اول فضای حافظه می خواند و آدرس آن از نوع prog_uint32_t می باشد.
– تابع char * strcpy_P ( char * dest, PGM_P src ):
این تابع رشته src که در فضای حافظه برنامه قرار دارد در آرایه ای که dest به آن اشاره می کند و در فضای SRAM قرار داردکپی می کند.
مثال- برنامه ای برای کپی کردن چند رشته در فضای حافظه برنامه در فضای حافظه SRAM بنویسید.

 

#include <avr/pgmspace.h>
prog_char string_0[] PROGMEM = “String 0”; // “String 0” etc are strings to store – change to suit.
prog_char string_1[] PROGMEM = “String 1”;
prog_char string_2[] PROGMEM = “String 2”;
prog_char string_3[] PROGMEM = “String 3”;
prog_char string_4[] PROGMEM = “String 4”;
prog_char string_5[] PROGMEM = “String 5”;

// Then set up a table to refer to your strings.

PROGMEM const char *string_table[] = // change “string_table” name to suit
{
string_0,
string_1,
string_2,
string_3,
string_4,
string_5 };

char buffer[30]; // make sure this is large enough for the largest string it must hold

void setup()
{
Serial.begin(9600);
}

void loop()
{
/* Using the string table in program memory requires the use of special functions to retrieve the data.
The strcpy_P function copies a string from program space to a string in RAM (“buffer”).
Make sure your receiving string in RAM is large enough to hold whatever
you are retrieving from program space. */

for (int i = 0; i < 6; i++)
{
strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); // Necessary casts and dereferencing, just copy.
Serial.println( buffer );
delay( 500 );
}
}

– اشاره گر ها
اشاره گرها برای آدرس دهی غیر مستقیم به کارمی روند.یک اشاره گر به یک متغیر آدرس آن متغیرمی باشد اگرمتغیرpxیک اشاره گربه یک متغیراز نوع int باشد و نیز یک متغیراز نوع int باشد آدرس x رامی توانیم به صورت زیر به px نسبت دهیم:
px = & x
عملگرAND به کامپایلر می گوید که آدرس xرا درون متغیرpx عکس این عمل به صورت زیر می باشد:

x = *px;

علامت ستاره کامپایلررابه خواندن متغیری که آدرس آن درpx است هدایت می کند.اشاره گرها می توانند به عنوان آرگومان های ورودی یک تابع مورد استفاده نیز قرار گیرند .مثال زیر جای دو متغیری را که px وpyبه آن اشاره می کند عوض می کند:

void swap(int* px, int* py)
{
int temp;
temp = *px;
*px = *py;
*py = temp;
}

همان طورکه گفتیم آرایه های چند بعدی آرایه ای از آرایه ها می باشند به طور مثال آرایه زیر را در نظر بگیرید:

int ar[3][5];

این آرایه متشکل از سه آرایه بابعد پنج می باشد همان طور که دیدیم داده ذخیره شده دراین آرایه به صورت ستونی می باشد یعنی ar[n][0] و ar[n][1] در خانه های حافظه ی مجاور یکدیگر ذخیره شده اند اسم آرایه ar اشاره گری به اولین المان آرایه می باشد و *(ar+1) اشاره گری به المان ar[1][0] درآرایه می باشد این ایده را می توان به آرایه های چند بعدی تامین داد به طور مثال *(*(ar+n)+i) مقدار المان ar[n][i] رابه دست می دهد همچنین *(*(*(br+1)+2)+3) مقدارالمان [1][2][3] را نشان می دهد از آن جا که رجیستر های مختلف آدرس های مختلفی دارند بااشاره گر ها می توانیم اسامی و آدرس رجیستر ها را تعریف کنیم فرض کنید آدرس 0x1000 را به پورتA نسبت دهیم ابتدا آدرس 0x1000 را به صورت یک اشاره گر تعریف می کنیم

(int *) 0x1000

حال باید پورت A رابه صورت محتوای آدرس 0x1000 تعریف کنیم بنابراین باید از یک اشاره گر دیگر به صورت زیر استفاده کنیم

#define PORTA (*(int *) 0x1000)

ساختار
زبان C یک ویژگی برای قرار دادن انواع مختلف متغیر در یک گروه تحت یک نام دارد که ساختار (struct) نام دارد. مثال زیر یک ساختار با دو عنصر را نشان می دهد:

struct person{
int height ;
char weight;
};

عبارت بالا یک متغیر جدید با نام struct nf تعریف می کند که با نقطه می توان به المانهای آن (x,y) دسترسی پیدا کرد. در زیر دو متغیر struct nf با نامهای f1 و f2 تعریف شده که المانهای آن به طور مجزا مقداردهی شده است.

struct person p1, p2 ;
p1.x = 170;
p2.y = 60;

چنانچه
ثابت ها
زبان Arduino چندین مقدار از پیش تعریف شده دارد که به فهم بیش تر برنامه کمک می کند این متغیر های ثابت عبارتند از
– الف:true/false :
این متغیرها از نوع بولی می باشند که سطوح منطقی را تعریف می کنند FALSE عددصفر تعریف شده وهرچیزی به غیر از صفر TRUE تعریف می شود بنابراین اعداد 10،10-و1000 همگیTRUE می باشند .
– ب:high/low :
این متغیر ها سطوح ولتاژ بروی پایه های میکرو را تعریف می کنند HIGH به یک منطقی ویا پنج ولت وlow به معنای صفر منطقی ویا صفر ولت تعریف می شود .
– ساختار های کنترل حلقه
if:
جمله if صحت یک شرط را بررسی می کند و چناچه شرط صحیح (TRUE) باشد جملات Statement1 اجرا می شوند و در صورت غلط بودن شرط جملات Statement2 اجرا می شوند.
if (Condition)
{
Statement1;
{
else{
Statement2;
}
درصورتی که شرط ما چندین مقدار داشته یاشد و به ازای هر مقدار بایستی دستورات خاصی اجرا شوند از شکل زیر دستور if استفاده می کنیم.

if(condition 1)
{
Statement 1;
}
else if (condition 2)
{
Statement 2;
}
.
.
.
else if (condition n)
{
Statement n;
}
else
{

}

مثال: برنامه ای بنویسید که اگر متغیر a زوج بود انگاه یک واحد به متغیر b اضافه شود در غیر این صورت متغیر b یک واحد کاهش یابد.

if( a%2==0)
{
b++;
}
else
{
b–;
}

حلقه while
حلقه while تاهنگامی که شرط آن درست باشد اجرا می شود،ساختار این دستور به شکل زیر می باشد :

while (Condition)
{
statement;
}

مثال : برنامه ای بنویسید که تا هنگامی که متغیر temp<30 یک واحد به متغیر a اضافه کند :

while (temp<30)
{
a++;
}

تذکر- چنانچه شرط حلقه while همیشه صحیح باشد یک حلقه بی نهایت تشکیل می شود. در برنامه اصلی قسمتی که همیشه باید اجرا شود در حلقه بی نهایت نوشته می شود که معمولا این حلقه با while به صورت زیر پیاده سازی می شود:

while(1)
{
//endless loop
}

در Arduino حلقه بی نهایت را در زیر برنامه void loop() می نویسیم.
– حلقه DO/While
در حلقه while قبل از اجرای جملات ابتداشرط حلقه بررسی می شود چنانچه نادرست باشد جملات داخل حلقه اجرا نمی شوند گاهی اوقات لازم است که جملات یکبار اجراشده و سپس شرط مورد نظر بررسی شود در این هنگام از حلقه do/while استفاده کنیم که شکل آن به صورت زیر است:

do
{
statement;
} while (Condition);

یک کاربرد این حلقه می تواند در هنگامی باشد که داده یکی از ماژولهای میکرو حداقل برای یکبار خوانده شده و سپس با توجه به مقدار آن دستورات لازم اجرا شوند.
– دستورbreak
دستورbreak کنترل برنامه را به خارج از حلقه منتقل می کند. این دستور را می توان برای خروج از حلقه های for،while،
while do-،switch statements به کار برد .
مثال:برنامه ای بنویسید تا هنگامی که متغیر aبین صفر تا 30 است یک واحد از متغیر b کم کند و هنگامی که مقدار a برابر با 50 شد از حلقه خارج شود.

while( ( a>0) && (a<30) )
{
b–;
if ( a==50) break;
}

– دستورcontinue
هنگامی که این دستور در داخل یک حلقه اجرا شود خطوط زیر این دستور در حلقه اجرا نشده و کنترل برنامه به ابتدای حلقه منتقل می شود. این دستور برخلاف break شرط حلقه را دوباره بررسی می کند. یک شکل کاربرد این دستور به صورت زیر است:

while (<expression>) {

if (<condition>)
continue;


// control jumps here on the continue
}

حلقه for
حلقه forدر C برای تکرار خطوطی از برنامه بر ای تعداد دفعات معین به کار می رود ساختار این دستور از سه قسمت تشکیل شده که به وسیله نقطه ویرگول از یکدیگر جدا شده اند. این سه قسمت عبارتند از مقداردهی اولیه، شرط ادامه و عمل حلقه. ابتدا یک متغیر محلی که شمارنده حلقه می باشد برای یکبار مقداردهی اولیه شده و سپس اگر شرط ادامه برقرار بود عمل حلقه بر روی شمارنده اجرا شده و سپس خطوط برنامه داخل آکولاد اجرا می شوند.

for (<initialization>; <continuation>; <action>) {
<statement>
}

مثال- با استفاده از تابع تاخیر یک میلی ثانیه ، یک تاخیر به مدت یک ساعت ایجاد کنید.
تابع delay() یک تاخیر بر حسب میلی ثانیه ایجاد می کند. برای ایجاد تاخیر یک ساعت، این تابع را 3600 بار تکرار میکنیم

for( int i = 0 ; i<3600; i++)
{
delay(1000);
}

تذکر- چنانچه بخواهیم با استفاده از دستور for حلقه بی نهایت ایجاد کنیم باید از عبارت زیر استفاده کنیم:

for(;;)
{
// code executed forever
}

 

– دستورswitch
دستور switch نوع خاصی از دستور if است که برای جداسازی قسمت های برنامه باتوجه به مقدار یک متغیر به کار می رود ابتدا مقدار متغیر محاسبه شده و باتوجه به عدد به دست آمده زیر برنامه ی مربوط به آن عدد اجرا می شود. شکل کلی این دستور به صورت زیر است:

switch (<expression>) {
case <const-expression-1>:
<statement>
break;
case <const-expression-2>:
<statement>
break;
case <const-expression-3>: // here we combine case 3 and 4
case <const-expression-4>:
<statement>
break;
default: // optional
<statement>
}

مثال :مقدار متغیر a از یک صفحه کلید خوانده شده وبا توجه به مقدار آن بایستی کارهای زیر صورت گیرد. اگر مقدار a یک بود بیت چهارم عدد b صفر شود و اگر مقدارa دو بود یک تاخیر دو ثانیه ای ایجاد شود وچنانچه مقدار آن سه بود بیت سوم متغیر b یک شود.

switch(a)
{
case 1:
b&=~(1<<4);

case 2:
delay(2000);

case 3:
b|=(1<<3) ;
break;
}

– توابع
تابع ساختاری برای جمع آوری قسمتی از برنامه می باشد. یک تابع دارای یک اسم، تعدادی آرگومان ورودی، خروجی و خطوطی از برنامه می باشد. شکل یک تابع در حالت کلی به صورت زیر می باشد:

{ (متغیرهای ورودی) <اسم تابع> <نوع خروجی>
//function code

}
مثال زیر یک تابع ساده برای دو برابر کردن مقدار ورودی را نشان می دهد اسم این تابع Twice بوده و آرگومان ورودی آن 8 بیتی بدون علامت می باشد و آرگومان خروجی آن از نوع 16 بیتی می باشد

 

int Twice(int num) {
int result = num * 2;
return result;
}

متغیر های داخل تابع result و num به صورت موقت تنها هنگامی که تابع در حال اجرا است وجود دارند و به اصطلاح متغیر های محلی تابع می باشند دستور return متغیر خروجی تابع را محاسبه می کند به عبارت دیگر هنگامی که تابع فراخوانی می شود خروجی آن متغیر تنها متغیر خروجی آن result قابل دسترسی است چنانچه خروجی ویا ورودی نداشته باشد ازمتغیر void استفاده می کنیم .
مثال:تابعی بنویسید که متغیر a را به صورت ورودی دریافت کرده، بیت پنجم ان را مکمل کند و سپس به صورت خروجی تحویل دهد.

unsigned char comp(unsigned char a)
{
a = a ^ (1 << 5 ) ;
return a;
}

مثال- تابعی بنویسید که دو عدد را به صورت ورودی دریافت کرده و منیمم آنها را به صورت خروجی تحویل دهد.

unsigned char minfun(unsigned char a, unsigned char b)
{
int min;
if (a<b) min = a ;
else min = b ;
return min;
}

مثال:
تابعی بنویسید که دو متغیر هشت بیتی را با هم جمع کرده وخروجی رابه صورت شانزده بیتی تحویل دهد.

int addfun(unsigned char a, unsigned char b)
{
int c;
c=a+b;
return c;
}

با دستور return، متغیر c به عنوان خروجی تابع تعریف می گردد. کلیه جملات تابع توسط آکولاد مشخص می شوند.

مثال- تابعی بنویسید که مقدار دو متغیر x و y را با یکدیگر عوض کند.
void Swap(int* x, int* y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
هنگام فراخوانی تابع باید به صورت زیر عمل میکنیم. این تابع مقدار دو متغیر a و b را با هم عوض می کند. توجه داشته باشید که متغیر های ورودی این تابع باید به صورت آدرس متغیرهای ورودی باشد.

Swap(&a, &b);

ساختاراولیه زبان برنامه نویسی Arduino بسیار ساده بوده و از دو تابع تشکیل می شود. این دو تابع مجموعه ای ازجملات را در برمی گیرند که برنامه را تشکیل می دهند:

void setup()
{
statements;
}
void loop()
{
statements;
}

حلقه setup()فقط یکباردرابتدای برنامه اجرا شده ومتغیرهای برنامه و رجیسترهای مختلف مقداردهی اولیه می شوند. حلقه loop()به طورمداوم اجراشده وبرنامه اصلی در این حلقه نوشته می شود.

 

 

جمع آوری شده از :  وب سایت آردینو

وب سایت رسمی کمپانی آردینو :arduino.cc

درباره‌ Admin

تیم مدیریتی ای ال سی وان تصمیم دارد که تمام تجربیات و دانسته های خود را بخصوص در زمینه الکترونیک در اختیار شما دوستان عزیز قرار دهد . بانظرات خود ، خودتان را در پیشرفت سایت سهیم بدانید

جوابی بنویسید

ایمیل شما نشر نخواهد شدخانه های ضروری نشانه گذاری شده است. *

*