پیشرفت یادگیری
۳ ۴
بخش ۳ از ۴
بخش سوم از ۴

توابع و عملگرها
عملگرها، توابع ریاضی و تبدیل نوع داده

بخش قبلی: ساختارهای کنترلی بخش ۳ از ۴ بخش بعدی: ورودی/خروجی و ارتباطات
توابع و عملگرها زبان فارسی C/C++ سطح: مبتدی تا متوسط زمان مطالعه: ۴۰ دقیقه

در این بخش چه می‌آموزیم؟

در این بخش با عملگرها و توابع پرکاربرد در برنامه‌نویسی آردوینو آشنا می‌شویم. عملگرها برای انجام عملیات بر روی داده‌ها و توابع برای انجام محاسبات و تبدیلات استفاده می‌شوند.

عملگرهای حسابی

+ - * / %

عملگرهای مقایسه‌ای

== != > < >= <=

عملگرهای منطقی و بیتی

&& || ! & | ^ ~

توابع ریاضی و زمانی

abs, map, delay, millis

۳-۱ عملگرهای حسابی

عملگرهای حسابی برای انجام عملیات ریاضی پایه بر روی اعداد استفاده می‌شوند.

عملگر نام مثال نتیجه
= انتساب x = 5; x = 5
+ جمع a + b مجموع a و b
- تفریق a - b تفاضل a و b
* ضرب a * b حاصل ضرب a و b
/ تقسیم a / b خارج قسمت a بر b
% باقی‌مانده a % b باقی‌مانده تقسیم a بر b
int a = 10;
int b = 3;

int sum = a + b;      // 13
int diff = a - b;      // 7
int mult = a * b;      // 30
float div = (float)a / b;  // 3.33
int mod = a % b;       // 1 (باقی‌مانده ۱۰ تقسیم بر ۳)

۳-۲ عملگرهای مقایسه‌ای

عملگرهای مقایسه‌ای برای مقایسه‌ی دو مقدار و تعیین رابطه‌ی بین آن‌ها استفاده می‌شوند. نتیجه‌ی این عملگرها یک مقدار بولی (true یا false) است.

عملگر نام مثال
== مساوی x == y
!= نامساوی x != y
> بزرگ‌تر x > y
< کوچک‌تر x < y
>= بزرگ‌تر یا مساوی x >= y
<= کوچک‌تر یا مساوی x <= y
if (sensorValue > 500) {
    // اگر sensorValue بزرگتر از ۵۰۰ باشد
    digitalWrite(ledPin, HIGH);
} else {
    digitalWrite(ledPin, LOW);
}

۳-۳ عملگرهای منطقی و بیتی

عملگرهای منطقی (بولی)

عملگرهای منطقی برای ترکیب چند شرط و ایجاد عبارات شرطی پیچیده‌تر استفاده می‌شوند.

&& (AND)
|| (OR)
! (NOT)
if (temp > 30 && humidity > 70) {
    // اگر دما بیشتر از ۳۰ و رطوبت بیشتر از ۷۰ باشد
    digitalWrite(fanPin, HIGH);
}

if (buttonState == LOW || motionDetected == HIGH) {
    // اگر کلید فشرده شده یا حرکت تشخیص داده شده
    digitalWrite(lightPin, HIGH);
}

if (!doorOpen) {
    // اگر درب باز نباشد
    digitalWrite(lockPin, HIGH);
}

عملگرهای بیتی

عملگرهای بیتی برای انجام عملیات در سطح بیت بر روی اعداد صحیح استفاده می‌شوند.

& AND بیتی
| OR بیتی
^ XOR بیتی
~ NOT بیتی
<< شیفت چپ
>> شیفت راست
byte a = 0b1010;  // ۱۰ در دسیمال
byte b = 0b1100;  // ۱۲ در دسیمال

byte result = a & b;  // 0b1000 (۸)
result = a | b;         // 0b1110 (۱۴)
result = a ^ b;         // 0b0110 (۶)
result = a << 1;       // 0b10100 (۲۰)
result = a >> 1;       // 0b0101 (۵)

۳-۴ عملگرهای مرکب و افزایشی

عملگرهای مرکب

عملگرهای مرکب، یک عملیات حسابی یا بیتی را با عمل انتساب ترکیب می‌کنند و دستور را مختصرتر می‌سازند.

+=
-=
*=
/=
%=
&=
|=
^=
int x = 5;
x += 3;  // معادل x = x + 3  → x = 8
x -= 2;  // معادل x = x - 2  → x = 6
x *= 4;  // معادل x = x * 4  → x = 24
x /= 3;  // معادل x = x / 3  → x = 8

عملگرهای افزایشی و کاهشی

این عملگرها برای افزایش یا کاهش یک واحد از مقدار متغیر استفاده می‌شوند.

++ (افزایش یک واحد)
-- (کاهش یک واحد)
int count = 0;

void loop() {
    count++;            // افزایش یک واحد (پس‌افزایش)
    Serial.println(count);
    
    if (count > 10) {
        count = 0;   // بازنشانی
    }
    delay(1000);
}

۳-۵ توابع تبدیل نوع داده

توابع تبدیل نوع داده برای تغییر نوع یک مقدار از یک نوع داده به نوع دیگر به کار می‌روند.

تابع توضیح مثال
char(x) تبدیل به کاراکتر char(65) = 'A'
byte(x) تبدیل به بایت byte(255) = 255
int(x) تبدیل به عدد صحیح int(3.14) = 3
float(x) تبدیل به عدد اعشاری float(10) = 10.0
long(x) تبدیل به عدد صحیح بزرگ long(123456789)
word(x) تبدیل به word word(65535)
float temperature = 25.7;
int tempInt = int(temperature);          // ۲۵
byte tempByte = byte(temperature);          // ۲۵

