مسميات المكونات في Tinkercad

قد تختلف أسماء بعض المكونات في Tinkercad عن الأسماء المستخدمة في الوحدة.

استخدم الجدول التالي عند البحث عن المكوّن داخل المحاكي:

الاسم في Tinkercadالاسم المستخدم في الوحدة
Soil Moisture SensorWater Level Detection Sensor
PiezoPassive Buzzer
Micro ServoServo Motor
Tilt SensorTilt Ball Switch
PIR Motion SensorHC-SR501 PIR Motion Sensor
PhotoresistorPhotoresistor / LDR
Keyboard 4x4Membrane Keypad

لماذا بعض المكونات ليست مطابقة تمامًا؟

لأن Tinkercad لا يوفر دائمًا نفس القطعة المستخدمة في هذه الوحدة، لذلك نستخدم مكوّنًا يؤدي وظيفة مشابهة أو يعتمد على نفس الفكرة البرمجية.

مثال على ذلك:

  • Soil Moisture Sensor ليس هو نفسه Water Level Detection Sensor، لكنه يعطي قيمة تناظرية متغيرة ويمكن قراءته باستخدام analogRead().
  • Piezo في Tinkercad يستخدم لتوليد النغمات، وهو مناسب لتطبيقات Passive Buzzer.
  • أما Micro Servo وTilt Sensor وPIR Motion Sensor وPhotoresistor فهي قريبة جدًا من المكونات المستخدمة في الوحدة من حيث الوظيفة وطريقة البرمجة.

الوحدة الرابعة

التعامل مع الحساسات والوحدات والمكتبات البرمجية

في هذه الوحدة سنتعامل مع مجموعة من الحساسات والوحدات المختلفة، ونطبق عليها عمليات القراءة والكتابة التي تعلمناها سابقًا.

ثم نتعلم كيفية إضافة المكتبات البرمجية واستخدامها مع المكونات التي تحتاج إليها.

مجموعة من مكونات الوحدة، تشمل لوحة مفاتيح 4x4 وحساس الحركة والمقاومة الضوئية وحساس المسافة ومفتاح الميل وحساس رطوبة التربة
أهداف الوحدة

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

  • تحديد ما إذا كان المكوّن Input أو Output.
  • تحديد ما إذا كانت الإشارة Digital أو Analog.
  • اختيار الدالة المناسبة للتعامل مع المكوّن.
  • قراءة قيم مجموعة من الحساسات.
  • التحكم في مجموعة من وحدات الإخراج.
  • إضافة مكتبة برمجية إلى بيئة تطوير أردوينو.
  • استدعاء مكتبة داخل البرنامج.
  • استخدام الأمثلة الجاهزة للمكتبات.
  • استخدام مكونات تحتاج إلى مكتبات برمجية.
ما الذي سنطبقه؟

تعلمنا في الوحدة السابقة أربع عمليات أساسية:

ما الذي سنطبقه؟ — مخطط 1Digital Input ↓ digitalRead()Digital InputdigitalRead()
ما الذي سنطبقه؟ — مخطط 2Digital Output ↓ digitalWrite()Digital OutputdigitalWrite()
ما الذي سنطبقه؟ — مخطط 3Analog Input ↓ analogRead()Analog InputanalogRead()
ما الذي سنطبقه؟ — مخطط 4PWM Output ↓ analogWrite()PWM OutputanalogWrite()

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

كيف أتعامل مع مكوّن جديد؟

قبل كتابة الكود، اسأل:

كيف أتعامل مع مكوّن جديد؟ — مخطط 1ما وظيفة المكوّن؟ ↓ هل هو Input أم Output؟ ↓ هل يتعامل مع Digital أم Analog؟ ↓ ما أطرافه؟ ↓ ما جهد تشغيله؟ ↓ ما الدالة المناسبة؟ ↓ هل يحتاج إلى مكتبة برمجية؟ما وظيفة المكوّن؟هل هو Input أم Output؟هل يتعامل مع Digital أم Analog؟ما أطرافه؟ما جهد تشغيله؟ما الدالة المناسبة؟هل يحتاج إلى مكتبة برمجية؟

أولًا: مكونات لا تحتاج إلى مكتبات برمجية

Tilt Ball Switch

Tilt Ball Switch مفتاح تتغير حالته عند تغيير اتجاهه أو إمالته.

يعطي حالتين فقط:

HIGH
أو
LOW

لذلك نتعامل معه كـ:

