5 بهترین نکات برنامه نویسی آردوینو (ترفند کدنویسی)
چند نکته تصادفی برای برنامه نویسان آردوینو. ما با ذخیره سازی متن در حافظه برنامه، آسان تر کردن خواندن برنامه های شما، روشی برای جلوگیری از طولانی شدن تاخیر، عملگر سه گانه ++ C و تایمر واچ داگ، صرفه جویی در مصرف RAM را پوشش می دهیم.
۱-قرار دادن رشته های متنی در حافظه برنامه موجب صرفه جویی در رم می شود
به جای (Serial.println(“Hello World!”));، Serial.println(F(“Hello World” را بنویسید.
وقتی می نویسید:
Serial.println(“Hello World!”);
متن ” Hello World” در دو مکان ذخیره می شود:
۱- حافظه برنامه
۲- حافظه دسترسی تصادفی (RAM)
محتویات RAM با هر بار راه اندازی مجدد آردوینو یا قطع شدن برق، از دست می رود. حافظه برنامه از طریق راه اندازی مجدد مجدد و قطع شدن برق حفظ می شود، بنابراین در شروع هر برنامه، رشته های عادی از حافظه برنامه در RAM کپی می شوند تا بتوانند توسط برنامه شما استفاده شوند.
اگرچه بسیاری از بردهای آردوینو RAM زیادی ندارند: به عنوان مثال، تراشه ۳۲۸ مورد استفاده در Uno تنها ۲ کیلوبایت حافظه دارد. بنابراین اگر برنامه شما از رشته های مختلف یا متغیرهای دیگر استفاده کند، به راحتی حافظه RAM پر می شود.
وقتی می نویسید:
Serial.println(F(“Hello World!”))
تابع println متن را مستقیماً از حافظه برنامه می گیرد، با استفاده از یک بافر موقت که مقدار زیادی از حافظه RAM را مصرف نمی کند.
۲-ثابت ها باعث می شوند برنامه ها راحت تر خوانده شوند
فرض کنید می خواهید برادر کوچک خود را اذیت کنید: به یکی از خروجی های دیجیتال آردوینو یک زنگ وصل کنید و هر چند ثانیه آن را به صدا در بیاورید. اگر زنگ به پورت ۶ متصل است، باید ۶ را در سه مکان وارد کنید:
۱- تنظیم حالت پین به عنوان یک خروجی
۲- روشن کردن زنگ
۳- خاموش کردن زنگ
در عوض، یک ثابت در بالای برنامه خود تعریف کنید:
const int BuzzerPort = 6;
- /*
- Beeper
- Makes a noise every few seconds.
- */
- // A constant for the port that the buzzer is connected to.
- const int BuzzerPort = 6;
- // These constants define how often the beeper sounds, and how long it sounds for.
- const int BuzzerPeriod = 5000; // [milliseconds]
- const int BuzzerOnTime = 100; // [milliseconds]
- void setup()
- {
- pinMode(BuzzerPort, OUTPUT);
- }
- // the loop routine runs over and over again forever:
- void loop()
- {
- digitalWrite(BuzzerPort, HIGH);
- delay(BuzzerPeriod);
- digitalWrite(BuzzerPort, LOW);
- delay(BuzzerOnTime);
- }
همچنین کد واضح تر می شود. بلافاصله می دانیم که (digitalWrite (BuzzerPort, HIGH باید یک زنگ را روشن کند. با (digitalWrite (6 , HIGH، باید بخاطر داشته باشیم که چه ارتباطی به پورت ۶ دارد.اکنون، هنگامی که زنگ را به پورت ۷ وصل می کنید (بعد از اینکه برادر کوچک شما سیم را بیرون کشید تا بتواند آن را خاموش کند)، باید پورت را فقط در یک مکان تغییر دهید.
پس چرا به جای فقط یک متغیر از یک ثابت استفاده می کنیم؟ ;int BuzzerPort = 6 به همان خوبی کار نمی کند؟
با تغییر پورت هنوز فقط یک شماره دارید که می توانید تغییر دهید. اما وقتی “متغیر” به عنوان یک ثابت اعلام شود، کامپایلر، ابزاری که برنامه شما را به چیزی که آردوینو می تواند استفاده کند تبدیل می کند، به شما اجازه نمی دهد آن را به طور تصادفی تغییر دهید. بنابراین اگر شما ساختار const int BuzzerPort = 6 را دارید و سعی کنید مقدار را تغییر دهید:
- void setup()
- {
- BuzzerPort = 7;
- pinMode(BuzzerPort, OUTPUT);
- }
۳-تأخیرها خسته کننده هستند
کامپایلر یک خطا را گزارش می کند. بنابراین با ثابت ها می توانید به مقداری اعتماد کنید که پس از تنظیم هرگز تغییر نمی کند.
تابع delay برنامه شما را متوقف می کند. برنامه کلاسیک چشمک زدن بیشتر وقت خود را صرف انجام کاری نمی کند:
- void loop()
- {
- digitalWrite(LedPin, HIGH);
- delay(1000); // yawn. Nothing is happening here.
- digitalWrite(LedPin, LOW);
- delay(1000); // zzz. Or here!
- }
یک راه ساده وجود دارد، اما ما به چند متغیر نیاز خواهیم داشت:به همه کارهای بزرگی که می توانید در آن زمان هدر رفته انجام دهید فکر کنید: خواندن سنسورها، ایجاد صدا، رانندگی موتورها. تأخیرها می توانند مفید باشند، اما اغلب آن ها فقط اتلاف وقت هستند.
- // Time stamp when the LED was last turned on or off.
- unsigned long LastLEDToggleTime = 0;
- // Current state of the LED; true => on; false => off.
- bool IsLEDOn = false;
- // Time between turning the LED on or off
- const int LEDTogglePeriod = 1000; // [milliseconds]
- // The pin the LED is connected to
- const int LEDPin = 13;
و حلقه تبدیل می شود به:
- void loop()
- {
- // This will toggle the LED on and off, with no wasteful delays
- if ((millis() – LastLEDToggleTime) > LEDTogglePeriod)
- {
- LastLEDToggleTime = millis();
- if (IsLEDOn)
- {
- IsLEDOn = false;
- digitalWrite(LEDPin, LOW);
- }
- else
- {
- IsLEDOn = true;
- digitalWrite(LEDPin, HIGH);
- }
- }
- // Do something else here.
- }
از ArduinoTimer در کتابخانه و عملگر سه گانه استفاده کنید:
- #include “ArduinoTimer.h”
- // A variable to keep track of time
- ArduinoTimer BlinkTimer;
- // Current state of the LED; true => on; false => off.
- bool IsLEDOn = false;
- // Time between turning the LED on or off
- const int LEDTogglePeriod = 1000; // [milliseconds]
- // The pin the LED is connected to
- const int LEDPin = 13;
- void loop()
- {
- // This will toggle the LED on and off, with no wasteful delays
- if (BlinkTimer.TimePassed_Milliseconds(LEDTogglePeriod))
- {
- IsLEDOn = !IsLEDOn; // toggle status
- digitalWrite(LEDPin, IsLEDOn ? HIGH : LOW);
- }
- // Do something else here.
- }
۴-عملگر های سه گانه
C++ ، زبانی که پلتفرم آردوینو از آن استفاده می کند، شامل یک عبارت مفید برای انتخاب بین دو مقدار است:
(expression) ? (true-value) : (false-value)
این عملگر سه گانه نامیده می شود … زیرا دارای ۳ آرگومان است:
۱- (expression)، آزمایشی درست یا غلط است
۲- اگر (expression) درست باشد نتیجه (true-value) می شود
۳- اگر (expression) نادرست باشد نتیجه (false-value) می شود
این مورد به شما اجازه می دهد مواردی مانند این را بنویسید:
- IsLEDOn = !IsLEDOn; // toggle value of IsLEDOn
- digitalWrite(LEDPin, IsLEDOn ? HIGH : LOW)
به جای:
- if (IsLEDOn)
- {
- IsLEDOn = false;
- digitalWrite(LEDPin, LOW);
- }
- else
- {
- IsLEDOn = true;
- digitalWrite(LEDPin, HIGH);
- }
۵-مهار برنامه های فراری با تایمر واچ داگ
ریزپردازنده آردوینو دارای یک تایمر واچ داگ است. تایمر واچ داگ به نوعی سوئیچ مرد مرده است: اگر برنامه شما دائماً به تایمر نگوید که همه چیز خوب نیست، آردوینو را منفجر می کند.
در واقع، این فقط میکرو را تنظیم مجدد می کند: کاری که در هنگام تنظیم مجدد انجام می دهید مسئولیت خود شما است.
برای استفاده از تایمر واچ داگ، باید:
۱- یک کتابخانه اضافه کنید
۲- واچ داگ را فعال کنید
۳- به واچ داگ بگویید که همه چیز خوب است
این مثال باید بر روی هر آردوینو که از میکروکنترلر Atmel استفاده می کند، از جمله Uno ، Mini و Mega کار کند. توجه داشته باشید، Mega قدیمی در بوت لودر خود مشکل داشت. اگر مهلت زمانی watch-dog را خیلی کم تنظیم کنید، نمی توانید آردوینو را با استفاده از بوت لودر سریال مجدداً برنامه ریزی کنید. برای رفع این مشکل به جدیدترین بوت لودر Mega به روز شوید.
- // Include the watch-dog library functions
- #include
- unsigned CountDown = 10;
- void setup()
- {
- Serial.begin(9600);
- // enable the watchdog timer and set a timeout.
- // if we don’t call wdt_reset() before the time is up, the program will reset automatically.
- wdt_enable(WDTO_1S); // WDTO_1S => 1 second timeout.
- }
- void loop()
- {
- // the program is alive…for now.
- wdt_reset();
- while (CountDown >= 0)
- {
- Serial.println(CountDown);
- CountDown = CountDown – 1;
- delay(30);
- }
- Serial.println(F(“Kaboom!”));
- }
این برنامه در حلقه while گیر می کند. از آنجا که ()wdt_reset فقط اولین بار در حلقه فراخوانی می شود، تایمر watch-dog سرانجام منقضی می شود و برنامه مجدداً تنظیم می شود.این برنامه حاوی یک اشکال است یعنی شمارش معکوس هرگز به پایان نخواهد رسید. آیا می توانید آن را مشاهده کنید؟
سلام من یک مشکلی دارم یک کد کنترل وسایل با اردوینو و پیامک نوشتم و واچ داگز رو هم فعال کردم در بعضی از موارد و مشکلات سخت افزاری میکرو هنگ میکنه ولی واچ داگز اون رو ریست نمیکنه
پاسخنکته . مدار رو کامل رو pcb طراحی کردم و از برد اردوینو اماده استفاده نکردم
سپاس