يمكنك استخدام الأسهم (يسار/يمين) في لوحة المفاتيح للتنقل

الوحدة الثالثة: قراءة وكتابة منافذ Arduino

في هذه الوحدة سنتعلم كيفية قراءة الإشارات القادمة إلى Arduino، والتحكم في المخرجات، ومراقبة القيم أثناء تشغيل البرنامج.

أهداف الوحدة

بنهاية الوحدة، يُتوقع القدرة على:

  • استخدام Serial Monitor لمراقبة البرنامج.
  • استخدام المنافذ الرقمية كمدخلات ومخرجات.
  • استخدام digitalRead() و digitalWrite().
  • توصيل Pushbutton باستخدام INPUT و INPUT_PULLUP.
  • قراءة قيمة تناظرية باستخدام analogRead().
  • استخدام PWM بواسطة analogWrite().
  • ربط المدخلات بالمخرجات في تطبيق واحد.
  • استخدام Serial Monitor للمساعدة في اكتشاف الأخطاء.
العمليات الأساسية على المنافذ

نتعامل مع منافذ Arduino بأربع عمليات أساسية:

Digital Input قراءة HIGH أو LOW.

Digital Output إخراج HIGH أو LOW.

Analog Input قراءة قيمة من 0 إلى 1023.

PWM Output إخراج قيمة من 0 إلى 255.

خلال الوحدة سنستخدم Serial Monitor لمشاهدة القراءات أثناء تشغيل البرنامج.

ما هو Serial Monitor؟

Serial Monitor أداة داخل Arduino IDE تعرض البيانات التي يرسلها Arduino إلى الكمبيوتر عبر USB.

نستخدمها من أجل:

  • مشاهدة قراءات المنافذ.
  • متابعة تغير القيم.
  • التأكد من عمل الدائرة.
  • تتبع البرنامج أثناء التشغيل.
  • المساعدة في اكتشاف الأخطاء.
لقطة Arduino IDE مع إبراز Serial Monitor وظهور نصوص وقيم داخله
مثال 1 — إرسال بيانات إلى Serial Monitor

نبدأ الاتصال داخل setup():

Serial.begin(9600);

ونرسل البيانات باستخدام:

Serial.print();
Serial.println();

مثال:

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

void loop()
{
    Serial.println("Arduino is running");

    delay(1000);
}

يجب أن تكون سرعة Serial Monitor:

9600 baud
تدريب عملي 1

شغّل المثال السابق وافتح Serial Monitor.

المطلوب:

  • غيّر النص إلى:
Hello Arduino
  • اجعل النص يظهر كل نصف ثانية.
OUTPUT و digitalWrite()

عندما نريد من Arduino إرسال إشارة من المنفذ نهيئ المنفذ كـ:

pinMode(8, OUTPUT);

ثم نستخدم:

digitalWrite();

عند كتابة:

digitalWrite(8, HIGH);

يعطي المنفذ مستوى مرتفعًا يقارب:

5V

أما:

digitalWrite(8, LOW);

فيعطي مستوى منخفضًا يقارب:

0V

بشكل مبسط:

OUTPUT + HIGH → Arduino يرسل HIGH
OUTPUT + LOW  → Arduino يرسل LOW
مثال 2 — التحكم في LED

التوصيل:

D8 → مقاومة 220Ω → LED → GND

الكود:

const int ledPin = 8;

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

void loop()
{
    digitalWrite(ledPin, HIGH);
    delay(1000);

    digitalWrite(ledPin, LOW);
    delay(1000);
}

النتيجة:

HIGH → LED تعمل
LOW  → LED تنطفئ
دائرة Arduino UNO توضح D8 متصلًا بمقاومة 220 أوم ثم LED ثم GND
INPUT و digitalRead()

عندما نريد من Arduino قراءة إشارة قادمة إلى المنفذ نستخدم:

pinMode(2, INPUT);

في وضع INPUT لا يخرج Arduino جهدًا من المنفذ، بل يقرأ المستوى الكهربائي الموجود عليه.