Tilt Ball Switch — مخطط 2Digital Input ↓ digitalRead()Digital InputdigitalRead()
Tilt Ball Switch موصل بين D2 وGND لاستخدام INPUT_PULLUP
مثال 1 — قراءة Tilt Ball Switch

التوصيل:

مثال 1 — قراءة Tilt Ball Switch — مخطط 1D2 ↓ Tilt Switch ↓ GNDD2Tilt SwitchGND

يوصل أحد طرفي Tilt Switch بالمنفذ D2 والطرف الآخر بـ GND.

الكود:

const int tiltPin = 2;

void setup()
{
    pinMode(tiltPin, INPUT_PULLUP);
    Serial.begin(9600);
}

void loop()
{
    int state = digitalRead(tiltPin);

    Serial.println(state);

    delay(200);
}

غيّر اتجاه الحساس ولاحظ تغير القراءة في Serial Monitor.

حساس الحركة PIR

الحساس:

HC-SR501 PIR Motion Sensor

يستخدم لاكتشاف الحركة.

أهم طرف للإشارة هو:

OUT

وتكون حالته:

حساس الحركة PIR — مخطط 3HIGH → تم اكتشاف حركة LOW → لم يتم اكتشاف حركةHIGHتم اكتشافحركةLOWلم يتماكتشاف حركة

إذن نستخدم:

حساس الحركة PIR — مخطط 4Digital Input ↓ digitalRead()Digital InputdigitalRead()
حساس حركة PIR متصل بأردوينو مع لمبة خارجية
مثال 2 — اكتشاف الحركة

التوصيل:

مثال 2 — اكتشاف الحركة — مخطط 1VCC → 5V OUT → D2 GND → GNDVCC5VOUTD2GNDGND

الكود:

const int pirPin = 2;

void setup()
{
    pinMode(pirPin, INPUT);
    pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
    int motion = digitalRead(pirPin);

    if (motion == HIGH)
    {
        digitalWrite(LED_BUILTIN, HIGH);
    }
    else
    {
        digitalWrite(LED_BUILTIN, LOW);
    }
}

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

Photoresistor

Photoresistor أو المقاومة الضوئية تتغير مقاومتها حسب شدة الضوء.

نريد الحصول على قيمة تتغير حسب الإضاءة:

Photoresistor — مخطط 1شدة الضوء ↓ قيمة متغيرة ↓ Analog Input ↓ analogRead()شدة الضوءقيمة متغيرةAnalog InputanalogRead()

نستخدم Photoresistor مع مقاومة 10kΩ لتكوين دائرة Voltage Divider بين 5V وGND.

يقرأ A0 الجهد المتغير عند نقطة التقاء Photoresistor مع المقاومة.

دائرة Voltage Divider بمقاومة ضوئية ومقاومة 10kΩ، مع توصيل نقطة الالتقاء إلى A0
مثال 3 — قراءة شدة الضوء

التوصيل:

مثال 3 — قراءة شدة الضوء — مخطط التوصيل5V ↓ Photoresistor ↓ نقطة القراءة إلى A0 ↓ مقاومة 10kΩ ↓ GND5VPhotoresistorنقطة القراءة إلى A0مقاومة 10kΩGND

يقرأ A0 الجهد المتغير عند نقطة التقاء Photoresistor مع المقاومة.

الكود:

const int lightPin = A0;

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

void loop()
{
    int lightValue = analogRead(lightPin);

    Serial.println(lightValue);

    delay(200);
}

جرّب:

  • تغطية Photoresistor.
  • تعريضه لضوء أقوى.

ثم راقب تغير القراءة.

حساس مستوى الماء

Water Level Detection Sensor يستخدم لاكتشاف وجود الماء أو تغير مستواه.

يعطي قيمة تتغير حسب مقدار ملامسة الماء للحساس.

لذلك يمكن قراءته باستخدام:

حساس مستوى الماء — مخطط 1Analog Input ↓ analogRead()Analog InputanalogRead()

وتكون القراءة في أردوينو UNO ضمن المجال:

حساس مستوى الماء — مخطط 20 → 102301023
Soil Moisture Sensor في Tinkercad موصل إلى 5V وGND وA0

الصورة تستخدم Soil Moisture Sensor في Tinkercad بديلًا تعليميًا لحساس مستوى الماء، كما توضّح شريحة التسميات.

مثال 4 — قراءة حساس مستوى الماء

التوصيل:

مثال 4 — قراءة حساس مستوى الماء — مخطط 1S → A0 + → 5V - → GNDSA0+5V-GND