int sensorValue = analogRead(A0);        // ۰ تا ۱۰۲۳
float voltage = sensorValue * (5.0 / 1023.0);  // تبدیل به ولتاژ

نکته: تبدیل نوع داده به از دست رفتن دقت یا تغییر مقدار منجر می‌شود. مثلاً float به int تبدیل شود، بخش اعشاری حذف می‌شود.

۳-۶ توابع ریاضی

توابع ریاضی برای انجام محاسبات پیشرفته‌تر در پروژه‌های علمی و مهندسی کاربرد دارند.

تابع توضیح مثال
abs(x) قدر مطلق abs(-5) = 5
constrain(x, a, b) محدود کردن مقدار در بازه constrain(15, 10, 20) = 15
map(value, fL, fH, tL, tH) نگاشت از بازه‌ای به بازه‌ی دیگر map(512, 0, 1023, 0, 255) = 127
max(x, y) بیشینه max(5, 10) = 10
min(x, y) کمینه min(5, 10) = 5
pow(base, exp) توان pow(2, 3) = 8
sqrt(x) جذر sqrt(9) = 3
sq(x) مربع sq(4) = 16
random(max) عدد تصادفی ۰ تا max-1 random(100)
random(min, max) عدد تصادفی min تا max-1 random(10, 20)
// تبدیل محدوده سنسور به PWM
int sensorValue = analogRead(A0);  // ۰ تا ۱۰۲۳
int brightness = map(sensorValue, 0, 1023, 0, 255);
analogWrite(ledPin, brightness);

// محدود کردن مقدار
int constrainedValue = constrain(sensorValue, 100, 900);

// تولید اعداد تصادفی
int randomNumber = random(10, 50);  // عدد تصادفی بین ۱۰ تا ۴۹

۳-۷ توابع زمانی

توابع زمانی برای ایجاد تأخیر و اندازه‌گیری زمان سپری‌شده استفاده می‌شوند.

تابع توضیح مثال
delay(ms) تاخیر به میلی‌ثانیه delay(1000)
delayMicroseconds(us) تاخیر به میکروثانیه delayMicroseconds(100)
millis() زمان سپری‌شده از شروع (میلی‌ثانیه) millis()
micros() زمان سپری‌شده از شروع (میکروثانیه) micros()
// تأخیر ساده
digitalWrite(ledPin, HIGH);
delay(1000);              // ۱ ثانیه صبر کن
digitalWrite(ledPin, LOW);
delay(1000);

// اندازه‌گیری زمان سپری‌شده بدون توقف برنامه
unsigned long previousMillis = 0;
unsigned long interval = 1000;

void loop() {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis;
        // کدی که هر ۱ ثانیه اجرا می‌شود
        digitalWrite(ledPin, !digitalRead(ledPin));
    }
}

نکته مهم: استفاده از millis() به جای delay() باعث می‌شود برنامه همزمان بتواند کارهای دیگر را نیز انجام دهد.

۳-۸ مثال‌های عملی

مثال ۱: تبدیل سنسور آنالوگ به ولتاژ

int sensorPin = A0;
float voltage;

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

void loop() {
    int sensorValue = analogRead(sensorPin);
    voltage = sensorValue * (5.0 / 1023.0);  // تبدیل به ولتاژ
    
    Serial.print("Voltage: ");
    Serial.println(voltage);
    
    delay(500);
}

مثال ۲: کنترل LED با map و constrain

int sensorPin = A0;
int ledPin = 9;  // پایه PWM

void setup() {
    pinMode(ledPin, OUTPUT);
}

void loop() {
    int sensorValue = analogRead(sensorPin);
    
    // محدود کردن محدوده سنسور
    int constrainedValue = constrain(sensorValue, 100, 900);
    
    // تبدیل محدوده ۱۰۰-۹۰۰ به ۰-۲۵۵ برای PWM
    int brightness = map(constrainedValue, 100, 900, 0, 255);
    
    analogWrite(ledPin, brightness);
}

مثال ۳: تولید اعداد تصادفی برای LED

int ledPin = 9;

void setup() {
    pinMode(ledPin, OUTPUT);
    randomSeed(analogRead(A0));  // اولیه‌سازی مولد اعداد تصادفی
}

void loop() {
    int randomValue = random(0, 256);  // عدد تصادفی ۰ تا ۲۵۵
    analogWrite(ledPin, randomValue);
    
    delay(200);
}

تمرین: برنامه‌ای بنویسید که با استفاده از millis() یک LED را هر ۲ ثانیه بدون استفاده از delay() چشمک بزند.

خلاصه بخش سوم

عملگرهای حسابی

+ - * / %

عملگرهای مقایسه‌ای

== != > < >= <=

عملگرهای منطقی و بیتی

&& || ! & | ^ ~

توابع تبدیل

char, byte, int, float, long

توابع ریاضی

abs, map, constrain, random, pow

توابع زمانی

delay, millis, micros

بخش قبلی: ساختارهای کنترلی بخش ۳ از ۴ بخش بعدی: ورودی/خروجی و ارتباطات
#توابع_آردوینو #عملگرهای_آردوینو #عملگرهای_حسابی #توابع_ریاضی_آردوینو #توابع_زمانی_آردوینو #برنامه_نویسی_آردوینو