نستخدم:

digitalRead(2);

والنتيجة تكون:

HIGH → 1
LOW  → 0

الفرق الأساسي:

OUTPUT → Arduino يرسل إشارة
INPUT  → Arduino يستقبل ويقرأ إشارة
مثال 3 — تجربة digitalRead()

نقرأ المنفذ D2 ونعرض النتيجة في Serial Monitor:

const int inputPin = 2;

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

    pinMode(inputPin, INPUT);
}

void loop()
{
    int value = digitalRead(inputPin);

    Serial.println(value);

    delay(100);
}

جرّب:

D2 → 5V

النتيجة:

HIGH → 1

ثم:

D2 → GND

النتيجة:

LOW → 0
D2 متصل بـ5V — القراءة 1
D2 → 5V · القراءة: HIGH (1)
D2 متصل بـGND — القراءة 0
D2 → GND · القراءة: LOW (0)
توصيل الزر باستخدام مقاومة Pull-up

نريد أن تكون قراءة الزر:

غير مضغوط → HIGH
مضغوط     → LOW

نستخدم مقاومة:

10kΩ

التوصيل:

5V → مقاومة 10kΩ → D2
                    |
                   زر
                    |
                   GND

تسمى هذه المقاومة:

Pull-up Resistor

دائرة Arduino UNO على Breadboard: 5V إلى مقاومة 10kΩ، والطرف الآخر للمقاومة متصل بالنقطة نفسها مع D2 وطرف الزر، والطرف الآخر للزر إلى GND
كيف تعمل دائرة Pull-up؟

عندما يكون الزر غير مضغوط

يصل D2 إلى 5V عبر المقاومة:

5V → 10kΩ → D2

فتكون القراءة:

HIGH

عندما نضغط الزر

يتصل D2 مع GND:

D2 → Button → GND

فتصبح القراءة:

LOW

إذن:

Released → HIGH
Pressed  → LOW

المقاومة أيضًا تمنع وجود اتصال مباشر بين 5V و GND عند الضغط.

مثال 4 — قراءة Pushbutton باستخدام INPUT
const int buttonPin = 2;

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

    pinMode(buttonPin, INPUT);
}

void loop()
{
    int buttonState = digitalRead(buttonPin);

    if (buttonState == LOW)
    {
        Serial.println("Pressed");
    }
    else
    {
        Serial.println("Released");
    }

    delay(100);
}

النتيجة:

Released → HIGH
Pressed  → LOW
ما هو INPUT_PULLUP؟

في المثال السابق استخدمنا مقاومة Pull-up خارجية بقيمة 10kΩ.

Arduino يحتوي على مقاومة Pull-up داخلية يمكن تشغيلها برمجيًا:

pinMode(2, INPUT_PULLUP);

عند استخدامها نحذف المقاومة الخارجية.

التوصيل يصبح:

D2 → Pushbutton → GND

وتبقى القراءة:

Released → HIGH
Pressed  → LOW
رسم Arduino UNO يوضح مقاومة Pull-up داخلية من 5V إلى D2، وخارج اللوحة زر فقط بين D2 وGND
INPUT أم INPUT_PULLUP؟

INPUT مع Pull-up خارجية

pinMode(2, INPUT);

التوصيل:

5V → 10kΩ → D2
             |
            زر
             |
            GND

INPUT_PULLUP

pinMode(2, INPUT_PULLUP);

التوصيل:

D2 → زر → GND

في الحالتين:

Released → HIGH
Pressed  → LOW

الفرق:

INPUT
→ مقاومة Pull-up خارج Arduino

INPUT_PULLUP
→ مقاومة Pull-up داخل Arduino
مثال 5 — زر يتحكم في LED

التوصيل:

Pushbutton:
D2 → Button → GND

LED:
D8 → 220Ω → LED → GND

الكود:

const int buttonPin = 2;
const int ledPin = 8;

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