الكود:

const int waterPin = A0;

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

void loop()
{
    int waterValue = analogRead(waterPin);

    Serial.println(waterValue);

    delay(200);
}

راقب تغير القراءة عند تغير مقدار ملامسة الماء للحساس.

Passive Buzzer

يمكننا باستخدام Passive Buzzer تحديد تردد الصوت.

نستخدم:

tone();

ولإيقاف الصوت:

noTone();

ولا نحتاج إلى مكتبة برمجية خارجية.

مثال 5 — تشغيل عدة نغمات

في هذا المثال نستخدم Piezo ذا طرفين.

التوصيل:

مثال 5 — تشغيل عدة نغمات — مخطط التوصيل+ → D8 - → GND+D8-GND
Piezo ذو طرفين، الطرف الموجب إلى D8 والطرف السالب إلى GND

سنكتب ترددات النغمات مباشرة داخل البرنامج.

const int buzzerPin = 8;

int melody[] = {
    523, 587, 659, 698,
    784, 880, 988, 1047
};

void setup()
{
}

void loop()
{
    for (int i = 0; i < 8; i++)
    {
        tone(buzzerPin, melody[i], 500);
        delay(700);
    }

    noTone(buzzerPin);

    delay(2000);
}

القيم مثل:

523
587
659

تمثل ترددات صوتية بوحدة Hertz.

Ultrasonic Sensor Module

الحساس:

HC-SR04

يستخدم لقياس المسافة.

يحتوي على طرفين مهمين:

Trig
Echo

وظيفتهما:

Ultrasonic Sensor Module — مخطط 3Trig → Digital Output من أردوينوTrigDigital Output من أردوينو
Ultrasonic Sensor Module — مخطط 4Echo → Digital Input إلى أردوينوEchoDigital Input إلى أردوينو

Trig = Digital Output، وEcho = Digital Input.

إذن الحساس يستخدم:

Ultrasonic Sensor Module — مخطط 5Digital Output + Digital InputDigital Output+Digital Input
رسم توضيحي لحساس HC-SR04 موصل بأردوينو

أرقام المنافذ في الصورة مختلفة؛ التوصيل المعتمد في مثالي الوحدة هو Trig → D9 وEcho → D10، مع VCC → 5V وGND → GND.

كيف يقيس Ultrasonic المسافة؟

يرسل أردوينو نبضة قصيرة إلى:

Trig

ثم يرسل الحساس موجة صوتية.

عندما ترتد الموجة من جسم، تظهر نبضة على:

Echo

نقيس زمن عودة الموجة:

كيف يقيس Ultrasonic المسافة؟ — مخطط 3إرسال نبضة ↓ خروج الموجة ↓ ارتدادها من الجسم ↓ قياس الزمن ↓ حساب المسافةإرسال نبضةخروج الموجةارتدادها من الجسمقياس الزمنحساب المسافة
مثال 6 — قياس المسافة بدون مكتبة

التوصيل:

مثال 6 — قياس المسافة بدون مكتبة — مخطط 1VCC → 5V Trig → D9 Echo → D10 GND → GNDVCC5VTrigD9EchoD10GNDGND

Trig = Digital Output، وEcho = Digital Input.

الكود:

const int trigPin = 9;
const int echoPin = 10;

void setup()
{
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);

    Serial.begin(9600);
}

void loop()
{
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);

    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);

    digitalWrite(trigPin, LOW);

    long duration = pulseIn(echoPin, HIGH);

    float distance = duration * 0.0343 / 2;

    Serial.println(distance);

    delay(200);
}
ماذا استخدمنا مع Ultrasonic؟

لإرسال النبضة:

digitalWrite();

لإنشاء تأخير صغير جدًا:

delayMicroseconds();

لقياس مدة نبضة Echo:

pulseIn();

ثم حسبنا المسافة بأنفسنا:

float distance = duration * 0.0343 / 2;

سنعود لاحقًا إلى الحساس نفسه بعد تعلم استخدام المكتبات البرمجية.

ثانيًا: التعامل مع المكتبات البرمجية

استخدام المكتبات البرمجية

تعرفنا سابقًا على مفهوم المكتبة البرمجية.

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

استخدام المكتبات البرمجية — مخطط 1إضافة المكتبة إلى بيئة تطوير أردوينو ↓ استدعائها داخل البرنامج ↓ استخدام الدوال التي توفرها ↓ الاستفادة من أمثلتها الجاهزةإضافة المكتبة إلى بيئة تطويرأردوينواستدعائها داخل البرنامجاستخدام الدوال التي توفرهاالاستفادة من أمثلتها الجاهزة

