البحث في الموقع
المحتوى عن 'دليل أردوينو'.
-
سنتعلم في هذا المقال كيفية بناء مشروع جديد من سلسلة دليل أردوينو والذي من خلاله سنتعرف على عناصر ومكونات إلكترونية جديدة وكيفية ربطها وتوصيلها مع لوحة الأردوينو أونو Arduino Uno لتنفيذ مشروع مفيد وظيفته قياس المسافة بين الحساس والحاجز الذي أمامه، ومن ثم عرضها على الشاشة بصيغة مناسبة، والذي يمكن استخدامه كمسطرة إلكترونية أو إضافته إلى أفكار عديدة، مثل استخدامه في أنظمة السيارات لمساعدة السائق على ركنها، أو تطبيقات الأبواب الذكية لفتحها وإغلاقها آليًا، أو قياس مستوى السوائل، وتطبيقات أخرى. العناصر المستخدمة لمشروع بناء مسطرة إلكترونية باستخدام الأردوينو Arduino سنستخدم مجموعة من العناصر الإلكترونية والأدوات وهي: لوحة أردوينو أونو Arduino Uno كابل البرمجة USB Cable لوحة توصيل التجارب Breadboard حساس الأمواج فوق الصوتية UltraSonic Sensor شاشة الكريستال السائلة Liquid Crystal Display مقاومة متغيرة Potentiometer مجموعة أسلاك توصيل من نوع Male to Male سنتعرف في البداية على العناصر الإلكترونية الجديدة المستخدمة في هذا المشروع، وهي حساس الأمواج فوق الصوتية UltraSonic Sensor وشاشة الكريستال السائلة Liquid Crystal Display، وسنتعلم طريقة ربط كل منها على حدة مع الأردوينو Arduino، ومن ثم سنربط جميع العناصر مع بعضها لتنفيذ فكرة مشروعنا. شاشة الكريستال السائلة Liquid Crystal Display تعرفنا في المشاريع السابقة مثل مشروع تخمين عدد مرات وميض الليد باستخدام الأردوينو Arduino على أدوات وعناصر إلكترونية استخدمناها لعرض البيانات مثل نافذة الاتصال التسلسلية Serial Monitor المدمجة مع بيئة الأردوينو المتكاملة Arduino IDE والتي تُعَد أداةً مفيدةً لعرض البيانات المرسلة من لوحة الأردوينو Arduino على شاشة الحاسوب والتواصل معه، ولكن في بعض المشاريع يتطلب الأمر أن يكون الجهاز الذي نريد تصميمه متنقلًا ومنفصلًا عن الحاسوب، وقد نحتاج لعرض البيانات وقيم الحساسات للمستخدم دون اتصال الأردوينو Arduino مع الحاسوب. في هذه الحالة، يأتي دور شاشات العرض مثل شاشة العرض ذات السبع أجزاء Seven Segment Display التي استخدمناها في مشروع لعبة تخمين الأرقام باستخدام الأردوينو Arduino ولكن تبقى هذه الشاشة محدودة لعرض الأرقام وبعض الأحرف فقط، ورغم بساطتها إلا أننا سنحتاج العديد من التوصيلات عند استخدام عدة خانات. سنستخدم في هذا المشروع نوع جديد من الشاشات وهو شاشات الكريستال السائلة Liquid Crystal Displays والتي تعرف اختصارًا LCD، وتُعَد هذه الشاشة مثاليةً لعرض الرسائل والنصوص والقيم الرقمية للحساسات أو حتى الرموز الخاصة وإضافة بعض المؤثرات البصرية. أنواع شاشة الكريستال السائلة LCD تتوفر هذه الشاشة بعدة أبعاد مثل 1×8 و 1×16 و 2×16 و 4×20 وتتميز بأن جميعها لها نفس طريقة التوصيل مع لوحة الأردوينو Arduino، ولكن الحجم الأكثر انتشارًا واستخدامًا هو 2×16 حيث يمثل الرقم 16 عدد الأعمدة في الشاشة ويمثل الرقم 2 عدد الأسطر الموجودة في الشاشة، ويحتوي كل عمود على 5×8 بكسل ويمثل محرف واحد يمكن عرض حرف أو رقم أو رمز فيه، بالتالي أصبح لدينا 32 محرفًا في شاشة الكريستال السائلة LCD ذات الحجم 2×16، كما يوجد عدة ألوان لها مثل اللون الأبيض للنص مع خلفية زرقاء أو اللون الأسود للنص مع خلفية خضراء. أقطاب شاشة الكريستال السائلة LCD قطب Vss: قطب التغذية السالب للشاشة والدائرة الرقمية التي بداخلها، ويوصل مع قطب الأرضي GND قطب Vdd: قطب التغذية الموجب للشاشة والدائرة الرقمية التي بداخلها، ويوصل مع مصدر تغذية 5 فولت قطب Vo: قطب التحكم بشدة تباين شاشة LCD، ويوصل مع قطب الخرج للمقاومة المتغيرة Potentiometer؛ أما الأقطاب الأخرى للمقاومة المتغيرة توصل مع قطب التغذية 5 فولت وقطب الأرضي GND، وبتغيير محور المقاومة المتغيرة سيؤدي لتغيير قيمة الجهد على القطب Vo، وبالتالي ستتغير شدة التباين في الشاشة قطب Rs: قطب تحديد نوع البيانات المرسلة للشاشة، إذا كانت حالة القطب 0 منطقي ستكون البيانات المرسلة للشاشة عبارة عن أوامر مثل مسح النصوص المعروضة على الشاشة أو تحديد مكان المؤشر في الشاشة؛ أما إذا كانت حالة القطب 1 منطقي، فستكون البيانات عبارة عن نصوص ستعرض على الشاشة قطب RW: قطب تحديد نمط العمل للشاشة قطب E: قطب تفعيل الكتابة في مسجلات الشاشة، فعند إرسال البيانات للشاشة يجب أن تتغير حالة هذا القطب من 1 منطقي إلى 0 منطقي لاستقبال البيانات أقطاب D0-D7: أقطاب نقل البيانات والأوامر إلى الشاشة ويمكن استخدام 4 أقطاب فقط أو 8 أقطاب، والنمط الأكثر استخدامًا عادةً هو 4 أقطاب فقط وذلك لتقليل التوصيلات قطب A: قطب التغذية الموجب الخاص بإضاءة خلفية الشاشة ويوصل مع القطب 5 فولت قطب C: قطب التغذية السالب الخاص بإضاءة خلفية الشاشة ويوصل مع القطب الأرضي GND سننفذ تطبيقًا بسيطًا لتجربة شاشة الكريستال السائلة LCD مع لوحة الأردوينو Arduino من خلال عرض العبارة Hasoub Academy في السطر الأول، والعبارة !LCD Example في السطر الثاني على الشاشة، ومع إضافة بعض الحركة على الشاشة. مخطط توصيل شاشة الكريستال السائلة LCD مع الأردوينو Arduino لربط شاشة الكريستال السائلة LCD سنتبع الخطوات التالية: نضع الشاشة في لوحة توصيل التجارب BreadBoard عرضيًا نصل أقطاب التغذية في لوحة الأردوينو أونو Arduino Uno مع لوحة توصيل التجارب BreadBoard، إذ يوصل القطب 5v في لوحة الأردوينو مع المسرى الموجب للوحة التجارب، والقطب GND في لوحة الأردوينو مع المسرى السالب للوحة التجارب من خلال أسلاك التوصيل نصل قطب الشاشة ذو الرمز Vs مع المسرى السالب والقطب ذو الرمز Vdd مع المسرى الموجب للوحة التجارب BreadBoard، والتي تمثل أقطاب التغذية للدائرة الإلكترونية والرقمية للشاشة نصل قطب الشاشة ذو الرمز Vo مع قطب الخرج الخاص بالمقاومة المتغيرة الموجود في المنتصف، ونوصل باقي الأقطاب المتغيرة مع المسرى السالب والمسرى الموجب للوحة التجارب BreadBoard نصل قطب الشاشة ذي الرمز Rs مع القطب ذو الرقم 12 في لوحة الأردوينو أونو Arduino Uno نصل قطب الشاشة ذي الرمز RW مع المسرى السالب للوحة التجارب BreadBoard أو يمكن وصله مع قطب الشاشة ذو الرمز Vs لترتيب التوصيل أكثر نصل قطب الشاشة ذو الرمز E مع القطب ذو الرقم 11 في لوحة الأردوينو أونو Arduino Uno نصل أقطاب الشاشة الخاصة بالبيانات من D4-D7 على الترتيب مع الأقطاب ذات الأرقام من 7-4 في لوحة الأردوينو أونو Arduino Uno نصل قطب الشاشة ذو الرمز A مع المسرى الموجب والقطب ذو الرمز K مع المسرى السالب للوحة التجارب BreadBoard، والتي تمثل أقطاب التغذية لإضاءة خلفية الشاشة وفي حال عدم توصيلها ستعمل الشاشة ولكن بدون إضاءة توضح الصورة التالية مخطط توصيل شاشة LCD مع لوحة الأردوينو أونو Arduino Uno: الكود البرمجي الخاص بشاشة الكريستال السائلة LCD مع لوحة الأردوينو Arduino لكتابة الكود البرمجي الخاص بشاشة LCD سنعتمد على المكتبة البرمجية LiquidCrystal المدمجة مع بيئة الأردوينو واستخدام التعليمات البرمجية الخاصة بها بشكل مباشر، فقط كل ما نحتاجه هو تضمين المكتبة في بداية الكود بالشكل التالي: #include <LiquidCrystal.h> في الخطوة التالية سننشئ متغيرًا خاصًا بالمكتبة البرمجية للشاشة من نوع LiquidCrystal ونستطيع اختيار الاسم الذي نريده مثل lcd، ومن خلال هذا المتغير نستطيع تحديد طريقة نقل البيانات بنمط نصف بايت عبر استخدام 4 أقطاب فقط، أو بايت كامل باستخدام 8 أقطاب. غالبًا ما نستخدم نمط نصف بايت لتقليل التوصيلات، وسيأخذ هذا المتغير 6 وسطاء إجبارية وتمثل أرقام أقطاب الشاشة التي وصلناها مع لوحة الأردوينو بالترتيب التالي Rs ،E ،D4 ،D5 ،D6 ،D7 في حال استخدام نمط نصف بايت فقط، أما في حال استخدام نمط بايت كامل سيأخذ 10 وسطاء بالترتيب التالي Rs ،E ،D0 ،D1 ،D2 ،D3 ،D4 ،D5 ،D6 ،D7. LiquidCrystal lcd(11, 10, 4, 5, 6, 7); سنهيئ شاشة LCD في الدالة الرئيسية ()setup من خلال الدالة ()lcd.begin، والتي تأخذ وسيطين إجباريين هما عدد الأعمدة وعدد الأسطر الموجودة في الشاشة، بالإضافة إلى وسيط ثالث اختياري يمثل عدد البكسلات الموجودة في كل عمود والقيمة الإفتراضية له هي 8×5 بكسل. نريد أن نطبع في بداية التشغيل رسالة ترحيبية Hello World لمرة واحدة فقط ولمدة ثانية واحدة، ومن ثم نمسح المحتوى الموجود على الشاشة، لذلك سننفذ هذا الأمر في الدالة الرئيسية، وللطباعة على الشاشة سنستخدم الدالة ()lcd.print والتي تأخذ وسيطين: إجباري: وهو البيانات التي نريد طباعتها ويمكن أن تكون من نوع int أو long أو char أو byte أو string اختياري: ويمثل صيغة البيانات Bin أو Dec أو Oct أو Hex. وسنستخدم الدالة المدمجة ()delay لعمل تأخير الزمني كما تعلمنا في المشاريع السابقة. أما لمسح النص المعروض على الشاشة سنستخدم الدالة ()lcd.clear والتي لا تأخذ أي وسيط: void setup() { lcd.begin(16, 2); lcd.print("Hello World"); delay(1000); lcd.clear(); } سنستخدم في الدالة التكرارية ()loop الدالة ()lcd.setCursor لتحريك مؤشر الكتابة للمكان الذي نريد، وتأخذ هذه الدالة وسيطين هما رقم العمود ورقم السطر، ونلاحظ أن عبارة "Hasoub Academy" مكونة من 16 محرف، بالتالي سنحرك مؤشر الكتابة إلى العمود الثاني ذي رقم 1 لأن الترقيم يبدأ من 0، والسطر الأول ذو الرقم 0 لتصبح العبارة في منتصف السطر الأول. وبعد طباعة العبارة الأولى في السطر الأول، سنحرك مؤشر الكتابة إلى السطر الثاني ذو الرقم 1 بنفس الطريقة السابقة، وكذلك الأمر مع العمود الثالث ذي الرقم 2، لكي تكون محاذاة العبارة !LCD Example في منتصف الشاشة. void loop() { lcd.setCursor(1, 0); lcd.print("Hasoub Academy"); lcd.setCursor(2, 1); lcd.print("LCD Example!"); } يمكن إجراء بعض التعديلات في الدالة التكرارية السابقة لإضافة بعض المؤثرات الحركية على النص خلال عرضه على الشاشة، مثل تحريكه إلى اليمين أو اليسار بستمرار، وذلك من خلال الدالة ()lcd.scrollDisplayLeft لتحريك النص من اليمين إلى اليسار بمقدار محرف واحد، والدالة ()lcd.scrollDisplayRight لتحريك النص من اليسار إلى اليمين بمقدار محرف واحد في كل مرة، وبالتالي يصبح الكود بالشكل التالي: void loop() { lcd.setCursor(1, 0); lcd.print("Hasoub Academy"); lcd.setCursor(2, 1); lcd.print("LCD Example!"); for (int positionCounter = 0; positionCounter <16; positionCounter ++) { lcd.scrollDisplayLeft (); // lcd.scrollDisplayRight(); delay (150); } } يمكن الاطلاع أكثر على التوثيق الرسمي الخاص بمكتبة LiquidCrystal لمزيد من المعلومات عنها، وماهي التوابع الأخرى الخاصة بها من خلال الموقع الرسمي لمنصة أردوينو Arduino من الرابط التالي. حساس الأمواج فوق الصوتية UltraSonic Sensor هو عبارة عن جهاز استشعار يتكون من مرسل Transmitter ومستقبل Receiver وبعض العناصر الإلكترونية والرقمية الأخرى. يُستخدم هذا الحساس لقياس المسافة بينه وبين الحاجز الذي أمامه ضمن المجال من 2 سم إلى 400 سم وبدقة 0.3 سم أو ما يعادل من 0.8 بوصة إلى 157 بوصة وبدقة 0.1 بوصة، ويُعَد هذا الحساس سهل الاستخدام ورخيص الثمن مقارنةً مع المجال والدقة التي يقدمها والتي تُعَد مناسبةً لكثير من المشاريع الإلكترونية. مبدأ عمل حساس الأمواج فوق الصوتية UltraSonic Sensor يعتمد في عمله أساسًا على الأمواج فوق الصوتية، فعند إعطاء أمر الإرسال على قطب Trig، سترسل موجة فوق صوتية مكونة من ثماني نبضات عن طريق المرسل بتردد 40KHZ تنتقل عبر الهواء، وفي حال وجود جسم أو حاجز أمامها ستصطدم به وتنعكس إلى الحساس. ونتيجة استقبال الموجة، ستتولد نبضة موجبة على قطب Echo تمثل الزمن الذي استغرقته الموجة من لحظة إرسالها حتى عودتها وتتراوح بين 150 مايكرو ثانية و 25 مللي ثانية، ومن خلال قانون السرعة نستطيع حساب المسافة من خلال الزمن الذي أصبح لدينا. وكما نعلم، قيمة سرعة الصوت معروفة وهي 340m/s عند درجة حرارة 20 درجة مئوية وتختلف قليلًا عند تغير درجة الحرارة والرطوبة والضغط الجوي، وبالتالي يمكن حساب المسافة من خلال العلاقة التالية: Distance = Speed x Time أقطاب حساس الأمواج فوق الصوتية UltraSonic Sensor قطب Vcc: قطب التغذية الموجب ويوصل مع القطب 5v في لوحة الأردوينو Arduino قطب Trig: عبارة عن قطب خرج وهو القطب المسؤول عن إرسال موجة فوق صوتية من خلال إعطائه إشارة HIGH لمدة 10µs قطب Echo: عبارة عن قطب دخل وهو القطب المسؤول عن إستقبال الموجة، حيث تتغير حالته إلى قيمة HIGH عند نهاية إرسال الموجة ويعود إلى حالة LOW عند استقبال الموجة قطب GND: قطب التغذية السالب ويوصل مع القطب GND في لوحة الأردوينو أونو Arduino مواصفات حساس الأمواج فوق الصوتية UltraSonic Sensor لا بد من توفر المواصفات الآتية في حساس الأمواج فوق الصوتية UltraSonic Sensor: جهد التغذية: 5 فولت تيار العمل: 15 مللي أمبير زاوية القياس الفعالة: 15 درجة مجال القياس: من 2 سم إلى 400 سم دقة القياس: 0.3 سم الأبعاد: 45 مم × 20 مم × 15 مم سننفذ تطبيق بسيط باستخدام لوحة أردوينو Arduino وحساس الأمواج فوق الصوتية UltraSonic Sensor وسنتعلم كيفية أخذ القراءات من الحساس وتحويل هذه القيمة إلى المسافة وكيفية كتابة الكود البرمجي والتوصيل المناسب. مخطط توصيل حساس الأمواج فوق الصوتية UltraSonic Sensor مع لوحة الأردوينو Arduino سنتبع الخطوات التالية لتوصيل الحساس مع لوحة الأردوينو: نصل القطب الأول Vcc في الحساس مع القطب 5v في لوحة الأردوينو أونو نصل القطب الثاني Trig في الحساس مع القطب ذو الرقم 9 في لوحة الأردوينو أونو نصل القطب الثالث Echo في الحساس مع القطب ذو الرقم 8 في لوحة الأردوينو أونو نصل القطب الرابع GND في الحساس مع القطب GND في لوحة الأردوينو أونو الكود البرمجي الخاص بحساس لأمواج فوق الصوتية UltraSonic Sensor مع لوحة الأردوينو Arduino من الممكن استخدام مكتبات برمجية جاهزة نستطيع تحميلها من الإنترنت أو من بيئة الأردوينو البرمجية، ولكننا لن نستخدم هذه المكتبات حاليًا، لأن الكود الخاص بالحساس بسيط وسهل جدًا. في البداية نحتاج لتعريف أرقام الأقطاب الموصولة مع الحساس Trig وEcho من خلال الماكرو define#، بالإضافة إلى متغيرين من نوع عدد صحيح intهما: duration سنخزن فيه قيمة الزمن التي سنحصل عليها من الحساس distance سنخزن فيه قيمة المسافة #define trigPin 9 #define echoPin 8 int duration = 0; int distance = 0; سنضبط القطب trigPin في الدالة الرئيسية ()setup كقطب خرج OUTPUT، والقطب echoPin كقطب دخل INPUT من خلال الدالة المدمجة ()pinMode والتي تأخذ وسيطين هما رقم القطب ونوع القطب، إما خرج OUTPUT أو دخل INPUT. كما سنفعل واجهة الاتصال التسلسلية Serial Communication من خلال الدالة المدمجة ()Serial.begin التي تأخذ وسيطين على النحو الآتي: إجباري: سرعة نقل البيانات Baud rate بمعدل بت في الثانية وسنختار القيمة 9600 اختياري: وهو خاص بضبط الإعدادات config الأخرى لواجهة الاتصال ويمكن تركه فارغًا حيث يأخذ الضبط الافتراضي SERIAL_8N1 في هذه الحالة void setup() { pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); Serial.begin(9600); } أما في الدالة التكرارية ()loop، سنغير حالة القطب trigPin إلى القيمة HIGH لبدء عملية الإرسال من خلال الدالة المدمجة ()digitalWrite التي تأخذ وسيطين هما رقم القطب وحالة أو قيمة القطب، وذلك بإعطاءه قيمة 1 منطقي أو HIGH للتشغيل و 0 منطقي أو LOW للإطفاء ولمدة 10µs من خلال الدالة المدمجة ()delayMicroseconds التي تأخذ وسيطًا واحدًا هو قيمة التأخير بالمايكرو ثانية، ومن ثم سنعيد حالة القطب trigPin إلى القيمة LOW. void loop() { digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); بعد انتهاء إرسال الموجة، سنقيس الزمن الذي يكون فيه القطب echoPin في حالة HIGH وتخزينه في المتغير duration، وذلك من خلال استخدام الدالة المدمجة ()pulseIn التي تأخذ ثلاثة وسطاء على النحو الآتي: الوسيط pin: يمثل رقم القطب المراد حساب طول النبضة المولَّدة عليه الوسيط value: يمثل نوع النبضة المراد قراءتها لحساب طولها وتكون إمَّا HIGH أو LOW الوسيط timeout: يحدِّد المهلة الزمنية بالميكروثانية التي ستنتظر الدالة خلالها بدء النبضة، وتعيد هذه الدالة عدد يمثل طول النبضة المولدة على الرجل pin بالميكروثانية، أو تعيد القيمة 0 إن لم تبدأ أيَّة نبضة عند الحافة value قبل انتهاء المهلة timeout الزمنية. duration = pulseIn(echoPin, HIGH); لحساب المسافة سنستخدم العلاقة الرياضية التي ذكرناها سابقًا وهي: Distance = Speed x Time والتي تمثل قانون المسافة ولكن نحتاج لتحويل قيمة السرعة من 340m/s إلى 0.034cm/µs لكي تتناسب مع قيمة الزمن المقاس والحصول على المسافة بواحدة cm؛ بالإضافة لتقسيم الزمن على 2 لأنه يمثل زمن ذهاب وعودة الموجة، فتصبح العلاقة برمجيًا: distance = 0.034 * (duration / 2); الخطوة الأخيرة هي طباعة قيمة المسافة على نافذة الاتصال التسلسلية، وذلك باستخدام الدالة المدمجة ()Serial.print والدالة ()Serial.println التي سنمرر لها البيانات المراد طباعتها، وإضافة بعض التأخير الزمني لنستطيع قراءة القيم على نافذة Serial Monitor. Serial.print("distance = "); Serial.println(distance); delay(500); } مخطط توصيل مشروع بناء مسطرة إلكترونية باستخدام الأردوينو Arduino توضح الصورة التالية التوصيل النهائي للمشروع، حيث أن خطوات التوصيل هي نفسها التي اتَّبعناها في تطبيق الشاشة والحساس معًا: الكود البرمجي لمشروع بناء مسطرة إلكترونية باستخدام الأردوينو Arduino سندمج الكود الخاص بشاشة LCD مع كود حساس الأمواج فوق الصوتية UltraSonic Sensor وعرض قيمة المسافة على الشاشة بدلًا من عرضها على نافذة الاتصال التسلسلية Serial Monitor فيكون الكود النهائي بالشكل التالي: #include <LiquidCrystal.h> LiquidCrystal lcd(11, 10, 4, 5, 6, 7); #define trigPin 9 #define echoPin 8 int duration; int distance; void setup() { lcd.begin(16, 2); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); lcd.print("Hello World"); delay(1000); } void loop() { lcd.clear(); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); distance = duration * (0.0343 / 2); lcd.setCursor(0, 0); lcd.print("Digital Ruler"); lcd.setCursor(0, 1); lcd.print("Distance = "); lcd.print(distance); lcd.print("cm"); delay(500); } محاكاة لمشروع بناء مسطرة إلكترونية باستخدام الأردوينو Arduino سنتبع نفس الخطوات التي تعلمناها في مقال التحكم بتشغيل وإطفاء ليد LED باستخدام الأردوينو Arduino للوصول الى الصفحة الخاصة بمحاكاة مشروعك على موقع وكوي Wokwi. سنضيف الآن العناصر الإلكترونية اللازمة للمشروع وهي: BreadBoard و LCD 16x2 و Potentiometer بعد ذلك سنرتب العناصر على لوحة التجارب بالشكل الذي نراه مناسبًا، ثم نصل العناصر بعضها ببعض حسب مخطط التوصيل الذي عرضناه سابقًا. وعند الانتهاء من كل ما سبق، سنكتب الكود البرمجي في الجزء الخاص به ثم نشغل المحاكاة. سنلاحظ أنه عند بداية تشغيل المشروع ستطبع العبارة Hello World على الشاشة في السطر الأول لمدة ثانية واحدة، بعد ذلك ستطبع العبارة Digital Ruler على الشاشة في السطر الأول دائمًا، وفي السطر الثاني سيطبع في بدايته = Distance ومن ثم قيمة المسافة وبجانبها الواحدة وهي سم cm. نستطيع محاكاة تغيير المسافة من خلال النقر على الحساس أثناء تشغيل المشروع، فتظهر لنا نافذة في الأعلى تحتوي على شريط نستطيع تحريكه لتغيير قيمة المسافة كما يلي: وعند تحريك الشريط المسؤول عن قيمة المسافة، سيحصل تحديث للقيمة المعروضة على الشاشة كل نصف ثانية باستمرار. الخاتمة بهذا نكون قد تعلمنا في هذا المقال كيفية إنشاء مسطرة إلكترونية باستخدام أردو ينو، كما وضحنا كيفية قياس المسافة من خلال حساس الأمواج فوق الصوتية Ultrasonic Sensor ولوحة الأردوينو Arduino، وتعرفنا على عنصر إلكتروني جديد وهو شاشة الكريستال السائلة LCD وأنواعها وكيفية عرض النصوص عليها وإضافة مؤثرات حركية، وفي النهاية استعرضنا خطوات محاكاة للمشروع من خلال منصة وكوي Wokwi. اقرأ أيضًا المقال السابق: نظام قياس عدد الزوار باستخدام الأردوينو Arduino التعرف على أساسيات الأردوينو وتجهيز بيئة العمل إضاءة زينة بأنماط مختلفة باستخدام الأردوينو Arduino التحكم بعدد الليدات المضاءة وشدة إضاءتها باستخدام أردوينو Arduino
-
سنوظف في هذا المقال ما تعلمناه سابقًا في بناء مشروع جديد من سلسلتنا التعليمية دليل أردوينو وهو عبارة عن نظام لقياس عداد الزوار باستخدام لوحة الأردوينو أونو Arduino Uno، حيث يمكن استخدامه في العديد من الأماكن، لنفترض أننا بحاجة لمعرفة عدد الأشخاص ضمن متجر أو مكتب مثلًا، بحيث إذا كان أكبر من العدد المسموح به، فيجب أن ينتظر الشخص حتى خروج أحد الأشخاص من المكان حتى يدخل هو. ولبناء هذا المشروع، سنستخدم عنصرًا جديدًا يتمثل في حساس الأشعة تحت الحمراء Infrared Sensor الذي سنتعرف عليه في هذا المقال. فكرة مشروع نظام قياس عدد الزوار باستخدام الأردوينو Arduino سنبني نظامًا لقياس عدد الزوار ضمن متجر يتسع لتسعة أشخاص على الأكثر، وذلك من خلال حساسين من حساسات الأشعة تحت الحمراء Infrared Sensors وشاشة العرض ذات السبع أجزاء Seven Segment Display، حيث يوضع الحساس الأول عند باب الدخول وعند مرور أي جسم أمام هذا الحساس ستزداد قيمة العداد بمقدار واحد، والحساس الثاني يوضع عند باب الخروج وعند مرور أي جسم من أمام هذا الحساس ستنقص قيمة العداد بمقدار واحد، وتعرض قيمة عدد الأشخاص الموجودين داخل المتجر على الشاشة وتحدث باستمرار، والمخطط الآتي يوضح آلية العمل: العناصر المستخدمة لمشروع نظام قياس عدد الزوار باستخدام الأردوينو Arduino سنستخدم مجموعةً من العناصر الإلكترونية والأدوات وهي: لوحة أردوينو أونو Arduino Uno كابل البرمجة USB Cable لوحة توصيل التجارب Breadboard حساس الأشعة تحت الحمراء Infrared Sensor عدد 2 مقاومة بقيمة 220 أوم عدد 7 شاشة العرض ذات السبع أجزاء Seven Segment Display من نوع CC مجموعة أسلاك توصيل من نوع Male to Male تعرفنا في المقال السابق على شاشة العرض ذات السبع أجزاء Seven Segment Display وأهميتها في بناء مشاريع إلكترونية تفاعلية وبنينا لعبة بسيطة لتخمين الأرقام، وسنتعرف في هذا المقال على عنصر جديد ومهم وهو حساس الأشعة تحت الحمراء Infrared Sensor. حساس الأشعة تحت الحمراء Infrared Sensor يعرف اختصارًا IR Sensor وهو عبارة عن جهاز إلكتروني يتكون من مجموعة من العناصر الإلكترونية المتصلة مع بعضها في دارة إلكترونية، ومن أهم هذه العناصر هي المرسل IR Emitter والمستقبل IR Receiver اللذان يعملان بالاعتماد على الأشعة تحت الحمراء. المرسل IR Emitter: عبارة عن عنصر إلكتروني يشبه الليد من حيث الشكل، ولكن يختلف في الوظيفة، حيث عند تغذيته بالجهد الكهربائي المناسب، يرسل أشعة تحت الحمراء غير المرئية للعين البشرية المستقبل IR Receiver: عبارة عن عنصر إلكتروني يشبه المرسل من حيث الشكل ولكن يعاكسه في الوظيفة ويستخدم في استقبال واكتشاف الأشعة تحت الحمراء ويحولها إلى إشارة كهربائية مضخم عملياتي Op-Amp: عبارة عن عنصر إلكتروني وظيفته تضخيم الإشارة الكهربائية الموجود على أطراف لمستقبل IR Receiver وتحويلها من إشارة تشابهية إلى إشارة رقمية LOW و HIGH مقاومة متغيرة: تكون على شكل يشبه البرغي، وظيفتها معايرة مجال المسافة التي يعمل عندها الحساس عناصر إلكترونية أخرى: مثل الليدات والمقاومات والمكثفات الإلكترونية آلية عمل حساس الأشعة تحت الحمراء Infrared Sensor يعمل هذا الحساس بطريقة بسيطة جدًا، وذلك بالاعتماد على انعكاس الضوء حيث يرسل الليد المرسل IR Emitter إشارةً تتكون من أشعة تحت الحمراء Infrared، وفي حال وجود أي حاجز أو جسم أمام الحساس تنعكس هذه الإشارة وتعود ليستشعرها الليد المستقبل IR Receiver ويحولها إلى إشارة كهربائية، ومن ثم تدخل هذه الإشارة لدارة تحويل رقمية لتعالج وتصبح مناسبة للتعامل معها مع لوحة الأردوينو أو أي متحكم آخر. أقطاب حساس الأشعة تحت الحمراء Infrared Sensor يحتوي حساس الأشعة تحت الحمراء IR Sensor على ثلاثة أقطاب وهي: القطب الأول من اليمين: هو قطب التغذية الموجب رمزه VCC ويوصل مع القطب 5v في لوحة الأردوينو القطب الثاني: هو قطب التغذية السالب رمزه GND ويوصل مع القطب الأرضي في لوحة الأردوينو القطب الثالث: هو قطب خرج الحساس رمزه OUT ويعطي إشارة LOW في حال وجود جسم أمامه وإشارة HIGH في حال عدم وجود جسم ويوصل هذا القطب مع أي قطب رقمي في لوحة الأردوينو مواصفات حساس الأشعة تحت الحمراء جهد العمل: 3.3 الى 5 فولت تيار العمل: 20 مللي أمبير مجال الاستشعار: 2 الى 10 سم زاوية الاستشعار: 35 درجة حالة الخرج: LOW في حالة الانعكاس و HIGH في حالة عدم الانعكاس ربط حساس الأشعة تحت الحمراء Infrared Sensor مع الأردوينو Arduino سنبني تطبيقًا بسيطًا لفهم آلية استخدام الحساس مع لوحة الأردوينو أونو Arduino Uno، حيث وظيفة هذا التطبيق هو اكتشاف العوائق الموجودة أمام الحساس وتشغيل ليد في حال وجود أي جسم أمامه، ولتنفيذ التطبيق علينا اتباع الخطوات الآتية: وصل قطب التغذية الموجب للحساس Vcc مع القطب 5v في لوحة الأردوينو أونو وصل قطب التغذية السالب للحساس GND مع القطب GND في لوحة الأردوينو أونو وصل قطب خرج الحساس مع القطب رقم 3 في لوحة الأردوينو أونو لا نحتاج لتوصيل ليد خارجي لأننا سنستخدم الليد الموجود في لوحة الأردوينو أونو ويكون موصول داخليًا مع القطب رقم 13 الصورة الآتية توضح طريقة التوصيل: الخطوة التالية هي كتابة الكود البرمجي للتطبيق. سنضبط القطب رقم 13 الخاص بالليد في الدالة الرئيسية ()setup كقطب خرج OUTPUT، والقطب رقم 3 الخاص بالحساس كقطب دخل INPUT، وذلك من خلال الدالة المدمجة ()pinMode التي تأخذ وسيطين هما رقم القطب ونوع القطب وتكون إما خرج OUTPUT أو دخل INPUT. أما في الدالة التكرارية ()loop، فسنقرأ حالة للقطب الموصول معه خرج الحساس من خلال الدالة المدمجة ()digitalRead التي تأخذ وسيطًا واحدًا وهو رقم القطب، وتعيد القيمة الفيزيائية الموجودة على القطب، ومن ثم سنتحقق من هذه القيمة من خلال العبارة الشرطية ()if في حال كانت القيمة LOW أي بحالة وجود جسم أمام الحساس، حيث سنشغل الليد LED الموصول على القطب رقم 13 من خلال الدالة المدمجة ()digitalWrite التي تأخذ وسيطين هما رقم القطب وقيمة القطب، وذلك بإعطائه قيمة 1 منطقي أو HIGH للتشغيل و 0 منطقي أو LOW للإطفاء؛ أما في حال كانت القيمة HIGH بمعنى أن حالة عدم وجود حاجز أمام الحساس، فسنطفئ الليد LED. void setup(){ pinMode(13, OUTPUT); pinMode(3, INPUT); } void loop(){ if(digitalRead(3) == LOW){ digitalWrite(13, HIGH); } else{ digitalWrite(13, LOW); } } بعد توصيل العناصر وكتابة الكود البرمجي في بيئة Arduino IDE، نصل كابل البرمجة مع لوحة أردوينو أونو والحاسب ومن ثم نذهب إلى بيئة البرمجية للأردوينو Arduino IDE لاختيار نوع لوحة الأردوينو ورقم المنفذ الموصل معه على الحاسب، وذلك من خلال القائمة العلوية Tools ومن ثم Boards لاختيار نوع اللوحة وPort لاختيار رقم المنفذ، بعد ذلك نضغط على أيقونة Upload لرفع الكود البرمجي على لوحة الأردوينو. بعد رفع الكود البرمجي على لوحة الأردوينو أونو بنجاح، لا بد لنا من تمرير يدنا أمام الحساس بمسافة قريبة منه، وتكون أقل من 10 سم، وعندها نلاحظ إضاءة الليد LED الموجود في لوحة الأردوينو أونو Arduino Uno. مخطط التوصيل لمشروع نظام قياس عدد الزوار باستخدام الأردوينو Arduino سنتبع الخطوات الآتية في عملية توصيل العناصر والأسلاك مع لوحة الأردوينو Arduino لتنفيذ فكرة المشروع: وصل أقطاب التغذية في لوحة الأردوينو أونو Arduino Uno مع لوحة توصيل التجارب BreadBoard، إذ يوصل القطب 5v في لوحة الأردوينو مع المسرى الموجب للوحة التجارب، والقطب GND في لوحة الأردوينو مع المسرى السالب للوحة التجارب من خلال أسلاك التوصيل تثبيت شاشة العرض ذات السبع أجزاء Seven Segment Display على لوحة توصيل التجارب BreadBoard ثم صل أقطاب الشاشة مع المقاومات الإلكترونية ولوحة الأردوينو Arduino بالترتيب التالي: وصل الرِّجل ذات الرمز A من الشاشة مع الرِّجل الأولى للمقاومة، ووصل الرِّجل الثانية للمقاومة مع القطب رقم 2 في لوحة الأردوينو وصل الرِّجل ذات الرمز B من الشاشة مع الرِّجل الأولى للمقاومة، ووصل الرِّجل الثانية للمقاومة مع القطب رقم 3 في لوحة الأردوينو وصل الرِّجل ذات الرمز C من الشاشة مع الرِّجل الأولى للمقاومة، ووصل الرِّجل الثانية للمقاومة مع القطب رقم 4 في لوحة الأردوينو وصل الرِّجل ذات الرمز D من الشاشة مع الرِّجل الأولى للمقاومة، ووصل الرِّجل الثانية للمقاومة مع القطب رقم 5 في لوحة الأردوينو وصل الرِّجل ذات الرمز E من الشاشة مع الرِّجل الأولى للمقاومة، ووصل الرِّجل الثانية للمقاومة مع القطب رقم 6 في لوحة الأردوينو وصل الرِّجل ذات الرمز F من الشاشة مع الرِّجل الأولى للمقاومة، ووصل الرِّجل الثانية للمقاومة مع القطب رقم 7 في لوحة الأردوينو وصل الرِّجل ذات الرمز G من الشاشة مع الرِّجل الأولى للمقاومة، ووصل الرِّجل الثانية للمقاومة مع القطب رقم 8 في لوحة الأردوينو وصل الرِّجل المشتركة CO من الشاشة مع القطب السالب GND في لوحة الأردوينو وصل قطب التغذية الموجب Vcc لحساس الأشعة تحت الحمراء IR Sensor الأول والثاني مع المسرى الموجب للوحة التجارب BreadBoard وصل قطب التغذية السالب GND لحساس الأشعة تحت الحمراء IR Sensor الأول والثاني مع المسرى السالب للوحة التجارب BreadBoard وصل قطب الخرج OUT لحساس الأشعة تحت الحمراء IR Sensor الأول مع القطب رقم 9، والثاني مع القطب رقم 10 في لوحة الأردوينو أونو Arduino UNO توضح الصورة الآتية مخطط التوصيل لمشروع نظام قياس عدد الزوار باستخدام الأردوينو Arduino: الكود البرمجي لمشروع نظام قياس عدد الزوار باستخدام الأردوينو Arduino في بداية الكود البرمجي سنعرف عدة متغيرات خاصة بأقطاب العناصر الإلكترونية الموصولة مع لوحة الأردوينو أونو Arduino Uno، فكما رأينا في مخطط التوصيل، سنوصل أقطاب خرج الحساسات مع الأقطاب 9 و 10 في لوحة الأردوينو أونو Arduino Uno وسنخزنها في متغيرات من نوع int؛ أما بالنسبة لأقطاب شاشة العرض ذات السبع أجزاء Seven Segment فستوصل على الترتيب مع الأقطاب 2 وحتى 8 وستخزَّن هذه الأقطاب داخل مصفوفة أحادية بحجم 7 عناصر من نوع int. int Inc_Sensor = 10; int Dec_Sensor = 9; int displayPins [7] = {2, 3, 4, 5, 6, 7, 8}; سنحتاج أيضًا لتعريف خمسة متغيرات أخرى، أولهم هو Number_Of_Visitors من نوع int وقيمة ابتدائية تساوي الصفر، وهو خاص بتخزين قيمة عدد الزوار لأن نوع القيم هنا ستكون من نوع عدد صحيح وضمن المجال من 0 وحتى 9؛ أما المتغيرات الأربعة الأخرى، فهي خاصة بقراءة وتخزين قيمة الحساسات الحالية والقيم السابقة لها. int Number_Of_Visitors = 0; int Cur_Inc_Val = 0; int Cur_Dec_Val = 0; int Las_Inc_Val = 0; int Las_Dec_Val = 0; كما تعلمنا في المقال السابق نستطيع عرض الأرقم على شاشة العرض ذات السبع أجزاء من خلال إعطاء أوامر التشغيل والإطفاء بشكل منفصل لكل ليد من ليدات الشاشة، ولكن هذه الطريقة ستستهلك أسطر برمجية كثيرة، فعند كل رقم نريد إظهاره على الشاشة، سنحتاج إلى 7 أسطر، بالتالي استهلاك كبير لذاكرة البرنامج Flash Memory في الأردوينو Arduino، ولذلك سنبني دالةً خاصةً تستقبل وسيطًا واحدًا وهو الرقم الذي نريد عرضه على الشاشة، وتعرض هذه الدالة الرقم بطريقة ديناميكية بسيطة وسهلة. سنعرف داخل هذه الدالة مصفوفةً من نوع بايت byte بحجم 10 عناصر لأنه لدينا عشرة أرقام من الرقم 0 إلى الرقم 9؛ وبداخل هذه المصفوفة سنكتب القيم الخاصة بتشغيل وإطفاء ليدات الشاشة بالنظام الثنائي binary system بنفس قيم الجدول السابق، وبعد ذلك سنستخدم حلقة تكرارية ()for للمرور على جميع عناصر المصفوفة []displayPins التي تخزن أرقام أقطاب الشاشة وإعطاء أمر التشغيل أو الإطفاء المقابل للقطب من خلال المصفوفة []numbers باستخدام الدالة المدمجة ()digitalWrite. وللوصول الصحيح للقيمة المقابلة لكل قطب من الشاشة نستخدم الدالة المدمجة ()bitRead التي تأخذ وسيطين: الأول هو الرقم الذي نريد قراءة بت واحد منه، أما الثاني هو رقم البت حيث يبدأ من الرقم 0 للبت الأول من اليمين، وتعيد هذه الدالة قيمة هذا البت 1 أو 0. void displayNumber(int num) { const byte numbers[10] = { 0B0111111, // 0 0B0000110, // 1 0B1011011, // 2 0B1001111, // 3 0B1100110, // 4 0B1101101, // 5 0B1111101, // 6 0B0000111, // 7 0B1111111, // 8 0B1101111 // 9 }; for (int i = 0; i < 7; i++) { digitalWrite(displayPins[i], bitRead(numbers[num], i)); } } سنضبط الأقطاب الخاصة بحساسات الأشعة تحت الحمراء IR Sensors في الدالة الرئيسية ()setup كأقطاب دخل INPUT، والأقطاب الخاصة بالشاشة كأقطاب خرج OUTPUT، وذلك من خلال الدالة المدمجة ()pinMode. void setup() { pinMode(Inc_Sensor, INPUT); pinMode(Dec_Sensor, INPUT); for (int i = 0; i < 7; i++) { pinMode(displayPins[i], OUTPUT); } } من الممكن استخدام الطريقة التالية في آلية العمل داخل الدالة التكرارية ()loop: قراءة قيمة الحساس الأول المسؤول عن استشعار زيادة عدد الزوار قراءة قيمة الحساس الثاني المسؤول عن استشعار نقصان عدد الزوار في حالة اكتشاف جسم أمام الحساس الأول، ستزيد قيمة المتغير الخاص بعدد الزوار بمقدار واحد في حالة اكتشاف جسم أمام الحساس الثاني، ستنقص قيمة المتغير الخاص بعدد الزوار بمقدار واحد عرض قيمة المتغير الخاص بعدد الزوار على شاشة العرض ذات السبع أجزاء Seven Segment Display ولكن هناك مشكلة تقنية مع الطريقة السابقة، وهي أنه في حال وقوف الجسم أمام الحساس سواءً الأول أو الثاني، فستزداد أو تنقص قيمة المتغير الخاص بعدد الزوار أكثر من مرة، ولذلك سنتبع طريقةً تعلمناها في مشروع التحكم بالليد LED باستخدام مفتاح الضغط اللحظي Push Button والأردوينو Arduino، وهي التحقق من القيمة الحالية والسابقة لكل حساس، فإذا كانت القيمة الحالية للحساس الأول LOW بمعنى حالة وجود جسم أمام الحساس، وكانت الحالة السابقة له HIGH أي حالة عدم وجود جسم أمام الحساس، فعندها سنزيد قيمة المتغير الخاص بعدد الزوار بمقدار واحد؛ أما في حال كانت القيمة الحالية للحساس الأول LOW وهي حالة وجود جسم أمام الحساس وكانت الحالة السابقة له أيضًا LOW أي حالة وجود جسم أمام الحساس، فعندها سيكون الجسم ما يزال موجود أمام الحساس، وفي هذه الحالة لن نزيد قيمة المتغير الخاص بعدد الزوار، والأمر نفسه بالنسبة للحساس الثاني. في بداية الدالة التكرارية ()loop سنقرأ القيمة الحالية لكل من الحساس الأول والثاني من خلال الدالة المدمجة ()digitalRead وسنخزنها في المتغيرات الخاصة بها Cur_Dec_Val Cur_Inc_Val. void loop() { int Cur_Inc_Val = digitalRead(Inc_Sensor); int Cur_Dec_Val = digitalRead(Dec_Sensor); سنتحقق بعد ذلك من القيمة الحالية والسابقة لحساس الأشعة تحت الحمراء IR Sensor الأول المسؤول عن زيادة قيمة المتغير الخاص بعدد الزوار وذلك من خلال العبارة الشرطية ()if، ففي حال كانت القيمة الحالية هي LOW أي حالة وجود جسم أمام الحساس الآن والقيمة السابقة هي HIGH أي عدم وجود جسم أمام الحساس سابقًا؛ فعندها ستزداد قيمة المتغير الخاص بعدد الزوار بمقدار واحد وفي حال أصبحت قيمة هذا المتغير أكبر من 9 لن تزداد قيمته. if ((Cur_Inc_Val == LOW) && (Las_Inc_Val == HIGH)) { Number_Of_Visitors++; if ( Number_Of_Visitors > 9) Number_Of_Visitors = 9; } سنتحقق أيضًا من القيمة الحالية والسابقة لحساس الأشعة تحت الحمراء IR Sensor الثاني المسؤول عن نقصان قيمة المتغير الخاص بعدد الزوار من خلال العبارة الشرطية ()if في حال كانت القيمة الحالية هي LOW والقيمة السابقة هي HIGH، فعندها ستنقص قيمة المتغير الخاص بعدد الزوار بمقدار واحد؛ وفي حال أصبحت قيمة هذا المتغير أصغر من 0، فلن تنقص قيمته. if ((Cur_Dec_Val == LOW) && (Las_Dec_Val == HIGH)) { Number_Of_Visitors--; if ( Number_Of_Visitors < 0) Number_Of_Visitors = 0; } سنحدّث القيمة السابقة لكل من الحساس الأول والثاني للقيمة الحالة ومن ثم سنعرض قيمة عدد الزوار على شاشة العرض ذات السبع أجزاء من خلال استدعاء الدالة الخاصة ()displayNumber التي كتبناها سابقًا وسنمرر المتغير Number_Of_Visitors كوسيط لها، مع إضافة تأخير زمني صغير في النهاية بمقدار 50 مللي ثانية من خلال الدالة المدمجة ()delay التي تأخذ وسيطًا واحدًا وهو قيمة التأخير بالمللي ثانية. Las_Inc_Val = Cur_Inc_Val; Las_Dec_Val = Cur_Dec_Val; displayNumber(Number_Of_Visitors); delay(50); } الكود البرمجي النهائي لمشروع نظام قياس عدد الزوار باستخدام الأردوينو Arduino بعد كتابة جميع أجزاء الكود السابقة في ملف واحد نحصل على الكود النهائي التالي للمشروع: int Inc_Sensor = 10; int Dec_Sensor = 9; int displayPins [7] = {2, 3, 4, 5, 6, 7, 8}; int Number_Of_Visitors = 0; int Cur_Inc_Val = 0; int Cur_Dec_Val = 0; int Las_Inc_Val = 0; int Las_Dec_Val = 0; void displayNumber(int num) { const byte numbers[10] = { 0B0111111, // 0 0B0000110, // 1 0B1011011, // 2 0B1001111, // 3 0B1100110, // 4 0B1101101, // 5 0B1111101, // 6 0B0000111, // 7 0B1111111, // 8 0B1101111 // 9 }; for (int i = 0; i < 7; i++) { digitalWrite(displayPins[i], bitRead(numbers[num], i)); } } void setup() { pinMode(Inc_Sensor, INPUT); pinMode(Dec_Sensor, INPUT); for (int i = 0; i < 7; i++) { pinMode(displayPins[i], OUTPUT); } } void loop() { int Cur_Inc_Val = digitalRead(Inc_Sensor); int Cur_Dec_Val = digitalRead(Dec_Sensor); if ((Cur_Inc_Val == LOW) && (Las_Inc_Val == HIGH)) { Number_Of_Visitors++; if ( Number_Of_Visitors > 9) Number_Of_Visitors = 9; } if ((Cur_Dec_Val == LOW) && (Las_Dec_Val == HIGH)) { Number_Of_Visitors--; if ( Number_Of_Visitors < 0) Number_Of_Visitors = 0; } Las_Inc_Val = Cur_Inc_Val; Las_Dec_Val = Cur_Dec_Val; displayNumber(Number_Of_Visitors); delay(50); } محاكاة لمشروع نظام قياس عدد الزوار باستخدام الأردوينو Arduino تعرفنا في المشاريع السابقة على منصة وكوي Wokwi التي تتيح لنا إمكانية محاكاة لوحة الأردوينو ومجموعة متنوعة من العناصر الإلكترونية؛ ولكن على الرغم من هذا التنوع إلا أنها لا تحتوي على جميع العناصر الموجودة في الواقع، فضمن هذه العناصر، حساس الأشعة تحت الحمراء الذي لم يتم إضافته في المنصة حتى الآن، ولكن نستطيع عمل محاكاة لفكرة المشروع مع تعديل بسيط يكمن في استبدال حساس الأشعة تحت الحمراء IR Sensor بمفتاح الضغط اللحظي Push Button، فكلاهما يستخدمان كعنصر دخل رقمي مع الأردوينو، والإختلاف بينهما أن الحساس هو عنصر إلكتروني يعمل تلقائيًا عند وجود جسم أمامه بينما المفتاح هو عنصر ميكانيكي يحتاج للضغط عليه لكي يعمل. سنتبع نفس الخطوات التي تعلمناها في مقالٍ التحكم بتشغيل وإطفاء ليد LED باستخدام الأردوينو Arduino للوصول الى الصفحة الخاصة بمحاكاة مشروعك على موقع وكوي Wokwi. سنضيف الآن العناصر الإلكترونية اللازمة للمشروع، والمتمثللة في كل من Seven Segment و Push Button و Resistors و BreadBoard. غيّر قيم مقاومات الشاشة إلى 220 أوم من خلال الضغط عليها فتظهر لك نافذة في الأعلى تمكنك من تغير القيمة والواحدة. بالطريقة نفسها يمكننا تغيير نوع الشاشة إلى Anode أو Cathode، كما يمكننا تغيير لونها أيضًا من خلال الضغط عليها، حيث ستظهر لنا نافذة بالأعلى نستطيع من خلالها تحديد النوع. بعد ذلك نرتب العناصر على لوحة التجارب بالشكل الذي تراه مناسبًا، ثم صل العناصر بعضها ببعض حسب مخطط التوصيل الآتي: نكتب الكود البرمجي في الجزء الخاص به ثم شغل المحاكاة، ونلاحظ الحالات الآتية: عند بداية التشغيل، ستُعرض القيمة الإبتدائية لمتغير الخاص بعدد الزوار وهي 0 على شاشة العرض ذات السبع أجزاء ومن ثم بانتظار مرور جسم أمام حساس الأشعة تحت الحمراء الأول الخاص بباب الدخول ستزداد قيمة المتغير الخاص بعدد الزوار بمقدار واحد وتتحدث القيمة المعروضة على الشاشة عند مرور جسم أمام حساس الأشعة تحت الحمراء الأول، ويجب هنا الضغط على مفتاح الضغط اللحظي الأول في المحاكاة ستنقص قيمة المتغير الخاص بعدد الزوار بمقدار واحد وتتحدث القيمة المعروضة على الشاشة عند مرور جسم أمام حساس الأشعة تحت الحمراء الثاني عند الضغط على مفتاح الضغط اللحظي الثاني في المحاكاة في حال وقوف الجسم إمام الحساس الأول أو الثاني، لن تتغير قيمة المتغير الخاص بعدد الزوار إلا مرة واحدة. الخلاصة تعلمنا في هذا المقال خطوات تصميم وتنفيذ مشروع نظام لقياس عدد الزوار باستخدام حساس الأشعة تحت الحمراء IR Sensor الذي تعرفنا على بنيته وآلية عمله وكيفية استخدامه مع الأردوينو Arduino، بالإضافة إلى كيفية توصيل العناصر مع بعضها وكتابة الكود الخاص ببرمجة الأردوينو باستخدام بيئة التطوير المتكاملة IDE الخاصة به لتنفيذ المشروع، وعمل محاكاة لآلية عمل المشروع من خلال منصة وكوي Wokwi. نشجعكم لتجربة بناء هذا المشروع والتطوير عليه للحصول على تجربة عملية مفيدة وممتعة. اقرأ أيضًا المقال السابق: لعبة تخمين الأرقام باستخدام الأردوينو Arduino التعرف على أساسيات الأردوينو وتجهيز بيئة العمل بناء إشارة مرور باستخدام الأردوينو Arduino
-
سنتعلم في هذا المقال كيفية بناء لعبة تفاعلية ممتعة من خلال عدة خطوات بسيطة. تطلب هذه اللعبة من المستخدم تخمين الرقم المولد عشوائيًا باستخدام لوحة الأردوينو Arduino، ومجموعة مختلفة من العناصر الإلكترونية التي سبق وأن تعاملنا معها في المشاريع السابقة من سلسلتنا دليل أردوينو، كما سنتعرف في هذا المشروع على عنصر إلكتروني جديد وهو شاشة العرض ذات السبع أجزاء Seven Segment Display. فكرة مشروع لعبة تخمين الأرقام باستخدام الأردوينو Arduino تبدأ اللعبة بعرض الرقم 0 على شاشة العرض ذات الأجزاء السبع Seven Segment Display، ومن ثمة تنتظر حتى يُضغط مفتاح الضغط اللحظي Push Button الأول الخاص بتوليد الرقم العشوائي وعرضه سريعًا على الشاشة كجزء مساعد للمستخدم ليستطيع تخمين الرقم. وفي حال استمرار الضغط على المفتاح الأول، سيتغير الرقم كل 200 مللي ثانية. بعد توليد الرقم العشوائي وتخمينه من قبل المستخدم، سيتمكن من إدخاله إلى اللعبة عبر مفتاح الضغط اللحظي Push Button الثاني من خلال الضغط المستمر عليه، فتبدأ الأرقام بالتزايد بدءًا من الرقم 0 وحتى الرقم 9، ويجب على اللاعب إزالة الضغط عن المفتاح عند الرقم الصحيح، مع إمكانية ضبط سرعة تغير الأرقام من خلال مقاومة متغيرة Potentiometer لتحديد مستوى صعوبة اللعبة. في حال كان تخمين الرقم صحيحًا فإنه سيعرض الرقم الصحيح على شكل وميض مرتين بتأخير زمني لمدة نصف ثانية على الشاشة، ومن ثم ستعود اللعبة إلى البداية؛ أما إذا كان الرقم المخمن خاطئ فإن الرقم 0 سيعرض على شكل وميض مرتين بتأخير زمني لمدة نصف ثانية على الشاشة، ثم ستعود اللعبة إلى البداية لمحاولة تخمين الرقم مرةً أخرى أو لتوليد رقم عشوائي جديد. يوضح المخطط الحالي فكرة المشروع وطريقة تصميمه: العناصر المستخدمة لمشروع التحكم بألوان الإضاءة باستخدام الأردوينو Arduino سنستخدم مجموعةً من العناصر الإلكترونية والأدوات وهي: لوحة أردوينو أونو Arduino Uno كابل البرمجة USB Cable لوحة توصيل التجارب Breadboard مفتاح الضغط اللحظي Push Button عدد 2 مقاومة إلكترونية بقيمة 220 أوم عدد 7 مقاومة متغيرة Potentiometer بقيمة 10 كيلو أوم شاشة العرض ذات السبع أجزاء Seven Segment Display من نوع CC مجموعة أسلاك توصيل من نوع Male to Male شاشة العرض ذات السبع أجزاء Seven Segment Display تستخدم شاشة العرض ذات الأجزاء السبع Seven Segment Display كثيرًا وفي عدة أجهزة وأدوات لعرض القيم الرقمية، مثل الساعات الرقمية الكبيرة وأجهزة عد النقود والميزان الإلكتروني. تتميز هذه الشاشات ببساطة استخدامها وانخفاض ثمنها وسهولة قراءة القيم في جميع ظروف الإضاءة. تتكون شاشة العرض ذات السبع أجزاء Seven Segment Display من ثمانية ليدات LEDs، سبعة منها مخصصة لعرض الأرقام وتكون متوضعة ومرتبة على شكل رقم 8، بحيث يكون كل ليد على شكل خط صغير ويشكل جزءًا من الرقم، ولذلك سميت بشاشة العرض ذات السبع أجزاء Seven Segment، ومن خلال تشغيل الليدات المناسبة، يمكن استخدام هذه الشاشة لعرض الأرقام من 0 حتى 9 بالإضافة إلى بعض الأحرف الأبجدية مثل F ،E ،D ،C ،B ،A؛ أما اللِّيد الثامن فيكون على شكل نقطة ويستخدم في حالة عرض الأرقام العشرية. أنواع شاشة العرض ذات السبع أجزاء Seven Segment Display هناك نوعان من شاشة العرض ذات السبع أجزاء Seven Segment Display من حيث البنية: الشاشات ذات المصاعد المشتركة Common Anode يُعرف هذا النوع من الشاشات اختصارًا بالرمز CA، حيث توصل أقطاب المصاعد لجميع الليدات وهي القطب الموجب لكل ليد ببعضها في هذا النوع، ونتحكم في هذا النوع من الشاشات من خلال توصيل القطب المشترك مع قطب التغذية الموجب Vcc؛ أما القطب الأخر لليدات وهو القطب السالب لكل ليد تكون مرمزة أبجديًا DP ،F ،G ،D ،E ،C ،B ،A، وتوصل مع أقطاب الأردوينو ونعطيها إشارة LOW لتشغيلها أو HIGH لإطفائها. ذات المهابط المشتركة Common Cathode تعرف اختصارًا بالرمز CC، حيث توصل أقطاب المهابط السالبة لجميع الليدات ببعضها في هذا النوع، ونتحكم في هذا النوع من الشاشات من خلال توصيل القطب المشترك مع قطب التغذية السالب Gnd؛ أما القطب الأخر لليدات وهو القطب الموجب لكل ليد، فتكون مرمزة أبجديًا على النحو DP ،F ،G ،D ،E ،C ،B ،A وتوصل مع أقطاب الأردوينو وإعطائها إشارة HIGH لتشغيلها أو LOW لإطفائها. كما تتوفر عدة أنواع أخرى من شاشة العرض ذات السبع أجزاء Seven Segment Display من حيث ألوان الليدات وهي الأحمر والأخضر والأزرق، ويختلف حجم الشاشة أيضًا حسب الاستهلاك الأكبر، وحسب عدد الخانات التي سنستخدمها في مشاريع مستقبلية. كيفية استخدام شاشة العرض ذات السبع أجزاء Seven Segment Display نستطيع عرض الأرقام من خلال تشغيل بعض الليدات وإطفاء الأخرى على حسب الرقم المراد عرضه على الشاشة، فلعرض الرقم 0 مثلًا، سنحتاج لتشغيل جميع الليدات عدا اللِّيد ذي الرمز G؛ أما لعرض الرقم 1 فنحتاج لتشغيل اللِّيد B وC فقط، وهكذا بنفس الطريقة نستطيع عرض أي رقم من 0 وحتى 9 من خلال تغيير الليدات المضاءة فقط، والجدول الآتي يوضح الليدات التي يجب أن تضيء مع كل رقم: تطبيق بسيط على شاشة العرض ذات السبع أجزاء Seven Segment Display سنبني تطبيقًا بسيطًا لعرض بعض الأرقام من خلال لوحة الأردوينو Arduino وشاشة العرض ذات السبع أجزاء Seven Segment Display. ولتنفيذ هذا التطبيق سنتبع الخطوات التالية لتوصيل الشاشة مع لوحة الأردوينو: نصل الرِّجل ذات الرمز A من الشاشة مع الرِّجل الأولى للمقاومة، ووصل الرِّجل الثانية للمقاومة مع القطب رقم 2 في لوحة الأردوينو Arduino نصل الرِّجل ذات الرمز B من الشاشة مع الرِّجل الأولى للمقاومة، ونصل الرِّجل الثانية للمقاومة مع القطب رقم 3 في لوحة الأردوينو Arduino نصل الرِّجل ذات الرمز C من الشاشة مع الرِّجل الأولى للمقاومة، ونصل الرِّجل الثانية للمقاومة مع القطب رقم 4 في لوحة الأردوينو Arduino نصل الرِّجل ذات الرمز D من الشاشة مع الرِّجل الأولى للمقاومة، ونصل الرِّجل الثانية للمقاومة مع القطب رقم 5 في لوحة الأردوينو Arduino نصل الرِّجل ذات الرمز E من الشاشة مع الرِّجل الأولى للمقاومة، ونصل الرِّجل الثانية للمقاومة مع القطب رقم 6 في لوحة الأردوينو Arduino نصل الرِّجل ذات الرمز F من الشاشة مع الرِّجل الأولى للمقاومة، ونصل الرِّجل الثانية للمقاومة مع القطب رقم 7 في لوحة الأردوينو Arduino نصل الرِّجل ذات الرمز G من الشاشة مع الرِّجل الأولى للمقاومة، ونصل الرِّجل الثانية للمقاومة مع القطب رقم 8 في لوحة الأردوينو Arduino نصل الرِّجل المشتركة CO من الشاشة مع القطب السالب GND في لوحة الأردوينو Arduino توضح الصورة التالية مخطط التوصيل وأقطاب شاشة العرض ذات السبع أجزاء: الخطوة التالية هي كتابة الكود البرمجي للتطبيق. سنتعرف في البداية على مجموعة من الماكرو باستخدام تعليمات define# من أجل ربط أقطاب الشاشة مع لوحة الأردوينو، وداخل الدالة الرئيسية ()setup سنضبط هذه الأقطاب كأقطاب خرج OUTPUT من خلال الدالة المدمجة ()pinMode التي تأخذ وسيطين: الأول رقم القطب والثاني نوع القطب إما بخرج OUTPUT أو دخل INPUT؛ أما في الدالة التكرارية ()loop فسنشغل بعض الليدات للحصول على الرقم المطلوب، وقد اخترنا الرقم 1، لتشغيل اللِّيد B واللِّيد C، ويمكن تعديل تشغيل وإطفاء الليدات حسب الجدول السابق للحصول على الرقم الذي تريده؛ كما يمكن أن نتحكم بتشغيل وإطفاء الأقطاب الرقمية من خلال الدالة المدمجة ()digitalWrite التي تأخذ وسيطين هما رقم القطب، وحالة أو قيمة القطب من خلال إعطاءه قيمة 1 منطقي أو HIGH للتشغيل و 0 منطقي أو LOW للإطفاء. #define a 2 #define b 3 #define c 4 #define d 5 #define e 6 #define f 7 #define g 8 void setup() { pinMode(a, OUTPUT); pinMode(b, OUTPUT); pinMode(c, OUTPUT); pinMode(d, OUTPUT); pinMode(e, OUTPUT); pinMode(f, OUTPUT); pinMode(g, OUTPUT); } void loop() { digitalWrite(a, LOW); digitalWrite(b, HIGH); digitalWrite(c, HIGH); digitalWrite(d, LOW); digitalWrite(e, LOW); digitalWrite(f, LOW); digitalWrite(g, LOW); } ملاحظة: الكود السابق خاص بالشاشة من نوع مهابط مشتركة CC، لذا في حال كانت الشاشة من نوع المصاعد المشتركة CA، فيكفي أن نعكس أوامر التشغيل والإيقاف فقط، بحيث تصبح بالشكل التالي: digitalWrite(a, HIGH); digitalWrite(b, LOW); digitalWrite(c, LOW); digitalWrite(d, HIGH); digitalWrite(e, HIGH); digitalWrite(f, HIGH); digitalWrite(g, HIGH); ولمعرفة نوع الشاشة التي لدينا يمكن استخدام جهاز القياس المتعدد Multimeter في وضع فحص الليد ونجرب وصل القطب المشترك CO للشاشة الموجود في المنتصف مع الطرف الموجب الأحمر للمقياس، وإحدى الأقطاب الأخرى للشاشة نوصلها مع الطرف الأسود السالب للمقياس. وهنا في حال إضاءة جزء من الشاشة تكون من نوع مصاعد مشتركة Common Anode أو CA. بعد ذلك، سنوصل القطب المشترك الموجود بالمنتصف CO للشاشة مع الطرف الأسود السالب للمقياس، وإحدى الأقطاب الأخرى للشاشة نوصلها مع الطرف الأحمر الموجب للمقياس، وهنا في حال إضاءة جزء من الشاشة، ستكون من نوع مهابط مشتركة Common cathode أو CC. مخطط التوصيل لمشروع لعبة تخمين الأرقام باستخدام الأردوينو Arduino سنتبع الخطوات الآتية في عملية توصيل العناصر والأسلاك مع لوحة الأردوينو Arduino لتنفيذ فكرة المشروع نصل أقطاب التغذية في لوحة الأردوينو أونو Arduino Uno مع لوحة توصيل التجارب BreadBoard نثبت شاشة العرض ذات السبع أجزاء Seven Segment Display على لوحة توصيل التجارب BreadBoard نصل أقطاب الشاشة مع المقاومات الإلكترونية ولوحة الأردوينو Arduino بنفس الخطوات التي نفذناها في التطبيق السابق نصل رجل التغذية الأولى Vcc للمقاومة المتغيرة Potentiometer مع المسرى الموجب في لوحة توصيل التجارب BreadBoard نصل رجل التغذية الأخرى Gnd للمقاومة المتغيرة Potentiometer مع المسرى السالب في لوحة توصيل التجارب BreadBoard نصل رجل إشارة الخرج التشابهي Sig للمقاومة المتغيرة Potentiometer مع القطب A5 في لوحة الأردوينو أونو Arduino Uno وصل الطرف الأول لجميع مفاتيح الضغط اللحظية Push Buttons مع المسرى السالب للوحة التجارب BreadBoard وصل الطرف الثاني للمفتاح الأول مع القطب رقم 9، والطرف الثاني للمفتاح الثاني مع القطب رقم 10 في لوحة الأردوينو أونو Arduino Uno وبهذا سنُفعّل مقاومة الرفع الداخلية للمتحكم الموجود في لوحة الأردوينو Arduino برمجيًا؛ لذلك لا داعي لتوصيل مقاومات رفع Pull-Up أو مقاومات خفض Pull-Down مع مفاتيح الضغط اللحظية Push Buttons. توضح الصورة التالية مخطط التوصيل لمشروع لعبة تخمين الأرقام باستخدام الأردوينو Arduino: الكود البرمجي لمشروع لعبة تخمين الأرقام باستخدام الأردوينو Arduino سنعرف اثنين من الماكرو في بداية الكود خاصة بأرقام الأقطاب الرقمية لمفاتيح الضغط اللحظية Push Button ورقم القطب التشابهي الخاص بالمقاومة المتغيرة Potentiometer. #define guessButtonPin 9 #define SetButtonPin 10 #define POT A5 شرحنا سابقًا كيفية استخدام الماكرو في مقال تخمين عدد مرات وميض اللِّيد باستخدام الأردوينو Arduino، كما يمكن الاطلاع أكثر على مفهوم الماكرو وأنواعه من خلال مقال الماكرو Macro والمعالج المسبق Preprocessor في لغة سي C؛ أما بالنسبة لأرقام الأقطاب الرقمية الخاصة بشاشة العرض ذات السبع أجزاء، فسنعرفها ضمن مصفوفة أحادية من نوع أعداد صحيحة int وبداخلها أرقام أقطاب الشاشة بالترتيب. const int displayPins[7] = {2, 3, 4, 5, 6, 7, 8}; سنحتاج أيضًا لتعريف ثلاثة متغيرات صحيحة EstimatedNumber لتخزين الرقم المخمن، وnumberToGuess لتخزين الرقم المراد تخمينه، وspeed لتخزين مستوى السرعة عند إدخال الرقم المخمن. int EstimatedNumber = 0; int numberToGuess = 1; int speed = 0; كما رأينا في التطبيق السابق فقد عرضنا الرقم على الشاشة من خلال إعطاء أمر التشغيل والإطفاء منفصلًآ لكل ليد من ليدات الشاشة، ولكن هذه الطريقة تستهلك أسطرًا برمجيةً كثيرة، فعند كل رقم نريد إظهاره على الشاشة سنحتاج إلى 7 أسطر برمجية، بالتالي استهلاك كبير لذاكرة البرنامج Flash Memory في الأردوينو Arduino، ولذلك سنبني دالةً خاصةً تستقبل وسيطًا واحدًا، وهو الرقم الذي نريد عرضه على الشاشة، مع عرض هذا الرقم بطريقة ديناميكية وسهلة. سنعرف داخل هذه الدالة مصفوفة من نوع بايت byte بحجم 10 عناصر لأنه لدينا عشرة أرقام من الرقم 0 إلى الرقم 9، وبداخل هذه المصفوفة سنكتب القيم الخاصة بتشغيل وإطفاء ليدات الشاشة بالنظام الثنائي Binary System بنفس قيم الجدول السابق، وبعد ذلك سنستخدم حلقةً تكراريةً ()for للمرور على جميع عناصر المصفوفة []displayPins التي تخزن أرقام أقطاب الشاشة وإعطاء أمر التشغيل أو الإطفاء المقابل للقطب من خلال المصفوفة []numbers باستخدام الدالة المدمجة ()digitalWrite. وللوصول الصحيح للقيمة المقابلة لكل قطب من الشاشة سنستخدم الدالة المدمجة ()bitRead التي تأخذ وسيطين هما الرقم الذي نريد قراءة بت واحد منه، ورقم البت حيث يبدأ من الرقم 0 للبت الأول من اليمين؛ وتعيد هذه الدالة قيمة هذا البت 1 أو 0. void displayNumber(int num) { const byte numbers[10] = { 0B0111111, // 0 0B0000110, // 1 0B1011011, // 2 0B1001111, // 3 0B1100110, // 4 0B1101101, // 5 0B1111101, // 6 0B0000111, // 7 0B1111111, // 8 0B1101111 // 9 }; for (int i = 0; i < 7; i++) { digitalWrite(displayPins[i], bitRead(numbers[num], i)); } } سنحتاج أيضًا إلى دالة خاصة أخرى ()displayOFF وظيفتها إطفاء الشاشة وعدم عرض أي رقم، وذلك من خلال حلقة تكرارية ()for للمرور على جميع عناصر المصفوفة []displayPins التي تخزن أرقام أقطاب الشاشة، وإطفائها من خلال الدالة المدمجة ()digitalWrite . void displayOFF() { for (int i = 0; i < 7; i++) { digitalWrite(displayPins[i], LOW); } } في الدالة الرئيسية ()setup سنضبط الأقطاب الخاصة بالمفاتيح اللحظية Push Button كأقطاب دخل مع تفعيل مقاومة الرفع الداخلية INPUT_PULLUP، والأقطاب الخاصة بالشاشة كأقطاب خرج OUTPUT، وذلك من خلال الدالة المدمجة ()pinMode، بعدها سنعرض الرقم 0 على الشاشة من خلال استدعاء الدالة الخاصة ()displayNumber وتمرير الرقم 0 كوسيط لها. void setup() { pinMode(guessButtonPin, INPUT_PULLUP); pinMode(SetButtonPin, INPUT_PULLUP); for (int i = 0; i < 7; i++) { pinMode(displayPins[i], OUTPUT); } displayNumber(0); } في بداية الدالة التكرارية ()loop سنقرأ قيمة المقاومة المتغيرة Potentiometer عبر الدالة المدمجة ()analogRead التي تأخذ وسيطًا واحدًا Pin وهو رقم القطب الموصول عليه العنصر التشابهي، من A0 إلى A5 في لوحة الأردوينو أونو Arduino Uno. تعيد هذه الدالة قيمةً عدديةً صحيحةً ضمن المجال من 0 إلى 1023، وتمثل القيمة الرقمية المقابلة لقيمة الجهد الموصول على القطب المحدد Pin، وسنخزن هذه القيمة في المتغير speed ثم نغير مجال القيم من 0-1023 إلى المجال 100-500، من خلال الدالة المدمجة ()map التي تأخذ خمسة وسطاء كالآتي: قيمة المتغير الذي نريد تحويله الوسيط الثاني لمجال القيم القديم الذي نريد التحويل منه الوسيط الثالث لمجال القيم القديم الذي نريد التحويل منه 4.الوسيط الرابع لمجال القيم الجديد الذي نريد التحويل إليه الوسيط الخامس لمجال القيم القديم الذي نريد التحويل منه void loop() { speed= analogRead(POT); speed = map(speed, 0, 1024, 100, 500); بعد ذلك سنتحقق من حالة المفتاح اللحظي الأول المسؤول عن توليد رقم عشوائي لتخمينه من خلال العبارة الشرطية ()if، وفي حال كان هذا المفتاح مضغوطًا فسنولد رقمًا عشوائيًا باستخدام الدالة المدمجة ()random التي تأخذ وسيطين هما: الوسيط الأقل قيمة، وتكون ضمن المجال الوسيط الأكبر قيمة وتكون خارج المجال تعيد هذه الدالة قيمة عشوائية سنخزنها في المتغير numberToGuess، وسنعرض هذا الرقم على الشاشة بسرعة، وفي حال استمرار الضغط على المفتاح أكثر من 200 مللي ثانية سيولّد رقمًا عشوائيًا جديدًا. if (digitalRead(SetButtonPin) == LOW) { numberToGuess = random(0, 10); displayNumber(numberToGuess); delay(500); } الآن أصبح الرقم المراد تخمينه مخزنًا في المتغير numberToGuess ضمن ذاكرة الأردوينو، وبانتظار الضغط على المفتاح اللحظي الثاني لإدخال الرقم المخمن؛ بالتالي سنتحقق برمجيًا من حالة المفتاح الثاني المسؤول عن إدخال الرقم المخمن من خلال العبارة الشرطية ()if؛ وفي حال كان مضغوطًا، سنزيد قيمة المتغير EstimatedNumber بمقدار 1؛ أما في حال أصبح أكبر من الرقم 9، فسنعيد قيمته إلى الصفر، ومن ثم نعرض الرقم على الشاشة ونضع تأخير زمني بمقدار قيمة المتغير speed من خلال من خلال الدالة ()delay. if (digitalRead(guessButtonPin) == LOW) { EstimatedNumber++; if (EstimatedNumber > 9) EstimatedNumber = 0; displayNumber(EstimatedNumber); delay(speed); displayNumber(0); } الخطوة الأخيرة هي التأكد من قيمة الرقم المخمن إذا كانت مطابقة للرقم المراد تخمينه؛ فعند إزالة الضغط عن المفتاح الثاني والتأكد أن للرقم المخمن قيمة لا تساوي الصفر، سنقارن قيمة الرقم المخمن مع قيمة الرقم المراد تخمينه. وهنا في حال كانت مطابقة، سنعيد قيمة الرقم المخمن إلى الصفر ثم نعرض الرقم الصحيح على الشاشة لمدة نصف ثانية واحدة، ثم نطفئ الشاشة لمدة نصف ثانية ونكرر هذه العملية مرةً أخرى ثم نعود إلى بداية اللعبة من خلال عرض الرقم 0 على الشاشة. لكن في حال كانت القيمة غير مطابقة، فسنعيد قيمة الرقم المخمن إلى الصفر أيضًا ونعرض الرقم 0 لمدة نصف ثانية واحدة، ثم نطفئ الشاشة لمدة نصف ثانية ونكرر هذه العملية مرةً أخرى ثم نعود إلى بداية اللعبة من خلال عرض الرقم 0، ويكون ثابتًا على الشاشة. else if ((digitalRead(guessButtonPin) == HIGH) && (EstimatedNumber != 0)) { if (EstimatedNumber == numberToGuess) { EstimatedNumber = 0; displayNumber(numberToGuess); delay(500); displayOFF(); delay(500); displayNumber(numberToGuess); delay(500); displayOFF(); delay(500); displayNumber(0); } else { EstimatedNumber = 0; displayNumber(0); delay(500); displayOFF(); delay(500); displayNumber(0); delay(500); displayOFF(); delay(500); displayNumber(0); } } الكود البرمجي النهائي لمشروع لعبة تخمين الأرقام باستخدام الأردوينو Arduino سنعرض الآن الكود البرمجي النهائي للعبة تخمين الأرقام التي عملنا عليها: #define guessButtonPin 9 #define SetButtonPin 10 #define POT A5 const int displayPins[7] = {2, 3, 4, 5, 6, 7, 8}; int EstimatedNumber = 0; int numberToGuess = 1; int speed = 0; void displayNumber(int num) { const byte numbers[10] = { 0B0111111, // 0 0B0000110, // 1 0B1011011, // 2 0B1001111, // 3 0B1100110, // 4 0B1101101, // 5 0B1111101, // 6 0B0000111, // 7 0B1111111, // 8 0B1101111 // 9 }; for (int i = 0; i < 7; i++) { digitalWrite(displayPins[i], bitRead(numbers[num], i)); } } void displayOFF() { for (int i = 0; i < 7; i++) { digitalWrite(displayPins[i], LOW); } } void setup() { pinMode(guessButtonPin, INPUT_PULLUP); pinMode(SetButtonPin, INPUT_PULLUP); for (int i = 0; i < 7; i++) { pinMode(displayPins[i], OUTPUT); } displayNumber(0); } void loop() { speed= analogRead(A5); speed = map(speed, 0, 1024, 100, 500); if (digitalRead(SetButtonPin) == LOW) { numberToGuess = random(0, 10); displayNumber(numberToGuess); delay(200); displayNumber(0); } if (digitalRead(guessButtonPin) == LOW) { EstimatedNumber++; if (EstimatedNumber > 9) EstimatedNumber = 0; displayNumber(EstimatedNumber); delay((speed)); displayNumber(0); } else if ((digitalRead(guessButtonPin) == HIGH) && (EstimatedNumber != 0)) { if (EstimatedNumber == numberToGuess) { EstimatedNumber = 0; displayNumber(numberToGuess); delay(500); displayOFF(); delay(500); displayNumber(numberToGuess); delay(500); displayOFF(); delay(500); displayNumber(0); } else { EstimatedNumber = 0; displayNumber(0); delay(500); displayOFF(); delay(500); displayNumber(0); delay(500); displayOFF(); delay(500); displayNumber(0); } } } محاكاة لمشروع لعبة تخمين الأرقام باستخدام الأردوينو Arduino سنتبع نفس الخطوات التي تعلمناها في مقال التحكم بتشغيل وإطفاء ليد LED باستخدام الأردوينو Arduino للوصول للصفحة الخاصة بمحاكاة المشروع على موقع وكوي Wokwi. بعد ذلك سنضيف العناصر الإلكترونية اللازمة للمشروع وهي كل من Seven Segment و Potentiometer و Push Button و Resistors و BreadBoard. سنغيّر قيم مقاومات الشاشة إلى 220 أوم من خلال الضغط عليها، وستظهر لنا نافذة في الأعلى تمكننا من تغيير القيمة والواحدة. بالطريقة نفسها يمكننا تغير نوع الشاشة ولونها من خلال الضغط عليها، لتظهر لنا نافذة بالأعلى نستطيع من خلالها تحديد النوع. سنرتب الآن العناصر على لوحة التجارب بالشكل الذي نراه مناسبًا، ثم نصل العناصر بعضها ببعض حسب مخطط التوصيل الذي عرضناه سابقًا. بعد الانتهاء من كل شيء لا بد من التأكد من كتابة الكود البرمجي في الجزء الخاص به ثم نشغل المحاكاة ونلاحظ الآتي: عند بداية اللعبة سيعرض الرقم 0 على الشاشة. وهنا علينا انتظار ضغط اللعبة على المفتاح اللحظي الأول Push Button الأول لتوليد رقم عشوائي لتخمينه عند استمرار الضغط على المفتاح الأول لمدة تزيد عن 200 مللي ثانية سيتولد رقم عشوائي جديد مع عرض هذا الرقم على الشاشة بسرعة بعد توليد رقم عشوائي وتخمينه، سنضغط على المفتاح اللحظي Push Button الثاني باستمرار لإدخال الرقم المخمن إلى اللعبة، وسيبدأ من الرقم 0 ويزداد كل فترة زمنية تحدد من خلال المقاومة المتغيرة، وعند الوصول للرقم الذي نريده، سنتوقف عن الضغط عن المفتاح في حال كان الرقم المخمن صحيح سيعرض على الشاشة على شكل وميض مرتين كل ثانية وإذا كان خاطئ سيعرض الرقم 0 على الشاشة على شكل وميض مرتين كل ثانية في النهاية ستعود اللعبة إلى البداية ويعرض الرقم 0 على الشاشة إلى أن يضغط المفتاح الأول لتوليد رقم عشوائي جديد أو أن يضغط المفتاح الثاني لتخمين الرقم السابق مرةً أخرى. الخاتمة بهذا نكون قد قدمنا شرحًا مفصلًا حول كيفية بناء لعبة تفاعلية باستخدام لوحة الأردوينو من خلال عدة خطوات بسيطة وتعرفنا على شاشة العرض ذات السبع أجزاء Seven Segment وأنواعها وكيفية استخدامها وربطها مع الأردوينو، بالإضافة إلى مجموعة من النصائح والمهارات لتحسين جودة وكفاءة مشروعنا. اقرأ أيضًا المقال السابق: بناء آلة بيانو بسيطة باستخدام الأردوينو التعرف على أساسيات الأردوينو وتجهيز بيئة العمل إضاءة زينة بأنماط مختلفة باستخدام الأردوينو Arduino التحكم باللِّيد LED باستخدام مفتاح الضغط اللحظي Push Button والأردوينو Arduino
-
نوضح في هذا المقال كيفية إصدار الأصوات والنغمات من خلال لوحة الأردوينو Arduino وعنصر الجرس الإلكترونية Buzzer ومجموعة من مفاتيح الضغط اللحظية Push Button لبناء مشروع لآلة البيانو الموسيقية. فكرة مشروع بناء آلة البيانو الموسيقية سنصمم بيانو صغير يحتوي على سبعة مفاتيح لحظية Push Buttons، يسبب كل مفتاح إصدار صوت بتردد Frequency مختلف عند الضغط عليه من خلال الجرس الإلكتروني Buzzer وهو العنصر المسؤول عن إصدار الصوت، حيث أن هذه الترددات السبعة التي اخترناها هي الترددات الأساسية في السلم الموسيقي دو، ري، مي، فا، صول، لا، سي وسنخزن هذه الترددات في الذاكرة الخاصة بلوحة الأردوينو، مما يتيح لنا إمكانية تغيير أصوات البيانو برمجيًا عن طريق تعديل هذه الترددات. العناصر المستخدمة لمشروع بناء آلة البيانو الموسيقية باستخدام أردوينو سنستخدم في مشروعنا مجموعة من العناصر الإلكترونية والأدوات وهي: لوحة أردوينو أونو Arduino Uno كابل البرمجة USB Cable لوحة توصيل التجارب Breadboard مفتاح الضغط اللحظي Push Button عدد 7 جرس إلكتروني Buzzer غير فعال Passive مجموعة أسلاك توصيل من نوع Male to Male وقد تعاملنا مع معظم هذه العناصر في المشاريع التي طورناها في المقالات السابقة من سلسلتنا دليل أردوينو وسنتعامل في هذا المشروع مع عنصر إلكتروني جديد لم يسبق لنا استخدامه وهو الجرس الإلكتروني Buzzer. الجرس الإلكتروني Buzzer هو عبارة عن عنصر إلكتروني يستخدم لتوليد الأصوات والنغمات من خلال تحويل الطاقة الكهربائية إلى صوت مسموع، ويتكون من غشاء يشبه الطبل يصنع عادة من مواد مرنة قابلة للاهتزاز كالبلاستيك أو المعدن،عندما يمر التيار الكهربائي عبر الجرس، يُسبب ذلك تشوه الغشاء. وعندما يتوقف التيار الكهربائي، يعود الغشاء إلى شكله الطبيعي، ومع تكرار مرور التيار وإيقافه بسرعة سيؤدي ذلك إلى اهتزاز هذا الغشاء مما سيؤدي بدوره لتوليد الصوت، ويستخدم الجرس الإلكتروني Buzzer في العديد من التطبيقات مثل أجهزة الإنذار والألعاب والهواتف وغيرها. هناك نوعان من الأجراس الإلكترونية Buzzers الأول هو النوع الفعّال Active، والذي يحتوي على دائرة كهربائية داخلية مدمجة تمكنه من العمل عند تغذيته مباشرة من مصدر جهد مستمر ثابت DC. أما النوع الثاني فهو النوع غير الفعّال Passive، والذي يختلف عن النوع الأول بأنه لا يحتوي على دائرة داخلية لتوليد الصوت، وبالتالي يحتاج إلى مصدر تغذية يعمل بتردد معين لتوليد الأصوات. تحديد نوع الجرس الإلكتروني يمكن تحديد نوع الجرس الإلكتروني بسهولة من خلال تجربة توصيله بمصدر تغذية مستمر بجهد 5V. فإذا أصدر الجرس صوتًا عند توصيله، فإن الجرس يكون من النوع الفعّال Active، ويُستخدم هذا النوع عادة في التطبيقات التي تتضمن دوائر إلكترونية بسيطة دون وجود وحدة تحكم، إذ يُستخدم الجرس لإصدار تنبيهات بسيطة من خلال تشغيله وإيقافه مباشرة. أما إذا لم يصدر الجرس أي صوت عند توصيله، فسيكون من النوع غير الفعّال Passive، ويُستخدم هذا النوع في الدوائر الإلكترونية الأكثر تعقيدًا والتي تحتوي على وحدة تحكم، حيث يُمكن التحكم بالصوت بشكل أكبر وتوليد نغمات وأصوات مخصصة. توضح الصورة التالية الفرق بين الجرس الإلكتروني الفعّال Activ وغير الفعّال Passive. يعد الجرس الإلكتروني عنصرًا رقميًّا ويمكننا توصيله مع أحد الأقطاب الرقمية والتحكم في تشغيله من خلال الدالة المدمجة ()digitalWrite، ومن الممكن أيضًا توصيله مع أقطاب تقنية تعديل عرض النبضة PWM للحصول على نغمات وأصوات مختلفة، كما تتيح بيئة تطوير أردوينو Arduino IDE دوال مدمجة أخرى خاصة بالتعامل مع الجرس الإلكتروني Buzzer بسهولة وسنتعرف عليها في الفقرات التالية. الدوال البرمجية الخاصة بالجرس الإلكتروني Buzzer يمكننا إنشاء الأصوات والتحكم في نغمات الجرس الإلكتروني، من خلال الدوال التالية: دالة إصدار صوت الجرسtone تستخدم الدالة ()tone لتوليد إشارة مربعة لتشغيل الجرس بتردد محدد وبدورة عمل Duty Cycle تساوي 50%، ونمرر لهذه الدالة ثلاثة وسطاء عند وهي: رقم القطب الموصول عليه الجرس الإلكتروني Buzzer، ويمكن استخدام أي قطب من الأقطاب الرقمية في لوحة الأردوينو أونو Arduino Uno التردد الخاص بالإشارة المربعة، وبتغير قيمة هذا الوسيط سنحصل على نغمات وأصوات مختلفة، ويجب أن لا يقل تردد الإشارة عن 31 هرتز الوسيط الثالث اختياري ويمكن عدم كتابته، وهو مدة تشغيل الجرس بالمللي ثانية، وفي حال عدم وضعه سيستمر الجرس بالعمل دالة إيقاف صوت الجرس noTone تستخدم الدالة ()noTone لإيقاف توليد الإشارة المربعة المولدة من الدالة ()tone أي أنها توقف الجرس عن العمل، وتأخذ وسيطًا واحدًا وهو رقم القطب الموصول عليه الجرس الإلكتروني Buzzer مخطط توصيل مشروع آلة البيانو الموسيقية باستخدام أردوينو لتنفيذ فكرة المشروع، اتبع الخطوات الآتية لتوصيل العناصر والأسلاك مع لوحة الأردوينو Arduino صل أقطاب التغذية في لوحة الأردوينو أونو Arduino Uno مع لوحة توصيل التجارب BreadBoard، إذ يوصل القطب 5v في لوحة الأردوينو مع المسرى الموجب للوحة التجارب، والقطب GND في لوحة الأردوينو مع المسرى السالب للوحة التجارب من خلال أسلاك التوصيل صل الرجل الأقصر التي تمثل القطب السالب الخاصة بالجرس الإلكتروني Buzzer مع المسرى السالب في لوحة توصيل التجارب BreadBoard صل الرجل الأطول التي تمثل القطب الموجب الخاصة بالجرس الإلكتروني Buzzer مع القطب رقم 12 في لوحة الأردوينو أونو Arduino Uno صل الطرف الأول لجميع مفاتيح الضغط اللحظية Push Buttons مع المسرى السالب للوحة التجارب BreadBoard، ثم صل الطرف الثاني للمفاتيح Push Buttons على الترتيب مع الأقطاب في لوحة الأردوينو أونو Arduino Uno من القطب رقم 10 وحتى القطب رقم 4 سنفعّل مقاومة الرفع الداخلية للمتحكم الموجود في لوحة الأردوينو Arduino برمجيًا لذلك لا داعي لتوصيل مقاومات رفع Pull-Up أو مقاومات خفض Pull-Down مع مفاتيح الضغط اللحظية Push Buttons الكود البرمجي لمشروع بناء آلة البيانو الموسيقية بأردوينو في البداية سنعرف مجموعة من الماكرو خاصة بالترددات التي تمثل النغمات الرئيسية في السلم الموسيقي دو، ري، مي، فا، صول، لا، سي ويمكننا اختيار أي نغمات نريدها بوضع تردد النغمة فقط. #define C_4 261 #define D_4 293 #define E_4 329 #define F_4 349 #define G_4 392 #define A_4 440 #define B_4 493 نحتاج لتعريف مجموعة أخرى من الماكرو خاصة بأقطاب المفاتيح التي ستوصل مع لوحة الأردوينو بالإضافة إلى القطب الذي سيوصل الجرس الإلكتروني Buzzer مع لوحة الأردوينو #define C 10 #define D 9 #define E 8 #define F 7 #define G 6 #define A 5 #define B 4 #define Buzz 12 شرحنا كيفية استخدام الماكرو في مقال تخمين عدد مرات وميض الليد باستخدام الأردوينو Arduino كما يمكنك الاطلاع أكثر على مفهوم الماكرو وأنواعه من خلال مقال الماكرو Macro والمعالج المسبق Preprocessor في لغة سي C. سنضبط في الدالة الرئيسية ()setup نوع الأقطاب المستخدمة، حيث أن القطب الخاص بالجرس الإلكتروني Buzzer يُضبط كقطب خرج OUTPUT والاقطاب الخاصة بالمفاتيح اللحظية Push Buttons تُضبط كأقطاب دخل مع تفعيل مقاومة الرفع الداخلية INPUT_PULLUP، حيث أن الدالة المدمجة المسؤولة عن ضبط نوع القطب هي ()pinMode والتي تأخذ وسيطين الأول رقم القطب والثاني نوع القطب إما خرج OUTPUT أو دخل INPUT. void setup() { pinMode(C, INPUT_PULLUP); pinMode(D, INPUT_PULLUP); pinMode(E, INPUT_PULLUP); pinMode(F, INPUT_PULLUP); pinMode(G, INPUT_PULLUP); pinMode(A, INPUT_PULLUP); pinMode(B, INPUT_PULLUP); pinMode(Buzz, OUTPUT); } وسنستخدم في الدالة التكرارية ()loop عدة حلقات تكرارية ()While كل حلقة خاصة بكل مفتاح وسيكون الشرط بداخل كل حلقة هو أن يكون المفتاح مضغوط LOW حيث نقرأ حالة المفتاح من خلال الدالة المدمجة ()digitalRead التي تأخذ وسيطًا واحدًا وهو رقم القطب وتعيد القيمة الفيزيائية الموجودة على القطب، فعند الضغط على المفتاح الأول الموصول على القطب رقم 10 مثلًا سيتحقق الشرط الخاص بالحلقة التكرارية الأولى ويعمل الجرس الإلكتروني Buzzer وفق التردد الأول 261 هرتز ونستخدم الدالة المدمجة ()tone لتشغيل الجرس الإلكتروني Buzzer كما شرحنا سابقًا. void loop() { while (digitalRead(C) == LOW) { tone(Buzz, C_4); } while (digitalRead(D) == LOW) { tone(Buzz, D_4); } while (digitalRead(E) == LOW){ tone(Buzz, E_4); } while (digitalRead(F) == LOW) { tone(Buzz, F_4); } while (digitalRead(G) == LOW) { tone(Buzz, G_4); } while (digitalRead(A) == LOW) { tone(Buzz, A_4); } while (digitalRead(B) == LOW) { tone(Buzz, B_4); } عند تجربة الكود السابق نلاحظ أنه يعمل بشكل جيد ولكن مع وجود مشكلة صغيرة فعند إزالة الضغط عن المفتاح سيستمر الجرس الإلكتروني Buzzer بإصدار الصوت بنفس التردد السابق حتى الضغط على مفتاح آخر ليصدر الجرس الإلكتروني Buzzer صوت آخر بتردد مختلف، لذا نحتاج لحل هذه المشكلة بحيث يتوقف الجرس عن إصدار الصوت بشكل تام عند إزالة الضغط عن أي مفتاح. ونستطيع حل هذه المشكلة بسهولة من خلال إيقاف تشغيل الجرس الإلكتروني Buzzer في نهاية الكود من خلال استدعاء الدالة ()noTone التي شرحناها سابقًا noTone(Buzz); بهذه الطريقة يكون الكود البرمجي جاهزًا لتجربته. كما يمكننا التعديل على الكود فمثلًا يمكن استخدام العبارات الشرطية if و else if بدلًا من الحلقة التكرارية While وتعديل ما يلزم، أو إضافة ميزات أخرى مثل إضافة الليد متعدد الألوان RGB LED ليضيء بلون مختلف عند كل صوت مختلف فمثلًا عند الضغط على المفتاح الأول سيضيء الليد متعدد الألوان RGB LED باللون الأحمر وستصبح الحلقة التكرارية الأولى بالشكل الآتي: while (digitalRead(C) == LOW) { tone(Buzz, C_4); analogWrite(Red_Pin, 255); analogWrite(Green_Pin, 0); analogWrite(Blue_Pin, 0); } ولكن علينا الانتباه لتعديل مخطط التوصيل بحيث أن أقطاب الليد متعدد الألوان RGB LED يجب أن توصل مع أقطاب لوحة الأردوينو التي تدعم تقنية تعديل عرض النبضة PWM والتي نجد بجانبها الرمز ~ وأرقام هذه الأقطاب هي 3، 5، 6، 9، 10، 11 الكود البرمجي النهائي لمشروع آلة بيانو باستخدام الأردوينو #define C_4 261 #define D_4 293 #define E_4 329 #define F_4 349 #define G_4 392 #define A_4 440 #define B_4 493 #define C 10 #define D 9 #define E 8 #define F 7 #define G 6 #define A 5 #define B 4 #define Buzz 12 void setup(){ pinMode(C, INPUT_PULLUP); pinMode(D, INPUT_PULLUP); pinMode(E, INPUT_PULLUP); pinMode(F, INPUT_PULLUP); pinMode(G, INPUT_PULLUP); pinMode(A, INPUT_PULLUP); pinMode(B, INPUT_PULLUP); } void loop(){ while (digitalRead(C) == LOW){ tone(Buzz, C_4); } while (digitalRead(D) == LOW){ tone(Buzz, D_4); } while (digitalRead(E) == LOW){ tone(Buzz, E_4); } while (digitalRead(F) == LOW){ tone(Buzz, F_4); } while (digitalRead(G) == LOW){ tone(Buzz, G_4); } while (digitalRead(A) == LOW){ tone(Buzz, A_4); } while (digitalRead(B) == LOW){ tone(Buzz, B_4); } noTone(Buzz); } محاكاة مشروع آلة البيانو باستخدام الأردوينو سنتبع نفس الخطوات التي تعلمناها في مقالٍ التحكم بتشغيل وإطفاء ليد LED باستخدام الأردوينو Arduino للوصول الى الصفحة الخاصة بمحاكاة مشروعنا على موقع وكوي Wokwi. نضيف العناصر الإلكترونية اللازمة للمشروع وهي لوحة التجارب BreadBoard والجرس الإلكتروني Buzzer والمفتاح اللحظي. نغيّر ألوان المفاتيح للتميز بينها من خلال الضغط عليها فتظهر لنا نافذة في الأعلى نستطيع من خلالها اختيار اللون. نرتب العناصر على لوحة التجارب بالشكل الذي نراه مناسبًا، ثم نصل العناصر بعضها ببعض حسب مخطط التوصيل الذي عرضناه سابقًا. نكتب الكود البرمجي في الجزء الخاص به ثم نشغل المحاكاة، ونلاحظ الحالات الآتية: نضغط على المفتاح الأول الموصول على القطب رقم 10 في لوحة الأردوينو أونو Arduino Uno، سنلاحظ أن الجرس الإلكتروني Buzzer يصر صوت بنفس التردد الأول، وعند إزالة الضغط عن المفتاح سيتوقف الجرس عن العمل وذلك بسبب الدالة ()noTone. نجرب الضغط على المفاتيح الأخرى ونلاحظ أن كل مفتاح يسبب إصدار صوت مختلف عن الآخر في حال الضغط على المفاتيح بشكل تسلسلي بالترتيب سنلاحظ أن الأصوات أو النغمات متناسقة لأننا استخدمنا الترددات الأساسية في السلم الموسيقي، ويمكن تجربة ترددات مختلفة حتى نحصل على النتيجة التي نريدها الخلاصة تعلمنا في هذا المقال كيفية إصدار أصوات من خلال الأردوينو Arduino، وتعرفنا على عنصر إلكتروني جديد وهو الجرس الإلكتروني Buzzer وآلية عمله وأنواعه، وقمنا ببناء مشروع جديد من هذه السلسلة وهو بناء آلة البيانو الموسيقية باستخدام الأردوينو Arduino، وختمنا المقال بعرض خطوات محاكاة للمشروع من خلال منصة وكوي Wokwi. اقرأ أيضًا المقال السابق: التحكم بألوان الإضاءة باستخدام أردوينو التعرف على أساسيات الأردوينو وتجهيز بيئة العمل إضاءة زينة بأنماط مختلفة باستخدام الأردوينو Arduino التحكم بألوان الإضاءة باستخدام الأردوينو Arduino
-
سنتعلم في هذا المقال كيفية بناء مشروع أردوينو للتحكم بألوان الإضاءة، ونتعرف على أفكار جديدة تساعدنا على تطوير مهاراتنا الإلكترونية والبرمجية، حيث سنستخدم عناصر بسيطة مثل ليد إضاءة متعدد الألوان من نوع RGB LED، وثلاثة مقاومات متغيرة Potentiometers، ومفتاح ضغط لحظي Push Button، ونربطها جميعًا مع لوحة الأردوينو. فكرة مشروع التحكم بألوان الإضاءة باستخدام الأردوينو Arduino يهدف مشروعنا إلى التحكم في شدة ألوان الإضاءة من خلال مصابيح LED RGB باستخدام لوحة الأردوينو، وهو يعمل وفق ثلاثة أنماط رئيسية: النمط الأول: نضيء الليد بشكل تلقائي وبعدة ألوان مختلفة، ونغير اللون كل فترة زمنية تحدد من خلال مقاومة متغيرة Potentiometer حيث يمكننا تدوير القرص الخاص بها لزيادة أو تقليل الزمن مع الانتباه لأن الزمن لن يتجاوز مجال محدد برمجيًا. النمط الثاني: نولد ألوانًا عشوائية بالضغط على مفتاح الضغط اللحظي Push Button، فعند كل ضغطة على المفتاح تتغير شدة إضاءة اللون الأحمر والأخضر والأزرق عشوائيًا ضمن مجال قيم من 0 إلى 255. النمط الثالث: نحدد شدة إضاءة كل لون من الألوان الأساسية الخاصة بهذا الليد كالأحمر أو الأخضر أو الأزرق من خلال ثلاثة مقاومات متغيرة، وعند تدوير القرص الخاص بكل مقاومة تتغير شدة إضاءة اللون الخاص بهذه المقاومة للحصول على اللون الذي نريده. العناصر المستخدمة لمشروع التحكم بألوان الإضاءة سنستخدم في مشروعنا مجموعة من العناصر الإلكترونية والأدوات وهي كالتالي: لوحة أردوينو أونو Arduino Uno كابل البرمجة USB Cable لوحة توصيل التجارب Breadboard مقياس متعدد Multimeter ليد متعدد الألوان RGB LED من نوع CC عدد 1 مفتاح الضغط اللحظي Push Button عدد 1 مقاومة بقيمة 220 أوم عدد 3 مقاومة متغيرة Potentiometer بقيمة 10 كيلو أوم عدد 3 مجموعة أسلاك توصيل من نوع Male to Male وقد تعرفنا على معظم هذه العناصر في المقالات السابقة من السلسلة، ولكن هناك عنصر جديد لم نتعامل معه بعد، وهو الليد متعدد الألوان RGB LED وسنعرفكم عليه في الفقرات التالية. ما هو الليد متعدد الألوان RGB LED هو عبارة عن ثلاثة ليدات بالألوان الأساسية الأحمر والأخضر والأزرق مدمجة داخليًا في ليد واحد، نستطيع من خلاله الحصول على أي لون نريده عن طريق دمج هذه الألوان الأساسية. فللحصول على اللون الأزرق باستخدام الليد متعدد الألوان يمكننا تشغيل الليد الأزرق بأقصى شدة إضاءة وإطفاء الليدين الأحمر والأخضر، وللحصول على اللون الأبيض يمكننا تشغيل جميع الليدات بأقصى شدة إضاءة ممكنة، وهكذا نستطيع الحصول على أي لون نريده من خلال تحديد شدة إضاءة كل ليد، وبما أن الليدات تكون قريبة من بعضها بشكل كبير فإن عين الإنسان لن تلاحظ الألوان بشكل منفصل عن بعضها نسبيًا وإنما سترى نتيجة دمج إضاءة الليدات الثلاثة مع بعضها. وكنا قد شرحنا في المقال السابق كيفية التحكم بشدة إضاءة الليد وآلية الحصول على جهد متغير من مصدر جهد ثابت من خلال تقنية تعديل عرض النبضة PWM. توضح الصورة الآتية طريقة دمج الألوان الرئيسية مع بعضها وكيفية الحصول على ألوان أخرى: أنواع الليد متعدد اللون RGB LED هناك نوعان من الليدات متعددة الألوان RGB LEDs من حيث البنية وهما: 1. ليد متعددة الألوان بمصاعد مشتركة Common Anodes في الليد متعددة الألوان ذي المصاعد المشتركة Common Anodes أو ما يعرف اختصارًا بالرمز CA، توصل أقطاب المصاعد لجميع الليدات -أي القطب الموجب لكل ليد- مع بعضها البعض، ونتحكم في زيادة شدة إضاءة كل لون من خلال خفض قيمة الجهد الخاص بكل ليد من خلال المتحكم، أما القطب المشترك فينبغي علينا توصيله مع القطب الموجب 5v. 2. ليد متعددة الألوان بمهابط مشتركة Common Cathodes في الليد متعددة الألوان ذي المهابط المشتركة Common Cathodes أو ما يعرف اختصارًا بالرمز CC، نوصل أقطاب المهابط لجميع الليدات -أي القطب السالب لكل ليد- ببعضها، ونتحكم في زيادة شدة إضاءة كل لون من خلال رفع قيمة الجهد الخاص بكل ليد من خلال المتحكم، أما القطب المشترك فعلينا توصيله مع القطب السالب GND. أقطاب الليد متعدد الألوان سواء كان الليد الذي لديك من نوع CA أو CC ستجد أن له أربعة أقطاب وهي: قطب لليد الأحمر Red LED قطب لليد الأخضر Green LED قطب لليد الأزرق Blue LED قطب مشترك Common توضح الصورة الآتية أقطاب الليد في حال كان من نوع CA أو CC كما نلاحظ من الصورة السابقة فالقطب المشترك Common يملك الرجل الأطول دائمًا، ويمكن معرفة نوع الليد الذي لديك باستخدام جهاز القياس المتعدد Multimeter وذلك في وضع فحص الليد وتجريب ما يلي: نوصل القطب المشترك لليد أي أطول رجل مع الطرف الأحمر الموجب للمقياس، ونوصل إحدى الأقطاب الأخرى لليد مع الطرف الأسود السالب للمقياس، في حال إضاءة الليد يكون من نوع مصعد مشترك Common Anode أو CA نوصل القطب المشترك لليد وهي أطول رجل مع الطرف الأسود السالب للمقياس، ونوصل إحدى الأقطاب الأخرى لليد مع الطرف الأحمر الموجب للمقياس، في حال إضاءة الليد يكون من نوع مهبط مشترك Common cathode أو CC مخطط توصيل مشروع التحكم بألوان الإضاءة بعد أن تعرفنا بالتفصيل على الليد متعدد الألوان المستخدم في مشروعنا الحالي، دعنا نوضح الخطوات المطلوبة لتوصيل العناصر والأسلاك مع لوحة الأردوينو Arduino وتحقيق فكرة المشروع كما في الصورة التالية: نصل أقطاب التغذية في لوحة الأردوينو أونو مع لوحة توصيل التجارب BreadBoard، إذ يوصل القطب 5v في لوحة الأردوينو مع المسرى الموجب للوحة التجارب، والقطب GND في لوحة الأردوينو مع المسرى السالب للوحة التجارب من خلال أسلاك التوصيل نصل الرجل الأطول التي تمثل القطب المشترك لليد المتعدد الألوان RGB LED مع المسرى السالب في لوحة توصيل التجارب BreadBoard، حيث أن الليد الذي لدينا من نوع CC نصل الأرجل الخاصة بكل لون الأحمر والأخضر والأزرق من الليد مع الرجل الأولى للمقاومات ذات القيمة 220 أوم الخاصة بكل لون، ونوصل الرجل الأخرى للمقاومات مع الأقطاب 11 و 10 و 9 على الترتيب في لوحة الأردوينو أونو نصل رجل التغذية الأولى Vcc لجميع المقاومات المتغيرة مع بعضها البعض، ومن ثم نوصل رجل التغذية الموجب Vcc لإحدى المقاومات المتغيرة مع المسرى الموجب في لوحة توصيل التجارب BreadBoard نصل رجل التغذية الأخرى Gnd لجميع المقاومات المتغيرة مع بعضها البعض، ومن ثم نوصل رجل التغذية السالبة GND لإحدى المقاومات المتغيرة مع المسرى السالب في لوحة توصيل التجارب BreadBoard نصل رجل إشارة الخرج التشابهي Analog Output والتي تسمى Sig للمقاومة المتغيرة الأولى مع القطب A0 في لوحة الأردوينو أونو نصل رجل إشارة الخرج التشابهي Sig للمقاومة المتغيرة الثانية مع القطب A1 في لوحة الأردوينو أونو نصل رجل إشارة الخرج التشابهي Sig للمقاومة المتغيرة الثالثة مع القطب A2 في لوحة الأردوينو أونو نصل الطرف الأول لمفتاح الضغط اللحظي Push Button مع المسرى السالب للوحة التجارب، ثم نوصل الطرف الثاني للمفتاح Push Button مع القطب رقم 3 في لوحة الأردوينو أونو سنفعّل مقاومة الرفع الداخلية على القطب رقم 3 للمتحكم الموجود في لوحة الأردوينو برمجيًا، لذا لا داعي لتوصيل مقاومة رفع Pull-Up أو مقاومة خفض Pull-Down مع مفتاح الضغط اللحظي Push Button الكود البرمجي لمشروع التحكم بألوان الإضاءة في أردوينو سنعرف مجموعة من الماكرو في بداية الكود البرمجي لتحديد أرقام الأقطاب الرقمية لمفتاح الضغط اللحظي Push Button والليد متعدد الألوان RGB LED وأرقام الأقطاب التشابهية للمقاومات المتغيرة الثلاثة، وقد شرحنا كيفية استخدام الماكرو في مقال سابق في هذه السلسلة يمكنك الرجوع إليه من خلال مقال تخمين عدد مرات وميض الليد باستخدام الأردوينو Arduino كما يمكنك الاطلاع أكثر على مفهوم الماكرو وأنواعه من خلال مقال الماكرو Macro والمعالج المسبق Preprocessor في لغة سي C #define RED_LED 11 #define GREEN_LED 10 #define BLUE_LED 9 #define RED_Pot A0 #define GREEN_Pot A1 #define BLUE_Pot A2 #define BUTTON 3 سنعرف بعد ذلك متغير Mode من نوع عدد صحيح int بقيمة ابتدائية تساوي 1، وظيفة هذا المتغير تحديد نمط عمل المشروع، حيث أن لدينا ثلاثة أنماط كما ذكرنا سابقًا، بالتالي ستكون قيمته إما 1 أو 2 أو 3. int MODE = 1; سنضبط نوع الأقطاب في الدالة الرئيسية ()setup من خلال الدالة المدمجة ()pinMode التي تأخذ وسيطين الأول رقم القطب والثاني نوع القطب إما خرج OUTPUT أو دخل INPUT، حيث أن الأقطاب الخاصة بالليد متعدد الألوان هي أقطاب خرج OUTPUT، وسيُضبَط القطب الخاص بالمفتاح كقطب دخل مع تفعيل مقاومة الرفع الداخلية INPUT_PULLUP، أما أقطاب المقاومات المتغيرة ستكون أقطاب دخل INPUT ومن الممكن عدم ضبط نوع أقطاب المقاومات لأن الحالة الافتراضية لجميع الأقطاب في بيئة الأردوينو هي أقطاب دخل INPUT. void setup() { pinMode(RED_LED, OUTPUT); pinMode(GREEN_LED, OUTPUT); pinMode(BLUE_LED, OUTPUT); pinMode(BUTTON, INPUT_PULLUP); } بعدها سنعرف دالة باسم ()setColor هدفها عدم تكرار كتابة التعليمات البرمجية الخاصة بتشغيل الليد ثلاث مرات فهناك ثلاثة أقطاب لليد، وإنما سنستخدم هذه الدالة من خلال سطر برمجي واحد، وتأخذ هذه الدالة ثلاثة وسطاء هي قيم شدة إضاءة الألوان الثلاث الأحمر والأخضر والأزرق على الترتيب، سنستدعي داخل هذه الدالة الدالة المدمجة ()analogWrite لتوليد إشارة PWM لكل لون، والتي تأخذ بدورها وسيطين الأول رقم القطب Pin والثاني دورة العمل Duty Cycle وتكون ضمن المجال من 0 وحتى 255. void setColor(int red, int green, int blue) { analogWrite(RED_LED, red); analogWrite(GREEN_LED, green); analogWrite(BLUE_LED, blue); } كما سنُعرّف دالة جديدة باسم ()GET_MODE، مسؤولة عن تحديد نمط عمل الجهاز بناءً على مدة الضغط على المفتاح اللحظي. سنعرّف داخل هذه الدالة، متغيرًا باسم Time من نوع عدد صحيح int بقيمة ابتدائية تساوي صفر. بعدها سنفحص من خلال الحلقة التكرارية ()while حالة المفتاح فالحلقة تستمر في العمل طالما زمن الضغط أقل من 1 ثانية. فإذا كانت قيمة Time تساوي صفر أي أن المفتاح مضغوط، سنزيد قيمة المتغير Time بمقدار 10. بعد ذلك، سنضيف تأخير زمني قدره 10 مللي ثانية باستخدام الدالة المدمجة ()delay. إذا استمر الضغط على المفتاح لمدة 1000 مللي ثانية أي عندما تصل قيمة المتغير Time إلى 1000، سيومض الليد باللون الأحمر عدة مرات كمؤشر للمستخدم لتغيير النمط. بعد ذلك سنزيد قيمة متغير النمط Mode بمقدار 1. إذا أصبحت قيمة المتغير Mode أكبر من 3، سنعيد قيمته إلى 1. وأخيرًا، نخرج من الحلقة التكرارية while. أما إذا كانت قيمة المتغير Time أقل من 1000، فسنستمر في التكرار داخل الحلقة. void GET_MODE(){ int Time = 0; while(!digitalRead(BUTTON)){ Time+=10; delay(10); if(Time == 1000){ setColor(255, 0, 0); delay(500); setColor(0, 0, 0); delay(500); setColor(255, 0, 0); delay(500); setColor(0, 0, 0); delay(500); MODE++; if(MODE > 3) MODE = 1; break; } } } سنستدعي في بداية الدالة التكرارية ()loop الدالة ()GET_MODE لتحديث قيمة المتغير الخاص بالنمط MODE، ومن ثم نتحقق من قيمة هذا المتغير باستخدام العبارة الشرطية ()if على النحو التالي: في حال قيمة MODE تساوي 1: يعمل المشروع وفق النمط الأول، وفيه نعرّف متغير Delay_Speed من نوع صحيح int لتخزين التأخير الزمني بين إضاءة كل لون والآخر، ونحصل على قيمة التأخير الزمني من خلال قراءة قيمة المقاومة المتغيرة الأولى الموصولة على القطب A0 من خلال الدالة ()analogRead التي تأخذ وسيطًا واحدًا Pin وهو رقم القطب الموصول عليه العنصر التشابهي، وتعيد قيمة عددية صحيحة ضمن المجال من 0 إلى 1023 تمثل القيمة الرقمية المقابلة لقيمة الجهد الموصول على القطب المحدد Pin. بعدها نحول المجال من 0-1023 إلى 100-1500 مللي ثانية من خلال الدالة ()map، وبعد ذلك سنشغّل الليد باستدعاء الدالة ()setColor بعدة ألوان مختلفة. في حال قيمة MODE تساوي 2: يعمل المشروع وفق النمط الثاني، سنتحقق في هذا النمط من حالة المفتاح في حال كان مضغوط سنولد ثلاثة قيم عشوائية ضمن المجال 0-255 باستخدام الدالة ()random التي تأخذ وسيطين الأول أصغر قيمة للرقم، والثاني هو أكبر قيمة للرقم، وتعيد رقم عشوائي من نوع long خاص بقيم الألوان الثلاث الأحمر والأخضر والأزرق، ومن ثم سنشغل الليد باستدعاء الدالة ()setColor مع تمرير القيم السابقة له، وهكذا يضيء الليد بشكل عشوائي في كل مرة يُضغط المفتاح. في حال قيمة MODE تساوي 3: يعمل المشروع وفق النمط الثالث، وفي هذا النمط سنعرف ثلاثة متغيرات خاصة بتخزين قيم قراءات المقاومات المتغيرة الثلاث، وسنعمل على تحويل الدقة من 10 بت وهي دقة المبدل التناظري إلى رقمي ADC، إلى 8 بت وهي دقة تعديل عرض النبضة PWM. وذلك عن طريق إزاحة القيم بمقدار 2 بت نحو اليمين. ومن ثم تشغيل الليد باستدعاء الدالة الخاصة ()setColor وتمرير المتغيرات الثلاثة التي تحتوي على قيم كل لون. void loop() { GET_MODE(); if(MODE == 1){ int Delay_Speed = map(analogRead(RED_Pot), 0, 1023, 100, 1500); setColor(255, 0, 0); // Red delay(Delay_Speed); setColor(255, 255, 0); // Yellow delay(Delay_Speed); setColor(0, 255, 0); // Green delay(Delay_Speed); setColor(0, 255, 255); // Cyan delay(Delay_Speed); setColor(0, 0, 255); //Blue delay(Delay_Speed); setColor(255, 0, 255); //Magenta delay(Delay_Speed); } else if(MODE == 2){ if (!digitalRead(BUTTON)){ int Red = random(0, 255); int green = random(0, 255); int blue = random(0, 255); setColor(Red, green, blue); } } else if(MODE == 3){ int RED_POT_VAL = analogRead(RED_Pot) >> 2; int GREEN_POT_VAL = analogRead(GREEN_Pot) >> 2; int BLUE_POT_VAL = analogRead(BLUE_Pot) >> 2; setColor(RED_POT_VAL, GREEN_POT_VAL, BLUE_POT_VAL); } } الكود البرمجي النهائي للمشروع فيما يلي الكود الكامل لمشروع التحكم بألوان الإضاءة باستخدام الأردوينو Arduino: #define RED_LED 11 #define GREEN_LED 10 #define BLUE_LED 9 #define RED_Pot A0 #define GREEN_Pot A1 #define BLUE_Pot A2 #define BUTTON 3 int MODE = 1; void setup() { pinMode(RED_LED, OUTPUT); pinMode(GREEN_LED, OUTPUT); pinMode(BLUE_LED, OUTPUT); pinMode(BUTTON, INPUT_PULLUP); Serial.begin(9600); } void loop() { GET_MODE(); if(MODE == 1){ int Delay_Speed = map(analogRead(RED_Pot), 0, 1023, 100, 1500); setColor(255, 0, 0); // Red delay(Delay_Speed); setColor(255, 255, 0); // Yellow delay(Delay_Speed); setColor(0, 255, 0); // Green delay(Delay_Speed); setColor(0, 255, 255); // Cyan delay(Delay_Speed); setColor(0, 0, 255); //Blue delay(Delay_Speed); setColor(255, 0, 255); //Magenta delay(Delay_Speed); } else if(MODE == 2){ if (!digitalRead(BUTTON)){ int Red = random(0, 255); int green = random(0, 255); int blue = random(0, 255); setColor(Red, green, blue); } } else if(MODE == 3){ int RED_POT_VAL = analogRead(RED_Pot) >> 2; int GREEN_POT_VAL = analogRead(GREEN_Pot) >> 2; int BLUE_POT_VAL = analogRead(BLUE_Pot) >> 2; setColor(RED_POT_VAL, GREEN_POT_VAL, BLUE_POT_VAL); } } void setColor(int red, int green, int blue) { analogWrite(RED_LED, red); analogWrite(GREEN_LED, green); analogWrite(BLUE_LED, blue); } void GET_MODE(){ int Time = 0; while(!digitalRead(BUTTON)){ Time+=10; delay(10); if(Time == 1000){ setColor(255, 0, 0); delay(500); setColor(0, 0, 0); delay(500); setColor(255, 0, 0); delay(500); setColor(0, 0, 0); delay(500); MODE++; if(MODE > 3) MODE = 1; break; } } } محاكاة مشروع التحكم بألوان الإضاءة بالأردوينو سنتبع نفس الخطوات التي تعلمناها في مقال التحكم بتشغيل وإطفاء ليد LED باستخدام الأردوينو Arduino للوصول الى الصفحة الخاصة بمحاكاة مشروعنا على موقع وكوي Wokwi: نضيف العناصر الإلكترونية اللازمة للمشروع وهي المقاومة المتغيرة Potentiometer، والليد متعدد الألوان RGB LED، ولوحة التجارب BreadBoard، وزر الضغط Push Button، والمقاومات Resistors. نغيّر قيم مقاومات الليد إلى 220 أوم من خلال الضغط عليها فتظهر لنا نافذة في الأعلى تمكننا من تغير القيمة والواحدة. يمكن بالطريقة نفسها تغيير نوع الليد Anode أو Cathode من خلال الضغط عليه فتظهر نافذة بالأعلى نستطيع من خلالها تحديد النوع. نرتب العناصر على لوحة التجارب بالشكل الذي نراه مناسبًا، ثم نصل العناصر بعضها ببعض حسب مخطط التوصيل الذي عرضناه سابقًا. نكتب الكود البرمجي في الجزء الخاص به ثم نشغل المحاكاة، ونلاحظ الحالات الآتية: في البداية سيضيء الليد بعدة ألوان مختلفة بشكل متكرر كل فترة معينة، ندور القرص الخاص بالمقاومة المتغيرة الأولى الموصولة على القطب A0 نحو اليمين سنلاحظ عندها أن فترة الإنتقال من لون إلى آخر أصبحت أبطأ، وفي حال تدوير القرص نحو اليسار سنلاحظ أن فترة الانتقال من لون لآخر أصبحت أسرع نضغط على المفتاح بشكل مستمر لمدة 1 ثانية ولاحظ أن الليد يومض باللون الأحمر عدة مرات وهذا يدل على الانتقال من النمط الأول إلى النمط الثاني، سيضئ عندها الليد بلون عشوائي، وعند الضغط اللحظي في كل مرة على المفتاح سيتغير اللون بشكل عشوائي نضغط على المفتاح بشكل مستمر مرة أخرة حتى يومض الليد باللون الأحمر عدة مرات للانتقال من النمط الثاني إلى النمط الثالث، ثم ندور أقراص المقاومات المتغيرات الثلاث نحو أقصى اليسار لإطفاء الليد، ومن ثم ندور القرص الخاص بالمقاومة المتغيرة الأولى نحو اليمين سيضيء الليد عندها باللون الأحمر، وبتدوير القرص الخاص بالمقاومة المتغيرة الثانية نحو اليمين أيضًا بشكل تدريجي سيُدمج اللون الأخضر مع اللون الأحمر بحسب دوران القرص، وبنفس الطريقة نستطيع تدوير القرص الخاص بالمقاومة المتغيرة الثالثة لإضافة اللون الأزرق والحصول على أي لون نريده عند الضغط على المفتاح بشكل مستمر مرة أخرى سيعود الجهاز إلى النمط الأول الخلاصة وصلنا لنهاية مقالنا الذي شرحنا فيه خطوات بناء مشروع للتحكم بألوان الإضاءة باستخدام أردوينو Arduino، واستعرضنا كيفية توصيل العناصر المطلوبة، بما في ذلك لوحة الأردوينو والليد والمقاومات والمفتاح اللحظي،وكتبنا الكود البرمجي اللازم لتحقيق منطق المشروع، وأخيرًا نفذنا مشروعنا من خلال محاكاته على منصة وكوي Wokwi وجربنا الحالات المختلفة لاختباره. اقرأ أيضًا المقال السابق: التحكم بعدد الليدات المضاءة وشدة إضاءتها باستخدام أردوينو التحكم بالليد LED باستخدام مفتاح الضغط اللحظي Push Button والأردوينو Arduino دوال التحكم بأرجل الدخل والخرج التشابهي في أردوينو إضاءة زينة بأنماط مختلفة باستخدام الأردوينو Arduino
-
سنشرح في هذا المقال كيفية بناء نظام بسيط يسمح للمستخدم بالتحكم بعدد الليدات المضاءة وشدة إضاءتها، وسنتعلم ما هي العناصر الأساسية اللازمة لتنفيذ المشروع، وكيفية توصيلها وبرمجتها خطوة بخطوة، كما سنستعرض بعض المفاهيم المهمة في مجال الإلكترونيات وبرمجة المتحكمات والأنظمة المدمجة مثل المقاومة المتغيرة Potentiometer، والمبدل التشابهي الرقمي ADC، وتقنية تعديل عرض النبضة PWM. فكرة مشروع التحكم بعدد الليدات المضاءة وشدة إضاءتها يحتوي المشروع على أربعة ليدات LEDs يتحكم المستخدم بها من خلال عنصر المقاومة المتغيرة Potentiometer، وسنحتاج هنا لمقاومتين الأولى خاصة بتحديد عدد الليدات المضاءة بحيث يستطيع المستخدم تدوير قرص هذه المقاومة لزيادة أو إنقاص عدد الليدات المضاءة، والثانية خاصة بتحديد شدة إضاءة هذه الليدات ويستطيع المستخدم تدوير قرص هذه المقاومة لزيادة أو إنقاص شدة إضاءة الليدات. مثلًا، إذا كان قرص المقاومة الأولى نحو المنتصف وقرص المقاومة الثانية نحو النهاية في هذه الحالة سيضيء اثنان من الليدات فقط وبشدة إضاءة كاملة 100%، وفي حال كان قرص المقاومة الأولى نحو النهاية وقرص المقاومة الثانية نحو المنتصف عندها ستضيء جميع الليدات بنصف شدة الإضاءة 50%، أما إذا كان قرص المقاومة الأولى أو المقاومة الثانية نحو البداية ستنطفئ جميع الليدات أيًا كان موضع قرص المقاومة الأخرى. العناصر المستخدمة للمشروع سنستخدم مجموعة من العناصر الإلكترونية والأدوات وهي: لوحة أردوينو أونو Arduino Uno كابل البرمجة USB Cable لوحة توصيل التجارب Breadboard ليد أحمر Red LED عدد 4 مقاومة 220 أوم عدد 4 مقاومة متغيرة Potentiometer بقيمة 10 كيلو أوم عدد 2 مجموعة أسلاك توصيل من نوع Male to Male ما هي المقاومة المتغيرة Potentiometer هي إحدى أنواع المقاومات الإلكترونية، وتستخدم كعنصر دخل مع الأردوينو والمتحكمات للحصول على إشارة تشابهية، إذ يمكن تغيير قيمتها بشكل يدوي ضمن مجال من القيم عند تدوير القرص الإسطواني الخاص بها نحو اليمين أو اليسار، وتحتوي على ثلاثة أرجل وهي: رجل التغذية الموجب Vcc رجل الخرج التشابهي Sig رجل التغذية السالب Gnd تعمل المقاومة المتغيرة بنفس مبدأ عمل مقسّم الجهد فيمكن تخيل المقاومة المتغيرة على أنها مقاومتان متصلتان ببعضهما على التسلسل، حيث أن الرجل الأولى للمقاومة الأولى هي رجل التغذية الموجب Vcc، والرجل الثانية للمقاومة الثانية هي رجل التغذية السالب Gnd، أما النقطة المشتركة بين الرجل الثانية للمقاومة الأولى والرجل الأولى للمقاومة الثانية هي رجل الخرج التشابهي Sig كما هو موضح في الصورة الآتية: وعند تدوير القرص الخاص بالمقاومة المتغيرة Potentiometer فإن نسبة المقاومة الأولى ستزيد أو تنقص بالنسبة للمقاومة الثانية بحسب جهة تدوير القرص، بالتالي ستتغير قيمة جهد الخرج ضمن مجال لا يتجاوز جهد التغذية، فعندما تكون المقاومة المتغيرة في المنتصف أي قيمة المقاومة الأولى مماثلة مع قيمة المقاومة الثانية فإن قيمة جهد الخرج سيكون مساويًا لنصف قيمة جهد التغذية. المبدل التشابهي الرقمي Analog to Digital Converter هو أحد أهم الأجزاء الموجودة في لوحة الأردوينو ويعرف اختصارًا ADC، يسمح بتحويل الإشارات التشابهية إلى إشارات رقمية يستطيع الأردوينو قراءتها والتعامل معها، ويستخدم في العديد من التطبيقات مثل قياس درجة الحرارة وقياس شدة الإضاءة وقياس التيار والجهد الكهربائي وغيرها من الإشارات التشابهية. تحتوي لوحة أردوينو أونو على 6 أقطاب تشابهية من A0 وحتى A5 كما شرحنا في مقال التعرف على أساسيات الأردوينو وتجهيز بيئة العمل، ويمكن استخدام هذه الأقطاب لقراءة الإشارات التشابهية ضمن المجال من 0 إلى 5 فولت وتجدر الإشارة لأن قيمة الإشارة التشابهية لا يجب أن تتجاوز هذا المجال وإلا ستؤدي إلى حدوث خلل في المتحكم، ويعد المبدل التشابهي الرقمي الموجود في لوحة الأردوينو أونو Arduino Uno بدقة 10 بت، مما يعني أنه يمكن تحويل قيمة الجهد التي تقع بين 0 و 5 فولت إلى قيمة عددية صحيحة مقابلة لها تقع بين 0 و 1023 وبالتالي تكون دقة عمليات قراءة القيم التشابهية هي 1024/ 5 أو 0.0049 فولط بكل وحدة رقمية. توصيل المقاومة المتغيرة Potentiometer مع الأردوينو Arduino سنوضح في هذا الجزء طريقة ربط المقاومة المتغيرة مع الأردوينو من خلال مثال بسيط يقرأ القيم التشابهية من خرج المقاومة المتغيرة من خلال القطب رقم A0 في لوحة الأردوينو أونو Arduino Uno ومن ثم عرضها على نافذة الاتصال التسلسلية Serial Monitor ونافذة Serial Plotter. لإجراء التوصيل الخاص بهذا المثال في البداية سنصل أرجل التغذية Vcc, Gnd للمقاومة المتغيرة مع القطب 5v والقطب GND في لوحة الأردوينو، وليس هناك فرق في حال أجرينا التوصيل بشكل معاكس لأن المقاومة ليس لها قطبية فستختلف جهة التدوير فقط، ومن ثم سنصل رجل الخرج التشابهي Sig للمقاومة المتغيرة مع القطب A0 في لوحة الأردوينو أونو Arduino Uno. لكتابة الكود البرمجي، سنفعّل واجهة الاتصال التسلسلية Serial Communication داخل الدالة الرئيسية ()setup باستدعاء التابع Serial.begin() الذي يأخذ وسيطين الأول أساسي وهو سرعة نقل البيانات Baud rate بمعدل بت في الثانية وسنختار هنا القيمة 9600، والثاني اختياري وهو خاص بضبط الإعدادات config الأخرى لواجهة الاتصال ويمكن تركه فارغًا حيث يأخذ الضبط الافتراضي SERIAL_8N1 في هذه الحالة. أما في الدالة التكرارية ()loop فسنعرف متغير صحيح من نوع int تخزن فيه قيمة قراءة المبدل التشابهي الرقمي ADC من خلال الدالة المدمجة analogRead() التي تأخذ وسيطًا واحدًا Pin وهو رقم القطب الموصول عليه العنصر التشابهي وقيمته من A0 إلى A5 في لوحة الأردوينو أونو Arduino Uno وتعيد قيمة عددية صحيحة ضمن المجال 0 إلى 1023 وتمثل القيمة الرقمية المقابلة لقيمة الجهد الموصول على القطب المحدد Pin، ومن ثم سنطبع هذه القيمة على نافذة الاتصال التسلسلي باستدعاء الدالة ()Serial.println، وفي النهاية سنستخدم الدالة ()delay لعمل تأخير زمني حيث نمرر لها الزمن المطلوب بواحدة ميللي ثانية ms. void setup() { Serial.begin(9600); } void loop() { int Val = analogRead(A0); Serial.println(Val); delay(100); } بعد توصيل لوحة الأردوينو مع الحاسوب ورفع الكود البرمجي، سنذهب إلى قائمة أدوات Tools ومن ثم نختار أداة Serial Plotter لإظهار القيم على شكل منحني بياني أو Serial Monitor لعرضها على شكل قيم رقمية، والآن جرب تدوير القرص الخاص بالمقاومة المتغيرة نحو اليمين أو اليسار ستلاحظ أن القراءات ستتغير ولكنها لن تتجاوز المجال 0 إلى 1023. تقنية تعديل عرض النبضة تعرف تقنية عرض النبضة Pulse Width Modulation أو ما بيعرف اختصارًا PWM، بأنها تقنية تستخدم للحصول على جهد بقيمة متغيرة من مصدر جهد رقمي ذي قيمة ثابتة، حيث تتولد إشارة مربعة يكون فيها عرض النبضة متغيرًا وتردد الإشارة الناتجة ثابت، وتستخدم هذه التقنية في تطبيقات عديدة أشهرها التحكم بسرعة محرك والتحكم بشدة الإضاءة. كي تتمكن من فهم تقنية PWM جيدًا نحتاج أولًا لمعرفة مفهومين مهمين: الأول هو التردد Frequency، والثاني هو دورة العمل Duty Cycle. التردد Frequency هو عبارة عن عدد مرات تكرار الإشارة في الثانية الواحدة، مثلا عندما نقول أنه لدينا إشارة بتردد 5 هرتز هذا يعني أن الإشارة تتكرر 5 مرات خلال ثانية واحدة. دورة العمل Duty Cycle أي إشارة رقمية تتكون من فترة تشغيل HIGH وفترة إيقاف LOW، وتعرف فترة التشغيل بالنسبة للإشارة الكلية بدورة العمل Duty Cycle، وتحسب من العلاقة التالية: Duty Cycle [%] = (Ton/(Ton+Toff)) × 100 ومن خلال تكرار حدوث فترة التشغيل HIGH وفترة الإيقاف LOW بتردد مناسب وبنسبة تشغيل Duty Cycle محددة سنحصل على قيمة جهد متغير تحدد قيمته من خلال دورة العمل Duty Cycle ويحسب من العلاقة الآتية: Vout = Vmax × Duty Cycle [%] مثال: إذا أردنا الحصول على جهد متغير بقيمة 2 فولت من مصدر جهد ثابت يعطي 5 فولت عند فترة التشغيل HIGH و 0 فولت عند فترة الإيقاف LOW، نستطيع استخدام تقنية تعديل عرض النبضة PWM بنسبة تشغيل 40% من الزمن للحصول على قيمة الجهد المطلوبة. Vout = 5v × 40% = 2v تحتوي لوحة أردوينو أونو Arduino Uno على 6 أقطاب يمكنها توليد إشارة PWM بدقة 8 بت، أي أنها تستطيع تقسيم دورة العمل Duty Cycle إلى 256 قيمة من 0 والتي تكافئ نسبة تشغيل 0% وحتى 255 التي تكافئ نسبة تشغيل 100%، وأرقام هذه الأقطاب هي 3، 5، 6، 9، 10، 11، ويمكن معرفة هذه الأقطاب أيضًا من خلال وجود الرمز ~ بجانب كل قطب منها. التحكم بشدة إضاءة ليد LED باستخدام الأردوينو Arduino سنوضح طريقة التحكم بشدة إضاءة ليد LED مع لوحة الأردوينو أونو Arduino Uno من خلال مثال بسيط يعطي قيم مختلفة من دورة العمل Duty Cycle بدءًا من 0% التي ينطفئ الليد عندها وحتى 100% التي يضيء الليد عندها بشكل كامل. لإجراء التوصيل الخاص بهذا المثال في البداية صل الرجل الأطول لليد التي تمثل الطرف الموجب مع القطب رقم 11 في لوحة الأردوينو أونو Arduino Uno، ومن ثم صل الرجل الثانية لليد التي تمثل الطرف السالب مع القطب السالب في لوحة الأردوينو أونو Arduino Uno . في الدالة الرئيسية ()setup سنضبط القطب رقم 11 على أنه قطب خرج OUTPUT من خلال الدالة ()pinMode التي تأخذ وسيطين الأول رقم القطب والثاني نوع القطب خرج OUTPUT أو دخل INPUT. أما في الدالة التكرارية ()loop فسنستخدم الدالة ()analogWrite لتوليد إشارة PWM، والتي تأخذ وسيطين الأول رقم القطب Pin والثاني دورة العمل Duty Cycle وتكون ضمن المجال من 0 وحتى 255 كما ذكرنا سابقًا، مع إضافة تأخير زمني بين كل نسبة تشغيل والأخرى. void setup () { pinMode(11, OUTPUT); } void loop() { analogWrite(11, 0); delay(500); analogWrite(11, 100); delay(500); analogWrite(11, 200); delay(500); analogWrite(11, 255); delay(500); } بعد توصيل لوحة الأردوينو مع الحاسوب ورفع الكود البرمجي نلاحظ تغيرات إضاءة الليد، ستزداد شدة الإضاءة كل نصف ثانية حتى تصل إلى الشدة العظمى ومن ثم ستعيد من الصفر. مخطط توصيل مشروع التحكم بشدة وعدد الإضاءة لنتبع الخطوات الآتية في عملية توصيل العناصر والأسلاك مع لوحة الأردوينو Arduino وتنفيذ فكرة مشروعنا: نصل أقطاب التغذية في لوحة الأردوينو أونو Arduino Uno مع لوحة توصيل التجارب BreadBoard، إذ يوصل القطب 5v في لوحة أردوينو مع المسرى الموجب للوحة التجارب، والقطب GND في اللوحة مع المسرى السالب للوحة التجارب من خلال أسلاك التوصيل نصل الرجل القصيرة التي تمثل الطرف السالب لجميع الليدات مع المسرى السالب في لوحة توصيل التجارب BreadBoard نصل الرجل الأطول التي تمثل الطرف الموجب لكل ليد من الليدات مع الرجل الأولى للمقاومة ذات القيمة 220 أوم الخاصة بكل ليد، والرجل الأخرى للمقاومة سنوصلها مع الأقطاب 5 و 6 و 9 و 10 على الترتيب في لوحة أردوينو أونو نصل أرجل التغذية Vccو Gnd للمقاومة المتغيرة الأولى والثانية مع المسرى الموجب والسالب في لوحة توصيل التجارب، وليس هناك فرق في حال تم التوصيل بشكل معاكس فالمقاومة ليس لها قطبية نصل رجل الخرج التشابهي Sig للمقاومة المتغيرة الأولى مع القطب A0 في لوحة الأردوينو أونو نصل رجل الخرج التشابهي Sig للمقاومة المتغيرة الثانية مع القطب A1 في لوحة الأردوينو أونو الكود البرمجي لمشروع التحكم بشدة وعدد الإضاءة باستخدام الأردوينو Arduino سنعرّف في بداية الكود مجموعة من الماكرو خاصة بأرقام الأقطاب الرقمية لليدات وأرقام الأقطاب التشابهية للمقاومات المتغيرة الأولى والثانية، وقد شرحنا كيفية استخدام الماكرو في مقال تخمين عدد مرات وميض الليد باستخدام الأردوينو Arduino كما يمكنك الاطلاع أكثر على مفهوم الماكرو وأنواعه من خلال مقال الماكرو Macro والمعالج المسبق Preprocessor في لغة سي C #define Red_Led_One 5 #define Red_Led_Two 6 #define Red_Led_Three 9 #define Red_Led_Four 10 #define Sig_One A0 #define Sig_Two A1 سنضبط هذه الأقطاب في الدالة الرئيسية ()setup من خلال الدالة()pinMode، فجميع الأقطاب الخاصة بالليدات هي أقطاب خرج OUTPUT، أما أقطاب المقاومات المتغيرة ستكون أقطاب دخل INPUT، ومن الممكن عدم ضبطها نوع أقطاب المقاومات لأن الحالة الإفتراضية لجميع الأقطاب في بيئة الأردوينو هي أقطاب دخل INPUT. void setup() { pinMode(Red_Led_One, OUTPUT); pinMode(Red_Led_Two, OUTPUT); pinMode(Red_Led_Three, OUTPUT); pinMode(Red_Led_Four, OUTPUT); } وفي الدالة التكرارية ()loop سنعرف متغيرين من نوع عدد صحيح int، الأول Number_Of_LEDs خاص بتخزين قيمة إشارة المقاومة المتغيرة الأولى المسؤولة عن تحديد عدد الليدات التي ستضيء، والثاني Brightness خاص بتخزين قيمة إشارة المقاومة الثانية المسؤولة عن تحديد شدة إضاءة الليدات، وتُقرأ القيمة التشابهية للمقاومات من خلال الدالة المدمجة ()analogRead void loop() { int Number_Of_LEDs = analogRead(Sig_One); int Brightness = analogRead(Sig_Two); بما أن المبدل التشابهي بدقة 10 بت بالتالي سيكون مجال القيم من 0 إلى 1023 ولكن هنا لدينا فقط أربعة ليدات لذلك نريد تحويل المجال 0 إلى 1023 إلى المجال 0 إلى 4 وذلك من خلال العلاقة 1023/(Value1*4)، كذلك الأمر بالنسبة لشدة الإضاءة نريد تحويل المجال 0 إلى 1023 إلى المجال 0 إلى 255، بما أن دقة PWM الموجودة في لوحة الأردوينو أونو هي 8 بت فقط سنستخدم العلاقة (1023/(255*Value2) للتحويل إلى المجال المطلوب Number_Of_LEDs = (Number_Of_LEDs * 4) / 1023; Brightness = (Brightness * 255) / 1023; سنستخدم بعد ذلك العبارة الشرطية ()if للتحقق من قيمة المتغير Number_Of_LEDs ووفقًا لقيمته سنحدد عدد الليدات التي ستضيء، أما لتحديد شدة إضاءة الليدات سنستخدم الدالة المدمجة ()analogWrite للتحكم بتشغيل وإطفاء الليدات بدلًا من الدالة المدمجة ()digitalWrite التي استخدمناها في المشاريع السابقة لأننا نريد أن تكون إضاءة الليدات بشدة محددة if(Number_Of_LEDs == 0){ analogWrite(Red_Led_One, 0); analogWrite(Red_Led_Two, 0); analogWrite(Red_Led_Three, 0); analogWrite(Red_Led_Four, 0); } else if(Number_Of_LEDs == 1){ analogWrite(Red_Led_One, Brightness); analogWrite(Red_Led_Two, 0); analogWrite(Red_Led_Three, 0); analogWrite(Red_Led_Four, 0); } else if(Number_Of_LEDs == 2){ analogWrite(Red_Led_One, Brightness); analogWrite(Red_Led_Two, Brightness); analogWrite(Red_Led_Three, 0); analogWrite(Red_Led_Four, 0); } else if(Number_Of_LEDs == 3){ analogWrite(Red_Led_One, Brightness); analogWrite(Red_Led_Two, Brightness); analogWrite(Red_Led_Three, Brightness); analogWrite(Red_Led_Four, 0); } else if(Number_Of_LEDs == 4){ analogWrite(Red_Led_One, Brightness); analogWrite(Red_Led_Two, Brightness); analogWrite(Red_Led_Three, Brightness); analogWrite(Red_Led_Four, Brightness); } } الكود البرمجي النهائي لمشروع التحكم بشدة وعدد الإضاءة بالأردوينو فيما يلي الكود البرمجي النهائي لتنفيذ مشروعنا: #define Red_Led_One 5 #define Red_Led_Two 6 #define Red_Led_Three 9 #define Red_Led_Four 10 #define Sig_One A0 #define Sig_Two A1 void setup() { pinMode(Red_Led_One, OUTPUT); pinMode(Red_Led_Two, OUTPUT); pinMode(Red_Led_Three, OUTPUT); pinMode(Red_Led_Four, OUTPUT); } void loop() { int Number_Of_LEDs = analogRead(Sig_One); int Brightness = analogRead(Sig_Two); Number_Of_LEDs = (Number_Of_LEDs * 4) / 1023; Brightness = (Brightness * 255) / 1023; if(Number_Of_LEDs == 0){ analogWrite(Red_Led_One, 0); analogWrite(Red_Led_Two, 0); analogWrite(Red_Led_Three, 0); analogWrite(Red_Led_Four, 0); } else if(Number_Of_LEDs == 1){ analogWrite(Red_Led_One, Brightness); analogWrite(Red_Led_Two, 0); analogWrite(Red_Led_Three, 0); analogWrite(Red_Led_Four, 0); } else if(Number_Of_LEDs == 2){ analogWrite(Red_Led_One, Brightness); analogWrite(Red_Led_Two, Brightness); analogWrite(Red_Led_Three, 0); analogWrite(Red_Led_Four, 0); } else if(Number_Of_LEDs == 3){ analogWrite(Red_Led_One, Brightness); analogWrite(Red_Led_Two, Brightness); analogWrite(Red_Led_Three, Brightness); analogWrite(Red_Led_Four, 0); } else if(Number_Of_LEDs == 4){ analogWrite(Red_Led_One, Brightness); analogWrite(Red_Led_Two, Brightness); analogWrite(Red_Led_Three, Brightness); analogWrite(Red_Led_Four, Brightness); } } محاكاة مشروع التحكم بشدة وعدد الإضاءة باستخدام الأردوينو سنتبع نفس الخطوات التي تعلمناها في مقال التحكم بتشغيل وإطفاء ليد LED باستخدام الأردوينو Arduino للوصول الى الصفحة الخاصة بمحاكاة المشروع على موقع وكوي Wokwi نضيف العناصر الإلكترونية اللازمة للمشروع وهي المقاومة المتغيرة Potentiometer و والليدات LEDs والمقاومات Resistors ولوحة التجارب BreadBoard. نغيّر قيمة مقاومة الليدات إلى 220 أوم من خلال الضغط عليها فتظهر لنا نافذة في الأعلى تمكننا من تغير القيمة والواحدة. بالطريقة نفسها يمكننا تغير ألوان الليدات من خلال الضغط عليها فتظهر نافذة بالأعلى نستطيع من خلالها اختيار اللون. نرتب العناصر على لوحة التجارب بالشكل الذي نراه مناسبًا، ثم نصل العناصر بعضها ببعض حسب مخطط التوصيل الذي عرضناه سابقًا. لنكتب الكود البرمجي في الجزء الخاص به ثم نشغل المحاكاة، ونلاحظ الحالات الآتية: ندور القرص الخاص بالمقاومة المتغيرة الأولى والثانية نحو أقصى اليسار، ونلاحظ أن جميع ستكون الليدات منطفئة في هذه الحالة ندور القرص الخاص بالمقاومة الأولى نحو اليمين بشكل تدريجي إلى أن يصل إلى أقصى اليمين، ونلاحظ أن جميع الليدات لا تزال منطفئة وذلك لأن قيمة المقاومة المتغيرة الثانية المسؤولة عن شدة إضاءة الليدات هي صفر عند تدوير القرص الخاص بالمقاومة المتغير الثانية نحو اليمين بشكل تدريجي، ستبدأ الليدات بالإضاءة بشدة متزايدة إلى أن يصل القرص إلى النهاية عندها ستضيء الليدات بالشدة الكاملة الآن بعد إضاءة الليدات بالشدة الكاملة، ندور القرص الخاص بالمقاومة المتغيرة الأولى نحو اليسار بشكل تدريجي ونلاحظ أن عدد الليدات المضاءة سيتناقص بشكل تدريجي إلى أن يصل القرص إلى البداية عندها ستنطفئ جميع الليدات الخاتمة بهذا نكون قد وصلنا لنهاية مقالنا الذي تعلمنا فيه كيفية التحكم بعدد الليدات المضاءة وشدة إضاءتها باستخدام الأردوينو Arduino، وتعرفنا على مجموعة من المصطلحات والمعلومات المهمة في مجال الإلكترونيات والأنظمة المدمجة، نشجعكم لتجربة بناء هذا المشروع والتطوير عليه للحصول على تجربة عملية مفيدة وممتعة. اقرأ أيضًا التعرف على أساسيات الأردوينو وتجهيز بيئة العمل إضاءة زينة بأنماط مختلفة باستخدام الأردوينو Arduino أساسيات في عالم الإلكترونيات: التيار والجهد والعناصر الساكنة برمجة الروبوت: الدليل الشامل
-
سنتعلم في مقال اليوم طريقة تنفيذ أنماط إضاءة مختلفة باستخدام الأردوينو، حيث يمكن استخدامها كإضاءة للزينة في بعض الأماكن مثل السيارات أو قاعات الاحتفال أو استخدامها كإشارة تنبيه لوقوع حالات الطوارئ في بعض الأماكن العامة. فكرة مشروع إضاءة زينة بأنماط مختلفة بأردوينو سنتحكم في آلية عمل مجموعة من الليدات LEDs كي تضيء وفق تسلسل محدد بعدة أنماط مختلفة يمكن التنقل بينها، وذلك من خلال ثمانية لِيدات باللون الأحمر إضافة لليد واحد باللون الأصفر كما سنستخدم مفتاح الضغط اللحظي Push Button في مشروعنا للتنقل بين أنماط الإضاءة عند الضغط عليه بشكل مستمر حتى إضاءة الليد الأصفر، عندها يمكن إزالة الضغط عن المفتاح حيث تستمر إضاءة الليد الأصفر لثلاث ثوان، ومن ثم تنتقل إضاءة الليدات للنمط التالي حيث سننفذ خمسة أنماط بأفكار مختلفة وسنشرح هذه الأنماط لاحقاً في فقرة الكود البرمجي. العناصر المستخدمة لمشروع إضاءة زينة سنستخدم مجموعة من العناصر الإلكترونية والأدوات وهي: لوحة أردوينو أونو Arduino Uno كابل البرمجة USB Cable لوحة توصيل التجارب Breadboard ليد اصفر Yellow LED عدد 1 ليد أحمر Red LED عدد 8 مفتاح من نوع Push Button عدد 1 مقاومة بقيمة 220 أوم عدد 9 مجموعة أسلاك توصيل من نوع Male to Male مخطط توصيل المشروع لتنفيذ فكرة المشروع، اتبع الخطوات الآتية في عملية توصيل العناصر والأسلاك مع لوحة الأردوينو Arduino: صل أقطاب التغذية في لوحة الأردوينو أونو Arduino Uno مع لوحة توصيل التجارب BreadBoard، إذ يوصل القطب 5v في لوحة الأردوينو مع المسرى الموجب للوحة التجارب، والقطب GND في لوحة الأردوينو مع المسرى السالب للوحة التجارب من خلال أسلاك التوصيل. قم بتوصيل الأرجل القصيرة، التي تمثل الأطراف السالبة لجميع الليدات، معًا في نقطة مشتركة، ثم اربط الرجل القصيرة لإحدى الليدات بالمسرى السالب GND على لوحة توصيل التجارب BreadBoard صل الرجل الأطول التي تمثل الطرف الموجب لكل ليد من الليدات الحمراء مع الرجل الأولى للمقاومة ذات القيمة 220 أوم الخاصة بكل ليد، وصل الرجل الأخرى للمقاومة مع أقطاب لوحة الأردوينو أونو Arduino Uno بالترتيب بدءًا من القطب رقم 3 لمقاومة الليد الأول وحتى القطب رقم 9 لمقاومة الليد الثامن صل الرجل القصيرة التي تمثل الطرف السالب لليد الأصفر مع المسرى السالب في لوحة توصيل التجارب BreadBoard أو مع إحدى الأرجل القصيرة لليدات الأخرى صل الرجل الأطول التي تمثل الطرف الموجب لليد الأصفر مع الرجل الأولى للمقاومة ذات القيمة 220 أوم الخاصة بالليد الأصفر، ثم الرجل الأخرى للمقاومة مع القطب رقم 12 في لوحة الأردوينو أونو Arduino Uno صل الطرف الأول لمفتاح الضغط اللحظي Push Button مع المسرى السالب للوحة التجارب ثم صل الطرف الثاني للمفتاح مع القطب رقم 2 في لوحة الأردوينو أونو Arduino Uno. سنفعّل مقاومة الرفع الداخلية للقطب رقم 2 في المتحكم الموجود في لوحة الأردوينو Arduino برمجيًا لذلك لا داعي لتوصيل مقاومة رفع Pull-Up أو مقاومة خفض Pull-Down مع مفتاح الضغط اللحظي Push Button. توضح الصورة الآتية مخطط توصيل المشروع الكود البرمجي لمشروع إضاءة زينة بأنماط مختلفة كما رأينا في فقرة مخطط التوصيل، سيوصَّل المفتاح اللحظي مع القطب رقم 2، ويوصَّل الليد الأصفر مع القطب رقم 12، أما الليدات ذات اللون الأحمر فستوصَّل مع الأقطاب من رقم 3 وحتى القطب رقم 10 بالترتيب مع لوحة الأردوينو أونو Arduino Uno . لذا سنعرف في بداية الكود عدد من الماكرو من نوع define# والتي ستخصص لأرقام الأقطاب لكل من الليد الأصفر والليدات ذات اللون الأحمر والمفتاح، وشرحنا كيفية استخدام الماكرو في مقال سابق في هذه السلسلة يمكنك الرجوع إليه من خلال تخمين عدد مرات وميض الليد باستخدام الأردوينو Arduino كما يمكنك الاطلاع أكثر على الماكرو وأنواعه من خلال مقال الماكرو Macro والمعالج المسبق Preprocessor في لغة سي C. #define BTN_PIN 2 #define YELLOW_LED 12 #define RED_LED_ONE 3 #define RED_LED_TWO 4 #define RED_LED_THREE 5 #define RED_LED_FOUR 6 #define RED_LED_FIVE 7 #define RED_LED_SIX 8 #define RED_LED_SEVEN 9 #define RED_LED_EIGHT 10 سنحتاج أيضًا لتعريف متغير من نوع int خاص بتخزين رقم النمط الذي سيحدد طريقة عمل الليدات وكما ذكرنا سابقًا أنه لدينا خمسة أنماط مختلفة int LEDs_Style= 0; سنضبط الأقطاب المستخدمة في المشروع في الدالة الرئيسية ()setup من خلال الدالة المدمجة ()pinMode التي تأخذ وسيطين الأول رقم القطب الذي خُزّن في الماكرو، والثاني نوع القطب إما خرج OUTPUT وإما دخل INPUT وإما دخل مع مقاومة رفع خارجية INPUT_PULLUP، حيث أن قطب المفتاح BTN_PIN سيكون قطب دخل مع تفعيل مقاومة رفع داخلية INPUT_PULLUP أما قطب الليد الأصفر YELLOW_LED وأقطاب الليدات الحمراء RED_LED_x ستكون أقطاب خرج OUTPUT void setup() { pinMode(BTN_PIN, INPUT_PULLUP); pinMode(YELLOW_LED, OUTPUT); pinMode(RED_LED_ONE, OUTPUT); pinMode(RED_LED_TWO, OUTPUT); pinMode(RED_LED_THREE, OUTPUT); pinMode(RED_LED_FOUR, OUTPUT); pinMode(RED_LED_FIVE, OUTPUT); pinMode(RED_LED_SIX, OUTPUT); pinMode(RED_LED_SEVEN, OUTPUT); pinMode(RED_LED_EIGHT, OUTPUT); } نلاحظ أن التعامل مع الليدات الحمراء بهذه الطريقة أي إعطاء الأمر الخاص بكل ليد بشكل منفصل صعب ويتطلب الكثير من الأكواد البرمجية؛ لذلك سنستبدل جميع الماكرو الخاصة بأقطاب هذه الليدات بمصفوفة أحادية []LEDs_PINs نخزن فيها أرقام الأقطاب بالترتيب، وستكون المصفوفة من نوع const int فأرقام الأقطاب أعداد صحيحة وثابتة لن يتم التعديل عليها أثناء تنفيذ الكود وهي تحتوي ثمانية عناصر بعدد الليدات الحمراء، وسنستخدم الحلقة التكرارية ()for للمرور على جميع عناصر المصفوفة []LEDs_PINs وإعطائها الأمر الخاص لكل عنصر من المصفوفة لكل قطب. const int LEDs_PINs[8] = {3, 4, 5, 6, 7, 8, 9, 10}; سنستخدم في هذه الحالة حلقة تكرارية ()for تبدأ من الرقم 0 لأن رقم العنصر الأول في المصفوفة دائمًا صفر وتنتهي عند الرقم 7 لأن رقم العنصر الأخير في المصفوفة يساوي دائمًا عدد عناصر المصفوفة مطروحًا منه واحد، تمر هذه الحلقة التكرارية على جميع عناصر المصفوفة []LEDs_PINs وتضبطها كأقطاب خرج من خلال الدالة المدمجة ()pinMode وسيمرر الوسيط الأول الخاص برقم القطب بدلالة اسم المصفوفة مع رقم العنصر، أما الوسيط الثاني سيكون OUTPUT لأننا نريد ضبطها كأقطاب خرج، ليصبح محتوى الدالة الرئيسية ()setup بالشكل الآتي: void setup() { pinMode(BTN_PIN, INPUT_PULLUP); pinMode(YELLOW_LED, OUTPUT); for (int i = 0; i <= 7; i++) { pinMode(LEDs_PINs[i], OUTPUT); } } سنكتب الكود الخاص بكل نمط في دالة خاصة به ومن ثم سننتقل إلى الكود الخاص بالدالة التكرارية ()loop ومعرفة كيفية استدعاء هذه الدوال الخاصة والتنقل بين الأنماط من خلال المفتاح BTN_PIN. تحقيق دالة إطفاء الليد سنكتب دالة خاصة في البداية باسم ()RESET_PINs لتطفئ جميع الليدات عند استدعائها، فعند الانتقال من نمط إلى آخر نريد أن تكون الحالة الافتراضية لجميع الليدات مطفئة لذا سنستدعي هذه الدالة بداية كل نمط، نكتب بداخل الدالة حلقة تكرارية ()for تمر على جميع عناصر المصفوفة []LEDs_PINs وتعطي أمر الإطفاء لكل عنصر فيها من خلال الدالة المدمجة ()digitalWrite التي تأخذ وسيطين: الأول رقم القطب ويحدد من خلال رقم عنصر المصفوفة المماثل لقيمة المتغير الخاص بالحلقة التكرارية i، والثاني حالة القطب وهي 1 منطقي أو HIGH للتشغيل، أو 0 منطقي أو LOW للإطفاء وبما أننا نريد إطفاء جميع الليدات سنعطيها القيمة LOW على النحو التالي: void RESET_PINs() { for (int i = 0; i <= 7; i++) { digitalWrite(LEDs_PINs[i], LOW); } } تحقيق أنماط الإضاءة النمط الأول RIGHT_TO_LEFT سنحقق النمط الأول بالدالة ()RIGHT_TO_LEFT لإضاءة جميع الليدات بشكل متتالي من اليمين إلى اليسار مع الحفاظ على إضاءة الليدات السابقة. يبدأ هذا النمط بإطفاء جميع الليدات من خلال استدعاء الدالة ()RESET_PINs التي عرفناها في الفقرة السابقة. ثم تبدأ إضاءة الليد الأول الموصول مع القطب رقم 3، ومن ثم الانتظار 250 مللي ثانية، ثم إضاءة الليد الثاني الموصول مع القطب رقم 4، والانتظار بعدها لمدة 250 مللي ثانية وهكذا تضيء الليدات بالتتالي بالطريقة نفسها حتى الوصول إلى الليد الثامن الموصول مع القطب رقم 10. سنستخدم الحلقة التكرارية ()for للمرور على جميع عناصر المصفوفة []LEDs_PINs بدءًا من العنصر الأول i=0 حتى الأخيرi=7، وإعطاء أمر التشغيل لعنصر المصفوفة المماثل لقيمة المتغير الخاص بهذه الحلقة التكرارية i من خلال الدالة المدمجة ()digitalWrite، أما لتحقيق التأخير الزمني بين إضاءة الليدات سنستخدم الدالة المدمجة ()delay وإعطاءها القيمة 250 مللي ثانية. void RIGHT_TO_LEFT() { RESET_PINs(); for (int i = 0; i <= 7; i++) { digitalWrite(LEDs_PINs[i], HIGH); delay(250); } } النمط الثاني LEFT_TO_RIGTHT سنحقق النمط الثاني بالدالة ()LEFT_TO_RIGTHT لإضاءة جميع الليدات بشكل متتالي من اليسار إلى اليمين مع الحفاظ على إضاءة الليدات السابقة. يبدأ هذا النمط بإطفاء جميع الليدات من خلال استدعاء الدالة ()RESET_PINs، ثم يضيء الليد الثامن الموصول مع القطب رقم 10، ومن ثم الانتظار لمدة 250 مللي ثانية، ثم إضاءة الليد السابق أي الليد السابع الموصول مع القطب رقم 9، والانتظار بعدها لمدة 250 مللي ثانية وهكذا تضيء الليدات بالتتالي بالطريقة نفسها حتى الوصول إلى الليد الأول الموصول مع القطب رقم يشبه الكود البرمجي لهذا النمط النمط السابق مع اختلاف بسيط وهو أن الحلقة التكرارية ()for تمر على جميع عناصر المصفوفة []LEDs_PINs بدءًا من العنصر الأخير j=7 وحتى العنصر الأول j=0، وإعطاء أمر التشغيل لعنصر المصفوفة المماثل لقيمة المتغير الخاص بهذه الحلقة التكرارية من خلال الدالة المدمجة ()digitalWrite، أما لتحقيق التأخير الزمني نستخدم الدالة المدمجة ()delay كما في النمط السابق. void LEFT_TO_RIGTHT() { RESET_PINs(); for (int j = 7; j >= 0; j--) { digitalWrite(LEDs_PINs[j], HIGH); delay(250); } } النمط الثالث GO_AND_BACK سنحقق النمط الثالث بالدالة ()GO_AND_BACK لإضاءة جميع الليدات بشكل متتالي من اليمين إلى اليسار ومن ثم إطفاء الليدات بشكل متتالي من اليسار إلى اليمين. يبدأ هذا النمط بإطفاء جميع الليدات من خلال استدعاء الدالة ()RESET_PINs ، ثم يضيء الليد الأول الموصول مع القطب رقم 3، ومن ثم الانتظار لمدة 250 مللي ثانية، ثم إضاءة الليد الذي يليه وهو الليد الثاني الموصول مع القطب رقم 4، والانتظار بعدها لمدة 250 مللي ثانية وهكذا تضيء الليدات بالتتالي بالطريقة نفسها حتى الوصول إلى الليد الثامن الموصول مع القطب رقم 10. بعد الانتهاء من تشغيل جميع الليدات ينطفئ الليد الثامن الموصول مع القطب رقم 10، ومن ثم الانتظار لمدة 250 مللي ثانية ، ثم إطفاء الليد السابق وأي الليد السابع الموصول مع القطب رقم 9، والانتظار بعدها لمدة 250 مللي ثانية وهكذا تنطفئ الليدات بالتتالي بالطريقة نفسها حتى الوصول إلى الليد الأول الموصول مع القطب رقم 3. سنستخدم الحلقة التكرارية ()for للمرور على جميع عناصر المصفوفة []LEDs_PINs، وإعطاء أمر التشغيل لعنصر المصفوفة المماثل لقيمة المتغير الخاص بهذه الحلقة التكرارية من خلال الدالة ()digitalWrite. وسنستخدم الحلقة التكرارية الثانية ()for للمرور على جميع عناصر المصفوفة []LEDs_PINs بدءًا من العنصر الأخير j=7 وحتى العنصر الأول j=0، وإعطاء أمر الإطفاء لعنصر المصفوفة المماثل لقيمة المتغير الخاص بهذه الحلقة التكرارية من خلال الدالة المدمجة ()digitalWrite، وسنستخدم الدالة المدمجة ()delay لتحقيق التأخير الزمني بين إضاءة الليدات وإعطاءها القيمة 250 مللي ثانية. void GO_AND_BACK() { RESET_PINs(); for (int i = 0; i <= 7; i++) { digitalWrite(LEDs_PINs[i], HIGH); delay(250); } for (int j = 7; j >= 0; j--) { digitalWrite(LEDs_PINs[j], LOW); delay(250); } } النمط الرابع LED_BY_LED سنحقق النمط الرابع بالدالة ()LED_BY_LED لإضاءة الليدات بشكل متتالي من اليمين إلى اليسار بدون الحفاظ على إضاءة الليدات السابقة. يشبه النمط الأول في تسلسل الإضاءة ولكن مع اختلاف بسيط أن الليدات السابقة ستنطفئ عند إضاءة الليد التالي، حيث يبدأ هذا النمط بإطفاء جميع الليدات من خلال استدعاء الدالة ()RESET_PINs التي كتبناها سابقًا ضمن الكود البرمجي، ثم يضيء الليد الأول الموصول مع القطب رقم 3 وإطفاء جميع الليدات الأخرى، ومن ثم الانتظار لمدة 250 مللي ثانية، ثم إضاءة الليد الثاني الموصول مع القطب رقم 4 وإطفاء جميع الليدات الأخرى، والانتظار بعدها لمدة 250 مللي ثانية وهكذا تضيء الليدات بالتتالي بشكل مستقل عن الليدات الأخرى وبالطريقة نفسها حتى الوصول إلى الليد الثامن الموصول مع القطب رقم 10. نلاحظ من الصورة السابقة أن لدينا ثمانية مراحل في كل مرحلة سيضىء الليد المطابق لرقم المرحلة فمثلًا عند المرحلة الخامسة i=4 سيضيء الليد الخامس j=4 لذلك يمكننا استخدام حلقتين تكراريتين ()for متداخلتين، الأولى للمرور على جميع المراحل بدءًا من i=0 وحتى i=7، أما الحلقة الثانية فهي للمرور على جميع عناصر المصفوفة []LEDs_PINs بدءًا من العنصر الأول j=0 وحتى العنصر الثامن j=7، ومن خلال استخدام الشرط i==j سنتحقق من تطابق رقم الحالة مع رقم الليد فإذا تحقق الشرط يعطى أمر التشغيل لعنصر المصفوفة، وإذا لم يتحقق يعطى أمر الإطفاء. void LED_BY_LED() { RESET_PINs(); for (int i = 0; i <= 7; i++) { for (int j = 0; j <= 7; j++) { if (i == j) { digitalWrite(LEDs_PINs[j], HIGH); } else { digitalWrite(LEDs_PINs[j], LOW); } } delay(250); } } النمط الخامس CUSTOM MODE سنحقق النمط الخامس بالدالة CUSTOM_MODE لتشغيل الليدات وإطفاءها وفق تسلسل خاص على شكل ستارة إلكترونية. يبدأ هذا النمط بإطفاء جميع الليدات من خلال استدعاء الدالة ()RESET_PINs التي كتبناها سابقًا ضمن الكود البرمجي، ومن ثم ستعمل الليدات وفق تسلسل خاص مشابه لفكرة الإضاءة على شكل ستارة إلكترونية، تبدأ بإضاءة ليد واحد من كل جهة ليد من اليمين وليد آخر من اليسار، ومن ثم الانتظار لمدة 250 مللي ثانية، ثم إضاءة ليد آخر من كل جهة، وهكذا إلى أن تضاء جميع الليدات، بعدها نعمل بشكل معاكس من خلال إطفاء الليدين من المنتصف، ومن ثم الانتظار لمدة 250 مللي ثانية وهكذا إلى أن تنطفئ جميع الليدات. نحدد طريقة إضاءة الليدات في هذا النمط من خلال تعريف مصفوفة ثنائية [][]Custom_Mode من نوع const int تحتوي على شكل الإضاءة في كل مرحلة، وذلك من خلال تحديد الليدات المضاءة والليدات المطفئة، نضع 1 منطقي مكان الليد الذي سيضيء و 0 منطقي مكان الليد الذي سينطفئ، وكما نعرف أن المصفوفة الثنائية تحتوي على أسطر وأعمدة، ولتحديد حجم المصفوفة يجب أن يكون عدد الأسطر بعدد المراحل التي ستضيء وتنطفئ فيها الليدات وفي حالتنا هذه لدينا ثمانية مراحل بالتالي ثمانية أسطر كما هو موضح بالشكل السابق، أما عدد أعمدة المصفوفة فيجب أن يكون بعدد الليدات التي لدينا وفي حالتنا هذه لدينا ثمانية ليدات بالتالي ثمانية أعمدة. سنستخدم حلقتين تكراريتين ()for الأولى للمرور على جميع أسطر المصفوفة والثانية للمرور على جميع أعمدتها وسنستخدمها أيضًا للوصول إلى أرقام الليدات المخزنة ضمن المصفوفة []LEDs_PINs، نعطي أمر التشغيل أو الإيقاف الخاص بكل ليد من خلال المصفوفة [][]Custom_Mode باستخدام الدالة ()digitalWrite، ونحقق التأخير الزمني بين إضاءة الليدات باستخدام الدالة ()delay. void CUSTOM_MODE() { RESET_PINs(); const int customMode[8][8] { {1, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 0, 0, 0, 0, 1, 1}, {1, 1, 1, 0, 0, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 0, 0, 1, 1, 1}, {1, 1, 0, 0, 0, 0, 1, 1}, {1, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0, 0, 0, 0}, }; for (int i = 0; i <= 7; i++) { for (int j = 0; j <= 7; j++) { digitalWrite(LEDs_PINs[j], customMode[i][j]); } delay(250); } } بهذا نكون انتهينا من تحقيق كافة أنماط الإضاءة التي سننجرزها في مشروعنا وحان دور برمجة عملية الانتقال فيما بينها. التبديل بين الأنماط باستخدام المفتاح التكراري سنبدل بين الأنماط ضمن الدالة التكرارية ()loop والتي سنعرف بداخلها متغير BTN_STAT من نوع int يخزن فيه حالة المفتاح الموصول على القطب BTN_PIN، ونقرأ حالته بالدالة ()digitalRead التي تأخذ وسيطًا واحدًا وهو رقم القطب وتعيد القيمة الفيزيائية الموجودة على القطب، وبما أن المفتاح موصول مع مقاومة رفع داخلية ستكون قيمة القطب LOW أو 0 منطقي في حالة الضغط على المفتاح وHIGH أو 1 منطقي عند إزالة الضغط عن المفتاح. وبعد ذلك سنتحقق من حالة المفتاح في حال كان مضغوط سنزيد قيمة LEDs_Style، ونستخدم عبارة شرطية لفحص قيمة النمط LEDs_Style في حال أصبحت أكبر من عدد الأنماط 4 سنرجع إلى النمط الأول، ونعطي أمر لتشغيل الليد الأصفر الذي يشير إلى أن المفتاح ضُغِط وعلينا الانتقال للنمط التالي والانتظار ثلاث ثواني وإعطاء أمر آخر لإطفاء الليد الأصفر. void loop(){ int BTN_STAT = digitalRead(BTN_PIN); if (BTN_STAT == 0) { LEDs_Style++; if (LEDs_Style > 4) { LEDs_Style= 0; } digitalWrite(YELLOW_LED, HIGH); delay(3000); digitalWrite(YELLOW_LED, LOW); } بعد تحديد قيمة النمط، تُستخدم العبارة الشرطية ()Switch لاستدعاء الدالة المطابقة لقيمة المتغير LEDs_Style وتنفيذ النمط المرتبط لكل حالة من 0 إلى 4 من خلال الدالة الخاصة به مع إنهاء التنفيذ بـ break لتجنب فحص باقي الحالات. switch (COUNTER) { case 0: RIGHT_TO_LEFT(); break; case 1: LEFT_TO_RIGTHT(); break; case 2: GO_AND_BACK(); break; case 3: LED_BY_LED(); break; case 4 : CUSTOM_MODE(); break; default: break; } } الكود البرمجي النهائي لمشروع إضاءة زينة بأنماط مختلفة باستخدام أردوينو #define BTN_PIN 2 #define YELLOW_LED 12 const int LEDs_PINs[8] = {3, 4, 5, 6, 7, 8, 9, 10}; int LEDs_Style = 0; void RESET_PINs() { for (int i = 0; i <= 7; i++) { digitalWrite(LEDs_PINs[i], LOW); } } void RIGHT_TO_LEFT() { RESET_PINs(); for (int i = 0; i <= 7; i++) { digitalWrite(LEDs_PINs[i], HIGH); delay(250); } } void LEFT_TO_RIGTHT() { RESET_PINs(); for (int j = 7; j >= 0; j--) { digitalWrite(LEDs_PINs[j], HIGH); delay(250); } } void GO_AND_BACK() { RESET_PINs(); for (int i = 0; i <= 7; i++) { digitalWrite(LEDs_PINs[i], HIGH); delay(250); } for (int j = 7; j >= 0; j--) { digitalWrite(LEDs_PINs[j], LOW); delay(250); } } void LED_BY_LED() { RESET_PINs(); for (int i = 0; i <= 7; i++) { for (int j = 0; j <= 7; j++) { if (i == j) { digitalWrite(LEDs_PINs[j], HIGH); } else { digitalWrite(LEDs_PINs[j], LOW); } } delay(250); } } void CUSTOM_MODE() { RESET_PINs(); const int customMode[8][8] { {1, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 0, 0, 0, 0, 1, 1}, {1, 1, 1, 0, 0, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 0, 0, 1, 1, 1}, {1, 1, 0, 0, 0, 0, 1, 1}, {1, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0, 0, 0, 0}, }; for (int i = 0; i <= 7; i++) { for (int j = 0; j <= 7; j++) { digitalWrite(LEDs_PINs[j], customMode[i][j]); } delay(250); } } void setup() { pinMode(BTN_PIN, INPUT_PULLUP); pinMode(YELLOW_LED, OUTPUT); for (int i = 0; i <= 7; i++) { pinMode(LEDs_PINs[i], OUTPUT); } } void loop() { int BTN_STAT = digitalRead(BTN_PIN); if (BTN_STAT == 0) { LEDs_Style++; if (LEDs_Style > 4) { LEDs_Style = 0; } digitalWrite(YELLOW_LED, HIGH); delay(3000); digitalWrite(YELLOW_LED, LOW); } switch (LEDs_Style) { case 0: RIGHT_TO_LEFT(); break; case 1: LEFT_TO_RIGTHT(); break; case 2: GO_AND_BACK(); break; case 3: LED_BY_LED(); break; case 4: CUSTOM_MODE(); break; default: break; } } محاكاة مشروع إضاءة زينة بأنماط مختلفة سنحاكي المشروع على موقع وكوي Wokwi وفق الخطوات التي شرحنا في مقال التحكم بتشغيل وإطفاء ليد LED باستخدام الأردوينو Arduino. أضف العناصر الإلكترونية اللازمة للمشروع المفتاح اللحظي Push Button والليدات LEDs والمقاومات Resistors ولوحة التجارب BreadBoard. غيّر قيمة مقاومة الليدات إلى 220 أوم من خلال النقر فوقها، حيث تظهر لك نافذة في الأعلى تمكنك من تغير القيمة والواحدة. بالطريقة نفسها يمكنك تغير ألوان الليدات والمفتاح من خلال النقر فوقها واختيار اللون من اللوحة الظاهرة. رتب العناصر على لوحة التجارب بالشكل الذي تراه مناسبًا، ثم صل العناصر بعضها ببعض حسب مخطط التوصيل الذي عرضناه سابقًا. اكتب الكود البرمجي في الجزء الخاص به ثم شغل المحاكاة، ولاحظ الحالات الآتية: في البداية ستضيء جميع الليدات بشكل متتالي من اليمين إلى اليسار مع الحفاظ على إضاءة الليدات السابقة أي أنها ستعمل وفق النمط الأول. اضغط على المفتاح اللحظي بشكل مستمر حتى إضاءة الليد الأصفر، عندها ستستمر إضاءة هذا الليد لمدة ثلاث ثواني ومن ثم ستضيء جميع الليدات بشكل متتالي من اليسار إلى اليمين مع الحفاظ على إضاءة الليدات السابقة أي أنها ستعمل وفق النمط الثاني. بالضغط على المفتاح مرة ثانية بشكل مستمر حتى إضاءة الليد الأصفر، عندها ستستمر إضاءة هذا الليد أيضًا لمدة ثلاث ثواني ومن ثم ستضيء جميع الليدات بشكل متتالي من اليمين إلى اليسار ثم ستنطفئ جميع الليدات بشكل متتالي من اليسار إلى اليمين، أي أنها ستعمل وفق النمط الثالث. بالضغط على المفتاح مرة ثالثة بشكل مستمر حتى إضاءة الليد الأصفر، ستستمر إضاءة هذا الليد أيضًا لمدة ثلاث ثواني ومن ثم إضاءة الليدات بشكل متتالي من اليمين إلى اليسار بدون الحفاظ على إضاءة الليدات السابقة، أي أنها ستعمل وفق النمط الرابع. أخيرًا، بالضغط على المفتاح مرة رابعة بشكل مستمر حتى إضاءة الليد الأصفر، عندها ستستمر إضاءة هذا الليد لمدة ثلاث ثواني ومن ثم تشغيل الليدات وإطفاءها وفق تسلسل خاص على شكل ستارة إلكترونية، أي أنها ستعمل وفق النمط الخامس. في حال تكرار الضغط على المفتاح مرة أخرى بعد ذلك سيعود إلى النمط الأول. الخاتمة في ختام هذا المقال نكون قد تعلمنا كيفية بناء مجموعة أنماط مختلفة من الإضاءات باستخدام الأردوينو Arduino، واكتسبنا العديد من المهارات البرمجية والإلكترونية، نشجعكم لتجربة بناء هذا المشروع وتطوير وإضافة أنماط جديدة عليها. اقرأ أيضًا المقال السابق: التحكم بالليد LED باستخدام مفتاح الضغط اللحظي Push Button في أردوينو التحكم بتشغيل وإطفاء ليد LED باستخدام الأردوينو Arduino التحكم بالليد LED باستخدام مفتاح الضغط اللحظي Push Button والأردوينو Arduino أساسيات في عالم الإلكترونيات: التيار والجهد والعناصر الساكنة
-
يعرفك هذا المقال كيفية بناء مشروع إلكتروني باستخدام لوحة الأردوينو Arduino للتحكم بتشغيل وإطفاء ليد LED من خلال استخدام اثنين من مفاتيح الضغط اللحظية Push Button الذي تعرفنا عليها في المقال السابق من سلسلتنا التعليمية لبناء المشاريع الإلكترونية باستخدام لوحات الأردوينو Arduino Board. فكرة مشروع التحكم بالليد باستخدام مفتاح الضغط اللحظي والأردوينو سنبني في هذا المشروع دائرة كهربائية بسيطة تستخدم مفتاحين من نوع Push Button للتحكم في تشغيل وإطفاء ليد بشكل دائم، فعند الضغط على المفتاح الأول (ونرمز له بالرمز S1) يضيء الليد، أما عند الضغط على المفتاح الثاني (ونرمز له بالرمز S2) فإن الليد سينطفئ، وفي حال الضغط على المفتاح الأول S1 والمفتاح الثاني S2 معًا وفي الوقت نفسه سينطفئ الليد أيضًا، وعند عدم الضغط على أي من المفتاحين S1 و S2 سيحافظ الليد على حالته السابقة سواء كان مضيء أو منطفئ، فنحصل بهذه الطريقة على تحكم دائم بالليد من خلال مفاتيح ضغط لحظية Push Button حتى عند إزالة الضغط عنها. يوضح لك الجدول الآتي جميع الحالات الممكنة للمفاتيح S1 و S2 ونتيجة تأثيرها على الليد LED سنتعلم من هذا المشروع كيفية تطوير مهارات التفكير والتحليل البرمجية حيث سنستطيع من خلال الكود البرمجي استخدام مفتاح الضغط اللحظي Push Button الذي يعطي إشارة للأردوينو فقط عندما يكون مضغوط كمفتاح دائم Switch من خلال بعض المهارات البرمجية. يمكن توظيف فكرة هذا المشروع في المشاريع المستقبلية للتحكم في بدء وإيقاف عمل الكود البرمجي من خلال هذه المفاتيح، فالمفتاح الأول S1 سيستخدم لبدء عمل الكود أما المفتاح الثاني S2 سيستخدم لإيقاف عمل الكود. العناصر المستخدمة للتحكم بالليد LED باستخدام مفتاح الضغط اللحظي Push Button والأردوينو Arduino سنستخدم مجموعة من العناصر الإلكترونية والأدوات وهي: لوحة أردوينو أونو Arduino Uno. كابل البرمجة USB Cable. لوحة توصيل التجارب Breadboard. ليد LED. مفتاحين من نوع Push Button. مقاومة بقيمة 220 أوم. مجموعة أسلاك توصيل من نوع Male to Male. مخطط التوصيل لمشروع التحكم بالليد باستخدام مفتاح الضغط اللحظي والأردوينو اتبع الخطوات الآتية في عملية توصيل العناصر والأسلاك مع لوحة الأردوينو Arduino لتنفيذ فكرة المشروع: صل أقطاب التغذية في لوحة الأردوينو أونو Arduino Uno مع لوحة توصيل التجارب BreadBoard، إذ يوصل القطب 5v في لوحة الأردوينو مع المسرى الموجب للوحة التجارب، والقطب GND في لوحة الأردوينو مع المسرى السالب للوحة التجارب من خلال أسلاك التوصيل. صل الرجل الأقصر (التي تمثل الطرف السالب) لليد مع الرجل الأولى للمقاومة ذات القيمة 220 أوم، ثم الرجل الأخرى للمقاومة ذات القيمة 220 أوم مع المسرى السالب في لوحة توصيل التجارب BreadBoard. صل الرِّجل الأطول (التي تمثل الطرف الموجب) لليد مع القطب رقم 8 في لوحة الأردوينو أونو Arduino Uno. ثبت المفتاحين الأول S1 والثاني S2 بشكل جيد في منتصف لوحة توصيل التجارب BreadBoard بحيث يكون نصف المفتاح في الجزء الأيمن للوحة التجارب BreadBoard والنصف الثاني للمفتاح في الجزء الأيسر للوحة التجارب BreadBoard. يوجد في مفتاح الضغط اللحظي Push Button أربعة أرجل أو أطراف كما ذكرنا سابقًا، كل اثنين منها متصلة ببعضها داخليًا ويمكن اعتبارها رجلًا واحدة، ولتجنب الخطأ أو التشتت في التوصيل سنعتمد أن نأخذ الأرجل القُطريَّة (الأرجل المختلفة للمفتاح) دائمًا. صل الطرف الأول للمفتاح الأول S1 مع المسرى السالب للوحة التجارب BreadBoard، ثم صل الطرف الثاني للمفتاح الأول S1 مع القطب رقم 7 في لوحة الأردوينو أونو Arduino Uno. صل الطرف الأول للمفتاح الثاني S2 مع المسرى السالب للوحة التجارب BreadBoard، ثم صل الطرف الثاني للمفتاح الثاني S2 مع القطب رقم 6 في لوحة الأردوينو أونو Arduino Uno. سنفعل مقاومة الرفع الداخلية للمتحكم الموجود في لوحة الأردوينو Arduino برمجيًا؛ لذلك لا داعي لتوصيل مقاومات رفع Pull-Up أو مقاومات خفض Pull-Down مع مفاتيح الضغط اللحظية Push Button. توضح الصورة الآتية مخطط التوصيل لمشروع التحكم بالليد باستخدام مفتاح الضغط اللحظي: الكود البرمجي لمشروع التحكم بالليد LED سنربط الأقطاب التي سنستخدمها في المشروع مع أسماء خاصة من خلال الماكرو define# في بداية الكود، وذلك لسهولة التعديل عليها عند الحاجة، فكما هو موضح في مخطط التوصيل سيوصل الليد مع القطب رقم 8، المفتاح الأول S1 مع القطب رقم 7، والمفتاح الثاني S2 مع القطب رقم 6 في لوحة الأردوينو أونو Arduino UNO. #define ledpin 8 #define button1pin 7 #define button2pin 6 استخدمنا الماكرو لربط أرقام الأقطاب بأسماء معبرة عنها فبدلًا من استخدام رقم القطب في الكود سنستخدم اسم الماكرو الخاص به، وعند الحاجة لتعديل رقم هذا القطب يمكننا ببساطة تعديله في مكان تعريف الماكرو فقط بدلًا من تعديله في جميع أماكن استخدامه في الكود، إضافة إلى أن الماكرو لا يأخذ حجم من ذاكرة البيانات SRAM الخاصة بالأردوينو Arduino على عكس المتغيرات. سنضبط الأقطاب المستخدمة في المشروع في الدالة الرئيسية ()setup، وذلك من خلال الدالة المدمجة ()pinMode التي تأخذ وسيطين: الأول رقم القطب (الذي خُزن في المتغير) والثاني نوع القطب (إما خرج وإما دخل)، حيث أن قطب الليد ledpin سيكون خرج OUTPUT وأقطاب المفاتيح button1pin وbutton2pin ستكون أقطاب دخل مع تفعيل مقاومة رفع داخلية INPUT_PULLUP void setup() { pinMode(ledpin, OUTPUT); pinMode(button1pin, INPUT_PULLUP); pinMode(button2pin, INPUT_PULLUP); } سنعرف في بداية الدالة التكرارية ()loop متغيرين: الأول button1stat خاص بتخزين قيمة القطب الموصول مع المفتاح الأول S1، والثانيbutton2stat خاص بتخزين قيمة القطب الموصول مع المفتاح الثاني S2، وذلك بعد قراءتها من خلال الدالة المدمجة ()digitalRead التي تأخذ وسيطًا واحدًا وهو رقم القطب وتعيد القيمة الفيزيائية الموجودة على القطب، وبما أن المفتاح موصول مع مقاومة رفع داخلية ستكون قيمة القطب LOW أو 0 منطقي في حالة الضغط على المفتاح وHIGH أو 1 منطقي عند إزالة الضغط عن المفتاح. int button1stat = digitalRead(button1pin); int button2stat = digitalRead(button2pin); بعد الحصول على حالة المفاتيح (الأول S1 والثاني S2) هل هي مضغوطة أم لا (تحوي القيمة 0 في حالة الضغط والقيمة 1 في حالة عدم الضغط)، سنستخدم العبارات الشرطية if وelse if لفحص حالة المفاتيح والتحكم بتشغيل وإطفاء الليد بالطريقة المناسبة (حسب الجدول الموضح مسبقًا)، ويتم تشغيل وإطفاء الليد برمجيًا من خلال الدالة المدمجة ()digitalWrite التي تأخذ وسيطين: الأول رقم القطب (الذي خُزن في المتغير) والثاني حالة أو قيمة القطب (إما 1 منطقي HIGH للتشغيل وإما 0 منطقي LOW للإطفاء). تحقق هل المفتاح الأول S1 مضغوط؟ وهل المفتاح الثاني S2 غير مضغوط؟ في حال تحقق الشرطين معًا (استخدمنا المعامل المنطقي AND الذي يرمز له && لضرورة تحقق الشرطين معًا)، إذًا شغّل الليد في هذه الحالة. if ((button1stat == 0) && (button2stat == 1)) { digitalWrite(ledpin, HIGH); } إن لم يتحقق الشرط السابق، تحقق من الشرط الآتي: هل المفتاح الأول S1 غير مضغوط؟ وهل المفتاح الثاني S2 مضغوط؟ في حال تحقق الشرطين معًا، إذًا أطفئ الليد في هذه الحالة. else if ((button1stat == 1) && (button2stat == 0)) { digitalWrite(ledpin, LOW); } إن لم يتحقق أي من الشروط السابقة، تحقق من الشرط الآتي: هل المفتاح الأول S1 مضغوط؟ والمفتاح الثاني S2 مضغوط أيضًا؟ في حال تحقق الشرطين معًا، إذًا أطفئ الليد في هذه الحالة. else if ((button1stat == 0) && (button2stat == 0)) { digitalWrite(ledpin, LOW); } إن لم يتحقق أي من الشروط السابقة، تحقق من الشرط الآتي: هل المفتاح الأول S1 غير مضغوط؟ والمفتاح الثاني S2 غير مضغوط؟ في حال تحقق الشرطين معًا، حافظ على حالة الليد وذلك من خلال إعطاء قيمة لليد في الدالة المدمجة ()digitalWrite تساوي القيمة المقروءة على قطب الليد من الدالة المدمجة ()digitalRead التي تأخذ رقم القطب وتعيد قيمته الفيزيائية. else if ((button1stat == 1) && (button2stat == 1)) { digitalWrite(ledpin, digitalRead(ledpin)); } الكود البرمجي النهائي لمشروع التحكم بالليد LED باستخدام مفتاح الضغط اللحظي والأردوينو #define ledpin 8 #define button1pin 7 #define button2pin 6 void setup() { pinMode(ledpin, OUTPUT); pinMode(button1pin, INPUT_PULLUP); pinMode(button2pin, INPUT_PULLUP); } void loop() { int button1stat = digitalRead(button1pin); int button2stat = digitalRead(button2pin); if ((button1stat == 0) && (button2stat == 1)) { digitalWrite(ledpin, HIGH); } else if ((button1stat == 1) && (button2stat == 0)) { digitalWrite(ledpin, LOW); } else if ((button1stat == 0) && (button2stat == 0)) { digitalWrite(ledpin, LOW); } else if ((button1stat == 1) && (button2stat == 1)) { digitalWrite(ledpin, digitalRead(ledpin)); } } محاكاة مشروع التحكم بالليد باستخدام مفتاح الضغط اللحظي اتبع الخطوات التي تعلمناها في مقالٍ سابق للوصول الى الصفحة الخاصة بمحاكاة مشروعك على موقع وكوي Wokwi .تستطيع الرجوع إليها من خلال مقال التحكم بتشغيل وإطفاء ليد LED باستخدام الأردوينو Arduino أضف العناصر الإلكترونية اللازمة للمشروع (مفاتيح Push Button، والليدات LEDs، والمقاومات Resistors، ولوحة التجارب BreadBoard). غيّر قيمة مقاومة الليد إلى 220 أوم من خلال الضغط عليها فتظهر لك نافذة في الأعلى تمكنك من تغير القيمة والواحدة. بالطريقة نفسها يمكنك تغير ألوان الليد والمفاتيح S1 و S2 من خلال الضغط عليها فتظهر لك نافذة بالأعلى تستطيع من خلالها اختيار اللون. رتب العناصر على لوحة التجارب بالشكل الذي تراه مناسبًا، ثم صل العناصر بعضها ببعض حسب مخطط التوصيل الذي عرضناه سابقًا. اكتب الكود البرمجي في الجزء الخاص به ثم شغل المحاكاة، ولاحظ الحالات الآتية: اضغط على المفتاح الأول S1 ستجد الليد يضيء (الحالة الأولى). أزل الضغط عنه ستجد ان الليد ما زال مضيئًا (الحالة الرابعة). الآن اضغط على المفتاح الثاني S2 ستجد أن الليد انطفئ (الحالة الثانية). أزل الضغط عنه ستجد أن الليد ما زال منطفئ (الحالة الرابعة). جرب إعادة الضغط على المفتاح الأول S1 لكي يضيء الليد ثم اضغط على المفتاحين معًا في وقت واحد سينطفئ الليد في هذه الحالة (الحالة الثالثة). الخلاصة تعلمنا في مقال اليوم خطوات تصميم وتنفيذ مشروع للتحكم بتشغيل وإطفاء ليد LED من خلال مفتاحين من نوع Push Button وهو المشروع الرابع في سلسلة دليل أردوينو التي تشرح بناء مجموعة من المشاريع الإلكترونية باستخدام الأردوينو Arduino، واستعرضنا أهم خطوات تنفيذ المشروع وتوصيل العناصر والأدوات والتعامل معها وكيفية كتابة الكود الخاص ببرمجة الأردوينو باستخدام بيئة التطوير المتكاملة (IDE) الخاصة به وعمل محاكاة للمشروع من خلال منصة وكوي Wokwi. اقرأ أيضًا المقال السابق: تخمين عدد مرات وميض الليد باستخدام الأردوينو Arduino التعرف على أساسيات الأردوينو وتجهيز بيئة العمل تثبيت أردوينو IDE ورفع الشيفرات على لوحة أردوينو بناء إشارة مرور باستخدام الأردوينو Arduino صنع قلب نابض باستخدام لوحة راسبيري باي بيكو
-
نشرح في هذا المقال كيفية بناء مشروع إلكتروني تفاعلي من خلال تصميم وتنفيذ لعبة بسيطة لتخمين عدد مرات وميض ليد باستخدام لوحة أردوينو أونو Arduino Uno ونوضح خطوات تنفيذ المشروع وأهم عناصره وطريقة محاكاته. فكرة مشروع تخمين عدد مرات وميض الليد سنبني مشروعًا يحسب عدد مرات تشغيل وإطفاء ليد بفترات زمنية عشوائية ضمن مجال محدد عند الضغط على مفتاح الضغط اللحظي Push Button (سنشرحه لاحقًا في هذا المقال) بشكل مستمر، ويجب على المستخدم حساب أو تخمين هذا الرقم، في النهاية بعد إزالة الضغط عن المفتاح سيتوقف الليد عن الومض ويطبع عدد مرات تشغيل وإطفاء الليد على نافذة الاتصال التسلسلي Serial monitor. سنتبع تسلسل الخطوات الآتية في آلية عمل المشروع: فحص حالة المفتاح (مضغوط أم لا) وإذا كان مضغوطًا تنفذ الخطوات من 2 إلى 5 وإلا تكرر الخطوة 1 يضيء الليد لفترة زمنية عشوائية ضمن مجال محدد ينطفئ الليد لفترة زمنية عشوائية ضمن مجال محدد تزداد قيمة العداد بمقدار 1 فحص حالة المفتاح (مضغوط أم لا) وإذا كان مضغوطًا تكرر الخطوات من 2 إلى 5 وإلا ينتقل إلى 6 فحص قيمة العداد إذا كانت أكبر من 0 (ومض الليد مرة واحدة على الأقل) وإذا كان الشرط محققًا تنفيذ الخطوة 7 و 8 وإلا الرجوع إلى الخطوة 1 طباعة قيمة العداد تصفير قيمة العداد العناصر المستخدمة لمشروع تخمين عدد مرات وميض الليد العناصر التي سنستخدمها لعمل هذا المشروع هي: لوحة أردوينو أونو Arduino Uno كابل البرمجة USB Cable لوحة توصيل التجارب Breadboard ليد LED مفتاح الضغط اللحظي Push Button مقاومة بقيمة 220 أوم مقاومة بقيمة 10 كيلو أوم مجموعة أسلاك توصيل من نوع Male to Male ما هو مفتاح الضغط اللحظي Push Button عبارة عن مفتاح ميكانيكي لحظي عند الضغط عليه تتصل أطرافه معًا مما يؤدي إلى إغلاق الدائرة الكهربائية المتصلة به، وعند إزالة الضغط يعود إلى حالته الأولى، يمكن أن يستخدم كعنصر للتحكم بالتشغيل والإيقاف بإعطاء إشارة رقمية Digital إلى الأردوينو Arduino من خلال توصيل أحد أطرافه مع 5v أو GND والطرف الآخر مع إحدى أقطاب الأردوينو الرقمية. مثلًا وصَّلنا الطرف الأول للمفتاح مع 5v والطرف الثاني مع القطب رقم 2 للأردوينو Arduino وضغطنا على المفتاح في هذه الحالة عند قراءة قيمة القطب ستكون HIGH أو 1 منطقي. أو إذا كان الطرف الأول للمفتاح وصل مع GND بدلًا من 5v والطرف الثاني مع القطب رقم 2 للأردوينو Arduino فإنه عند الضغط على المفتاح ستكون قيمة القطب LOW أو 0 منطقي. ولكن نلاحظ أنه في حال عدم الضغط على المفتاح فإنه يعطي قيم خاطئة أو عشوائية وذلك لأنه عند عدم الضغط على المفتاح لا يوجد أي إشارة على قطب الأردوينو (1 منطقي HIGH أو 0 منطقي LOW) وتسمى هذه الحالة بالحالة العائمة أو حالة مقاومة عالية (High-Z or High impedance). نحل هذه المشكلة من خلال إضافة مقاومة رفع Pull-Up Resistor من خلال توصيل مقاومة بين قطب الأردوينو و5v (تكون القيمة الافتراضية للقطب في حال عدم الضغط على المفتاح هي HIGH أو 1 منطقي أما عند الضغط على المفتاح فتكون قيمته LOW أو 0 منطقي) أو إضافة مقاومة خفض Pull-Down Resistor من خلال توصيل مقاومة بين قطب الأردوينو والأرضي GND (تكون القيمة الافتراضية للقطب في حال عدم الضغط على المفتاح هي LOW أو 0 منطقي أما عند الضغط على المفتاح فستكون قيمته HIGH أو 1 منطقي). توضح الصورة الآتية حالة قطب الدخل في لوحة الأردوينو أونو Arduino Uno في حال استخدام مقاومة رفع مع مفتاح الضغط اللحظي Push Button أو بدونها. وتوضح الصورة الآتية طريقة توصيل مقاومة الرفع والخفض مع مفتاح الضغط اللحظي Push Button في لوحة الأردوينوأونو Arduino UNO مخطط التوصيل لمشروع تخمين عدد مرات وميض الليد اتبع الخطوات الآتية في عملية توصيل العناصر والأسلاك مع لوحة الأردوينو Arduino لتنفيذ فكرة المشروع: صل أقطاب التغذية في لوحة الأردوينو أونو Arduino Uno مع لوحة توصيل التجارب BreadBoard، إذ يوصل القطب 5v في لوحة الأردوينو مع المسرى الموجب للوحة التجارب، والقطب GND في لوحة الأردوينو مع المسرى السالب للوحة التجارب من خلال أسلاك التوصيل صل الرِّجل الأطول التي تمثل الطرف الموجب لليد مع الرجل الأولى للمقاومة ذات القيمة 220 أوم، ثم صل الرجل الأخرى للمقاومة ذات القيمة 220 أوم مع القطب رقم 13 في لوحة الأردوينو أونو Arduino Uno صل الرجل الأقصر التي تمثل الطرف السالب لليد مع المسرى السالب في لوحة توصيل التجارب BreadBoard يوجد في مفتاح الضغط اللحظي Push Button أربعة أرجل أو أطراف كما ذكرنا سابقًا، كل اثنين منها متصلة ببعضها داخليًا ويمكن اعتبارها رجلًا واحدة، ولتجنب الخطأ أو التشتت في التوصيل سنعتمد أن نأخذ الأرجل القطرية أي الأرجل المختلفة للمفتاح دائمًا ثبت المفتاح بشكل جيد في منتصف لوحة توصيل التجارب BreadBoard، بحيث يكون نصف المفتاح في الجزء الأيمن للوحة التجارب BreadBoard والنصف الثاني للمفتاح في الجزء الأيسر للوحة التجارب BreadBoard صل الطرف الأول للمفتاح مع المسرى السالب للوحة التجارب BreadBoard، والطرف الثاني للمفتاح مع القطب رقم 2 في لوحة أردوينو أونو صل الطرف الأول للمقاومة ذات القيمة 10 كيلو أوم مع الطرف الثاني للمفتاح المتصل مع القطب رقم 2 في لوحة الأردوينو أونو صل الطرف الثاني للمقاومة ذات القيمة 10 كيلو أوم مع المسرى الموجب للوحة توصيل التجارب BreadBoard توضح الصورة الآتية مخطط التوصيل لمشروع تخمين عدد مرات وميض الليد: الكود البرمجي لمشروع تخمين عدد مرات وميض الليد نحتاج في البداية لتعريف متغيرات خاصة بأرقام أقطاب بالليد LED والمفتاح Push Button؛ فكما شرحنا في مخطط التوصيل سيوصل المفتاح مع القطب رقم 2 والليد مع القطب رقم 13، وبما أن هذه الأرقام صحيحة نخزنها في متغيرات من نوع int. int led = 13; int button = 2; شرحنا في فكرة المشروع أن الليد سيضيء وينطفئ لمدة زمنية عشوائية ولكن هذه المدة ضمن مجال محدد لذلك نخزن مجال القيم العشوائية الخاصة بالتأخير الزمني في متغيرات من نوع int وسنختار أقل مدة هي 100 مللي ثانية وأكثر مدة هي 500 مللي ثانية. int minDelay = 100; int maxDelay = 500; أخيرًا نحتاج إلى تعريف متغير من نوع int لتخزين قيمة العداد بقيمة ابتدائية 0. int count = 0; سنفعّل واجهة الاتصال التسلسلية Serial Communication داخل الدالة الرئيسية ()setup في البداية من أجل عرض قيمة العداد على نافذة الاتصال التسلسلي Serial Monitor الموجودة في بيئة الأردوينو البرمجية Arduino IDE وذلك من خلال التابع ()Serial.begin الذي تأخذ وسيطين: الأول أساسي وهو سرعة نقل البيانات Baud rate بمعدل بت في الثانية وسنختار 9600، والثاني اختياري خاص بضبط الإعدادات config الأخرى لواجهة الاتصال ويمكن تركه فارغًا حيث يأخذ الضبط الافتراضي في هذه الحالة. سنضبط بعدها القطب الخاص بالليد كقطب خرج OUTPUT والقطب الخاص بالمفتاح كقطب دخل INPUT من خلال الدالة المدمجة ()pinMode التي تأخذ وسيطين: الأول رقم القطب (الذي خُزن في المتغير) والثاني نوع القطب (إما خرج وإما دخل) void setup() { Serial.begin(9600); pinMode(led, OUTPUT); pinMode(button, INPUT_PULLUP); } سنعرف في الدالة التكرارية ()loop في البداية متغيرًا خاصًا بتخزين قيمة القطب الموصول مع المفتاح بعد قراءتها من خلال الدالة ()digitalRead التي تأخذ وسيطًا واحدًا وهو رقم القطب وتعيد القيمة الفيزيائية الموجودة على القطب، وبما أن المفتاح موصول مع مقاومة رفع خارجية ستكون قيمة القطب LOW أو 0 منطقي في حالة الضغط على المفتاح وHIGH أو 1 منطقي عند إزالة الضغط عن المفتاح. int buttonStat = digitalRead(button); سيومض الليد وتزداد قيمة العداد باستمرار ولكن بشرط استمرار الضغط على المفتاح؛ لذلك سنستخدم الحلقة التكرارية ()while والشرط الذي سنضعه هو أن تكون قيمة المتغير buttonStat هي 0. while (buttonStat == 0) { } سيضيء الليد وينطفئ داخل هذه الحلقة بتأخير زمني عشوائي ويتم التحكم بقيمة القطب من خلال الدالة ()digitalWrite التي تأخذ وسيطين: الأول رقم القطب (الذي خُزن في المتغير) والثاني حالة أو قيمة القطب (إما 1 منطقي HIGH للتشغيل وإما 0 منطقي LOW للإطفاء). لتحقيق التأخير الزمني نستخدم الدالة ()delay التي تحقق انتظار أو تأخير زمني في مكان كتابتها في الكود ويُكتب الزمن داخلها بواحدة المللي ثانية "ms" وللحصول على قيمة عشوائية نستخدم الدالة ()random التي يمكن أن تأخذ وسيطين الأول أقل قيمة والثاني أكبر قيمة وتعيد قيمة عشوائية ضمن هذا المجال. digitalWrite(led, HIGH); delay(random(minDelay, maxDelay)); digitalWrite(led, LOW); delay(random(minDelay, maxDelay)); اكتملت مرة واحدة من تشغيل وإطفاء الليد في هذه الحالة لذلك سنزيد قيمة العداد count بمقدار 1، ومن ثَم سنحتاج إلى قراءة حالة المفتاح مرة أخرى كي لا تصبح الحلقة التكرارية غير منتهية فإذا تمت إزالة الضغط عن المفتاح سيخرج البرنامج من هذه الحلقة ويكمل تنفيذ باقي البرنامج. count++; buttonStat = digitalRead(button); ليصبح الكود الخاص بالحلقة التكرارية ()while: while (buttonStat == 0) { digitalWrite(led, HIGH); delay(random(minDelay, maxDelay)); digitalWrite(led, LOW); delay(random(minDelay, maxDelay)); count++; buttonStat = digitalRead(button); } سنطبع قيمة العداد count على نافذة الاتصال التسلسلي إن تحقق الشرط أن العداد count لا يساوي الصفر (المفتاح ضغط والليد اشتغل وانطفأ مرة واحدة على الأقل) وسبب استخدام هذا الشرط هو تجنب طباعة رقم 0 باستمرار في حالة عدم الضغط على المفتاح. if (count != 0) { } بعد التأكد من أن قيمة العداد ليست صفرًا سنطبع العبارة ":Number of blinking" من خلال الدالة المدمجة ()Serial.print ونضع البيانات التي نريد طباعتها داخل الأقواس وبما أننا نريد طباعة نص نكتبه ضمن علامتي تنصيص " " وبجانبه نريد طباعة عدد مرات الوميض ثم النزول إلى سطر جديد؛ لذلك سنستخدم التابع ()Serial.println الذي يطبع البيانات ثم ينتقل إلى سطر جديد. وفي النهاية نصفر قيمة العداد كي يبدأ العد من الصفر إذا ضُغط على المفتاح مرة أخرى. if (count != 0) { Serial.print("number of blinking: "); Serial.println(count); count = 0; } تحسين الكود البرمجي للمشروع من أكثر المشكلات التي تواجه المطورين في المشاريع الضخمة هي استهلاك ذاكرة البرنامج بشكل مفرط ولعل أهم أسباب هذه المشكلة هو العدد الكبير للمتغيرات الموجودة في الكود، ونلاحظ أن لدينا في هذا المشروع المتغيرات الآتية: led وbutton وminDelay وmaxDelay التي لم نعدل على القيمة المخزنة فيها مطلقًا خلال الكود على عكس المتغيرات الأخرى count buttonStat التي تتغير قيمها. لهذا نستطيع الاستغناء عن المتغيرات التي لا نحتاج للتعديل عليها مثل led وbutton و minDelay وmaxDelay من أجل تقليل استهلاك ذاكرة البرنامج، واستبدال هذه المتغيرات بالماكرو Macro وهو عبارة عن طريقة لتعريف مجموعة من التعليمات البرمجية التي يمكن استخدامها مرارًا وتكرارًا في البرنامج دون استهلاك ذاكرة البرنامج، ويعرف الماكرو باستخدام الموجهات Directives وتبدأ بالكلمة المفتاحية define# ثم اسم الماكرو وبعدها القيمة الخاصة به مثال لاستبدال المتغيرات السابقة: #define led 13 #define button 2 #define minDelay 100 #define maxDelay 500 لاحظ الفرق بين حجم استهلاك ذاكرة البرنامج في كلا الحالتين الأولى هي عند استخدام المتغيرات والثانية هي عند استبدالها بالماكرو ويمكن أن يكون الماكرو بسيطًا كاستبدال نص معين أو أرقام ويمكن أن يكون معقدًا أكثر مثل ماكرو الدالة، للاطلاع أكثر على الماكرو وأنواعه من خلال مقال الماكرو Macro والمعالج المسبق Preprocessor في لغة سي C. رأينا سابقًا مشكلة الحالة العائمة floating الخاصة بالمداخل الرقمية Digital Input عندما لا يكون هناك قيمة محددة عليها واستطعنا حل هذه المشكلة من خلال التعرف على مفهوم مقاومة الرفع والخفض واستخدمنا مقاومة رفع خارجية في مشروعنا مع مفتاح الضغط اللحظي Push Button. تدعم بعض المتحكمات ومن بينها لوحات الأردوينو وجود مقاومة رفع داخلية نستطيع تفعيلها برمجيًا أثناء ضبط نوع القطب من خلال الدالة المدمجة ()pinMode التي نمرر لها رقم القطب ونوعه كما ذكرنا سابقًا وقد تعرفنا على حالتين لنوع القطب إما أن يكون خرج OUTPUT وإما دخل INPUT ولكن هناك حالة ثالثة وهي دخل مع تفعيل مقاومة رفع داخلية INPUT_PULLUP وبهذه الحالة نستطيع الإستغناء عن مقاومة الرفع الخارجية والتقليل من التوصيلات والعناصر التي قد تسبب تعقيدًا في تنفيذ المشروع للبعض بحل برمجي بسيط pinMode(button, INPUT_PULLUP); يصبح الكود البرمجي النهائي للمشروع: #define led 13 #define button 2 #define minDelay 100 #define maxDelay 500 int count = 0; void setup() { Serial.begin(9600); pinMode(led, OUTPUT); pinMode(button, INPUT_PULLUP); } void loop() { int buttonStat = digitalRead(button); while(buttonStat == 0){ digitalWrite(led, HIGH); delay(random(minDelay, maxDelay)); digitalWrite(led, LOW); delay(random(minDelay, maxDelay)); count++; buttonStat = digitalRead(button); } if(count !=0){ Serial.print("number of blinking: "); Serial.println(count); count = 0; } } محاكاة لمشروع تخمين عدد مرات وميض الليد اتبع الخطوات التي تعلمناها في المقال السابق للوصول الى الصفحة الخاصة بمحاكاة مشروعك على موقع وكوي Wokwi .تستطيع الرجوع إليها من خلال مقال التحكم بتشغيل وإطفاء ليد LED باستخدام الأردوينو Arduino أضف العناصر الإلكترونية اللازمة للمشروع وهي Push Button LEDs و Resistors و BreadBoard. غير قيمة مقاومة الليد إلى 220 أوم ومقاومة المفتاح إلى 10 كيلو أوم (في حال استخدام مقاومة خارجية) من خلال الضغط عليها فتظهر لك نافذة في الأعلى تمكنك من تغير القيمة والواحدة. بالطريقة نفسها يمكنك تغير ألوان الليد والمفتاح من خلال الضغط عليها فتظهر لك نافذة بالأعلى تستطيع من خلالها اختيار اللون. رتب العناصر على لوحة التجارب بالشكل الذي تراه مناسبًا، ثم صل العناصر بعضها ببعض حسب مخطط التوصيل الذي عرضناه سابقًا. أخيرًا اكتب الكود البرمجي في الجزء الخاص به، ثم شغل المحاكاة، اضغط على المفتاح سيبدأ الليد بالوميض حاول أن تركز في عدد مرات تشغيل وإطفاء الليد انتظر قليلًا ثم أزل الضغط عن المفتاح سيظهر لك عدد مرات وميض الليد في الاسفل، هل استطعت تخمينها بشكل صحيح؟ الخلاصة شرحنا في هذا المشروع طريقة بناء مشروع لقياس وتخمين عدد مرات وميض الليد عند الضغط عليه باستخدام لوحة الأردوينو، واستعرضنا كيفية بناء المشروع وتوصيل العناصر والأدوات، بما في ذلك الأردوينو والليد والمقاومات والمفتاح، وتعلمنا كيفية كتابة الكود الخاص ببرمجة الأردوينو باستخدام بيئة التطوير المتكاملة IDE الخاصة به وعمل محاكاة للمشروع من خلال منصة وكوي Wokwi وكيفية حل مشكلات المشروع وتحسينه للأفضل. اقرأ أيضًا المقال السابق: بناء إشارة مرور باستخدام الأردوينو Arduino أداة التهيئة في راسبيري باي تجميع راسبيري باي والتحضير لاستخدامه جولة في نظام تشغيل راسبيري باي
-
بعد أن أنشأنا أول مشروع بسيط لنا باستخدام لوحة أردوينو في المقال السابق، سنوظف ما تعلمناه حول التعامل مع الأقطاب الرقمية Digital Pins وكتابة التعليمات البرمجية لضبط نوع القطب وإعطاء أوامر التشغيل والإيقاف إليه وتوصيل العناصر على لوحة التجارب BreadBoard وربطها مع أقطاب لوحة أردوينو ونطور مشروعنا الثاني وهو مشروع يحاكي إشارة المرور. فكرة المشروع الهدف من هذا المشروع هو التحكم بإشارة مرور بسيطة مثل التي نراها في الطرقات والتي تحتوي على ثلاثة ليدات، أحمر وبرتقالي وأخضر، إذ تكون خطوات التشغيل بالشكل الآتي: يضيء الليد الأخضر في البداية وتنطفئ باقي الليدات لمدة زمنية محددة (5 ثوان). ينطفئ الليد الأخضر ويضيء الليد البرتقالي بشكل ومضات مرات عدة بفترات قصيرة (0.5 ثانية). يضيء الليد الأحمر وتنطفئ باقي الليدات لمدة زمنية محددة (5 ثوان). تتكرر عملية تشغيل وإطفاء الليد البرتقالي مرات عدة ( الخطوة نفسها رقم 2). إعادة تكرار الخطوات باستمرار بدءًا من الخطوة رقم 1. العناصر المستخدمة العناصر التي سنستخدمها لعمل هذا المشروع هي كالتالي: لوحة أردوينو أونو Arduino Uno. كابل البرمجة USB Cable. لوحة توصيل التجارب Breadboard. ليد أحمر RED LED. ليد أخضر GREEN LED. ليد برتقالي ORANGE LED. ثلاث مقاومات بقيمة 220 أوم. مجموعة أسلاك توصيل من نوع Male to Male. مخطط توصيل مشروع إشارة مرور باستخدام أردوينو لتنفيذ فكرة المشروع، اتبع الخطوات الآتية لتوصيل العناصر والأسلاك مع لوحة الأردوينو Arduino : صل أقطاب التغذية في لوحة الأردوينو أونو Arduino Uno مع لوحة توصيل التجارب BreadBoard، إذ يوصل القطب 5v في لوحة الأردوينو مع المسرى الموجب للوحة التجارب، والقطب GND في لوحة الأردوينو مع المسرى السالب للوحة التجارب من خلال أسلاك التوصيل. صل الرِّجل الأطول (التي تمثل الطرف الموجب) لليد الأخضر مع الرجل الأولى للمقاومة، ثم الرجل الأخرى للمقاومة مع القطب رقم 9 في لوحة الأردوينو أونو Arduino Uno. صل الرِّجل الأقصر (التي تمثل الطرف السالب) لليد الأخضر مع المسرى السالب في لوحة توصيل التجارب BreadBoard. كرر الخطوتين السابقتين بالطريقة ذاتها لليد البرتقالي والليد الأحمر ولكن مع تغيير أرقام الأقطاب في لوحة الأردوينو أونو Arduino Uno إلى القطب رقم 10 لمقاومة الليد البرتقالي والقطب رقم 11 لمقاومة الليد الأحمر. لترتيب التوصيل بصورة أفضل يمكنك توصيل الرِّجل الأقصر (التي تمثل الطرف السالب) لليد الأول مع الرِّجل الأقصر من الليدات الأخرى، ثم توصيل إحداها بالمسرى السالب في لوحة توصيل التجارب BreadBoard لأنها تشترك جميعًا بالنقطة ذاتها وفي النهاية النتيجة واحدة. توضح الصورة الآتية مخطط التوصيل: الكود البرمجي لمشروع إشارة المرور في البداية نحتاج لتعريف ثلاثة متغيرات من نوع عدد صحيح int تحتوي على رقم القطب الموصول مع كل ليد في لوحة Arduino Uno حيث سنوصلها مع الأقطاب 9 لليد الأخضر و 10 لليد البرتقالي و 11 لليد الأحمر كما وضحنا ذلك في جزء مخطط التوصيل، وبما أننا نريد استخدام هذه المتغيرات في أي جزء من الكود سنعرفها في البداية كمتغيرات عامة خارج الدالتين الرئيسية والتكرارية كما يلي. int Green_Led = 9; int Orange_Led = 10; int Red_Led = 11; الآن، سنضبط داخل الدالة الرئيسية الأقطاب الخاصة بالليدات التي خُزّنت أرقامها ضمن متغيرات كأقطاب خرج من خلال الدالة المدمجة ()pinMode التي تأخذ معاملين الأول رقم القطب (الذي خُزن في المتغير) والثاني نوع القطب (إما خرج وإما دخل) وفي حالتنا هذه الأقطاب جميعها خرج OUTPUT. void setup() { pinMode(Red_Led, OUTPUT); pinMode(Orange_Led, OUTPUT); pinMode(Green_Led, OUTPUT); } وبما أننا نحتاج لتشغيل المشروع باستمرار لذلك سنكتب التعليمات البرمجية الخاصة بأوامر التحكم بالتشغيل والإطفاء الخاصة بالليدات في الدالة التكرارية ()void loop التي تنفذ الكود البرمجي الموجود داخلها بشكل متكرر. void loop() { } ذكرنا سابقًا أننا سنشغل القطب الخاص بالليد الأخضر في البداية ونطفئ الأقطاب الخاصة بالليدات الأخرى (الأحمر والبرتقالي) بتأخير زمني 5000 مللي ثانية أي بمقدار 5 ثوان، وللتحكم بإشارة خرج أقطاب الليدات برمجيًا سنستخدم الدالة المدمجة ()digitalWrite التي تأخذ معاملين أيضًا: الأول رقم القطب (الذي خُزن في المتغير) والثاني حالة أو قيمة القطب (إما 1 منطقي HIGH وإما 0 منطقي LOW) وفي حالتنا هذه سيأخذ القطب الخاص بالليد الأخضر القيمة HIGH لأننا نريد تشغيله وستأخذ الأقطاب الخاصة بالليدات الأخرى (الأحمر والبرتقالي) القيمة LOW، ولتحقيق التأخير الزمني نستخدم الدالة المدمجة ()delay كما يلي: digitalWrite(Red_Led, LOW); digitalWrite(Orange_Led, LOW); digitalWrite(Green_Led, HIGH); delay(5000); سنشغل الليد البرتقالي ثم نطفئه بشكل متكرر مرات عدة وبتأخير زمني قصير (0.5 ثانية بعد كل عملية تشغيل أو إطفاء) ليحاكي النموذج الحقيقي لإشارة المرور، ولتنفيذ ذلك برمجيًا نستدعي الدالة ()digitalWrite حيث سيأخذ القطب الخاص بالليد البرتقالي القيمة HIGH وستأخذ الأقطاب الخاصة بالليدات الأخرى (الأحمر والأخضر) القيمة LOW لأننا نريد تشغيل الليد البرتقالي بالبداية، وبالطريقة نفسها نستخدم الدالة ()digitalWrite مع تغيير قيمة القطب الخاص بالليد البرتقالي إلى القيمة LOW لأننا نريد إطفاءه. ونستدعي دالة التأخير الزمني()delay بين كل عملية تشغيل وإطفاء أو العكس بمقدار نصف ثانية أو 500 مللي ثانية، بهذه الطريقة نحقق وميض الليد البرتقالي مرة واحدة، وبتكرار الكود مرات عدة نحصل على الوظيفة المطلوبة. digitalWrite(Red_Led, LOW); digitalWrite(Orange_Led, HIGH); digitalWrite(Green_Led, LOW); delay(500); digitalWrite(Red_Led, LOW); digitalWrite(Orange_Led, LOW); digitalWrite(Green_Led, LOW); delay(500); digitalWrite(Red_Led, LOW); digitalWrite(Orange_Led, HIGH); digitalWrite(Green_Led, LOW); delay(500); digitalWrite(Red_Led, LOW); digitalWrite(Orange_Led, LOW); digitalWrite(Green_Led, LOW); delay(500); digitalWrite(Red_Led, LOW); digitalWrite(Orange_Led, HIGH); digitalWrite(Green_Led, LOW); delay(500); digitalWrite(Red_Led, LOW); digitalWrite(Orange_Led, LOW); digitalWrite(Green_Led, LOW); delay(500); سيضيءالقطب الخاص بالليد الأحمر في النهاية وتنطفئ الأقطاب الخاصة بالليدات الأخرى (الأخضر والبرتقالي) بتأخير زمني 5000 مللي ثانية أي بمقدار 5 ثوان، لذا نستدعي الدالة()digitalWrite حيث سيأخذ القطب الخاص بالليد الأحمر القيمة HIGH لأننا نريد تشغيله وستأخذ الأقطاب الخاصة بالليدات الأخرى (الأخضر والبرتقالي) القيمة LOW، ونستدعي الدالة المدمجة ()delay بقيمة 5000 لتحقيق تأخير الزمني بمقدار 5 ثوان. digitalWrite(Red_Led, HIGH); digitalWrite(Orange_Led, LOW); digitalWrite(Green_Led, LOW); delay(5000); تحسين الكود البرمجي لمشروع إشارة مرور كما تلاحظ فإننا نكرر التعليمات البرمجية الخاصة بالتحكم بتشغيل وإطفاء الليد البرتقالي ثلاث مرات في الكود السابق، وفي كل مرة نعيد كتابة التعليمات البرمجية الخاصة بذلك، ويمكن اختصار الكود خلال كتابة التعليمات مرة واحدة فقط داخل حلقة تكرارية for بمتغير i تبدأ قيمته من 1 وتزداد بمقدار 1 في كل مرة حتى تصبح مساوية لـ 3 (تكرار تنفيذ ما بداخل الحلقة ثلاث مرات) ويصبح الكود الخاص بهذا الجزء: for (int i = 1; i <= 3; i++) { digitalWrite(Red_Led, LOW); digitalWrite(Orange_Led, HIGH); digitalWrite(Green_Led, LOW); delay(500); digitalWrite(Red_Led, LOW); digitalWrite(Orange_Led, LOW); digitalWrite(Green_Led, LOW); delay(500); } لاحظ أننا في كل مرة نتحكم بالأقطاب الثلاثة بالترتيب نفسه Red_Led ثم Orange_Led ثم Green_Led، يمكننا القيام بذلك بتعليمة برمجية واحد فقط بدلًا من أن نكتب ثلاث تعليمات برمجية خاصة بالتحكم بتشغيل وإطفاء هذه الليدات في كل مرة من خلال كتابة دالة باسم ()ROG_LED (أو أي اسم مناسب تريده) تأخذ ثلاثة معاملات، يمثل كل معامل حالة قطب من أقطاب الليدات الثلاثة وتكون بالترتيب الآتي: معامل حالة قطب الليد الأحمر Red_Stat، ومعامل حالة قطب الليد البرتقالي Orange_Stat، ومعامل حالة قطب الليد الأخضر Green_stat وبداخل هذه الدالة سنكتب التعليمات البرمجية التي تتحكم بتشغيل وإطفاء هذه الليدات مرة واحدة فقط وبقيمة الوسيط الخاص بكل ليد ذاتها. void ROG_LED(int Red_Stat, int Orange_Stat, int Green_stat) { digitalWrite(Red_Led, Red_Stat); digitalWrite(Orange_Led, Orange_Stat); digitalWrite(Green_Led, Green_stat); } يصبح الكود النهائي للمشروع كما يلي: int Red_Led = 11; int Orange_Led = 10; int Green_Led = 9; void ROG_LED(int Red_Stat, int Orange_Stat, int Green_stat) { digitalWrite(Red_Led, Red_Stat); digitalWrite(Orange_Led, Orange_Stat); digitalWrite(Green_Led, Green_stat); } void setup() { pinMode(Red_Led, OUTPUT); pinMode(Orange_Led, OUTPUT); pinMode(Green_Led, OUTPUT); } void loop() { // Green Light ROG_LED(LOW, LOW, HIGH); delay(5000); // Orange Light for (int i = 1; i <= 3; i++) { ROG_LED(LOW, HIGH, LOW); delay(500); ROG_LED(LOW, LOW, LOW); delay(500); } // Red Light ROG_LED(HIGH, LOW, LOW); delay(5000); } محاكاة المشروع: سننفذ المحاكاة باستخدام منصة ووكوي Wokwi باتباع الخطوات التي شرحناها في المقال السابق للوصول الى الصفحة الخاصة بمحاكاة المشروع كما توضح الصورة التالية: بعدها أضف العناصر الإلكترونية اللازمة للمشروع مثل لوحة التجارب BreadBoard، والليدات LEDs، والمقاومات Resistors. غيّر قيمة المقاومات إلى 220 أوم من خلال الضغط عليها فتظهر لك نافذة تمكنك من تغير القيمة والواحدة. يمكنك الطريقة نفسها تغير ألوان الليدات من خلال الضغط عليها فتظهر لك نافذة تستطيع من خلالها اختيار لون الليد. رتب العناصر على لوحة التجارب بالشكل الذي تراه مناسبًا، ثم صل العناصر بعضها ببعض حسب مخطط التوصيل الذي عرضناه سابقًا. اكتب الكود البرمجي في الجزء الخاص به، ثم شغل المحاكاة، ستجد أن الليدات تعمل بالترتيب الذي ذكرناه في وصف المشروع. الخلاصة تعلمنا في هذا المقال بناء المشروع الثاني في سلسلة دليل أدوينو وهو إشارة مرور بسيطة بعدة خطوات سهلة بدءًا من فهم فكرة المشروع ووصولًا إلى كتابة الكود البرمجي الخاص به، مع تعلم كيفية التفكير في تحسين وتطوير الكود، وسنستكمل في المقالات القادمة بناء المزيد من المشاريع الإلكترونية المفيدة ونتعلم من خلالها أفكارًا جديدة. اقرأ أيضًا المقال السابق: مشروع التحكم بتشغيل وإطفاء ليد LED باستخدام الأردوينو Arduino تصميم لعبة السلك والحلقة باستخدام برنامج سكراتش وحاسوب راسبيري باي تنفيذ مصباح ليد ثلاثي الأبعاد باستخدام سكراتش ولوحة راسبيري باي صنع آلة موسيقية باستخدام سكراتش وحاسوب راسبيري باي
-
بعد أن تعلمنا في المقال السابق مجموعة من المعلومات والمفاهيم الأساسية حول لوحات أردوينو وأنواعها ومكوناتها وبيئة برمجتها، سنتعلم في هذا المقال كيفية بناء أول مشروع باستخدام هذه اللوحة، وهو التحكم بتشغيل وإطفاء ليد LED. يعد هذا المشروع من المشاريع الأساسية والمهمة للمبتدئين في عالم الأردوينو، فمن خلاله تتعلم كيفية التعامل مع لوحة الأردوينو، وتوصيل العناصر البسيطة وربطها مع اللوحة، بالإضافة إلى فهم البنية البرمجية الأساسية لأي مشروع، وكيفية استخدام التعليمات البرمجية الأساسية. فكرة المشروع تعتمد فكرة المشروع على توصيل ليد LED على إحدى الأقطاب الرقمية Digital Pins في لوحة أردوينو أونو Arduino Uno، والتحكم في طريقة عمله، يُضبط القطب كقطب خرج OUTPUT، ثم يُشغل الليد لمدة ثانية واحدة وبعدها يوقف لمدة ثانية أخرى وتتكرر هذه العملية باستمرار. يمكن ربط هذه الفكرة بمثال بسيط لا بد أنك رأيته سابقًا في مكان ما، فهو يستخدم في الساعات الرقمية، إذ يوجد فيها شريحتان من الليدات تفصل بين أرقام الثواني والدقائق والساعات، وتومض بشكل متكرر كل ثانية. العناصر المستخدمة سنحتاج مجموعة من العناصر الضرورية لعمل هذا المشروع، وهي: لوحة أردوينو أونو Arduino Uno. كابل البرمجة USB Cable. لوحة توصيل التجارب Breadboard. ليد LED. مقاومة بقيمة 220 أوم. مجموعة أسلاك توصيل من نوع male to male. ما هي لوحة التجارب Breadboard لوحة التجاري هي لوحة مسطحة مصنوعة من البلاستيك، تحتوي على ثقوب متصلة ببعضها البعض بشكل أفقي أو رأسي بواسطة مسارات معدنية من الداخل. تُستخدم في توصيل العناصر الإلكترونية والأسلاك ببعضها البعض وبناء المشاريع والتجارب الإلكترونية دون الحاجة إلى عملية اللحام، مما يجعلها قابلة لإعادة الاستخدام ومن السهل تغيير مكوناتها. تتصل الثقوب متصلة ببعضها بشكل رأسي في المسارات الجانبية على الأطراف وتوصل عليها أقطاب التغذية غالبًا، لذلك يوجد مساران في كل طرف: الأول للقطب الموجب والآخر للقطب السالب. أما باقي الثقوب فتكون متصلة ببعضها بشكل أفقي وتُستخدم لإدخال العناصر الإلكترونية وتوصيلها ببعضها البعض، كما يوجد فراغ في المنتصف يقسم اللوحة إلى قسمين متناظرين ويسمح بتركيب الدوائر المتكاملة integrated circuit. مخطط توصيل المشروع Circuit Diagram سنوضح طريقة توصيل المشروع من خلال مجموعة من النصائح والخطوات البسيطة التي ستساعدك بإنجاز مشروعك بطريقة سهلة، اتبع الخطوات الآتية لتوصيل المشروع: صل أقطاب التغذية دائمًا بلوحة التجارب أولًا، فسوف تساعدك هذه الخطوة كثيرًا في أي مشروع، ويمكنك الحصول على التغذية من أقطاب الطاقة Power Pins في لوحة الأردوينو التي تحدثنا عنها في المقال السابق، صل القطب 5v مع المسرى الموجب للوحة التجارب والقطب GND مع المسرى السالب للوحة التجارب من خلال الأسلاك. صل الرِّجل الأطول للِّيد (التي تمثل الطرف الموجب) مع القطب رقم 13 في لوحة الأردوينو أونو Arduino Uno. صل الرِّجل الثانية للِّيد (التي تمثل الطرف السالب) مع الرجل الأولى للمقاومة (لا توجد قطبية للمقاومة، لذلك لا يوجد فرق إذا عكسنا بين الرجل الأولى والرجل الثانية). صل الرِّجل الأخرى للمقاومة مع المسرى السالب في لوحة التجارب. توضح الصورة التالية مخطط التوصيل: الكود البرمجي للتحكم بتشغيل وإطفاء ليد LED يجب أن يحتوي أي كود بلغة الأردوينو على دالتين، الأولى()void setup ينفذ ما بداخلها مرة واحدة فقط عند بداية التشغيل وسنسميها الدالة الرئيسية لسهولة الشرح، وبعدها ينتقل لتنفيذ ما بداخل الدالة الثانية ()void loop بشكل متكرر، وسنسميها الدالة التكرارية. void setup() { } void loop() { } تُضبط الأقطاب والطرفيات الخاصة بلوحة الأردوينو في الدالة الرئيسية، ففي مثالنا هذا سنضبط القطب رقم 13 على أنه قطب خرج OUTPUT من خلال الدالة المدمجة ()pinMode التي تأخذ معاملين: الأول يمثل رقم القطب والثاني نوع القطب (خرج أو دخل) فتصبح الدالة الرئيسية بالشكل الآتي: void setup () { pinMode(13, OUTPUT); } ملاحظة: توفر نواة أردوينو Arduino core مجموعة من الدوال المدمجة التي تتميز بأنها سهلة الفهم والاستخدام مما يجعل عملية البرمجة وتطوير المشاريع الإلكترونية أبسط وأكثر كفاءة وفعالية في الكثير من الأوقات كما أنها توفر الوقت والجهد على المبرمجين بتجنب إعادة كتابة الأكواد الشائعة والمستخدمة بكثرة من خلال استخدام هذه الدوال المبنية مسبقًا، مما يساعدهم على التركيز للإبداع والابتكار. يمكنك الاستزادة أكثر والإطلاع على جميع التوابع المدمجة التي توفرها نواة أردوينو من خلال زيارة توثيق أردوينو على موسوعة حسوب، أو الاطلاع على المرجع الرسمي Arduino Reference. وبما أننا نريد تشغيل وإطفاء الليد بشكل متكرر ومستمر لذلك سنكتب أمر التشغيل والإطفاء في الدالة()loop ونتحكم بالتشغيل والإطفاء من خلال الدالة ()digitalWrite التي تأخذ أيضًا معاملين: يمثل المعامل الأول رقم القطب، ويمثل الثاني حالة القطب (إما قيمة 1 منطقي HIGH، أو قيمة 0 منطقي LOW) void loop() { digitalWrite(13, HIGH); digitalWrite(13, LOW); } ولكن عند تجربة هذا الكود نجد أن الليد لا يومض بل يعمل بشكل مستمر، والسبب في ذلك أننا نشغل الليد ثم نطفئه بشكل مباشر وسريع بالتالي لا نلاحظ عملية الومض، في هذه الحالة علينا استخدام الدالة ()delay التي تضيف فترة انتظار أو تأخير زمني في موضع كتابتها في الكود ويمرر الزمن المطلوب لها بواحدة المللي ثانية ms. وبتعديل الكود السابق تصبح الدالة التكرارية على النحو التالي: void loop() { digitalWrite(13, HIGH); delay(1000); digitalWrite(13, LOW); delay(1000); } تحسين الكود البرمجي للتحكم بتشغيل وإطفاء ليد LED عند تجربة الكود السابق نجد أنه يعمل بشكل جيد كما هو مطلوب بالضبط، ولكن يمكن تحسينه أكثر، على فرض أنك تتحكم بحالة القطب من HIGH إلى LOW أو العكس عدة مرات خلال مشروعك، وتريد تغير رقم القطب لسبب ما كترتيب التوصيل ضمن الدارة أو استخدام هذا القطب في وظيفة أخرى خاصة به، ستحتاج في هذه الحالة لتعديل رقم القطب في كل تعليمة تغير فيها حالة القطب من HIGH إلى LOW أو العكس ضمن الكود. لهذا السبب، يجب تعريف متغير ثابت (بما أننا لن نعدل قيمة هذا المتغير أثناء تنفيذ الكود)، يحتوي هذا المتغير على رقم القطب وإذا اضطررنا لتغير رقم القطب فنغير قيمته في الكود مرة واحدة فقط ونُعرِّف المتغير في بداية الكود خارج التوابع ليكون متغيرًا عامًا global variable ونتمكن من استخدامه في أي مكان ضمن الكود. const int LED_PIN = 13; يصبح الكود النهائي للمشروع على النحو التالي: int LED_PIN = 13; void setup() { pinMode(LED_PIN, OUTPUT); } void loop() { digitalWrite(LED_PIN, HIGH); delay(1000); digitalWrite(LED_PIN, LOW); delay(1000); } محاكاة المشروع تعد ميزة المحاكاة مفيدة ومهمة في كثير من الأحيان لإجراء بعض التجارب أو المشاريع إضافة إلى أنها توفر الوقت والجهد. وتقدم منصة ووكوي Wokwi إمكانية محاكاة العديد من اللوحات الإلكترونية مثل لوحات الأردوينو Arduino ولوحات إي إس بي اثنان وثلاثين ESP32 ولوحات إس تي إم اثنان وثلاثين STM32 بالإضافة إلى العديد من الحساسات والعناصر والقطع الإلكترونية، يمكنك الاطلاع أكثر على القسم الخاص بتوثيق الموقع للمزيد من المعلومات حول المميزات والخدمات التي يقدمها، اتبع الخطوات الآتية لإنشاء ومحاكاة مشروعك من خلال هذه المنصة: بعد الدخول إلى موقع ووكوي Wokwi ستظهر لك في الواجهة الرئيسية اللوحات المختلفة التي تستطيع عمل محاكاة لها من خلال الموقع. اضغط على خيار Arduino، وانتظر انتهاء تحميل الصفحة ثم انزل قليلًا واختر لوحة أردوينو أونو Arduino Uno. ستظهر الصفحة الخاصة بمحاكاة مشروعك كما في الصورة التالية، الجزء الأيسر في الصورة خاص بكتابة الكود البرمجي، والجزء الأيمن خاص بإضافة العناصر الإلكترونية وتوصيل الدائرة الكهربائية. أضف العناصر الإلكترونية اللازمة للمشروع مثل لوحة توصيل التجارب BreadBoard، والليد LED، والمقاومة Resistor (ستلاحظ عند إضافة عنصر المقاومة ظهور نافذة تتيح لك تغير قيمتها، غيرها إلى 220 أوم). رتب العناصر على لوحة التجارب بالشكل الذي تراه مناسبًا، ثم صل العناصر بعضها ببعض حسب مخطط التوصيل الذي عرضناه سابقًا. أخيرًا اكتب الكود البرمجي في الجزء الخاص به، ثم شغل المحاكاة ستجد الليد يومض كل ثانية. تهانينا بهذا تكون قد أنجزت مشروعك الأول في أردوينو، ويمكنك بالطبع إجراء بعض التجارب والتعديلات على مشروعك مثل تغير زمن التأخير، أو تغير رقم القطب الخاص بالليد، أو إضافة أكثر من ليد LED. الخاتمة تعلمنا في هذا المقال بناء أول مشروع إلكتروني من خلال لوحة أردوينو بعدة خطوات بسيطة وتعرفنا على العديد من الخطوتات والنصائح المفيدة التي تساعد على محاكاة مشروعك وتنفيذه بطريقة صحيحة، وسنستكمل في المقالات القادمة رحلتنا هذه في عالم الأردوينو من خلال بناء المزيد من المشاريع الإلكترونية الممتعة الأكثر تقدمًا. اقرأ أيضًا المقال السابق: التعرف على أساسيات الأردوينو وتجهيز بيئة العمل أساسيات في عالم الإلكترونيات: التيار والجهد والعناصر الساكنة أساسيات في عالم الإلكترونيات: تشكيل الدوائر اﻹلكترونية والعناصر الفعالة مدخل إلى الدوائر المتكاملة Integrated Circuits والمتحكمات الصغرية Micro-processor بنية برنامج لغة سي C
-
هل سمعت بمصطلح أردوينو Arduino من قبل، وراودك الاهتمام بهذا المصطلح؟ سنشرح في هذا المقال عن لوحات أردوينو من خلال نظرة موسعة عنها وما هي الاختلافات بين أنواعها ومكوناتها الأساسية، بالإضافة إلى شرح كيفية تجهيز بيئة العمل للبدء برحلة ممتعة في عالم الأردوينو والمتحكمات وبناء المشاريع الإلكترونية من خلاله. هذا المقال هو جزء من سلسلة مقالات تعليمية حول الأردوينو وكيفية بناء المشاريع الإلكترونية من خلالها ويمكنك الوصول لكامل مقالات هذه السلسلة المنشورة تحت وسم دليل أردوينو. ما هي لوحة أردوينو Arduino هي لوحة إلكترونية تطويرية مفتوحة المصدر، طُورت لمساعدة المبتكرين والهواة في تعلم تصميم وتنفيذ المشاريع الإلكترونية بطريقة سهلة وبدون تعقيد. يمكن للمستخدم برمجة هذه اللوحة لتنفذ وظيفة إلكترونية معينة كالتحكم بتشغيل أو إطفاء ليد LED وشدة إضاءته، أو قراءة قيم من حساسات مختلفة سواء أكانت رقمية Digital أو تشابهية Analog، أو حتى التحكم بشكل كامل بروبوت يقوم بعدة وظائف معًا، إضافة إلى العديد من المشاريع الأخرى. وتُبرمَج هذه اللوحة من خلال بيئة تطوير متكاملة Arduino IDE تستخدم بشكل أساسي لكتابة الأكواد والتعليمات البرمجية من خلالها ورفع الكود إلى اللوحة الإلكترونية وتنفيذه. ما هو المتحكم المصغر Microcontroller يعد المتحكم المصغر (أو المتحكم الصغري) من أهم المكونات الموجودة في لوحة الأردوينو، ويمكن تعريفه باختصار على أنه حاسوب مصغر يحوي العناصر الأساسية التي يحتويها الحاسوب مثل المعالج والذواكر وطرفيات الإدخال والإخراج موجودة جميعها في شريحة واحدة ولكن بحجم وإمكانيات محدودة جداً مقارنة مع الحواسيب الشخصية، ويمكنك التعرف أكثر عن المتحكمات الصغرية والدوائر المتكاملة من خلال مقال مدخل إلى الدوائر المتكاملة والمتحكمات الصغرية مميزات أردوينو من أهم المميزات التي قد تجعلك ترغب في استخدام الأردوينو في مشاريعك الإلكترونية هي أن منصة الأردوينو تملك مجتمع دعم كبير، وسوف تجد العديد من المشاريع والمصادر والمكتبات والأشخاص لمساعدتك وتبادل الأفكار والحلول حول المشاكل التي قد تواجهها خلال تنفيذ مشروعك، بالإضافة إلى العديد من المميزات الأخرى ومنها: سهولة الاستخدام: تستطيع البدء باستخدام لوحة الأردوينو وبرمجتها من خلال برنامج Arduino IDE بدقائق وببضعة خطوات بسيطة ولذلك تعد مناسبة جداً للمبتدئين والهواة. انخفاض التكلفة: تعتبر لوحات الأردوينو والعناصر والمجموعات التعليمية الخاصة بها غير مكلفة نسبيًا مقارنة مع المتحكمات الأخرى، بالإضافة الى أن البيئة البرمجية الخاصة ببرمجتها مجانية بشكل كامل. العمل على جميع الأنظمة: يمكنك تشغيل برنامج Arduino IDE على جميع أنظمة التشغيل مثل نظام ويندوز Windows أو لينكس Linux أو ماك أو إس Mac OS، مفتوحة المصدر: يمكنك الوصول إلى الأكواد المصدرية للأردوينو لمعرفة المزيد عن لغة البرمجة التي تعتمد عليها أو تعديلها والتطوير عليها، وكذلك الأمر بالنسبة لمخططات الدوائر الإلكترونية circuit diagram إذ يمكنك الاستفادة منها أو عمل لوحة أردوينو خاصة بك. المكتبات: يوجد العديد من المكتبات الموجودة في البيئة البرمجية Arduino IDE، بالإضافة الى العديد من المكتبات التي طورها أشخاص من جميع أنحاء العالم حيث يمكنك الاستفادة من هذه المكتبات عن طريق استخدام التوابع الموجودة فيها مباشرة، مما يوفر الوقت والجهد اللازمين لإعادة كتابة هذه التوابع من البداية. أنواع لوحات أردوينو والفروقات بينها تختلف لوحات الأردوينو عن بعضها بعدة عوامل تشمل بشكل أساسي شكل اللوحة وحجمها، وجهد العمل 5v أو 3.3v، وشريحة البرمجة الخاصة بنقل الكود من الحاسوب إلى المتحكم، ونوع المتحكم الرئيسي الذي يؤثر على مواصفات اللوحة مثل سرعة المعالج وعدد أقطاب الرقمية والتشابهية وبروتوكولات التواصل مع الطرفيات والمتحكمات الأخرى، ولتوضيح الفروقات بين لوحات الأردوينو سنصنف أشهر لوحات الأردوينو واستعراض مواصفات كل منها. لوحة أردوينو أونو Arduino Uno أشهر لوحات الأردوينو وأكثرها انتشاراً وتعد الخيار الأفضل لإجراء التجارب والنماذج الأولية للمشاريع وذلك بسبب ثمنها المنخفض وسهولة استخدامها، ومن أهم مواصفاتها: نوع المتحكم: Atmega328 عدد أقطاب الدخل والخرج: 22 عدد أقطاب إشارة PWM: تحتوي 6 عدد الأقطاب التشابهية: 6 سرعة المعالج: 16MHz جهد العمل: 5V حجم ذاكرة البرنامج Flash: تأتي بحجم 32KB حجم ذاكرة البيانات SRAM: تأتي بحجم 2KB حجم ذاكرة القراءة القابلة للبرمجة EEPROM: تأتي بحجم 1KB لوحة أردوينو نانو Arduino Nano تشبه لوحة Arduino Uno من حيث المواصفات ولكن بحجم صغير وشكل مناسب للتركيب على لوحة التجارب BreadBoard وتعد أيضًا من الخيارات المفضلة للمطورين بسبب صغر حجمها وسعرها المنخفض، ومن أهم مواصفاتها: نوع المتحكم: ATmega328 عدد أقطاب الدخل والخرج: 22 عدد أقطاب إشارة PWM: تحتوي 6 عدد الأقطاب التشابهية: 8 سرعة المعالج: 16MHz جهد العمل: 5V حجم ذاكرة البرنامج Flash: تأتي بحجم 32KB حجم ذاكرة البيانات SRAM: تأتي بحجم 2KB حجم ذاكرة القراءة القابلة للبرمجة EEPROM: تأتي بحجم 1KB لوحة أردوينو برو ميني Arduino Pro Mini نسخة مصغرة من لوحة Arduino Nano ومشابهة لها في بعض المميزات، ولكن تختلف بعدم وجود شريحة برمجة مدمجة مع اللوحة وتحتاج أداة منفصلة لبرمجتها تسمى USB-TTL وتوصل بها من خلال طرفية الاتصال التسلسلي UART وهي مناسبة للمشاريع التي تكون فيها المساحة محدودة وصغيرة ومن أهم مواصفاتها: نوع المتحكم: atmega328 عدد أقطاب الدخل والخرج: 14 عدد أقطاب إشارة PWM: تحتوي 6 عدد الأقطاب التشابهية: 6 سرعة المعالج: 8MHz/16MHz جهد العمل: 3.3V/5V حجم ذاكرة البرنامج flash: تأتي بحجم 32KB حجم ذاكرة البيانات SRAM: تأتي بحجم 2KB حجم ذاكرة القراءة القابلة للبرمجة EEPROM: تأتي بحجم 1KB لوحة أردوينو ليوناردو Arduino Leonardo يختلف عن الأنواع السابقة بنوع المتحكم الموجود فيه ويحوي بروتوكول اتصال USB مدمج والذي يلغي الحاجة إلى وجود شريحة برمجة خاصة ويمكن استخدامه في تطبيقات الأجهزة التي تستخدم كمنفذ HID أو منفذ COM ومن أهم مواصفاته: نوع المتحكم: ATmega32U4 عدد أقطاب الدخل والخرج: 22 عدد أقطاب إشارة PWM: تحتوي 7 عدد الأقطاب التشابهية: 12 سرعة المعالج: 16MHz جهد العمل: 5V حجم ذاكرة البرنامج Flash: تأتي بحجم 32KB حجم ذاكرة البيانات SRAM: تأتي بحجم 2.5KB حجم ذاكرة القراءة القابلة للبرمجة EEPROM: تأتي بحجم 1KB لوحة أردوينو مايكرو Arduino Micro تشبه لوحة Arduino Nano من حيث الشكل والحجم بالضبط ولكن من حيث المميزات والمواصفات فهي مماثلة للوحة Arduino Leonardo فهي تحوي المتحكم نفسه والإمكانيات نفسها ومن أهم مواصفاته: نوع المتحكم: ATmega32U4 عدد أقطاب الدخل والخرج: 20 عدد أقطاب إشارة PWM: تحتوي 7 عدد الأقطاب التشابهية: 12 سرعة المعالج: 16MHz جهد العمل: 5V حجم ذاكرة البرنامج flash: تأتي بحجم 32KB حجم ذاكرة البيانات SRAM: تأتي بحجم 2.5KB حجم ذاكرة القراءة القابلة للبرمجة EEPROM: تأتي بحجم 1KB لوحة أردوينو ميغا Arduino mega يعد الأكبر من جميع اللوحات التي تحدثنا عنها ويستخدم في التطبيقات والمشاريع الكبيرة التي تتطلب عدداً كبيراً من الأقطاب وتحتاج حجم ذاكرة أكبر من الأنواع السابقة ومن أهم مواصفاته: نوع المتحكم: ATMEGA2560 عدد أقطاب الدخل والخرج: 54 عدد أقطاب إشارة PWM: تحتوي 15 عدد الأقطاب التشابهية: 16 سرعة المعالج: 16MHz جهد العمل: 5V حجم ذاكرة البرنامج Flash: تأتي بحجم 256KB حجم ذاكرة البيانات SRAM: تأتي بحجم 8KB حجم ذاكرة القراءة القابلة للبرمجة EEPROM: تأتي بحجم 4KB لوحة أردوينو ليلي باد Arduino LilyPad صُمم هذا النوع من اللوحات بشكل خاص للمشاريع التي يمكن ربطها مع الملابس والأجهزة القابلة للإرتداء إذ يمكن خياطته بشكل مناسب وسهل مع القماش بسبب تصميمه الخاص والثقوب الموجودة فيه والتي تستخدم أيضا كأقطاب ومن أهم مواصفاته: نوع المتحكم: Atmega328/Atmega168 عدد أقطاب الدخل والخرج: 14 عدد أقطاب إشارة PWM: تحتوي 6 عدد الأقطاب التشابهية: 6 سرعة المعالج: 8MHz جهد العمل: 2.7V-5.5V حجم ذاكرة البرنامج Flash: تأتي بحجم 16KB حجم ذاكرة البيانات SRAM: تأتي بحجم 1KB حجم ذاكرة القراءة القابلة للبرمجة EEPROM: تأتي بحجم 512B كيف تختار اللوحة المناسبة لك تعتبر اللوحات السابقة من أشهر أنواع لوحات الأردوينو والأكثر انتشاراً واستخداماً. والآن بعد أن استعرضنا هذه الأنواع ومواصفاتها قد يأتي سؤال لذهنك: كيف أختار اللوحة المناسبة من بين كل هذه الأنواع العديدة؟ يعتمد اختيارك لنوع لوحة الأردوينو المناسبة على هدفك الرئيسي منها، فإذا كنت تبحث عن لوحة للتعلم فيجب أن تختار لوحة سهلة الاستخدام ومناسبة لعمل التجارب الإلكترونية وشائعة الاستخدام؛ لسهولة البحث عن المشاكل وإيجاد الحلول التقنية مثل لوحة أردوينو أونو التي سوف نعتمد عليها في هذه السلسلة التعليمية. أما إذا كنت تريد اختيار اللوحة المناسبة من أجل عمل مشروع إلكتروني فهناك عدة عوامل مثل: الميزانية المخصصة للمشروع، وعدد الأقطاب التي تحتاجها، وحجم الكود البرمجي، واستهلاك الذواكر، ودعم المكتبات البرمجية للوحة في حال استخدمت مكتبات في مشروعك، وكما يعد الحجم والشكل من العوامل المهمة في اختيار اللوحة المناسبة وضمان نجاح مشروعك والقدرة على تطويره بسلاسة. الفرق بين أردوينو Arduino وراسبيري باي Raspberry Pi إذا كنت قد بدأت حديثًا في عالم برمجة المتحكمات والأنظمة الرقمية، فقد تتساءل ما الاختلاف بين لوحة أردوينو Arduino ولوحة راسبيري باي Raspberry Pi، في الواقع كلاهما لوحتان رائعتان لإنجاز مشاريع إلكترونية مبتكرة وإبداعية، ولكن هناك بعض الاختلافات بينهما، دعنا نتعرف عليها. أردوينو Arduino: كما وضحنا سابقًا هي لوحة مبنية بالاعتماد على متحكمات مصغرة microcontrollers، والمتحكم هو حاسوب صغير مناسب لتشغيل برنامج واحد في كل مرة، وهو ملائم للمهام البسيطة مثل قياس درجة الحرارة أو تشغيل مجموعة من الليدات LED. راسبيري باي Raspberry Pi: هي عبارة عن حاسوب مبني بالاعتماد على معالج مصغر microprocessor يمكنه تشغيل عدة برامج معقدة في الوقت نفسه مثل أنظمة التشغيل. وقد تتساءل ماذا أختار بينهما؟ والجواب هو أن الخيار المناسب لك على نوع المشاريع التي تريد القيام بها فلوحة أردوينو مناسبة للمشاريع الإلكترونية الصغيرة والتعامل مع بيانات صغيرة نسبياً، أما لوحة راسبيري باي فمثالية للاستخدام مع المشاريع الكبيرة وتنفيذ عمليات الحوسبة المعقدة. المكونات الأساسية للوحة أردوينو أونو Arduino Uno بعد اختيار لوحة أردوينو أونو لشرح هذه السلسلة، سنتعرف في هذا الجزء أكثر على أجزاء هذه اللوحة ومكوناتها حتى نستطيع التعامل معها بسهولة ونتجنب حدوث أخطاء ومشكلات أثناء عمل المشاريع. منفذ البرمجة USB Programming Port نستطيع من خلال هذا المنفذ وصل لوحة أردوينو مع حاسوبك لنقل البيانات ورفع الكود البرمجي على اللوحة من خلال كابل البرمجة USB Cable، حيث يمكنك وصلها مع الحاسوب من خلال كابل من نوع USB A - USB B كما يمكنك تغذية لوحة أردوينو بالطاقة من خلال هذا المنفذ، وللعلم يمكن توصيل اللوحة مع أي مصدر تغذية من نوع DC وبجهد 5v (مثل شاحن الموبايل أو وحدة التغذية Power Bank) لأنه الجهد المناسب لعمل هذه اللوحة. مأخذ التغذية Power Connector يستخدم هذا المأخذ لتغذية لوحة أردوينو أونو بالطاقة الكهربائية بجهد يتراوح بين 7V و 12V، وعادة ما تُستخدم بطارية 9V أو مكيّف Adapter من 220V تيار متردد AC إلى 12V أو 9V تيار مستمر DC. منظم الجهد Voltage Regulator تتمثل وظيفة منظم الجهد في التحكم بالجهد المزود إلى لوحة أردوينو من خلال تنظيمه وتثبيت قيمته كي يتناسب مع الجهد المطلوب للوحة والعناصر الإلكترونية الأخرى المتصلة بها. الهزازة الكريستالية Crystal Oscillator الهزازة الكريستالية هي عنصر إلكتروني أساسي في لوحة أردوينو، حيث تستخدم لتوليد نبضات كهربائية بتردد محدد بدقة، هذه النبضات ضرورية لمعرفة كيفية حساب الوقت أثناء قيام اللوحة بتنفيذ التعليمات البرمجية وضمان تنفيذها بدقة. زر إعادة التشغيل Reset يستخدم هذا الزر لمقاطعة عمل المتحكم وإعادة تشغيله من البداية، ويتم ذلك من خلال طريقتين: إما بالضغط مباشرة على الزر الموجود في اللوحة، أو من خلال سلك بين قطب Reset وقطب الأرضي GND كما هو موضح بالصورة أعلاه. أقطاب الطاقة Power Pins تستخدم هذه الأقطاب لتغذية العناصر والوحدات الإضافية التي ستوصل مع لوحة الأردوينو مثلا الحساسات Sensors والليدات LEDs ووحدات العرض Display وغيرها من العناصر الأخرى وهي كالتالي: 3.3v قطب تغذية للعناصر بقيمة 3.3v. 5v قطب تغذية للعناصر بقيمة 5v. GND الأرضي ويعتبر القطب السالب ويستخدم لإكمال مسار الدارة الإلكترونية. Vin قطب دخل يمكن من خلاله تغذية الأردوينو من مصدر خارجي. الأقطاب التشابهية Analog Pins تحتوي لوحة أردوينو أونو على ستة أقطاب تشابهية مرقمة من A0 إلى A5 حيث أن حرف A هنا هو اختصار لكلمة Analog والني تعني تشابهي أو تماثلي، تقرأ هذه الأقطاب الإشارات التشابهية من الحساسات المختلفة مثل حساس الحرارة وحساس الرطوبة وتحولها إلى قراءة رقمية يمكن أن تُقرأ بدورها عن طريق المعالج المصغر microprocessor. المتحكم المصغر Microcontroller يعد المتحكم المصغر المتحكم الرئيسي للوحة، فهو بمثابة عقل الدارة ويتكون من شريحة إلكترونية صغيرة تحتوي على وحدة المعالجة المركزية CPU، وذاكرة، ومجموعة من الدوائر الكهربائية المخصصة لإدخال البيانات ومعالجتها وإخراجها، وتحتوي كل لوحة أردوينو متحكمًا خاصًا بها يختلف من نوع لوحة إلى آخر. ليد مؤشر التشغيل وظيفة هذا الليد هي مراقبة حالة تشغيل اللوحة، ففي حالة تغذية اللوحة بمصدر طاقة كهربائية سيعمل الليد مباشرة ويضيء باللون الأخضر بشكل مستمر، وفي حالة عدم تغذية اللوحة لن يعمل. ليدات بروتوكول الاتصال UART تفيد في مراقبة حالة نقل البيانات، إذ تجد في لوحة الأردوينو هذه الكتابة "TX" و"RX" في مكانين مختلفين: الأول في الأقطاب 0 و1 المسؤولة عن الاتصال التسلسلي لإرسال واستقبال البيانات، والثاني في ليدات تحديد حالة إرسال البيانات واستقبالها، ففي حالة إرسال الأردوينو للبيانات سيضيء الليد الخاص بـ TX، وفي حالة استقبال البيانات يضيء الليد الخاص بـ RX. الأقطاب الرقمية Digital Pins تحتوي لوحة أردوينو أونو على 14 قطب رقمي يمكنك استخدامها كمداخل لتلقي البيانات أو مخارج لإرسال البيانات بشكل رقمي، حيث تعطي خرجين محددين إما 0 منطقي (يعادل 0 فولت)، وإما 1 منطقي (يعادل 5 فولت) كما يمكن استخدام الأقطاب التشابهية كأقطاب رقمية. قطب الجهد المرجعي AREF هو قطب لتحديد قيمة الجهد المرجعي المستخدم كمعيار أو موجه أجل تحويل الإشارة التشابهية Analog إلى رقمية Digital، ويكون ضمن مجال تغذية اللوحة ففي حال لوحتنا ستكون قيمة المجال من 0 إلى 5 فولت. لغة برمجة الأردوينو Arduino تعتمد لغة برمجة الأردوينو بشكل أساسي على لغتي C و ++C، إضافة إلى احتوائها على مجموعة كبيرة من المكتبات والدوال المبنية مسبقًا، ما يجعلها سهلة الاستخدام للمبتدئين وغير المبرمجين. تُبرمج المتحكمات الموجودة في لوحات الأردوينو باستخدام هذه اللغة للتفاعل مع الحساسات والمحركات والأجهزة والعناصر الأخرى المتصلة باللوحة. وتُستخدم بشكل واسع في مشاريع الروبوتات والأنظمة الذكية وإنترنت الأشياء. يمكنك التعرف بشكل أكبر على بنية لغة برمجة الأردوينو والدوال والتعليمات البرمجية المتوفرة فيها من خلال المرجع الرسمي على موقع الأردوينو Arduino Reference. تجهيز بيئة العمل البرمجية بعد أن تعرفنا على الأردوينو وما هي أنواع لوحات الأردوينو والأجزاء الرئيسية من لوحة أردوينو أونو Arduino UNO التي سوف نستخدمها في هذه السلسلة كما ذكرنا، علينا الآن تعلم كيفية إعداد بيئة العمل البرمجية. ففي هذا القسم، سنتعلم بخطوات سهلة، كيفية تثبيت البيئة البرمجية Arduino IDE على جهاز الحاسوب، وتجهيز اللوحة لاستقبال الكود البرمجي عبر كابل USB. تثبيت برنامج Arduino IDE 1.8 عملية تثبيت بسيطة جداً، كل ما عليك هو الذهاب إلى صفحة التحميل الخاصة بأردوينو لتظهر لك إصدارات مختلفة من برنامج Arduino IDE، حدد نسخة متوافقة مع نوع نظام التشغيل الخاص بك (Windows أو Mac-OS أو Linux) وبعد اكتمال تنزيل الملف فك ضغطه في المكان الذي تريده، وثبّت البرنامج مثل أي برنامج عادي والصور التالية توضح عملية التثبيت على نظام التشغيل ويندوز. بعد الانتهاء من التثبيتب ابحث في شريط البحث -الموجود بجانب قائمة ابدأ أسفل الشاشة- عن Arduino للعثور على البرنامج وتشغيله، كما ستجد أيقونة البرنامج على سطح المكتب لفتحه بسهولة، بعد فتح البرنامج ستظهر لك الواجهة التالية: المكان A يستخدم لتصليح الكود وفحصه من وجود الأخطاء. المكان B يستخدم لرفع الكود على لوحة الأردوينو. المكان C يستخدم لإنشاء مشروع جديد فارغ. المكان D يستخدم لفتح ملف محفوظ أو مثال جاهز. المكان E يستخدم لحفظ الملف. المكان F يستخدم لفتح نافذة العرض التسلسلي Serial Monitor. تمثل المنطقة رقم 1 المكان المخصص لكتابة الكود البرمجي والأوامر والتعليمات البرمجية. تمثل المنطقة رقم 2 المكان الذي يعرض معلومات عن استهلاك الذاكرة ورسائل الأخطاء. ربط لوحة أردوينو مع البرنامج في البداية عليك توصيل لوحتك مع الحاسوب من خلال كابل USB ثم فتح البرنامج Arduino IDE وبمجرد تشغيل البرنامج، سيكون أمامك خياران: إنشاء مشروع جديد فارغ من خلال الضغط على قائمة File في الأعلى، ثم New. فتح مثال جاهز من الأمثلة من خلال الضغط على قائمة File في الأعلى ثم الخيار Example ثم اختيار المثال الذي تريده. حاليًا سنستخدم المثال Blink الموجود في قسم Basics وهو عبارة عن مشروع بسيط يضيء ليد مدة زمنية معينة ويطفئه مدة زمنية معينة مع تكرار العملية بشكل مستمر. نحتاج الآن لتحديد نوع لوحة الأردوينو المستخدمة لتنفيذ المثال ورقم المنفذ الموصول عليه في الحاسوب: لتحديد نوع اللوحة من خلال الذهاب إلى قائمة Tools ومن ثم الخيار Board واختيار Arduino Uno. لتحديد رقم المنفذ من خلال الذهاب إلى قائمة Tools ومن ثَم الخيار Port واختيار المنفذ الخاص به (يمكنك معرفة رقم المنفذ الخاص بالأردوينو من خلال إزالة توصيله مع الحاسوب فستلاحظ أن هناك خيار اختفى فيكون هو المنفذ الصحيح). أخيراً يمكنك الضغط على اختصار رفع الكود في البرنامج، إذا نفذت الخطوات السابقة بشكل صحيح، انتظر بضع ثوان، وسترى مصابيح RX وTX تومض على اللوحة. في حالة نجاح التحميل، ستظهر رسالة "تم التحميل" أو "Done Uploading" في شريط الحالة وبعدها يبدأ الليد الموصول على القطب 13 في اللوحة بالوميض لفترة زمنية. وهكذا تكون قد تكون نفذت أول مشروع لك على الأردوينو بخطوات سهلة وبسيطة. الخلاصة تعرفنا في هذا المقال على العديد من المفاهيم المهمة في عالم الأردوينو والمتحكمات، واخترنا اللوحة المناسبة لتعلم التعامل مع لوحات أردوينو وهي لوحة Arduino Uno، واستعرضنا أهم مكونات وأجزاء هذه اللوحة وجهزنا بيئة العمل البرمجية، وتعرفنا على طريقة رفع الكود البرمجي إلى لوحة الأردوينو الخاصة بنا وطريقة تنفيذه، سوف نستكمل رحلتنا في المقال القادم وننفذ أول مشروع عملي يتحكم بتشغيل وإطفاء ليد ونشرح خطوات بناءه بالتفصيل. اقرأ أيضًا أساسيات في عالم الإلكترونيات: التيار والجهد والعناصر الساكنة أفضل لغات برمجة الروبوتات تعرف على جهاز راسبيري باي Raspberry Pi تعلم الذكاء الاصطناعي