void loop()
{
    if (digitalRead(buttonPin) == LOW)
    {
        digitalWrite(ledPin, HIGH);
    }
    else
    {
        digitalWrite(ledPin, LOW);
    }
}

النتيجة:

ضغط الزر → LED تعمل
ترك الزر → LED تنطفئ
دائرة Arduino UNO متصلة بزر على D2 وLED مع مقاومة 220Ω على D8
مثال 6 — ضغطة تشغيل وضغطة إطفاء

أحيانًا نريد أن تنفذ كل ضغطة أمرًا واحدًا فقط:

الضغطة الأولى  → ON
الضغطة الثانية → OFF
الضغطة الثالثة → ON

نستخدم متغيرًا لحفظ الحالة:

bool ledState = false;

وعند الضغط:

ledState = !ledState;

الكود:

const int buttonPin = 2;
const int ledPin = 8;

bool ledState = false;

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

void loop()
{
    if (digitalRead(buttonPin) == LOW)
    {
        delay(30);

        if (digitalRead(buttonPin) == LOW)
        {
            ledState = !ledState;

            digitalWrite(ledPin, ledState);

            while (digitalRead(buttonPin) == LOW)
            {
            }

            delay(30);
        }
    }
}

في هذا المثال:

delay(30)
→ يعطي الزر وقتًا للاستقرار

while()
→ ينتظر حتى يترك المستخدم الزر
تدريب عملي 2

استخدم زرًا وLEDين.

المطلوب:

في البداية:

LED 1 → ON
LED 2 → OFF

عند كل ضغطة على الزر تتبدل الحالتان:

الضغطة الأولى:
LED 1 → OFF
LED 2 → ON
الضغطة الثانية:
LED 1 → ON
LED 2 → OFF

استخدم:

INPUT_PULLUP

وانتظر تحرير الزر قبل قبول ضغطة جديدة.

ما هو Analog Input؟

المدخل الرقمي يقرأ حالتين:

HIGH أو LOW

أما المدخل التناظري فيقرأ مستوى جهد متغير.

في Arduino UNO توجد المنافذ:

A0 → A5

ونستخدم:

analogRead(pin);

وتكون القراءة:

0 → 1023

تقريبًا:

0V → 0
5V → 1023
Potentiometer

Potentiometer مقاومة متغيرة لها ثلاثة أطراف.

يمكن استخدامها لإنتاج جهد متغير يقرأه Arduino.

التوصيل:

الطرف الأول   → 5V
الطرف الأوسط → A0
الطرف الثالث → GND

عند تدوير Potentiometer يتغير الجهد على A0.

رسم Potentiometer بثلاثة أطراف متصل بـArduino UNO: طرف إلى 5V، والطرف الأوسط إلى A0، والطرف الثالث إلى GND
مثال 7 — قراءة Potentiometer
const int potPin = A0;

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

    pinMode(potPin, INPUT);
}

void loop()
{
    int value = analogRead(potPin);

    Serial.println(value);

    delay(100);
}

أدر Potentiometer ولاحظ تغير القراءة:

0 → 1023

في Serial Monitor.

تدريب عملي 3 — تحويل القراءة إلى نتيجة واضحة

استخدم:

  • Potentiometer على A0.
  • LED حمراء.
  • LED خضراء.
  • LED زرقاء.

المطلوب:

0 إلى 340
→ LED الحمراء تعمل
341 إلى 680
→ LED الخضراء تعمل
681 إلى 1023
→ LED الزرقاء تعمل

يجب أن تعمل LED واحدة فقط في كل مرة.

اعرض قيمة Potentiometer أيضًا في Serial Monitor.

ما هو PWM؟

Arduino UNO يستطيع قراءة جهد تناظري باستخدام:

analogRead();

لأنه يحتوي على:

ADC — Analog to Digital Converter

لكن Arduino UNO لا يحتوي على DAC لإنتاج جهد تناظري حقيقي من المنافذ العادية.

لذلك يستخدم تقنية:

PWM — Pulse Width Modulation

في PWM يتغير المنفذ بسرعة بين:

0V و 5V

كلما بقي المنفذ في حالة HIGH مدة أطول، زاد التأثير المتوسط.

مثال:

PWM منخفض → LED خافتة
PWM مرتفع → LED أكثر سطوعًا

نستخدم:

analogWrite(pin, value);

والقيمة تكون:

0 → 255

منافذ PWM في Arduino UNO:

3, 5, 6, 9, 10, 11
إشارات PWM بنسبة تشغيل 25% و50% و75% مع درجات سطوع LED
مثال 8 — تغيير سطوع LED

التوصيل:

D9 → مقاومة 220Ω → LED → GND

الكود:

const int ledPin = 9;

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

void loop()
{
    analogWrite(ledPin, 64);
    delay(1000);

    analogWrite(ledPin, 128);
    delay(1000);

    analogWrite(ledPin, 192);
    delay(1000);

    analogWrite(ledPin, 255);
    delay(1000);

    analogWrite(ledPin, 0);
    delay(1000);
}

لاحظ تغير سطوع LED مع تغير قيمة PWM.

دائرة Arduino UNO من D9 إلى مقاومة 220Ω ثم LED ثم GND، مع عرض عدة درجات لسطوع LED
مثال 9 — Potentiometer يتحكم في سطوع LED

analogRead() تعطينا:

0 → 1023

بينما analogWrite() تستخدم:

0 → 255

نحوّل القيمة باستخدام:

pwmValue = potValue / 4;

الكود:

const int potPin = A0;
const int ledPin = 9;

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

    pinMode(potPin, INPUT);
    pinMode(ledPin, OUTPUT);
}

void loop()
{
    int potValue = analogRead(potPin);

    int pwmValue = potValue / 4;

    analogWrite(ledPin, pwmValue);

    Serial.print("Analog = ");
    Serial.print(potValue);

    Serial.print("   PWM = ");
    Serial.println(pwmValue);

    delay(50);
}

النتيجة:

تدوير Potentiometer
        ↓
تتغير analogRead()
        ↓
تتغير قيمة PWM
        ↓
يتغير سطوع LED
دائرة Arduino UNO متصلة بـPotentiometer على A0 وLED مع مقاومة 220Ω على D9، مع Serial Monitor يعرض Analog وPWM
تدريب عملي 4 — نظام تفاعلي مصغر

استخدم:

  • Potentiometer.
  • Pushbutton على D12.
  • LED على منفذ PWM.

المطلوب:

عندما يكون النظام في حالة:

ON

يتحكم Potentiometer في سطوع LED.

كل ضغطة على الزر تغير حالة النظام:

الضغطة الأولى  → OFF
الضغطة الثانية → ON
الضغطة الثالثة → OFF
...

عندما تكون الحالة:

OFF

تبقى LED مطفأة مهما كانت قيمة Potentiometer.

استخدم الزر على المنفذ D12 مع:

INPUT_PULLUP

وانتظر تحرير الزر باستخدام:

while()

اعرض في Serial Monitor مثلًا:

Analog = 700
PWM = 175
LED = ON

أو:

Analog = 700
PWM = 0
LED = OFF
مراجعة الوحدة

تعلمنا في هذه الوحدة:

  • استخدام Serial Monitor.
  • OUTPUT و digitalWrite().
  • INPUT و digitalRead().
  • استخدام مقاومة Pull-up خارجية.
  • استخدام INPUT_PULLUP.
  • التعامل مع Pushbutton.
  • تنفيذ أمر مرة واحدة لكل ضغطة.
  • قراءة قيمة تناظرية باستخدام analogRead().
  • التعامل مع Potentiometer.
  • مفهوم PWM.
  • استخدام analogWrite().
  • ربط Analog Input مع PWM Output.

في الوحدة القادمة سنتعلم كيف نستخدم هذه الأساسيات للتعامل مع مكونات وحساسات مختلفة، وكيف نستفيد من المكتبات البرمجية والأمثلة الجاهزة.

100%
الصورة المكبّرة