المكتبة تساعدنا على التعامل مع المكونات التي تحتاج إلى خطوات برمجية أكثر تعقيدًا.

استدعاء مكتبة في البرنامج

نستدعي المكتبة باستخدام:

#include <LibraryName.h>

مثال:

#include <Servo.h>

تكتب #include في بداية البرنامج، قبل:

void setup()

بعد ذلك يمكننا استخدام الدوال والأدوات التي توفرها المكتبة.

تثبيت مكتبة برمجية

يمكن تثبيت المكتبات باستخدام:

Library Manager

داخل بيئة تطوير أردوينو.

الخطوات:

  1. افتح Library Manager.
  2. ابحث عن اسم المكتبة.
  3. اختر المكتبة المطلوبة.
  4. اضغط Install.
  5. انتظر حتى يكتمل التثبيت.
Library Manager في بيئة تطوير أردوينو مع مربع البحث وزر Install
الأمثلة الجاهزة للمكتبات

بعد تثبيت المكتبة يمكن الوصول إلى أمثلتها من:

الأمثلة الجاهزة للمكتبات — مخطط 1File ↓ Examples ↓ اسم المكتبةFileExamplesاسم المكتبة

عند استخدام مكوّن جديد:

الأمثلة الجاهزة للمكتبات — مخطط 2افتح مثالًا بسيطًا ↓ شغّله كما هو ↓ تأكد أن المكوّن يعمل ↓ افهم أهم الدوال ↓ عدّل المثال تدريجيًاافتح مثالًا بسيطًاشغّله كما هوتأكد أن المكوّن يعملافهم أهم الدوالعدّل المثال تدريجيًا

ثالثًا: مكونات نستخدم معها مكتبات برمجية

Ultrasonic باستخدام مكتبة

تعاملنا سابقًا مع HC-SR04 بدون مكتبة.

كان علينا تنفيذ:

Ultrasonic باستخدام مكتبة — مخطط 1إرسال Trig ↓ قياس Echo ↓ حساب الزمن ↓ حساب المسافةإرسال Trigقياس Echoحساب الزمنحساب المسافة

يمكن استخدام مكتبة جاهزة لتنفيذ جزء كبير من هذه التفاصيل.

من المكتبات المستخدمة لهذا الغرض:

NewPing
مثال 7 — Ultrasonic باستخدام NewPing

التوصيل:

مثال 7 — Ultrasonic باستخدام NewPing — مخطط التوصيلVCC → 5V Trig → D9 Echo → D10 GND → GNDVCC5VTrigD9EchoD10GNDGND

Trig = Digital Output، وEcho = Digital Input.

نستدعي المكتبة:

#include <NewPing.h>

ثم:

const int trigPin = 9;
const int echoPin = 10;
const int maxDistance = 200;

NewPing sonar(trigPin, echoPin, maxDistance);

لقراءة المسافة:

int distance = sonar.ping_cm();

فتعطينا المكتبة المسافة بالسنتيمتر مباشرة.

الكود الكامل باستخدام NewPing

التوصيل:

الكود الكامل باستخدام NewPing — مخطط التوصيلVCC → 5V Trig → D9 Echo → D10 GND → GNDVCC5VTrigD9EchoD10GNDGND

Trig = Digital Output، وEcho = Digital Input.

#include <NewPing.h>

const int trigPin = 9;
const int echoPin = 10;
const int maxDistance = 200;

NewPing sonar(trigPin, echoPin, maxDistance);

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

void loop()
{
    int distance = sonar.ping_cm();

    Serial.println(distance);

    delay(200);
}

قارن هذا الكود بالمثال الذي كتبناه سابقًا بدون مكتبة.

بدون مكتبة أم باستخدام مكتبة؟

بدون مكتبة

نحن مسؤولون عن:

Trig
Echo
قياس الزمن
حساب المسافة

باستخدام المكتبة

يمكن أن نكتب:

sonar.ping_cm();

وتعيد لنا المسافة مباشرة.

المكتبة لا تغير طريقة عمل الحساس.

إنما تجعل التعامل البرمجي معه أسهل.

Servo Motor

محرك Servo يستطيع التحرك إلى زاوية محددة.

مثل:

0°
90°
180°

نستخدم مكتبة:

Servo

ونستدعيها:

