آموزش متغیرها و انواع داده در آردوینو
مقدمه
در برنامه نویسی آردوینو، برای ذخیره کردن اطلاعاتی مانند شماره پایه، دمای محیط، ولتاژ باتری، وضعیت یک کلید یا متن دریافتی از کاربر، به محلی برای نگهداری داده ها نیاز داریم.
این محل ذخیره سازی را متغیر (Variable) می نامیم.
هر متغیر یک نام و یک نوع داده دارد. نوع داده مشخص می کند چه نوع اطلاعاتی در متغیر ذخیره می شود و چه محدوده ای از مقادیر را می توان در آن نگهداری کرد.
در این آموزش با پنج نوع داده پرکاربرد در آردوینو آشنا می شویم:
intبرای اعداد صحیحfloatبرای اعداد اعشاریcharبرای یک کاراکترboolبرای مقادیر منطقیStringبرای متن
۱. متغیر چیست؟
متغیر فضایی در حافظه است که برنامه برای نگهداری یک مقدار از آن استفاده می کند.
برای مثال، اگر بخواهیم شماره پایه ای را که یک LED به آن متصل شده است ذخیره کنیم، می توانیم بنویسیم:
int ledPin = 13;در این دستور:
intنوع داده متغیر را مشخص می کند.ledPinنام متغیر است.13مقدار اولیه متغیر است.- علامت
=مقدار سمت راست را در متغیر سمت چپ قرار می دهد. - علامت
;پایان دستور را مشخص می کند.
پس از تعریف این متغیر، می توانیم به جای نوشتن عدد ۱۳ در تمام قسمت های برنامه، از نام ledPin استفاده کنیم.
مثال:
int ledPin = 13;
void setup() {
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
}
void loop() {
}در این برنامه، پایه شماره ۱۳ به عنوان خروجی تنظیم و سپس روشن می شود.
استفاده از نام مناسب برای متغیرها باعث می شود برنامه خواناتر و اصلاح آن آسان تر شود.
۲. تعریف و مقداردهی متغیر
برای تعریف یک متغیر معمولا از ساختار زیر استفاده می کنیم:
نوع_داده نام_متغیر = مقدار;برای مثال:
int counter = 0;
float temperature = 25.5;
char grade = 'A';
bool ledState = true;
String message = "Hello Arduino";در این مثال، پنج متغیر با انواع داده متفاوت تعریف شده اند.
توجه کنید که مقدار متنی در String داخل علامت نقل قول دوتایی قرار می گیرد، اما مقدار char داخل علامت نقل قول تکی نوشته می شود.
همچنین می توان ابتدا متغیر را تعریف و سپس مقدار آن را تعیین کرد:
int counter;
counter = 10;اگر متغیر محلی را بدون مقداردهی اولیه تعریف کنیم، نباید فرض کنیم مقدار آن صفر است. پیش از خواندن متغیر باید مقدار مشخصی به آن بدهیم.
۳. نوع داده int
نوع داده int برای نگهداری اعداد صحیح، یعنی اعدادی بدون بخش اعشاری، استفاده می شود.
مثال:
int age = 25;
int ledPin = 13;
int counter = 0;
int temperature = -5;متغیرهای int می توانند مقادیر مثبت، منفی و صفر را نگهداری کنند؛ البته محدوده دقیق آن ها به معماری برد بستگی دارد.
در بسیاری از بردهای رایج آردوینو مانند Uno مبتنی بر ATmega328P، نوع int شانزده بیتی است و محدوده آن از ۳۲۷۶۸- تا ۳۲۷۶۷ است.
در بردهای ۳۲ بیتی مانند ESP32، نوع int معمولا ۳۲ بیتی است.
بنابراین، هنگام نوشتن برنامه برای بردهای مختلف، نباید بدون بررسی فرض کنیم int در همه آن ها محدوده یکسانی دارد.
مثال کاربردی int
در این مثال، یک شمارنده هر ثانیه یک واحد افزایش پیدا می کند:
int counter = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
counter++;
Serial.println(counter);
delay(1000);
}عملگر ++ مقدار متغیر را یک واحد افزایش می دهد. خروجی Serial Monitor به صورت ۱، ۲، ۳ و ... خواهد بود.
اگر شمارنده به محدوده قابل نگهداری نوع داده برسد، مقدار آن ممکن است سرریز کند و نتیجه قابل انتظار نباشد. برای شمارنده های بزرگ باید نوع داده مناسب انتخاب شود.
۴. نوع داده float
نوع داده float برای نگهداری اعداد اعشاری استفاده می شود.
این نوع داده برای مواردی مانند دما، ولتاژ، جریان و محاسباتی که بخش اعشاری دارند، کاربرد دارد.
مثال:
float temperature = 24.7;
float batteryVoltage = 3.85;
float current = 0.25;برای تعریف مقدار اعشاری از نقطه استفاده می کنیم، نه ویرگول.
مثال کاربردی float
float voltage = 3.75;
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.print("Voltage: ");
Serial.print(voltage, 2);
Serial.println(" V");
delay(1000);
}در دستور Serial.print(voltage, 2) عدد ۲ مشخص می کند که مقدار با دو رقم اعشار نمایش داده شود.
خروجی نمونه:
Voltage: 3.75 Vنکته مهم این است که float دقت نامحدود ندارد. بسیاری از اعداد اعشاری در حافظه به صورت تقریبی ذخیره می شوند. بنابراین، برای محاسبات حساس باید خطای گرد کردن و دقت مورد نیاز را در نظر گرفت.
همچنین اگر دو مقدار از نوع int را بر هم تقسیم کنیم، نتیجه تقسیم صحیح خواهد بود؛ حتی اگر آن را در متغیر float قرار دهیم.
برای مثال:
int a = 5;
int b = 2;
float result = (float)a / b;در این حالت نتیجه 2.5 خواهد بود؛ زیرا یکی از عملوندها پیش از تقسیم به float تبدیل شده است.
۵. نوع داده char
نوع داده char برای نگهداری یک کاراکتر استفاده می شود؛ مانند یک حرف انگلیسی، یک رقم به شکل کاراکتر یا یک نماد.
مثال:
char letter = 'A';
char command = 'Y';
char digit = '7';مقدار char با علامت نقل قول تکی مشخص می شود.
تفاوت این دو دستور را ببینید:
char digit = '7';
int number = 7;در دستور اول، کاراکتر 7 ذخیره شده است. در دستور دوم، مقدار عددی هفت ذخیره می شود. این دو مقدار از نظر نوع داده و کاربرد یکسان نیستند.
مثال کاربردی char
char command = 'Y';
void setup() {
Serial.begin(9600);
if (command == 'Y') {
Serial.println("Command accepted");
}
}
void loop() {
}در این برنامه، اگر مقدار command برابر با کاراکتر Y باشد، پیام مورد نظر نمایش داده می شود.
نوع char در بسیاری از بردهای آردوینو یک بایت حافظه اشغال می کند. برای نگهداری متن فارسی یا سایر نویسه های چندبایتی، یک متغیر char به تنهایی کافی نیست.
۶. نوع داده bool
نوع داده bool برای نگهداری یک مقدار منطقی استفاده می شود. این متغیر فقط دو مقدار دارد:
trueبه معنی درستfalseبه معنی نادرست
مثال:
bool ledState = true;
bool alarmEnabled = false;
bool buttonPressed = false;این نوع داده برای نگهداری وضعیت ها، نتیجه شرط ها و فعال یا غیرفعال بودن قابلیت های برنامه بسیار مناسب است.
مثال کاربردی bool
const int ledPin = 13;
bool ledState = false;
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
ledState = !ledState;
digitalWrite(ledPin, ledState);
delay(1000);
}در این مثال، عملگر ! مقدار منطقی را معکوس می کند. اگر ledState برابر false باشد، به true تبدیل می شود و برعکس.
در نتیجه LED هر ثانیه بین حالت روشن و خاموش تغییر می کند.
در این کد فرض شده است که LED با قرار گرفتن پایه در وضعیت HIGH روشن می شود. در مدارهایی که LED به شکل Active-Low متصل شده است، رفتار روشن و خاموش ممکن است برعکس باشد.
۷. نوع داده String
نوع داده String برای نگهداری متن و مجموعه ای از کاراکترها استفاده می شود.
مثال:
String deviceName = "ARDUnia";
String message = "Hello Arduino";
String status = "Ready";برخلاف char که یک کاراکتر را نگهداری می کند، String می تواند یک متن کامل را در خود جای دهد.
مثال کاربردی String
String deviceName = "ARDUnia";
void setup() {
Serial.begin(9600);
Serial.print("Device: ");
Serial.println(deviceName);
}
void loop() {
}خروجی Serial Monitor:
Device: ARDUniaترکیب متن و متغیرها
می توان از عملگر + برای ترکیب متن و مقدارهای دیگر استفاده کرد.
String deviceName = "ARDUnia";
int version = 2;
void setup() {
Serial.begin(9600);
String message = deviceName + " Version ";
message += version;
Serial.println(message);
}
void loop() {
}خروجی:
ARDUnia Version 2نکته مهم درباره String
در بسیاری از هسته های آردوینو، کلاس String برای ساخت و تغییر متن از حافظه پویا استفاده می کند. در برنامه های طولانی یا بردهایی با حافظه محدود، استفاده مکرر از ترکیب و تغییر رشته ها ممکن است باعث تکه تکه شدن حافظه و بروز خطا شود.
در پروژه های کوچک، استفاده از String معمولا ساده و مناسب است؛ اما در پروژه های بزرگ یا حساس به حافظه، استفاده از آرایه کاراکتری با نوع char می تواند انتخاب قابل کنترل تری باشد.
نمونه آرایه کاراکتری:
char deviceName[] = "ARDUnia";این آرایه شامل کاراکترهای متن و یک کاراکتر پایان رشته '\0' است.
همچنین String با حرف بزرگ آغاز می شود؛ زیرا نام یک کلاس در محیط آردوینو است، در حالی که int، float، char و bool نام نوع های داده زبان C++ هستند.
۸. مقایسه انواع داده
| نوع داده | کاربرد | نمونه تعریف | نکته |
|---|---|---|---|
int | اعداد صحیح | int count = 10; | اندازه و محدوده به برد بستگی دارد |
float | اعداد اعشاری | float voltage = 3.7; | دقت آن محدود است |
char | یک کاراکتر | char letter = 'A'; | از نقل قول تکی استفاده می کند |
bool | مقدار منطقی | bool enabled = true; | فقط true یا false |
String | متن | String name = "Arduino"; | استفاده از حافظه پویا ممکن است هزینه داشته باشد |
۹. تغییر مقدار متغیر
پس از تعریف متغیر، در صورت نیاز می توانیم مقدار آن را تغییر دهیم.
مثال:
int counter = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
counter = counter + 1;
Serial.println(counter);
delay(1000);
}عبارت زیر:
counter = counter + 1;یعنی مقدار فعلی counter را یک واحد افزایش بده و نتیجه را دوباره در همان متغیر ذخیره کن.
همین کار را می توان با دستور کوتاه تر زیر انجام داد:
counter++;برای افزایش دو واحدی می توان نوشت:
counter += 2;در مقابل، علامت = برای مقداردهی استفاده می شود، اما علامت == برای مقایسه دو مقدار به کار می رود.
مثال:
int temperature = 25;
if (temperature == 25) {
// شرط برقرار است
}۱۰. ثابت ها با const
گاهی مقدار یک متغیر نباید در طول اجرای برنامه تغییر کند. در این حالت می توانیم از const استفاده کنیم.
مثال:
const int ledPin = 13;
const float referenceVoltage = 5.0;کلمه const مشخص می کند که مقدار این متغیر از طریق روش های معمول برنامه قابل تغییر نیست.
استفاده از const برای مواردی مانند شماره پایه ها، نسبت تقسیم ولتاژ و مقادیر تنظیماتی که قرار نیست تغییر کنند، خوانایی برنامه را بهتر می کند و از تغییر ناخواسته آن ها جلوگیری می کند.
۱۱. محدوده دسترسی متغیرها
محل تعریف متغیر تعیین می کند کدام بخش های برنامه می توانند به آن دسترسی داشته باشند.
متغیر محلی
متغیری که داخل یک تابع یا بلوک تعریف می شود، معمولا فقط در همان محدوده قابل استفاده است.
void setup() {
int localValue = 10;
}در این مثال، localValue خارج از تابع setup() قابل استفاده نیست.
متغیر سراسری
متغیری که بیرون از توابع تعریف شود، می تواند در بخش های مختلف همان فایل برنامه مورد استفاده قرار بگیرد.
int counter = 0;
void setup() {
}
void loop() {
counter++;
}در این مثال، counter هم در setup() و هم در loop() قابل دسترسی است.
متغیرهای سراسری در محیط آردوینو به صورت خودکار مقدار اولیه صفر می گیرند، مگر اینکه مقدار دیگری برای آن ها تعیین شده باشد. با این حال، بهتر است برای وضوح برنامه، مقدار اولیه را صریح بنویسیم.
۱۲. اشتباهات رایج
اشتباه اول: استفاده از مقدار اعشاری در متغیر int
int voltage = 3.7;این متغیر مقدار اعشاری را به صورت دقیق نگهداری نمی کند و بخش اعشاری از بین می رود. برای نگهداری مقدار اعشاری از float استفاده کنید.
اشتباه دوم: استفاده نادرست از نقل قول
char letter = "A";این دستور برای تعریف یک کاراکتر منفرد درست نیست. شکل صحیح آن:
char letter = 'A';برای متن از String یا آرایه کاراکتری استفاده می کنیم:
String letterText = "A";اشتباه سوم: اشتباه گرفتن = و ==
=برای مقداردهی است.==برای مقایسه دو مقدار است.
اشتباه چهارم: فرض یکسان بودن اندازه int در تمام بردها
محدوده int در همه بردهای آردوینو یکسان نیست. هنگام کار با مقادیر بزرگ، نوع داده و معماری برد را بررسی کنید.
اشتباه پنجم: استفاده بی رویه از String
در بردهای دارای حافظه محدود، ترکیب مکرر رشته ها ممکن است مصرف حافظه را افزایش دهد. برای پروژه های حساس به حافظه، آرایه های کاراکتری و روش های مدیریت حافظه را نیز بررسی کنید.
جمع بندی
متغیرها ابزار اصلی ذخیره و مدیریت داده ها در برنامه نویسی آردوینو هستند. انتخاب نوع داده مناسب، استفاده از حافظه را بهتر می کند و از خطاهای محاسباتی و منطقی جلوگیری می کند.
- از
intبرای اعداد صحیح استفاده کنید. - از
floatبرای اعداد اعشاری استفاده کنید. - از
charبرای یک کاراکتر استفاده کنید. - از
boolبرای وضعیت های درست و نادرست استفاده کنید. - از
Stringبرای نگهداری متن استفاده کنید؛ در پروژه های محدود از نظر حافظه، هزینه آن را نیز در نظر بگیرید.
پیشنهاد تمرین: برنامه ای بنویسید که نام دستگاه را در یک متغیر String، شماره پایه LED را در یک متغیر int، ولتاژ باتری را در یک متغیر float، وضعیت LED را در یک متغیر bool و یک فرمان تک کاراکتری را در یک متغیر char ذخیره کند. سپس همه این مقادیر را در Serial Monitor نمایش دهید.
نمونه کد :
const int ledPin = 13;
float batteryVoltage = 3.75;
char command = 'Y';
bool ledState = false;
String deviceName = "ARDUnia";
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.print("Device: ");
Serial.println(deviceName);
Serial.print("Battery voltage: ");
Serial.println(batteryVoltage, 2);
Serial.print("Command: ");
Serial.println(command);
ledState = true;
digitalWrite(ledPin, ledState);
Serial.print("LED state: ");
Serial.println(ledState);
}
void loop() {
}