#include <Servo.h>
Servo صغير موصل إلى D9 و5V وGND
مثال 8 — التحكم في Servo

يستخدم المثال Servo صغيرًا بدون حمل.

التوصيل:

مثال 8 — التحكم في Servo — مخطط 1Signal → D9 VCC → 5V GND → GNDSignalD9VCC5VGNDGND

الكود:

#include <Servo.h>

Servo myServo;

void setup()
{
    myServo.attach(9);
}

void loop()
{
    myServo.write(0);
    delay(1000);

    myServo.write(90);
    delay(1000);

    myServo.write(180);
    delay(1000);
}
أهم أوامر Servo

إنشاء Servo باسم:

Servo myServo;

ربطه بمنفذ أردوينو:

myServo.attach(9);

تحريكه إلى زاوية:

myServo.write(90);

بفضل المكتبة أصبح التحكم في Servo باستخدام أوامر بسيطة.

Membrane Keypad

لوحة المفاتيح الغشائية تحتوي مجموعة أزرار مرتبة على شكل:

Rows
صفوف

و:

Columns
أعمدة

يمكن برمجة قراءة الصفوف والأعمدة يدويًا، لكن الكود سيكون أطول.

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

Keypad

لتسهيل معرفة الزر الذي تم ضغطه.

إعداد Membrane Keypad

نستدعي المكتبة:

#include <Keypad.h>

ثم نحدد عدد الصفوف والأعمدة:

const byte rows = 4;
const byte cols = 4;

ونحدد شكل الأزرار:

char keys[rows][cols] =
{
    {'1','2','3','A'},
    {'4','5','6','B'},
    {'7','8','9','C'},
    {'*','0','#','D'}
};
مثال 9 — قراءة Membrane Keypad

التوصيل:

مثال 9 — قراءة Membrane Keypad — مخطط التوصيلR1 → D9 R2 → D8 R3 → D7 R4 → D6 C1 → D5 C2 → D4 C3 → D3 C4 → D2R1D9R2D8R3D7R4D6C1D5C2D4C3D3C4D2

ترتيب أطراف الصفوف والأعمدة قد يختلف حسب نوع الـKeypad المستخدم.

Membrane Keypad 4x4 موصل بمنافذ أردوينو D9 إلى D2

الكود الكامل:

#include <Keypad.h>

const byte rows = 4;
const byte cols = 4;

char keys[rows][cols] =
{
    {'1','2','3','A'},
    {'4','5','6','B'},
    {'7','8','9','C'},
    {'*','0','#','D'}
};

byte rowPins[rows] = {9, 8, 7, 6};
byte colPins[cols] = {5, 4, 3, 2};

Keypad keypad = Keypad(
    makeKeymap(keys),
    rowPins,
    colPins,
    rows,
    cols
);

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

void loop()
{
    char key = keypad.getKey();

    if (key)
    {
        Serial.println(key);
    }
}
كيف أتعامل مع أي مكوّن جديد؟

عند الحصول على مكوّن جديد:

كيف أتعامل مع أي مكوّن جديد؟ — مخطط 1افهم وظيفة المكوّن ↓ حدد أطرافه ↓ حدد Input أو Output ↓ حدد Digital أو Analog ↓ حدد الدالة المناسبة ↓ تحقق هل يحتاج إلى مكتبة ↓ افتح مثالًا جاهزًا عند الحاجة ↓ اختبر المكوّن منفردًا ↓ عدّل المثال ↓ ادمجه مع بقية المشروعافهم وظيفة المكوّنحدد أطرافهحدد Input أو Outputحدد Digital أو Analogحدد الدالة المناسبةتحقق هل يحتاج إلى مكتبةافتح مثالًا جاهزًا عند الحاجةاختبر المكوّن منفردًاعدّل المثالادمجه مع بقية المشروع
مراجعة الوحدة

تعاملنا مع مكونات بدون مكتبات برمجية:

  • Tilt Ball Switch.
  • PIR Motion Sensor.
  • Photoresistor.
  • Water Level Sensor.
  • Passive Buzzer.
  • Ultrasonic Sensor.

ثم تعلمنا:

  • استدعاء مكتبة باستخدام #include.
  • تثبيت المكتبات من Library Manager.
  • استخدام الأمثلة الجاهزة.

وتعاملنا باستخدام المكتبات مع:

  • Ultrasonic Sensor.
  • Servo Motor.
  • Membrane Keypad.

الهدف الأساسي من الوحدة:

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

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