روبوت تفادي السقوط

 

قد تتطلب بعض المهام إرسال الروبوت للاستكشاف في بعض الأماكن الخطرة أو المرتفعة. في هذا المشروع سنقوم ببرمجة روبوت يتفادى السقوط من على الأسطح التي يسير عليها باستخدام وحدة تتبع المسار.

 

falling-avoiding-robot

 

 

 

الأدوات المطلوبة:

 

mBot Ranger - Transformable STEM Educational Robot Kit

mBot Ranger Kit

 

وحدة تتبع المسار Line Follower

 

تتكون وحدة تتبع المسار من مستشعرين كل مستشعر يتكون من  مصدر للأشعة تحت حمراء (LED) ومستقبل لهذه الأشعة
فكرة عمل مستشعر تتبع المسار تقوم على إطلاق أشعة تحت حمراء ورصد انعكاسها
عند سير الروبوت على الأسطح البيضاء فإن معظم الأشعة تنعكس من على السطح ويتم رصدها
أما عند سير الروبوت  على الأسطح السوداء فإن اللون الأسود يمتص معظم الأشعة فلا ينعكس إلا مقدار بسيط منها إلى المستشعر

falling-avoiding-robot

 

الأمر البرمجي لقراءة وحدة تتبع المسار

falling-avoiding-robot

يعطي قيم بين 0 – 3 بناء على الحالات التالية

الحالات قيمة القراءة المستشعر الأيمن المستشعر الأيسر
كلا المستشعرين على اللون الأسود 0
المستشعر الأيسر فقط على اللون الأسود 1
المستشعر الأيمن فقط على اللون الأسود 2
كلا المستشعرين على اللون الأبيض 3

 

 

 

 

برمجة الروبوت

 

تستخدم وحدة تتبع المسار لبرمجة الروبوتات لتتبع مسارات معينة يتم رسمها باللون الأسود
في هذا الدرس سنستخدم وحدة تتبع المسار لرصد حواف السطح الذي يتحرك عليه الروبوت ويتفادى السقوط من عليه
سنقوم ببرمجة الروبوت بحيث يتحرك على طاولة بيضاء وينعطف يمينا عند الوصول إلى حافة الطاولة.

نقوم أولا بإنشاء متغير edge

falling-avoiding-robot

 

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

falling-avoiding-robot

 

نستخدم الجملة الشرطية if else بحيث
إذا كانت قيمة قراءة المستشعر تساوي 3 يتم تنفيذ الأمر التالي وهو التحرك للأمام
عندما تكون القراءة 3 فذلك يعني أن كلا المستشعرين في وحدة تتبع المسار على اللون الأبيض

 

falling-avoiding-robot

 

 عندما يصل الروبوت إلى حافة الطاولة  لن يكون كلا المستشعرين على اللون الأبيض وبالتالي لن تكون قراءة المستشعر تساوي3
فيقوم الروبوت بتنفيذ الأوامر المكتوبة بعد الأمر else
وهي التحرك للخلف لمدة ثانيتين ثم الانعطاف نحو اليمين
نقوم بوضع أمر التأخير الزمني wait بعد أمر التحرك للخلف لكي نسمح للروبوت بالرجوع مسافة كافية حتى يتمكن من الانعطاف
ونضيف wait بعد أمر الانعطاف لليمين لتحديد مقدار الانعطاف ستحتاج إلى تغيير القيمة حسب شكل وحجم الطاولة التي لديك

falling-avoiding-robot

 

 

الكود البرمجي:

 

falling-avoiding-robot

 

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

تحدي الروبوت

قم ببرمجة روبوت يتفادى السقوط من الطاولة وفي نفس الوقت يتفادى الاصطدام بأي حاجز على الطاولة.
يمكنك مراجعة مشروع روبوت تتبع الكائنات لمعرفة كيفية استخدام مستشعر الموجات فوق الصوتية لتفادي الحواجز.




مشروع الاتصال اللاسلكي IR

 

تحتوي لوحة التحكم  mCore على LED (مُرسل IR Emitter) تقوم بإرسال أشعة تحت حمراء تحمل المعلومات المراد إرسالها
وتحتوى اللوحة كذلك على عنصر مستقبل لهذه الأشعة (IR Receiver).
سنقوم في هذا الدرس بعمل اتصال لاسلكي بين لوحتين mCore بحيث يقوم الروبوت الأول بالتوقف عند الحواجز وإرسال أمر إلى الروبوت الآخر بالتوقف أيضًا.

mbot-ir-communication

 

الأدوات المطلوبة:

 

mbot-ir-communication

mBot Kit (عدد 2)

الاتصال عبر الأشعة تحت الحمراء IR Communication

 

يعتبر الاتصال عبر الأشعة تحت الحمراء من التقنيات  الشائعة للتواصل بين الأجهزة مثل المستخدمة في الريموت كونترول للتحكم بقنوات التلفاز ، تحمل الأشعة تحت الحمراء والتي لا يمكن رؤيتها بالعين المجردة المعلومات المراد إرسالها المستقبل.

 

mbot-ir-communication

 

تحتوي مجموعة الأوامر البرمجية لروبوت mBot على أمرين متعلقين بالاتصال اللاسلكي

mbot-ir-communication

الروبوت المُرسل

 

يتم تعيين أحد الروبوتات كمُرسل
وكتابة الرسالة داخل الأمر البرمجي send mBot’s message

mbot-ir-communication

 يكفي أن تحتوي الرسالة على أحد الأحرف ويجب أن تكون قيمة ثابتة حيث لا يمكن للروبوت إرسال قيمة متغيرة (مثل قراءة مستشعر) كما لا يمكن للروبوت المستقبل استخدام القيم المتغيرة لآداء وظائف أخرى

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

بدايةً نقوم بوضع أمر الحركة للأمام داخل حلقة  forever وإضاءة LED على وضع الإطفاء
سيتحرك الروبوت للأمام فور تشغيله

mbot-ir-communication

نقوم بإنشاء متغير Distance وتعيينه لقؤاءة مستشعر الموجات فوق الصوتية

mbot-ir-communication

نقوم بإضافة شرط (if then)لتحديد المسافة التي يتوقف عندها الروبوت إذا واجه أحد الحواجز
إذا كانت المسافة بين الروبوت والحاجز أقل من 20 يتوقف الروبوت (السرعة صفر) ويرسل رسالة عبر الأشعة تحت الحمراء IR
ويعطي إضاءة LED باللون الأحمر  لتتم معرفة أن الروبوت أرسل رسالة

الكود البرمجي للروبوت المُرسل

 

mbot-ir-communication

 

يجب وضع الأوامر البرمجية المتعلقة بالاتصال اللاسلكي داخل loop ليتم إرسال واستقبال الرسائل في نفس الوقت

ملاحظة: إذا قمت بوضع الأمر البرمجي للإرسال داخل حلقة Repeat لإرسال رسائل متتالية سيتوقف الروبوت الآخر عن الاستجابة بعد فترة ، لتفادي ذلك قم بإضافة تأخير زمني بين إرسال الرسائل باستخدام الأمر wait

mbot-ir-communication

 

الروبوت المستقبل

 

تتغير وظيفة الروبوت المُستقبل عند استلام الرسالة التي يرسلها الروبوت الأول
يجب كتابة الرسالة داخل علامتي تنصيص double quote  ليعمل البرنامج بشكل صحيح

mbot-ir-communication

سنستخدم الجملة الشرطية if ونضع بداخلها مجموعة الأوامر التي يقوم  بها الروبوت المُستقبل عند استلام الرسالة
أي إذا استلم الروبوت الرسالة من الروبوت الأول  (المُرسل) سيتم تنفيذ الأوامر البرمجية المبنية على هذه الرسالة
في هذا المشروع سنقوم ببرمجة الروبوت المُستقبِل على أن يتحرك للأمام إلى أن يستقبل رسالة من الروبوت الأول فيتوقف ويعطي وميض ضوئي أخضر

 

برمجة الروبوت المستقبِل

 

بدايةً نقوم بوضع أمر الحركة للأمام داخل حلقة  forever وإضاءة LED على وضع الإطفاء
سيتحرك الروبوت للأمام فور تشغيله

mbot-ir-communication

نقوم بإضافة شرط if else
بحيث إذا استقبل الروبوت الرسالة من الروبوت الأول (a) يقوم بتنفيذ الأوامر التالية في الكود
وهي التوقف عن الحركة باستخدام أمر الحركة واختيار السرعة 0

mbot-ir-communication

لإعطاء وميض ضوئي أخضر نقوم بوضع أمر إضاءة LED
واختيارقيمة معينة للون الأخضر
ثم وضع نفس الأمر على وضع الإطفاء (جميع الألوان على القيمة 0)
ووضع أمر التأخير الزمني wait بينهم لنتمكن من ملاحظة الوميض

mbot-ir-communication

بعد الأمر else أي إذا لم يستقبل الروبوت رسالة من الروبوت الأول
يعاود الحركة ويطفئ إضاءة LED

mbot-ir-communication

 

الكود البرمجي للروبوت المستقبِل

 

mbot-ir-communication

 

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




توصيل مؤقت الساعة الحقيقي RTC على الراسبيري باي

فى هذا الدرس سنتعلم كيفية توصيل مؤقت الساعة الحقيقي Real Time Clock – RTC على الراسبيري باي عن طريق بروتوكول I2C، حيث سيمكننا ذلك من جعل توقيت الراسبري باي يعمل بإستمرار حتى مع قطع التيار الكهربي عنها.

فمؤقت الساعة الحقيقي RTC هو عنصر فى غاية الأهمية لأي مشروع تحكم خاصة لو كان المشروع يقوم بتخزين معلومات وقياسات معتمدة على الوقت والتاريخ، فهذا الموديول يجعل الوقت والتاريخ يعملان بإستمرار وذلك بسبب البطارية طويلة المدى المدمجة فيه.

Raspberry_Pi_RTC_2

المكونات المطلوبة

Raspberry Pi

راسبيري باي

Raspberry_Pi_RTC

مؤقت ساعة حقيقي Real Time Colck – RTC

Raspberry_Pi_RTC_Wires

أسلاك توصيل Female / Female jumper

 

توصيل الدائرة

نقوم بتوصيل الدائرة كما فى الصورة التالية مع ملاحظة أن هذا الموديول يعتمد على الشريحة DS3231 وهي تعمل على جهد 3.3 فولت، لذلك هي مناسبة لتعمل على الراسبري باي مباشرة بدون أي مكونات أخرى.

Raspberry_Pi_RTC_1

الكود البرمجي

في البداية نقوم بفتح الـ Terminal الخاص بالراسبري باي وكتابة الأوامر التالية أو نقوم بفتح نافذه الـ SSH الخاصة بها من جهاز آخر مربوط معها علي نفس الشبكة كما تم شرحه في الدرس الخامس.

فى البداية نقوم بتحديث نظام تشغيل الراسبيري باي.

sudo apt-get update
sudo apt-get –y upgrade

ثم نقوم بالتعديل في أحد ملفات النظام كالتالي.

sudo nano /etc/modules

قم بإضافة السطر التالي (rtc-ds1307) داخل ملف modules الذى قمنا بفتحه بمحرك النصوص Nano، ثم نقوم بالضغط على Ctrl+O ثم enter ثم Ctrl+X وذلك لحفظ الملف السابق.

Raspberry_Pi_RTC_4

نقوم بإعادة تشغيل الراسبري باي كالتالي.

sudo reboot

نقوم بتشغيل الراسبري باي وكتابة الأمر التالي، إذا كنت تستخدم راسبيرى باى ذات الإصدار Rev 1، ستحتاج لتغيير الرقم 1 فى آخر الأمر وإستبدالة بـ 0.

sudo i2cdetect -y 1

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

Raspberry_Pi_RTC_5

فى هذه التجربة يكون 0x68 هو عنوان الـ RTC Module .

ثم نقوم بالتعديل فى أحد ملفات النظام مرة أخرى كالتالي.

sudo nano /etc/rc.local

قم بإضافة السطرين التاليين داخل ملف rc.local الذي قمنا بفتحه بمحرك النصوص Nano.

echo ds1307 ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
hwclock –s
Raspberry_Pi_RTC_6

ثم نقوم بالضغط على Ctrl+O ثم enter ثم Ctrl+X وذلك لحفظ الملف السابق.

لاحظ أنه يجب تغيير العنوان 0x68 للعنوان الذي سيظهر لك من الخطوة السابقة، وكذلك إذا كنت تستخدم راسبيري باي Rev1 نقم بتغيير i2c-1 إلى i2c-0.

نقوم بإعادة تشغيل الراسبيري باي مرة أخرى.

sudo reboot

بعد إعادة التشغيل إذا قمت بكتابة أمر i2cdetect ستلاحظ أن عنوان الموديول قد تغير إلى UU، وهذا دليل على أن الموديول يعمل جيداً.

sudo i2cdetect -y 1
Raspberry_Pi_RTC_7

الآن نقوم بضبط إعدادات الوقت والتاريخ من خلال الأمر التالي.

sudo raspi-config

نقوم بإختيار Internationalisation Options ثم Change Timezone  وتختار بعد المنطقة والدولة التى تقيم بها.

Raspberry_Pi_RTC_8

 

Raspberry_Pi_RTC_9

 

Raspberry_Pi_RTC_10

يمكنك قراءة وقت وتاريخ الراسبيري باي بالأمر التالي.

date

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

sudo date -s “16 APR 2017 23 : 00 : 00”

وبمجرد تغيره يجب عليك كتابته على الـ RTC Module كالتالي.

sudo hwclock –w

وللتأكد يمكنك قراءة الوقت والتاريخ من الموديول مرة أخرى كالتالي.

sudo hwclock –r

يمكنك قراءة وقت الراسبيري باي وكذلك وقت الـ RTC Module سوياً لتتأكد من أنهم نفس التوقيت كالتالي.

sudo date; sudo hwclock –r
Raspberry_Pi_RTC_11

 




كيفية زيادة سرعة الراسبيري باي؟

فى هذا الدرس سنتعلم كيفية زيادة السرعة Overclocking للراسبيري باي مع الأخذ فى الإعتبار أن درجة الحرارة لن تزيد عن 50 أو 60 درجة مئوية.

raspberry_pi_overclock_1

المكونات المطلوبة

DSC00009

راسبيرى باى

raspberry-pi-overclock-2

مشتت حرارى

الكود البرمجى

في البداية يجب أن تلاحظ أن كسر السرعة فى الراسبيري باي كان يؤدى إلى فقد الضمان قبل عام 2012 حيث أن مؤسسة راسبري فاونديشن لم تكن تدعم كسر السرعة وذلك لخطورته على حرق اللوحة بسبب زيادة درجة الحرارة عليها بشكل كبير، ولكنها بعد ذلك قامت بدعم كسر السرعة في نظام راسبيان بما يحافظ على اللوحات ولا يعرضها للخطر وذلك فى كل الإصدارات من راسبري باي 1 و B+ و 2 ماعدا راسبري باي 3 حيث أن تعطى أداء يقارب أقصى إمكانيات ممكنة فى اللوحة فلا داعي لكسر السرعة.

بإمكانك بسهولة تغير تفعيل كسر السرعة من قائمة خصائص الراسبيري باي Raspi-config كالتالي فبإمكانك الإختيار من مجموعة من الإعدادات المعدة مسبقاً التي بإمكانها أن تصل الراسبيري باي حتى تردد 1000 ميجاهرتز.

raspberry_pi_overclock_3

 

raspberry_pi_overclock_4

أو من خلال سطر أوامر لينكس وذلك بالتعديل على ملف txt كالتالى فنقوم بكتابة الأمر التالي في سطر أوامر النظام Terminal.

sudo nano /boot/config.txt

سوف تلاحظ وجود كثر من الأختيارات بإمكانك تخطي الكثير منهم والتالي هو قائمة بأهم ما يمكن التحكم به.

Frequency Overclocking
arm_freq – تردد البروسيسور والقيمة الأولية لها هي 700
gpu_freq – تردد كارت الشاشة الخاص باللوحة والقيمة الأولية لها هي 250
sdram_freq – تردد الرامات والقيمة الأولية لها هي 500
core_freq – تردد ال core الخاص بكارت الشاشة وهو له تأثير على أداء البروسيسور حيث أنه يتم التحكم به من خلال الـ L2 cache
h264_freq – تردد دائرة فك تشفير الفيديو
isp_freq – تردد دائرة التحكم فى الكاميرا
v3d_freq – تردد عرض الفيديو  3D
Voltage Overclocking
over_voltage – مقدار فرق الجهد الذي سيصل له البروسيسور وكذلك كارت الشاشة وأقل قيمة له هي (-16) و أقصى قيمة له هي (8) والقيمة الأولية له هي (0)

بإمكانك تغيير الإعدادات السابقة كما تريد وليكن قم بتغييرهم إلى الآتي ويفضل أن تقوم بتركيب مشتت الحرارة الخاص بالراسبيري وذلك لزيادة الحماية عليها من أي تغير ممكن فى حرارة البروسيسور.

arm_freq=900
gpu_freq=300
core_freq=250
h264_freq=250
isp_freq=250
v3d_freq=250
sdram_freq=450
over_voltage=6

 




نظام التحكم ومراقبة الإضاءه عن بعد

نظام التشغيل الآلي والتحكم للمنزل لايربط كل الأجهزة التكنولوجية في منزلك ببعض وحسب، بل يربطك أنت بمنزلك. لقد صممنا نظام متكامل يمكنه التفاعل مع الأجهزة الكهربائية (الضوء)  لمراقبتها و التحكم بها عن بعد لتجعل من حياتك أكثر متعة وراحة خاصة مع الأشياء التي تستخدمها كل يوم ضمن روتينك اليومي.

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

b5

القطع المطلوبة :

الأدوات التي تحتاجها لهذا المشروع :

5mm Red LED

العدد :8

220 Ω resistor

مقاومة 220 اوم

العدد :8

Full size breadboard 830

  لوح تجارب كبير (Full size breadboard)

Raspberry Pi 3 Model B

Jumper Wires Male/Male

 اسلاك توصيل ذكر/ذكر (Jumper Wires Male Male)

Female-Male Jumper Wires

 اسلاك توصيل أنثى/ذكر (Jumper Wires Female/male)

5V 2A Switching Power Supply MicroUSB Cable

Power Supply

Samsung 8Gb Class 6 Microsd Memory Card 2

Samsung 8Gb Class 6 Microsd Memory Card

نظرة عامة :

يبدأ النظام من خلال ارسال اوامر المستخدم عن طريق استخدام تطبيق على الهواتف الذكية او صفحة web  الى الخادم (server)  عبر الانترنت، ومن ثم يقوم الخادم بإرسال هذه الأوامر الى لوحة التحكم (الراسبيري باي ) للتحكم في إيقاف و تشغيل الاضاءه المنزلية.

remote-control-raspberry-pi-leds

يمكنك من خلال هذا النظام التحكم بالتوصيلات الكهربائية (Powerstrip  )، التحكم تدفئة أو تبريد المنزل، التحكم في تشغيل و اطفاء الالات الكهربائية.

تصميم لوحة التجارب:

في جزء التوصيل الإلكتروني سيتم توصيل 8  LEDs فقط.الجزء المختلف في التوصيل هو إختيار المنفذ لكل LEDs . في الواقع ، سوف نستخدم في نظام التحكم ومراقبة الإضاءه  مكتبة تدعا wiringPi و أرقام المنافذ في هذه المكتبية ليست هي نفس التي على الراسبيري باي.سيتم تسمية المنافذ على الراسبيري باي اعتمادا على مكتبة wiringPi كما هو موضح بالجدول التالي :

remote-control-raspberry-pi-leds

قم بتوصيل القطع اللكترونية كما هو موضح بالصورة :

remote-control-raspberry-pi-leds

 يتم توصيل  الطرف السالب للـ LEDs بمقاومة 220 اوم و الطرف الموجب حسب الجدول التالي:

remote-control-raspberry-pi-leds

تثبيت و إستخدام المكتبة Wiring Pi :

مكتبة Wiring Pi هي مكتبة الوصول إلى GPIO  على لوحة الراسبيري باي . و انها تسمح لك التحكم بمداخل و مخارج الراسبيري باي من خلال bash script   او مباشر من خلال سطر أوامر.
تحقق أولا ما اذا كانت مكتبة wiringPi مثبتة مسبقا ام لا ، من خلال نافذة الـ  terminal قم بتشغل الامر التالي:

gpio -v

 اذا لم تقم بتثبيت GIT،  يمكنك تثبيتها من خلال الأمر التالي :

sudo apt-get install git-core

اذا تم ظهور رسالة خطأ هنا ، تأكد من تحديث الراسبيري باي إلى أخر اصدار من Raspbian :

sudo apt-get update
sudo apt-get upgrade

للحصول على WiringPi باستخدام GIT، قم بكتابة الأمر التالي:

cd
git clone git://git.drogon.net/wiringPi
cd ~/wiringPi
git pull origin

سوف تجلب النسخة المحدثة ثم يمكنك إعادة تشغيل البرنامج من خلال الأمر أدناه .
لبناء/ تثبيت البرنامج :

cd ~/wiringPi
./build

الكتابة و القراءة من المنافذ عن طريق استخدام أوامر المكتبة wiringPi :

الأن يجب أن تكون قادر على إستخدام الأداة، قم بكتابة الأمر التالي على نافذة الـ Terminal :

gpio mode 0 out

اذا لم يتم ظهور شي أو رسالة خطأ فقد تم التثبيت للمكتبة بشكل صحيح. في حال تم ظهور رسالة الخطأ “command not found error” أو شي من هذا القبيل، تأكد من تثبيت و بناء المكتبة. للقيام بتشغيل و إطفاء الـ Wiring pin 0 )LED) ، تحتاج اولا إلى تعيين الدبوس كمخرج من خلال الأمر التالي :

gpio mode 0 out

“0”هي رقم المنفذ wiring، و “OUT”  لتعيين المنفذ كمخرج . سيتم تشغيل الـ LED  من خلال الأمر التالي :

gpio write 0 1

“0” للدلاله على رقم المنفذ ، و “1”  لوضع الدبوس في حالة التشغيل الـ LED( للتشغيل 1 و إطفاءه 0) . و لإيقاف تشغيلك ببساطة استخدم الأمر :

gpio write 0 0

وهناك أيضا اوامر لقراءة GPIO  والتي تسمح لقراءة وضع الدبوس. فيمكن من خلاله معرفة حالة الضوء هل هو في حالة التشغيل او الإيقاف إذا لم تكن على إستطاعه لرؤية الضوء. يمكنك ذلك عن طريق الأمر التالي :

gpio read 0

“0” لتعيين رقم المنفذ Wiring. هذا الأمر يقوم بترجيع  قيمة 1 اذا كان الضوء في حالة التشغيل و قيمة 0 اذا كان الضوء في حالة الإيقاف.

وأخيرا مكتبة wiringPi تحتوي على الكثير من الأوامر و الدوال التي تمكنك من التحكم بمداخل و مخارج الراسبيري باي ولكن لن يتم تغطيتها جميعها في هذا المشروع. يمكنك الاطلاع على هذه الروابط اذا كنت مهتم بمعرفة المزيد :

http://wiringpi.com/reference/

https://projects.drogon.net/raspberry-pi/wiringpi/the-gpio-utility/

نظام التحكم ومراقبة الإضاءه عن بعد مع SSH  هو جميل ولكن الواجهة ليست سهلة الاستعمال  و كتابة الأوامر في كل مرة أمر طويل و مزعج. هذا هو السبب في أننا بحاجة إلى واجهة رسومية لمشروعنا.كما أن برمجة تطبيق لكل نظام تشغيل (IOS, Android, Windows phone ,Mac, Linux, Windows ,….) ستكون طويلة جدا و يتطلب أن تكون على معرفه  بعدة لغات مختلفة.

هذا هو السبب لإنشاء صفحة ويب على شبكة النت ، حيث انها ستكون متوافقه مع جميع الأجهزة ، و ستكون بحاجة لمعرفة اربع لغات : CSS,HTML (نمط الصفحة)، PHP (للتفاعل مع الخادم )،  JavaScript (التفاعلات مع المستخدم) . نحن بحاجة لتثبيت خادم الويب على الراسبيري باي. في حالتنا نحن لسنا بحاجة إلى قاعدة بيانات MySQL ، فقط بحاجة إلى خادم HTTP و PHP.

 تثبيت خادم الويب(Web Server) :

أولا قم بعمل تحديث للراسبيري باي :

sudo apt-get update

قم بتثبيت الخادم (Apache HTTP server ) وPHP من خلال الأمر التالي :

sudo apt-get install php libapache2-mod-php -y

الان قم بالتحقق ما اذا كان الخادم (Server) يعمل، قم بكتابة العنوان IP الخاص بالراسبيري باي على متصفح الويب. اذا كان يعمل ستظهر رسالة “It works!” كما هو موضح بالصورة أدناه.

remote-control-raspberry-pi-leds

إذا لم يتم مثل ما سبق، قم بالتحقق من العنوان IP الخاص بالراسبيري باي من خلال الأمر التالي :

ifconfig

أو قم بمحاولة إعادة تثبيت Apache  أو إعادة تشغيل الراسبيري باي.

الملف  الخاص بواجهة المستخدم :

قم بالدخول إلى ملف /var/www/html/ عبر نافذة الـTerminal من خلال الأمر التالي :

cd /var/www/html

قم بعرض الملفات الموجودة على هذا الملف بإستخدام الامر التالي:

ls

سيظهر لك ملف واحد يسمى “index.html”  هذا الملف يتوافق مع صفحة “It works!”. يمكنك حذفه ليتم إنشاء الصفحة الخاصة بهاذا المشروع. قم بحذف الملف بإستخدام الأمر التالي :

sudo rm index.html

و إنشاء ملف أخر يسمى “index.php”  :

sudo nano index.php

ثم قم بكتابة النص التالي داخل الملف:

<?php
phpinfo();
?>

بعد حفظ الملف ، قم بعمل تحديث للمتصفح الخاص بك. يجب أن تشاهد صفحة طويلة مع الكثير من المعلومات حول الخادم و PHP .

إنشاء واجهة المستخدم :

يمكننا التحكم بالراسبيري باي من خلال  PHP script ولكن لن يكون هناك واجهة لتفعال المستخدم ، و بالتالي فإننا لن نتمكن من إيقاف و تشغيل الـ LED.
واجهة المستخدم تتألف من صور عبارة عن أزرار تشغيل و إيقاف. الأخضر للدلالة على التشغيل و الأحمر للدلالة على اللإيقاف . كل صورة/ زر يتم ربطه مع LED خاص به . لذلك اذا تم النقر على أحد الصور/الأزرار ، سيتم تشغيل أو إيقاف الـ LED المرتبط به و سيتم تغيير الصورة من زر أحمر إلى أخضر او العكس .

remote-control-raspberry-pi-leds

سيتم إنشاء واجهة الصفحة بإستخدام لغةHTML، و لتفاعلات الخادم وتوليد الصفحة لغة PHP، و JAVAScript  لإدارة التفاعل مع المستخدم و الرسوم المتحركة للصفحة. ويمكنك استخدام CSS لتخطيط و تنسيق الصفحة مثل الخلفية .

remote-control-raspberry-pi-leds

اولا نحن بحاجة لملف “index.php” لإنشاء الواجهة ولتفاعل الخادم . هذه الصفحة هي الصفحة الرئيسية التي تحتوي على 8 ازرار.

التحكم بالإضاءة من خلال ملف PHP :

تنفيذ التطبيق مع كود PHP يمكن القيام به بكتابة دالتين مختلفين :exec و system  .أولا الدالة “system” ، تأخذ هذا الامر متغيرين :

system ( string $command, int $return_var )

المتغير الأول هو الأمر الذي سيتم تنفيذه، و المتغير الثاني هو الحاله المستردة من تنفيذ الأمر. والمتغير الثاني لا يكون إلزاميا.وهكذا يمكنك إستخدامه إذا كنت بحاجة إلى تنفيذ الأوامر”gpio mode 0 out” او “gpio write 0 1” مثال :

<?php
system ( "gpio mode 0 out" );
system ( "gpio write 0 1" );
?>

ثم الدالة “exec”،  هذة الدالة تقوم بالضبط بنفس العمل للدالة “system” ولكن تقوم بقراءة و تخزين ما طبعه الامر. حيث انه يأخذ ثلاث متغيرات :

 exec ( string $command, array $output, int $return_var )

الإختلاف بالمتغيرات هو مصفوفة $output . سيتم تخزين ما يتم قراءته خلال الأمر في هذه مصفوفة.وهكذا، يمكنك استخدام هذه الدالة إذا كنت بحاجة إلى قراءة أحد المنافذ مثل الأمر “gpio read 0” وتخزين القيم التي تم استجاعها. مثال:

<?php
exec ( "gpio read 0", $status );
print_r ( $status );
?>

سنقوم بهذا المشروع بالتحكم بالمصابيح المربوطة على المنافذ من 0 على 7، يتم إنشاء الثمانية أزرار لأول مره في For loop بإستخدام :

exec ( "gpio read ".$i, $output );

قم بفتح ملف index.php ، ثم قم بكتابة الكود التالي في الملف و قم بحفظه:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Raspberry Pi Gpio</title>
    <div id="rectangle" style="width:100%;left:0;height:70px; background:#f88238;"></div>
</head>

<body style="background-color: black;margin:0 auto ; align:middle;">
<!-- On/Off button's picture -->
<?php
  $val_array = array(0,0,0,0,0,0,0,0);
  //this php script generate the first page in function of the file
  for ( $i= 0; $i<8; $i++) {
     //set the pin's mode to output and read them
     system("gpio mode ".$i." out");
     exec ("gpio read ".$i, $val_array[$i], $return );
  }
  //for loop to read the value
  $i =0;
  for ($i = 0; $i < 8; $i++) {
     //if off
     if ($val_array[$i][0] == 0 ) {
     echo ("<img id='button_".$i."' src='data/img/red/red_".$i.".jpg' onclick='change_pin (".$i.");'/>");
    }
    //if on
    if ($val_array[$i][0] == 1 ) {
       echo ("<img id='button_".$i."' src='data/img/green/green_".$i.".jpg' onclick='change_pin (".$i.");'/>");
      }
  }
?>

<!-- javascript -->
<script src="script.js"></script>
</body>
</html>

 نحن بحاجة إلى التحقق ما اذا تم النقر على أحد الأزرار من قبل المستخدم . حيث ان JavaScript تفيد لهذا الغرض، سيتم وضعها في ملف منفصل يسمى “script.js” ولكنها لا تزال مدرجة في ملف”index.php“
Scrip هو مجرد إضافة مستمع (listener) إلى كل من الثمانية أزرار، في كل مرة يتم الضغط على هذه الأزرار ، سيتم استخدام دالة لسؤال ملف gpio.php عن حالة الإضاءة و تستقبل التحديثات كإجابة. و أخير ستقوم الـ javaScript  بتغير صورة الأزرار إلى الأحمر للدلالة على الإيقاف أو إلى أخضر في حالة تشغيل الإضاءة.
و في الملف الأخير ،gpio.php .  يحتوي على كود PHP لتشغيل و إيقاف الإضاءة اعتمادا على ما يتم ارسالة من الـ javaScript .

يمكنك تحميل برمجة كامل المشروع من خلال الرابط المباشر على الموقع هنـا . يمكنك تحميل الملف على الراسبيري باي على ملف /var/www/html/ ثم قم بفتح عنوان IP الخاص بالراسبيري باي على متصفح ويب.




التحكم باللوحة الإعلانية عن بعد

لوحة الإعلانات اللاسلكية هو إنتقاء جيد لهذا المشروع، بدلا من أن تكون مجرد لوحة إعلانية بسيطة. أولا يجب أن نفهم الغرض من هذا المشروع، في هذا النظام يمكننا عرض رسالة أو شعار لبعض أجهزة العرض مثل شاشات الكريستال السائل (LCD)، وهذه الرسالة يمكن بسهولة وضعها و تغييرها من أي مكان في العالم، عن طريق إستخدام الانترنت لإرسال الرسالة لاسلكيا من متصفح ويب إلى شاشة الـ (LCD) المتصلة بلوحة الراسبيري باي.لذالك يمكنك إرسال الرسالة بإستخدام الحاسوب، الهاتف الذكي أو tablet .

web-controlled-iot-notice-board-using-raspberry-pi

القطع المطلوبة :

في نظام التحكم بشاشات الإعلانات، سنقوم بإنشاء خادم الويب المحلي ( local web server)،  والذي يمكنه أن يكون (A global server) على شبكة الإنترنت. في الراسبيري باي ، سيتم إستخدام شاشة العرض LCD 16×2 لعرض الرسالة و Flask لإستقبال الرسالة عبر الشبكة. كلما يتلقى الراسبيري باي أي رسالة لاسلكية من صفحة ويب ، فإنه يعرض هذه الرسالة على شاشة الكريستال السائل (LCD).

الأدوات التي تحتاجها لهذا المشروع :

HD44780

LCD 16×2 شاشة

potentiometer 10k

Potentiometer 10K Ω

220 Ω resistor

مقاومة 220 اوم

Half-size Breadboard

لوح تجارب حجم متوسط (Half size breadboard )

Raspberry Pi 3 Model B

Jumper Wires Male/Male

 اسلاك توصيل ذكر/ذكر (Jumper Wires Male Male)

Female-Male Jumper Wires

 اسلاك توصيل أنثى/ذكر (Jumper Wires Female/male)

5V 2A Switching Power Supply MicroUSB Cable

Power Supply

Samsung 8Gb Class 6 Microsd Memory Card 2

Samsung 8Gb Class 6 Microsd Memory Card

تصميم لوح التجارب :

نحن بحاجة فقط لتوصيل شاشة العرض (LCD) مع لوحة الراسبيري باي عن طريق إستخدام بعض الاسلاك على لوحة التجارب.

قم بتوصيل الدائرة كما هو موضح بالصورة :

web-controlled-iot-notice-board-using-raspberry-pi

توصيل  شاشة الـ LCD :

راسبيري باي LCD شاشة
GND Vss
5v VDD
GND RW
GPIO7 RS pin
GPIO8 Enable pin
GPIO25 D4 pin
GPIO24 D5 pin
GPIO23 D6 pin
GPIO18 D7 pin

إنشاء صفحة ويب :

في هذا المشروع، العنصر الرئيسي هو الراسبيري باي، و التي تمثل قلب هذا المشروع،وتستخدم للتحكم على العمليات المرتبطة بهذا المشروع. مثل : التحكم بشاشة العرض (LCD)، وتلقي الرسائل من الخادم (Server) .

web-controlled-iot-notice-board-using-raspberry-pi

سيتم إنشاء خادم ويب (Web Server)، الذي يوفر وسيلة لإرسال “الرسالة المراد إعلانها” الى الراسبيري باي بإستخدام Flask في متصفح الويب. Flask  هو  إطار عمل مُصغّر/صغير (Micro-Framework) وقوي فى نفس الوقت لتطوير برامج الويب عبر لغة بايثون Python، يتوفّر على عدد لا بأس به من الدوال المُساعدة، مُناسب لتطوير تطبيقات صغيرة ومُتوسّطة (مُدونة، منتدى، موقع شخصي… ).

قم بإنشاء ملف  webapp ليتم حفظ الملفات المتعلق بهذا المشروع داخله عن طريق كتابة الأمر التالي على نافة Terminal :

mkdir webapp

في هذا المشروع سوف نقوم بإنشاء صفحة ويب مع مربع نص (TextBox) و زر إرسال (Submit button)، حيث يمكننا أن ندخل “رسالة الاعلان” في مربع نص ثم رفعها إلى الخادم (Server) عن طريق النقر على زر إرسال. يتم تطوير هذا التطبيق على شبكة الإنترنت باستخدام لغة HTML. الكود البرمجي لصفحة الويب هذه سيتم شرحه و عرضه في الخطوات التالية.

لإنشاء صفحة ويب :

أولا: قم بإنشاء ملف templates في الملف webapp  عن طريق إدخال  الأمر التالي في Terminal:

cd /home/pi/webapp
mkdir templates

تحتاج إلى كتابة  كود HTML في محرر نص (text editor) و حفظ الملف مع تمديد  (.HTML)
قم بفتح محرر نص (Text Editor) تحت قائمة Accessories  في القائمة الرئيسية :

web-controlled-iot-notice-board-using-raspberry-pi

قم بكتابة كود  HTML التالي :

<h1>Web Control Notice Board</h1>
</div>

<div data-role="content">

<form method="post" action="change">
<label for="slider-1">Notice Message:</label>
<input type="text" name="lcd" id="lcd" />
<br />

<input type="submit" value="Submit" />
</form>

{% if value %}
<p> Notice Submitted Successfully: {{ value }}</p>
{% endif %}

</div>
web-controlled-iot-notice-board-using-raspberry-pi

قم بحفظ الملف بتمديد(.HTML) مثل (index.html) في ملف templates ، الذي تم إنشاءه داخل ملف webapp.

لمحة عن الكود :
صفحة الويب يتم إنشاءها بلغة HTML ، والتي تحتوي على مربع نص :

 <input type="text" name="lcd" id="lcd" />

وزر إرسال  (Submit button) :

 <input type="submit" value="Submit" />

مع عنوان للصفحه :

<h1>Web Control Notice Board</h1>

عند النقر على زر إرسال سيتم إستخدام POST method  لتنفيذ الكود. ثم نقوم بعرض الرسالة التي تم إرسالها إلى الراسبيري باي عن طريق الخادم (Server).

{% if value %}
<p>Notice Submitted Successfully: {{ value }}</p>
{% endif %}

فهي تقوم بالتحقق ما اذا كانت هناك نص في مربع النص ثم تقوم بطباعة النص على صفحة الويب نفسها، بحيث يمكن للمستخدم أيضا رؤية الرسالة المرسلة.

أولا قم بتثبيت حزمة Flask. وتأكد من أنك متصل بالانترنت، إما عن طريق  Ethernet Cable أو عن طريق WIFI   قبل أن تبدأ.

قم بكتابة الأمر التالي على نافذة Terminal  لتثبيت الـ Flask :

sudo apt-get install python3-flask

جزء البرمجة في هذا المشروع يلعب دورا هاما للغاية لأداء جميع العمليات. أولا وقبل كل شي نحن بحاجة إلى درج المكتبات المطلوبة لـ  Flask .ثم تهيئة المتغييرات و تحديد Pins  لشاشة الكريستال السائل  (LCD) .

from flask import Flask
from flask import render_template, request
import RPi.GPIO as GPIO
import time
app = Flask(__name__)

# Define GPIO to LCD mapping
LCD_RS = 7
LCD_E = 8
LCD_D4 = 25
LCD_D5 = 24
LCD_D6 = 23
LCD_D7 = 18

لبرمجة شاشة الكريستال السائل (LCD) ، يتم إنشاء الدالة ()lcd_init لتهيئة شاشة LCD.

def lcd_init():
# Initialise display
  lcd_byte(0x33,LCD_CMD) # 110011 Initialise
  lcd_byte(0x32,LCD_CMD) # 110010 Initialise
  lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction
  lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off
  lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size
  lcd_byte(0x01,LCD_CMD) # 000001 Clear display
  time.sleep(E_DELAY)

 و الداله  ()lcd_byte لإرسال الأوامر إلى الشاشة، , و الداله  ()lcd_string لإرسال البيانات المراد عرضها على الشاشة إلى الـ LCD .

def lcd_string(message,line):
# Send string to display
  message = message.ljust(LCD_WIDTH," ")
  lcd_byte(line, LCD_CMD)
  for i in range(LCD_WIDTH):
     lcd_byte(ord(message[i]),LCD_CHR)

 و فيما يلي هذا الجزء من البرنامج يستخدم لإرسال رسالة من متصفح ويب إلى الراسبيري باي بإستخدام Flask .

@app.route("/")
def index():
   return render_template('index.html')
@app.route("/change", methods=['POST'])
def change():
  if request.method == 'POST':
    # Getting the value from the webpage
    data1 = request.form['lcd']
    print ("---Message is", data1)
    lcd_string(data1,LCD_LINE_1)
  return render_template('index.html', value=data1)
if __name__ == "__main__":
  app.debug = True
  app.run('192.168.1.19', port=8080,debug=True)

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

#import
from flask import Flask
from flask import render_template, request
import RPi.GPIO as GPIO
import time
app = Flask(__name__)

# Define GPIO to LCD mapping
LCD_RS = 7
LCD_E  = 8
LCD_D4 = 25
LCD_D5 = 24
LCD_D6 = 23
LCD_D7 = 18


# Define some device constants
LCD_WIDTH = 16    # Maximum characters per line
LCD_CHR = True
LCD_CMD = False

LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line

# Timing constants
E_PULSE = 0.0005
E_DELAY = 0.0005
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)       # Use BCM GPIO numbers
GPIO.setup(LCD_E, GPIO.OUT)  # E
GPIO.setup(LCD_RS, GPIO.OUT) # RS
GPIO.setup(LCD_D4, GPIO.OUT) # DB4
GPIO.setup(LCD_D5, GPIO.OUT) # DB5
GPIO.setup(LCD_D6, GPIO.OUT) # DB6
GPIO.setup(LCD_D7, GPIO.OUT) # DB7


def lcd_init():
  # Initialise display
  lcd_byte(0x33,LCD_CMD) # 110011 Initialise
  lcd_byte(0x32,LCD_CMD) # 110010 Initialise
  lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction
  lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off
  lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size
  lcd_byte(0x01,LCD_CMD) # 000001 Clear display
  time.sleep(E_DELAY)

def lcd_byte(bits, mode):
  # Send byte to data pins
  # bits = data
  # mode = True  for character
  #        False for command

  GPIO.output(LCD_RS, mode) # RS

  # High bits
  GPIO.output(LCD_D4, False)
  GPIO.output(LCD_D5, False)
  GPIO.output(LCD_D6, False)
  GPIO.output(LCD_D7, False)
  if bits&0x10==0x10:
    GPIO.output(LCD_D4, True)
  if bits&0x20==0x20:
    GPIO.output(LCD_D5, True)
  if bits&0x40==0x40:
    GPIO.output(LCD_D6, True)
  if bits&0x80==0x80:
    GPIO.output(LCD_D7, True)

  # Toggle 'Enable' pin
  lcd_toggle_enable()

  # Low bits
  GPIO.output(LCD_D4, False)
  GPIO.output(LCD_D5, False)
  GPIO.output(LCD_D6, False)
  GPIO.output(LCD_D7, False)
  if bits&0x01==0x01:
    GPIO.output(LCD_D4, True)
  if bits&0x02==0x02:
    GPIO.output(LCD_D5, True)
  if bits&0x04==0x04:
    GPIO.output(LCD_D6, True)
  if bits&0x08==0x08:
    GPIO.output(LCD_D7, True)

  # Toggle 'Enable' pin
  lcd_toggle_enable()

def lcd_toggle_enable():
  # Toggle enable
  time.sleep(E_DELAY)
  GPIO.output(LCD_E, True)
  time.sleep(E_PULSE)
  GPIO.output(LCD_E, False)
  time.sleep(E_DELAY)

def lcd_string(message,line):
  # Send string to display
  message = message.ljust(LCD_WIDTH," ")

  lcd_byte(line, LCD_CMD)

  for i in range(LCD_WIDTH):
    lcd_byte(ord(message[i]),LCD_CHR)

lcd_init()
lcd_string("Rasbperry Pi",LCD_LINE_1)

    
@app.route("/")
def index():
    return render_template('index.html')
@app.route("/change", methods=['POST'])
def change():
 if request.method == 'POST':
    # Getting the value from the webpage
   data1 = request.form['lcd']
   print ("---Message is", data1)
   lcd_string(data1,LCD_LINE_1)

 return render_template('index.html', value=data1)
if __name__ == "__main__":
    app.debug = True
    app.run('192.168.1.19', port=8080,debug=True)

قم بحفظ ملف الكود app.py داخل ملف webapp الذي تم إنشاءه مسبقا. flask  سوف يقوم بالبحث عن index.html في ملف templates، الموجود على نفس الملف الذي يحتوي ملف الكود app.py .
بعد ذلك يمكنك تشغيل برنامج البايثون ولكن قبل ذلك تحتاج إلى استبدال عنوان IP في برنامج مع عنوان IP للراسبيري باي الخاصه بك.يمكنك التحقق من عنوان IP عن طريق كتابة الامر التالي على نافذة terminal :

Ifconfig

بعد تشغيل كود البايثون ثم بفتح http://IP_address_of_your_Pi:8080 في متصفح الويب و ادخل الرسالة ثم انقر فوق زر الارسال .




التحكم بالاردوينو من خلال windows 10

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

windows-remote-arduino-experience

القطع المطلوبة:

الأدوات التي تحتاجها لهذا المشروع :

(Bluetooth Module(HC-06

Diffused RGB 5mm LED

RGB 5mm LED

220 Ω resistor

مقاومة 220 اوم

potentiometer 10k

Potentiometer 10K Ω

Half-size Breadboard

 لوح تجارب حجم متوسط (Half size breadboard)

arduino uno r3

Arduino Uno R3

Female-Male Jumper Wires

 اسلاك توصيل أنثى/ذكر (Jumper Wires Female/male)

Jumper Wires Male/Male

سلاك توصيل ذكر/ذكر (Jumper Wires Male Male)

ما هو Windows Remote Arduino وماذا يمكنك أن تفعل من خلاله؟

windows Remote Arduino  هي مكتبة ويندوز مفتوحة المصدر التي تسمح لأي جهاز ويندوز 10 -سواء كان هاتف ويندوز أو جهاز كمبيوتر أو حتى راسبيري باي 2 – التحكم بالاردوينو عن بعد.
تمكن المكتبة للمطورين من دمج أجهزة الاستشعار الخاصة بالاردوينو في مشاريع windows  الخاصة بهم . يمكنك العثور على المكتبة الخاصة لـ Windowd Remote Arduino  على الصفحة هنـا.

Windows Remote Arduino قادرة على التحكم بالوظائف التالية للأردوينو:
1- المداخل و المخارج الرقمية و التناظرية.
– الكتابة الرقمية.
– قراءة رقمية.
– الكتابة التناظرية (PWM).
– قراءة تناظرية.
– تعيين Pin Mode.
– تلقي الإشارات في حالة تم تغيير قيم الـ pins .
2- إرسال و إستقبال البيانات بين جهازين عبر I2C .

windows-remote-arduino-experience

للمستخدمين المتقدمين، تتيح Windows Remote Arduino  أوامر مخصصة عبر Firmata SysEx – يمكن الإطلاع على مزيد من المعلومات هنـا.

تصميم لوحة التجارب:

قم بتوصيل لوح التجارب كما هو موضح بالصورة :

windows-remote-arduino-experience

يمكنك الاطلاع على الدرس الرابع لمعرفة طريقة توصيل الـ RGB LED.

لتبدأ التحكم بالأردوينو بإستخدام التطبيق Windows Arduino Experience ، قم بإتباع الخطوات الثلاثة :
1- تهيئة الاردوينو.
2- تهيئة جهاز Windows 10.
3- إجراء عملية الإتصال و التحكم .

تهيئة الأردوينو:

قم بتنزيل مكتبة “Arduino Firmata ” قم بإتباع الخطوات التالية :
إذهب إلى الشيفرة البرمجية (Sketch menu) / إدراج مكتبة (Include Library)  /  إدارة المكتبات (Manage Library)  ثم قم بالبحث عن “ “Firmataو قم بتنزيل أخر إصدار للمكتبة.
الآن قم بفتح   “StandardFirmata”من ملف (File) / أمثلة StandardFirmata / Firmata /  Examples   .

قم بالعديل baud rate على الكود

Firmata.begin(9600);

ثم قم برفع الكود على الأردوينو.

تهيئة جهاز الويندوز :

لتنزيل تطبيق Windows Remote Arduino Experience من هنـا.

قم بتفعيل البلوتوث على جهازك ثم قم بالاقتران الى البلوتوث عن طريق ادخال كلمة المرور الافتراضية  1234 او   0000.

windows-remote-arduino-experience

إجراء عملية الإ تصال و التحكم :

قم بفتح تطبيق windows ، بمجرد اختيار الاعدادات الصحيحة ، قم بإختيار البلوتوث HC-06 ثم انقر فوق  “Connect” للإتصال بالاردوينو عن بعد.

windows-remote-arduino-experience

قم بالتحكم بالـ RGB LED من خلال نافذة PWM :

windows-remote-arduino-experience

كما يمكنك قراءة القيم التناظرية للمقاومة المتغيرة عبر النافذة Analog :

windows-remote-arduino-experience



التحكم بالروبوت عبر الهاتف الذكي

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

bluetooth-controlled-robot-car

القطع المطلوبة:

الأدوات التي تحتاجها لهذا المشروع :

4WD Robot Chassis kit

L298 Motor driver

L298 H bridge Module

serial port bluetooth module hc-06

وحدة البلوتوث (HC-06)

battery holder

حامل البطارية

arduino uno r3

Arduino Uno R3

Jumper Wires Male/Male

 اسلاك توصيل ذكر/ذكر  (Jumper Wires Male Male)

Female-Male Jumper Wires

 اسلاك توصيل أنثى/ذكر (Jumper Wires Female/male)

 

ما هو الروبوت ؟

الروبوت هو جهاز كهروميكانيكي قادر على التفاعل بطرية أو بأخرى مع بيئته، و اتخاذ قرارات مستقلة أو إجراءات من أجل تحقيق مهنمة محددة.
يتكون الروبوت من العناصر التالية:
1- الهيكل.
2- المشغل الميكانيكي .
3- وحدة التحكم.
4-المدخلات/ الحساسات.
5- امدادات الطاقة.
في الخطوات التالية سنذكر كل عنصر من العناصر المذكورة اعلاه، بحث يمكن أن نفهمها بسهولة.

الهيكل (Structure / Chassis) :

smartphone-controlled-arduino-robot

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

المشغل الميكانيكي Actuator :

smartphone-controlled-arduino-robot

المحرك هو جهاز يقوم بتحويل الطاقة (في مجال الروبوت، تكون الطاقة الكهربائية) الى طاقة حركية. تنتج معظم المحركات إما الحركة الدورانية أو الخطية.
في حالتنا المحرك هو(DC Gear motor)  وهو بالاساس عبارة عن محرك  DC مركب مع علبة تروس (gear) تعمل على تقليل سرعة المحرك و زيادة عزم الدورات .

هيكل الروبوت 

قطع اربع قطع من أسلاك (الحمراء و السوداء) مع طول حوالي 5-6 انش. قم بتجريد السلك من العازل في كل نهاية , ثم قم بلحم الأسلاك على المحركات.

smartphone-controlled-arduino-robot

يمكنك التحقق من قطبية المحركات من خلال توصيلها إلى بطارية. اذا كانت تدور في الاتجاه إلى الأمام (السلك الاحمر مع القطب الموجب و الأسود مع القطب السالب) هذا يدل على ان التوصيل تم بشكل صحيح.

تركيب المحرك :

smartphone-controlled-arduino-robot

لاحظ أن الأسلاك على كل محرك تشير الى إتجاه مركز الهيكل.

smartphone-controlled-arduino-robot

قم بضم اثنان من الأسلاك الحمراء و اثنان من الاسلاك السوداء معا على كل جانب من جوانب الهيكل. بعد الانضمام, سيكون لديك اثنان من النهايات على الجانب الايمن و اثنان على الجانب الأيسر.

تثبيت السقف العلوي:

بعد تركيب الاربع محركات في الطابق السفلي، قم بتركيب السقف العلوي. ثم قم بسحب نهايات الاسلاك نحو السطح العلوي.

smartphone-controlled-arduino-robot

هناك حاجة إلى المتحكم (العقل) لتحريك الروبوت من مكان إلى أخر. المتحكم له القدرة على تنفيذ برنامج و يكون مسؤولا عن جميع العمليات الحسابية، واتخاذ القرارات، و الاتصال . في هذا المشروع سيتم استخدام متحكمArduino  كـوحدة تحكم.

يمكنك استخدام وحدة التحكم لدوران المحركات في إتجاه واحد. ولكن اذا كنت تريد أن تكون  قادر على التحكم في المحرك بإتجاهات مختلفة (الأمام ،الخلف، يمين، ويسار) مع لوحة التحكم, فإنك بحاجة إلى مزيد من الدوائر . انت بحاجة إلى H-Bridge.

 L298  H Bridge Module

smartphone-controlled-arduino-robot

H-Bridge، يقوم بتحريك محرك الـ DC بإتجاه الامام و الخلف. وهو يتكون من اربع مفاتيح الكترونية S1,S2,S3,S4  (Transistors / MOSFETS / IGBT).

smartphone-controlled-arduino-robot

الية العمل: انظر للصورة اعلاه لفهم ألية العمل للـ H-Bridge . المفاتيح في نفس الجهة إما (S1,S2) أو  (S3,S4)لا يتم إغلاقهم بنفس الوقت , سيتم حدوث ماس كهربائي .
H-bridge توفر لك دائرة متكاملة، أو يمكنك أن تقوم ببناء الدائرة بنفسك عن طريق إستخدام اربع Transistor او MOSFETs. في هذا المشروع سيتم استخدام  L298 H-bridge Module الذي يمكن من خلاله التحكم في سرعة واتجاه المحركات.

وصف مداخل و مخراج الـ L298H-bridge Module : 

smartphone-controlled-arduino-robot

توصيل الدائرة  

توصيل الدائرة

الخطوات لتوصيل الدائرة 

 

قم بتوصيل الأسلاك الحمراء للمحركين على كل جهة معا و الأسلاك السوداء معا.

smartphone-controlled-arduino-robot

MOTOR A هو المسؤول عن المحركات على الجانب الأيمن, وفي المقابل يتم ربط المحركات على الجانب الايسر للـ MOTOR B.

اتبع التعليمات التالية ليتم توصيل كل شي :

smartphone-controlled-arduino-robot
يمكنك العودة لمشروع نظام التحكم في الإضاءة عبر البلوتوث للإطلاع على الشرح المتعلق بوحدة البلوتوث .

برمجة الأردوينو

في الكود البرمجي سنقوم بمراجعة البيانات الواردة وتنفيذ عملية المقارنة ، اذا كانت البيانات المستقبلة من الهاتف الذكي F يتم تحريك الروبوت للأمام و إذا كانت B يتم تحريكه للخلف و اذا كانت R  يتم تغير حركة لليمين و L  للتحرك لليسار. ويتم إيقافة إذا كانت البيانات المستقبلة 0 .

قم برفع البرنامج التالي إلى متحكم الأردوينو:

char data = 0;            //Variable for storing received data
#define right1 7 //IN1
#define right2 8
#define rightE 9
#define left1 6
#define left2 5
#define leftE 10

void Forward(); 
void Backward(); 
void Left(); 
void Right(); 
void Stop1(); 

void setup()
{
   Serial.begin(9600);   //Sets the baud for serial data transmission                               
   pinMode(left1, OUTPUT); 
   pinMode(left2, OUTPUT); 
   pinMode(leftE, OUTPUT); 
   pinMode(right1, OUTPUT);
   pinMode(right2, OUTPUT);
   pinMode(rightE, OUTPUT);
   delay(1000);
}
void loop()
{
   if(Serial.available() > 0)      
   {
     data = Serial.read();        //Read the incoming data & store into data    
      switch (data){
        case 'F':
            Forward();
            break; 
        case 'B':
            Backward();
            break; 
        case 'L':
           Left();           
           break; 
        case 'R':
           Right(); 
           break; 
        case '0':
           Stop1();
           break; 
      }
  } 
}
void Forward(){
  digitalWrite(right1,1); 
  digitalWrite(right2,0); 
  analogWrite(rightE, 255);      
  digitalWrite(left1,1); 
  digitalWrite(left2,0); 
  analogWrite(leftE, 255);                                                                                                                                                                                                                                                        
}
void Backward(){
  digitalWrite(right1,0); 
  digitalWrite(right2,1); 
  analogWrite(rightE, 255); 
  digitalWrite(left1,0); 
  digitalWrite(left2,1); 
  analogWrite(leftE, 255); 
}
void Left(){
  digitalWrite(right1,1); 
  digitalWrite(right2,0); 
  analogWrite(rightE, 255); 
  digitalWrite(left1,0); 
  digitalWrite(left2,1); 
  analogWrite(leftE, 255); 
  
}
void Right(){
  digitalWrite(right1,0); 
  digitalWrite(right2,1); 
  analogWrite(rightE, 255); 
  digitalWrite(left1,1); 
  digitalWrite(left2,0); 
  analogWrite(leftE, 255); 
}
void Stop1(){
  digitalWrite(left1,0); 
  digitalWrite(left2,0); 
  analogWrite(leftE, 0); 
  digitalWrite(right1,0); 
  digitalWrite(right2,0); 
  analogWrite(rightE, 0); 
}

 شرح الكود :

أولا لفعم الية العمل قم بالاطلاع على الجدول التالي. هو مفيد جدا أثناء كتابة التعليمات البرمجي :

smartphone-controlled-arduino-robot

في قسم الـ Loop يتم قراءة البيانات التي تم إرسالها من قبل الهاتف الذكي ثم يتم التحقق منها. فمثلا إذا كانت حرف “F” يتم إستدعاء الدالة Forward()ليتم تحريك الروبوت إلى الأمام ،وإذا كات حرف “B” يتم إستدعاء الدالة backward() ليتم تحريك الروبوت للخلف.

data = Serial.read();        //Read the incoming data & store into data    
      switch (data){
        case 'F':
            Forward();
            break; 
        case 'B':
            Backward();
            break; 
        case 'L':
           Left();           
           break; 
        case 'R':
           Right(); 
           break; 
        case '0':
           Stop1();
           break; 
      }

نقوم بإنشاء الدالة Forward() , Backward() , Right(),Left() لتحكم في إتجاهات الروبوت.
و الدالة Stop1() لإيقاف حركة الروبوت

void Stop1(){
  digitalWrite(left1,0); 
  digitalWrite(left2,0); 
  analogWrite(leftE, 0); 
  digitalWrite(right1,0); 
  digitalWrite(right2,0); 
  analogWrite(rightE, 0); 
}

تطبيق الاندرويد

في هذا المشروع لن يتم تغطية طريقة برمجة تطبيق الاندرويد , يمكنك تحميل البرنامج من هنا

كيف يمكن استخدام التطبيق؟
1- قم بتنزيل البرنامج من هنا
2- قم بإقتران جهازك مع البلوتوث   HC-06:
– تشغيل البلوتوث HC-06.
– تفحص الجهاز المتوفر .
-يتم الاقتران الى البلوتوث عن طريق ادخال كلمة المرور الافتراضية  1234 او   0000.
3- قم بفتح التطبيق , ثم قم بالضغط على زر الاجهزة المقترنة  ثم قم بإختيار وحدة البلوتوث الخاصة بك (HC-06) .

smartphone-controlled-arduino-robot

قم بالضغط على الأسهم لتغير حركة الروبوت و على زر Stop لإيقاف الحركة .

smartphone-controlled-arduino-robot



نظام حماية الخزنة

كما نعلم جميعا أن أنظمة الأمان و الحماية من أهم متطلبات العصر، في هذا المشروع ستتعلم كيفية عمل نظام الحماية و الإنذار من خلال استخدام الاردوينو.

security-alarm-system-project

القطع المطلوبة:

الأدوات التي تحتاجها لهذا المشروع :

matrix keypad 4x4

Matrix Keypad 4×4

 مستشعر الموجات فوق الصوتية (Ultrasonic Sensor HC-SR04)

Piezo sounder

Piezo sounder

HD44780

LCD 16×2 شاشة

potentiometer 10k

Potentiometer 10K Ω

220 Ω resistor

مقاومة 220 اوم

Full size breadboard 830

  لوح تجارب كبير (Full size breadboard)

arduino uno r3

Arduino Uno R3

Jumper Wires Male/Male

 اسلاك توصيل ذكر/ذكر (Jumper Wires Male Male)

نظرة عامة

لتفعيل نظام الحماية  في البداية يتم تفعيل أنظمة الانذار بعد 10 ثواني من الضغط على الزر A. وللكشف عن الأجسام يتم استخدام جهاز استشعار الموجات فوق الصوتية (Ultrasonic Sensor) ، في حال الكشف عن وجود جسم قريب يبدأ تفعيل صفارة الانذار (Buzzer) . ولإيقاف صفارة الانذار أنت بحاجة لادخال كلمة المرور المكونة من 4 أرقام ثم الضغط على زر النجمة للتحقق ما اذا كانت الكلمة المدخلة صحيحة او لا . تم وضع كلمة السر الحالية  1234 ولكن لديك ايضا امكانية تغيرها.

security-alarm-system-project

عن طريق الضغط على زر B سيتم الدخول على قائمة تغيير كلمة المرور ، أولا انت بحاجة إلى إدخال كلمة المرور الحالية من أجل المواصلة في إجراءات تغير كلمة المرور، ومن ثم يطلب منك النظام إدخال كلمة المرور الجديدة مكونة من اربع أرقام .

security-alarm-system-project

في حال تغيير كلمة المرور, اذا تم تفعيل الانذار سوف تكون قادر على إيقافة عن طريق إدخال كلمة المرور الجديدة فقط. إذا تم إدخال كلمة مرور خاطئة ستظهر رسالة تسمع بإعادة المحاولة.

 

لوحة المفاتيح Keypad

تعتبر لوحة المفاتيح من اهم وسائل الادخال حيث تمكنك من إدخال الارقام و الرموز و بعض الأحرف من خلالها. و يتم إستخدامها بكثرة في مشاريع المتحكمات الدقيقة وأنظمة الحماية و ستجدها حولك في العديد من الاجهزة الالكترونية مثل الهاتف المنزلي وغيره.

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

security-alarm-system-project

لوحة المفاتيح 4×4  تتكون من 8-Pins  ، أربعة منهم للصفوف و أربعة منهم للأعمدة . كل زر بالواقع عبارة عن مفتاح (Push button)عند الضغط يتم التوصيل بين الصف و العامود.

security-alarm-system-project

على سبيل المثال : اذا وضع على الصف الأول  (Row 1قيمة LOW) ، وجميع الأعمدة قيمة HIGH ، عندما يتم الضغط على الزر الثالث ، سيتم التوصيل بين الصف الأول والعامود الثالث فسوف تصبح قيمة العامود الثالث LOW، وبالتالي يمكننا معرفة الزر الذي تم الضغط عليه.

تصميم لوح التجارب

قم بتوصيل الدائرة الكهربائية للوحة المفاتيح كما هو موضح بالصورة :

security-alarm-system-project

توصيل لوحة المفاتيح :

الأردوينو لوحة المفاتيح
Pin A0  الصف الأول
Pin A1 الصف الثاني
Pin 6 الصف الثالث
Pin 7 الصف الرابع
Pin A5 العامود الأول
Pin A4 العامود الثاني
Pin A3 العامود الثالث
Pin A2 العامود الرابع

 قم بإضافة توصيل باقي القطع الإلكترونية كما هو موضح بالصورة التالية :

security-alarm-system-project

توصيل  شاشة الـ LCD :

Arduino LCD
Pin 12 RS pin
Pin 11 Enable pin
Pin 5 D4 pin
Pin 4 D5 pin
Pin 3 D6 pin
Pin 2 D7 pin
توصيل حساس الموجات فوق الصوتية (Ultrasonic Sensor) :
Ultrasonic Sensor Arduino
VCC +5V
Trig Pin 10
Echo Pin 9
Ground GND
توصيل Buzzer:
Buzzer Arduino
Shorter lead GND
Longer lead Pin 8

الكود البرمجي للأردوينو

لفهم الكود بشكل أفضل ، سيتم شرح الكود على أقسام وفي النهاية سأقوم بوضع الكود الكامل.

قم بتنزيل المكتبة الخاصة بلوحة المفاتيح KeyPad من هنـا او من خلال الرابط المباشر هنـا .

أولا نحن بحاجة الى مكتبة الـ LCD   و مكتبة لوحة المفاتيح. ثم تحديد و تعريف المتغيرات لدبابيس جهاز الانذار  (Buzzer)و جهاز استشعار الموجات فوق الصوتية  (Ultrasonic)، و تعريف بعض المتغيرات اللازمة لهذا المشروع.

#include <LiquidCrystal.h> // includes the LiquidCrystal Library 
#include <Keypad.h>
#define buzzer 8
#define trigPin 10
#define echoPin 9
long duration;
int distance, initialDistance, currentDistance, i;
int screenOffMsg =0;
String password="1234";
String tempPassword;
boolean activated = false; // State of the alarm
boolean isActivated;
boolean activateAlarm = false;
boolean alarmActivated = false;
boolean enteredPassword; // State of the entered password to stop the alarm
boolean passChangeMode = false;
boolean passChanged = false;
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keypressed;
//define the cymbols on the buttons of the keypads
char keyMap[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {A0,A1,6,7};
byte colPins[COLS] = {A5,A4,A3,A2};  //Column pinouts of the keypad
Keypad myKeypad = Keypad( makeKeymap(keyMap), rowPins, colPins, ROWS, COLS); 
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // Creates an LC object. Parameters: (rs, enable, d4, d5, d6, d7) 

في قسم الأعداد (setup)، نحن بحاجة لتهيئة الـ LCD وتحديد ما اذا كان الـ Pin الخاص بالمستشعر و جهاز الانذار مدخل او مخرج .

void setup() { 
  lcd.begin(16,2); 
  pinMode(buzzer, OUTPUT); // Set buzzer as an output
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input
}

في القسم Loop، نحن أولا بحاجة للتحقق ما اذا تم تفعيل أنظمة الانذار او لا. فإذا لم يتم التفعيل ، سيتم ظهور القائمة الرئيسية على شاشة الـ LCD التي تقدم خيارين ، خيار A لتفعيل الانذار وخيار B لتغير كلمة المرور.
ثم استخدام ()myKeypad.getKey لقراءة الزر الذي تم الضغط عليه من لوحة المفاتيح ، اذا تم الضغط على زر A ، يتم تفعيل جهاز الانذار لمدة200 milliseconds و تصبح قيمة المتغير activeAlarm =true.

if (!alarmActivated) {
if (screenOffMsg == 0 ){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("A - Activate");
lcd.setCursor(0,1);
lcd.print("B - Change Pass");
screenOffMsg = 1;
}
keypressed = myKeypad.getKey();
if (keypressed =='A'){ //If A is pressed, activate the alarm
tone(buzzer, 1000, 200);
activateAlarm = true; 
}

في حالة تم الضغط على زر A يتم تفعيل الانذار و يتم طباعة الرسالة “Alarm will be activated in” على شاشة الـ LCD و عن طريق استخدام while loop يتم انشاء عداد تنازلي لمدة 9 ثواني قبل تفعيل الانذار .
ثم يتم ظهور الرسالة “Alarm Activated ” على الشاشة ويتم حساب المسافة الأولية بين نظام الامن (بإستخدام حساس الموجات فوق الصوتية ) و اي جسم امامه .

if (activateAlarm) {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Alarm will be");
lcd.setCursor(0,1);
lcd.print("activated in");
int countdown = 9; // 9 seconds count down before activating the alarm
while (countdown != 0) {
lcd.setCursor(13,1);
lcd.print(countdown);
countdown--;
tone(buzzer, 700, 100);
delay(1000);
}
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Alarm Activated!");
initialDistance = getDistance();
activateAlarm = false;
alarmActivated = true;

في الخطوة التالية يقوم جهاز استشعار الموجات فوق الصوتية بالتحقق باستمرار ما إذا كانت المسافة المقاسة حاليا أصغر من المسافة الأولية ، فهذا يدل على وجود كائن اما جهاز الاستشعار فيتم تفعيل الانذار. يتم استخدام الدالة ()tone لتفعيل الـ Buzzer و ثم استدعاء الدالة ()enterPassword .

if (alarmActivated == true){
currentDistance = getDistance() + 10;
if ( currentDistance < initialDistance) {
tone(buzzer, 1000); // Send 1KHz sound signal 
lcd.clear();
enterPassword();
}
}

()enterPassword  هذة الدالة تقوم بطباعة رسالة على الشاشة توضح بها أن جهاز الانذار مفعل , وأننا بحاجة إلى إدخال كلمة السر من أجل إيقاف الانذار. وبإستخدام الـ while Loop سيتم التحقق باستمرار ما اذا تم ضغط زر على لوحة المفاتيح ، وكل زر يتم ضغطة يتم اضافته إلى متغير tempPassword. اذا تم ادخال اكثر من 4 ارقام او رمز # يتم مسح الادخال القديم و يمكنك اعادة ادخال كلمة المرور.

void enterPassword() {
  int k=5;
  tempPassword = "";
  activated = true;
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(" *** ALARM *** ");
  lcd.setCursor(0,1);
  lcd.print("Pass>");
      while(activated) {
      keypressed = myKeypad.getKey();
      if (keypressed != NO_KEY){
        if (keypressed == '0' || keypressed == '1' || keypressed == '2' || keypressed == '3' ||
            keypressed == '4' || keypressed == '5' || keypressed == '6' || keypressed == '7' ||
            keypressed == '8' || keypressed == '9' ) {
          tempPassword += keypressed;
          lcd.setCursor(k,1);
          lcd.print("*");
          k++;
        }
      }
      if (k > 9 || keypressed == '#') {
        tempPassword = "";
        k=5;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(" *** ALARM *** ");
        lcd.setCursor(0,1);
        lcd.print("Pass>");
      }
      if ( keypressed == '*') {
        if ( tempPassword == password ) {
          activated = false;
          alarmActivated = false;
          noTone(buzzer);
          screenOffMsg = 0; 
        }
        else if (tempPassword != password) {
          lcd.setCursor(0,1);
          lcd.print("Wrong! Try Again");
          delay(2000);
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print(" *** ALARM *** ");
          lcd.setCursor(0,1);
          lcd.print("Pass>");
        }
      }    
    }
}

و من ناحية أخرى إذا تم الضغط على زر النجمة سوف يتم التحقق ما اذا كانت الكلمة المدخلة صحيحة او لا. اذا كانت الكلمة صحيحة سيتم إيقاف الانزار و سيتم الرجوع الى الشاشة الرئيسية على شاشة الـ LCD. واذا تم ادخال كلمة مرور خاطئة يتم ظهور الرسالة (!Wrong! Try Again) و سيكون لدينا محاولة لإدخال كلمة المرور الصحيحة مرة أخرى .
لتغير كلمة المرور نستخدم طريقة مماثلة . أولا سنحتاج إلى ادخال كلمة المرور الحالية لتكون قادر على تعيين كلمة المرور الجديدة.

الكود التالي هو البرنامج الكامل قم برفعه على الاردوينو:

#include  // includes the LiquidCrystal Library 
#include 
#define buzzer 8
#define trigPin 10
#define echoPin 9
long duration;
int distance, initialDistance, currentDistance, i;
int screenOffMsg =0;
String password="1234";
String tempPassword;
boolean activated = false; // State of the alarm
boolean isActivated;
boolean activateAlarm = false;
boolean alarmActivated = false;
boolean enteredPassword; // State of the entered password to stop the alarm
boolean passChangeMode = false;
boolean passChanged = false;
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keypressed;
//define the cymbols on the buttons of the keypads
char keyMap[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {A0,A1,6,7};
byte colPins[COLS] = {A5,A4,A3,A2};  //Column pinouts of the keypad
Keypad myKeypad = Keypad( makeKeymap(keyMap), rowPins, colPins, ROWS, COLS); 
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // Creates an LC object. Parameters: (rs, enable, d4, d5, d6, d7) 
void setup() { 
  lcd.begin(16,2); 
  pinMode(buzzer, OUTPUT); // Set buzzer as an output
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input
}
void loop() {
  if (activateAlarm) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Alarm will be");
    lcd.setCursor(0,1);
    lcd.print("activated in");
   
    int countdown = 9; // 9 seconds count down before activating the alarm
    while (countdown != 0) {
      lcd.setCursor(13,1);
      lcd.print(countdown);
      countdown--;
      tone(buzzer, 700, 100);
      delay(1000);
    }
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Alarm Activated!");
    initialDistance = getDistance();
    activateAlarm = false;
    alarmActivated = true;
  }
  if (alarmActivated == true){
      currentDistance = getDistance() + 10;
      if ( currentDistance < initialDistance) { tone(buzzer, 1000); // Send 1KHz sound signal lcd.clear(); enterPassword(); } } if (!alarmActivated) { if (screenOffMsg == 0 ){ lcd.clear(); lcd.setCursor(0,0); lcd.print("A - Activate"); lcd.setCursor(0,1); lcd.print("B - Change Pass"); screenOffMsg = 1; } keypressed = myKeypad.getKey(); if (keypressed =='A'){ //If A is pressed, activate the alarm tone(buzzer, 1000, 200); activateAlarm = true; } else if (keypressed =='B') { lcd.clear(); int i=1; tone(buzzer, 2000, 100); tempPassword = ""; lcd.setCursor(0,0); lcd.print("Current Password"); lcd.setCursor(0,1); lcd.print(">");
      passChangeMode = true;
      passChanged = true;   
      while(passChanged) {      
      keypressed = myKeypad.getKey();
      if (keypressed != NO_KEY){
        if (keypressed == '0' || keypressed == '1' || keypressed == '2' || keypressed == '3' ||
            keypressed == '4' || keypressed == '5' || keypressed == '6' || keypressed == '7' ||
            keypressed == '8' || keypressed == '9' ) {
         tempPassword += keypressed;
         lcd.setCursor(i,1);
         lcd.print("*");
         i++;
         tone(buzzer, 2000, 100);
        }
      }
      if (i > 5 || keypressed == '#') {
        tempPassword = "";
        i=1;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Current Password");
        lcd.setCursor(0,1);
        lcd.print(">"); 
      }
      if ( keypressed == '*') {
        i=1;
        tone(buzzer, 2000, 100);
        if (password == tempPassword) {
          tempPassword="";
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Set New Password");
          lcd.setCursor(0,1);
          lcd.print(">");
          while(passChangeMode) {
            keypressed = myKeypad.getKey();
            if (keypressed != NO_KEY){
              if (keypressed == '0' || keypressed == '1' || keypressed == '2' || keypressed == '3' ||
                  keypressed == '4' || keypressed == '5' || keypressed == '6' || keypressed == '7' ||
                  keypressed == '8' || keypressed == '9' ) {
                tempPassword += keypressed;
                lcd.setCursor(i,1);
                lcd.print("*");
                i++;
                tone(buzzer, 2000, 100);
              }
            }
            if (i > 5 || keypressed == '#') {
              tempPassword = "";
              i=1;
              tone(buzzer, 2000, 100);
              lcd.clear();
              lcd.setCursor(0,0);
              lcd.print("Set New Password");
              lcd.setCursor(0,1);
              lcd.print(">");
            }
            if ( keypressed == '*') {
              i=1;
              tone(buzzer, 2000, 100);
              password = tempPassword;
              passChangeMode = false;
              passChanged = false;
              screenOffMsg = 0;
            }            
          }
        }
      }
    }
   }
 }
}
void enterPassword() {
  int k=5;
  tempPassword = "";
  activated = true;
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(" *** ALARM *** ");
  lcd.setCursor(0,1);
  lcd.print("Pass>");
      while(activated) {
      keypressed = myKeypad.getKey();
      if (keypressed != NO_KEY){
        if (keypressed == '0' || keypressed == '1' || keypressed == '2' || keypressed == '3' ||
            keypressed == '4' || keypressed == '5' || keypressed == '6' || keypressed == '7' ||
            keypressed == '8' || keypressed == '9' ) {
          tempPassword += keypressed;
          lcd.setCursor(k,1);
          lcd.print("*");
          k++;
        }
      }
      if (k > 9 || keypressed == '#') {
        tempPassword = "";
        k=5;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(" *** ALARM *** ");
        lcd.setCursor(0,1);
        lcd.print("Pass>");
      }
      if ( keypressed == '*') {
        if ( tempPassword == password ) {
          activated = false;
          alarmActivated = false;
          noTone(buzzer);
          screenOffMsg = 0; 
        }
        else if (tempPassword != password) {
          lcd.setCursor(0,1);
          lcd.print("Wrong! Try Again");
          delay(2000);
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print(" *** ALARM *** ");
          lcd.setCursor(0,1);
          lcd.print("Pass>");
        }
      }    
    }
}
// Custom function for the Ultrasonic sensor
long getDistance(){
  //int i=10;
  
  //while( i<=10 ) {
  // Clears the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);
  // Calculating the distance
  distance = duration*0.034/2;
  //sumDistance += distance;
  //}
  //int averageDistance= sumDistance/10;
  return distance;
}



مشروع الرادار الالكتروني

سنقوم في هذا المشروع بعمل نظام بسيط لرصد إحداثيات موقع الأجسام عن طريق صناعة رادار رقمي بإستخدام جهاز مستشعر الموجات فوق الصوتية HC-SR04، ولوحة الأردوينو كمتحكم للنظام . ويتم استخدام جهاز الحاسوب لعرض الواجهة الرسومية.

arduino-radar-project

القطع المطلوبة:

الأدوات التي تحتاجها لهذا المشروع :

 مستشعر الموجات فوق الصوتية (Ultrasonic sensor HC- SR04).

tower pro sg90

محرك سيرفو ( Servo Motor).

arduino uno r3

Arduino Uno R3

Half-size Breadboard

 لوح تجارب حجم متوسط (Half size breadboard)

Jumper Wires Male/Male

 اسلاك توصيل ذكر/ذكر (Jumper Wires Male Male)

Female-Male Jumper Wires

 اسلاك توصيل أنثى/ذكر (Jumper Wires Female/male)

تصميم لوح التجارب

يقوم الاردوينو بالتحكم بزاوية دوران محرك السيرفو(Servo motor) ، لذلك يتم تثبيت حساس الموجات فوق الصوتية على المحرك ليتم قياس المسافة عند تلك الزاوية.

قم بتوصيل الدائرة الكهربائية على لوحة التجارب كما هو موضح بالصورة.

arduino-radar-project

يتحتوي مستشعر الموجات فوق الصوتية على اربع منافذ، منفذ الطاقة  Vcc و منفذ GND و منفذ Trig الذي يتم من خلاله ارسال النبضة, و منفذ Echo الذي يتم من خلاله استقبال صدى النبضة المرسلة من قبل Trig.
يتم توصيل مستشعر الموجات فوق الصوتية بالاردوينو كالتالي:

حساس الموجات فوق الصوتية لوحة الاردوينو
Vcc 5v
GND GND
Trig Pin 10
Echo Pin 11

و توصيل محرك السيرفو كالتالي:

لوحة الاردوينو محرك السيرفو
5v السلك الأحمر
GND  السلك الأسود/البني
 Pin 9  السلك الاصفر/البرتقالي

عندما يقوم الاردوينو بتحريك محرك السيرفو بدرجات معينة (و بالتالي يتحرك حساس الموجات الفوق صوتية)  يتم حساب المسافة عند تلك الزاوية. سيتم ارسال هذة البيانات إلى جهاز الحاسوب عبر المنفذ التسلسلي (Serial port)، و بالتالي يقوم الحاسوب باستخدام برنامج لرسم الخريطة البيانية اعتمادا على هذة القيم .

واجهة المستخدم:

Processing IDE، هي بيئة تطوير متكاملة تم بناؤها من أجل الأشخاص المهتمين بالتصميم المرئي والفنون الإلكترونية الأخرى. حيث تمكنك من برمجة الرسوم و الصور المتحركة و تقوم بتحديث الرسومات المعروضه على شاشة الكمبيوتر و الاستجابة لتفاعل المستخدم.

arduino-radar-project

الان نحن بحتاج لعمل برنامج يتم رفعه على الاردوينو الذي من شأنه تمكين التفاعل بين    Arduino IDE  و  IDE Processing.

*يمكنك تنزيل برنامج Processing من هنـا.

الكود البرمجي للأردوينو

قم برفع البرنامج التالي على الاردوينو:

#include <Servo.h>

Servo leftRightServo; // set a variable to map the servo
int leftRightPos = 0; // set a variable to store the servo position
const int numReadings = 10; // set a variable for the number of readings to take
int index = 0; // the index of the current reading
int total = 0; // the total of all readings
int average = 0; // the average
int echoPin = 11; // the SRF05's echo pin
int initPin = 10; // the SRF05's init pin
unsigned long pulseTime = 0; // variable for reading the pulse
unsigned long distance = 0; // variable for storing distance

/* setup the pins, servo and serial port */
void setup() {
  leftRightServo.attach(9); 
// make the init pin an output:
  pinMode(initPin, OUTPUT); 
// make the echo pin an input:
  pinMode(echoPin, INPUT); 
// initialize the serial port:
  Serial.begin(9600);
}

void loop() {
  for(leftRightPos = 0; leftRightPos < 180; leftRightPos++) { // going left to right.
    leftRightServo.write(leftRightPos);
    average=Avg();
    Serial.print("X"); // print leading X to mark the following value as degrees
    Serial.print(leftRightPos); // current servo position
    Serial.print("V"); // preceeding character to separate values
    Serial.println(average); // average of sensor readings
  }
/*
start going right to left after we got to 180 degrees
*/
  for(leftRightPos = 180; leftRightPos > 0; leftRightPos--) { // going right to left
    leftRightServo.write(leftRightPos);
    average=Avg();
    Serial.print("X");
    Serial.print(leftRightPos);
    Serial.print("V");
    Serial.println(average);
  }
}

long Avg()
{
  for (index = 0; index<=numReadings;index++) {
  digitalWrite(initPin, LOW);
  delayMicroseconds(50);
  digitalWrite(initPin, HIGH);
  delayMicroseconds(50);
  digitalWrite(initPin, LOW);
  pulseTime = pulseIn(echoPin, HIGH);
  distance = pulseTime/58;
  total = total + distance;
  delay(10);
}
average = total/numReadings; // create average reading

if (index >= numReadings) { // reset the counts when at the last item of the array
index = 0;
total = 0;
}
return average;
}

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

يقوم محرك السيرفو بالدوران من 0 إلى 180 درجة  و العكس ، ومن خلاله يقوم مستشعر الموجات فوق الصوتية بالمسح الأرضي و الجوي لما يجري داخل منطقة محدودة وهي ابعد ما يستطيع المستشعر التعامل معه.

دالة for  تقوم بتغير قيمة زاوية الدوران للمحرك :

for(leftRightPos = 0; leftRightPos < 180; leftRightPos++) {
}
for(leftRightPos = 180; leftRightPos > 0; leftRightPos--){
}

تقوم الدالة ()AVG اعتمادا على القيم التي يتلقاها حساس الموجات فوق الصوتية بحساب المسافة التي يبعد عنها الجسم عن الحساس :

long Avg()
{
  for (index = 0; index<=numReadings;index++) {
  digitalWrite(initPin, LOW);
  delayMicroseconds(50);
  digitalWrite(initPin, HIGH);
  delayMicroseconds(50);
  digitalWrite(initPin, LOW);
  pulseTime = pulseIn(echoPin, HIGH);
  distance = pulseTime/58;
  total = total + distance;
  delay(10);
}
average = total/numReadings; // create average reading

if (index >= numReadings) { // reset the counts when at the last item of the array
index = 0;
total = 0;
}
return average;
}

* يمكنك الاطلاع على مشروع نظام الحسّاسات لاصطفاف السيارة لفهم الكود المتعلق بحساس الموجات فوق الصوتية و حساب المسافة , و الدرس الخامس عشر للاطلاع على شرح الكود المتعلق بمحرك السيرفو.

يتم ارسال قيمة المسافة و الزاوية عند هذة القيمة إلى الحاسوب فيقوم البرنامج  (Processing IDE)  برسم خطوط الرادار باستعمال الدوال المثلثة طبقا للمعلومات المستقبله.

Serial.print("X"); 
Serial.print(leftRightPos);
Serial.print("V"); 
Serial.println(average);

برمجة الواجهة الرسومية

 الحاسوب بعد ارسال قيم الزاوية و المسافة من الاردوينو الى (processing IDE) ، يتم استقبالها بإستخدام دالة ()SerialEvent  .
تقوم ()SerialEvent بقراءة البيانات من المنفذ التسلسلي (serial port) ثم نقوم بوضع قيم الزاوية و المسافة في متغيرات (degree, value). هذة المتغيرات سيتم استخدامها لرسم الرادار، و الخطوط، و الكشف عن الأجسام ، وتغير النصوص .

لعرض البيانات على الشاشة يتم انشاء Arrays  لتخزين القيم الحديثة على newValue Array و عمل تحديث للقيم القديمة على oldValue Array . لأن الموقع اتباعا لحركة  محرك السيرفو يتغير بإستمرار ، فسنفقد البيانات القديمة التي سيتم عرضها على الشاشة.

int[] newValue = new int[181];
int[] oldValue = new int[181];
رادار

لرسم الرادار سيتم كتابة الداله ()drawRadar التي تتكون من دوال ()arc و ()line.

void drawRadar() {

 for (int i = 0; i <=6; i++){
  noFill();
  strokeWeight(1);
  stroke(0, 255-(30*i), 0);
  arc(radius, radius, (100*i), (100*i),PI,TWO_PI); 
  fill(250, 103, 0);
  noStroke();
  text(Integer.toString(radarDist+50), 380, (305-radarDist), 50, 50);
  radarDist+=50;
 }

 radarDist = 0; 
 for (int i = 0; i <= 6; i++) {
   strokeWeight(1);
   stroke(0, 55, 0);
   line(radius, radius, radius + cos(radians(180+(30*i)))*w, radius + sin(radians(180+(30*i)))*w);
   fill(153, 153, 153);
   noStroke();
   if (180+(30*i) >= 300) {
    text(Integer.toString(180+(30*i)), (radius+10) + cos(radians(180+(30*i)))*(w+10), (radius+10) + sin(radians(180+(30*i)))*(w+10), 25,50);
   } 
  else {
   text(Integer.toString(180+(30*i)), radius + cos(radians(180+(30*i)))*w, radius + sin(radians(180+(30*i)))*w, 60,40);
  }
 }
}
رادار

ليتم عمل مسح للرادار يتم رسم الخط الذي يتحرك جنب إلى جنب اتباعا لحركة محرك السيرفو بإستخدام الدالة  ()setupSweep  .

تستخدم الدالة  ()setupSweep الدالة ()line التي تستخدم المتغير degree لإعادة رسم الخط لكل درجة.

void setupSweep(){
 strokeWeight(7); 
 if (motion == 0) { 
 for (int i = 0; i <= 20; i++) { 
 stroke(0, (10*i), 0); 
 line(radius, radius, radius + cos(radians(degree+(180+i)))*w, radius + sin(radians(degree+(180+i)))*w); 
 }
 } else { // if going right to left
 for (int i = 20; i >= 0; i--) { 
 stroke(0,200-(10*i), 0);
 line(radius, radius, radius + cos(radians(degree+(180+i)))*w, radius + sin(radians(degree+(180+i)))*w);
 }
 } 
}

لإعداد تحديث الأشكال يتم عمل الدالة ()SetupShapes . سنقوم بإستخدام الدالة  For loop للتحرك بين القيم التي تم تخزينها بالـ (Arrays  (newValue, oldValue

void SetupShapes(){
  noStroke();                           
  
  fill(0,50,0);                         
  beginShape();                         
  for (int i = 0; i < 180; i++) {     
  x = radius + cos(radians((180+i)))*((oldValue[i])); 
  y = radius + sin(radians((180+i)))*((oldValue[i])); 
  vertex(x, y);                     
  }
  endShape();                           
  
  fill(0,110,0);
  beginShape();
  for (int i = 0; i < 180; i++) {
  x = radius + cos(radians((180+i)))*(newValue[i]);
  y = radius + sin(radians((180+i)))*(newValue[i]);
  vertex(x, y);
  }
  endShape();
  
  fill(0,170,0);
  beginShape();
  for (int i = 0; i < 180; i++) {
  x = radius + cos(radians((180+i)))*((newValue[i]+oldValue[i])/2); 
  y = radius + sin(radians((180+i)))*((newValue[i]+oldValue[i])/2);
  vertex(x, y);
  }
  endShape();
}

لرسم موقع الاجسام التي تم رصدها  ، نقوم بعمل الدالة ()drawObject .التي تستخدم المسافة الملتقطة من مستشعر الموجات فوق الصوتية و بالاشتراك مع الزاوية لرسم الجسم على الرادار.

void drawObject() {
  if (firstRun >= 360) {
  stroke(250,103,0);
  strokeWeight(1);
  noFill();
  for (int i = 0; i < 180; i++) { if (oldValue[i] - newValue[i] > 35 || newValue[i] - oldValue[i] > 35) {
  x = radius + cos(radians((180+i)))*(newValue[i]);
  y = radius + sin(radians((180+i)))*(newValue[i]);
  ellipse(x, y, 10, 10); 
  }
  }
  } 
}

وللإطلاع على القيم التي تم استقبالها و النصوص تم إنشاء الدالة ()drawText  .

رادار

يمكنك تنزيل كود  الـ (Processing) المتعلق بالواجهة الرسومية للرادار من هنـا.




التحكم بإضاءة RGB LED من خلال واجهة رسومية عبر Matlab

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

في هذا المشروع ستتعلم كيفية انشاء واجهة المستخدم الرسومية بإستخدام الماتلاب ، للتحكم في RGB LED المتصل بالاردوينو.

matlab-gui

الماتلاب Matlab

الماتلاب أنسب للمشاريع المعقدة حيث يسمح بالتلاعب حسابيا بالمصفوفات، وبالرسم البياني للتوابع الرياضية، وبتنفيذ الخوارزميات المختلفة، وإنشاء واجهات المستخدم الرسومية، ومعالجة الصور فهي تعالج تخصص تحليل الصور وكتابة خوارزميات لترتيب البكسلات. فهو أكثر فاعلية , و يمكن تنفيذ أوامر الإدخال و الإخراج لحظياً دون الحاجة للبرمجة، الترجمة، التحميل و التنفيذ كل مرة.

سنقوم بإنشاء واجهة للمستخدم باستخدام برنامج الماتلاب (Matlab) للتحكم بالاجهزة المرتبطة بالاردوينو, ليتم ارسال الأوامر من جهاز الحاسوب (Matlab) للأردوينو عبر المنفذ التسلسلي (Serial port).

matlab-gui

تجهيز الأردوينو و إعداد الماتلاب:
1- قم بتحميل برنامج الماتلاب من الرابط هنـا.
2-  قم بتحميل حزمة الدعم للأردوينو من الرابط هنـا : لقراءة, وكتابة, وتحليل بيانات الأجهزة المربوطة مع الاردوينو .

القطع المطلوبة:

الأدوات التي تحتاجها لهذا المشروع :

Diffused RGB 5mm LED

RGB 5mm LED

220 Ω resistor

مقاومة 220 اوم

small size breadboard 170 colors

  لوح تجارب صغير (small size breadboard)

arduino uno r3

Arduino Uno R3

Jumper Wires Male/Male

 اسلاك توصيل ذكر/ذكر  (Jumper Wires Male Male)

 

تصميم لوحة التجارب:

قم بتوصيل الدائرة الكهربائية على لوحة التجارب كما هو موضح بالصورة:

matlab-gui

يمكنك العودة للـدرس الرابع للاطلاع على شرح و تفاصيل اكثر حول RGB LED .

إنشاء الواجهة الرسومية

واجهات المستخدم الرسومية GUI’s في الماتلاب يتم إنشاؤها بواسطة أداة تدعى :
GUIDE : Graphical User Interface Development Environment
هذه الأداة تسمح للمبرمج أن يقوم بتحرير الواجهة الرسومية GUI ،وتنسيقها وإضافة العناصر التي يريدها إلى الواجهة،كما يمكنه  تغيير الخصائص لكل كائن في الواجهة: الإسم،اللون،الحجم،نوع الخط,وغيرها من الخصائص .

على شاشة الاوامر للماتلاب قم بكتابة الأمر : guide

matlab-gui

 

matlab-gui

قم بالضغط على (Blank GUI(Default  الموجودة في علامة التويب (Create New GUI) كما هو مبين بالصورة اعلاه.
ثم  OK ليظهر محرر التخطيط الرسومي للواجهات.

matlab-gui

 

سنقوم بإنشاء ثلاثة Sliders لتتحكم بـ RGB LED عن طريق الواجهة الرسومية.
قم بالضغط على  Slider, ثم قم برسم الشكل على نافذة العمل , كما هو مبين بالشكل التالي :

matlab-gui

انقر نقرا مزدوجا على كلSlider  ليفتح اطار جديد يمكن من خلاله معرفة الخصائص  للعناصر المضافة و تغيرها  مثل تغيير الخلفية.
قم بتحديد القيمة الأكبر و الاقل لكل slider كما هو موضح بالشكل التالي

matlab-gui

في الاردوينو, الجهد على المداخل التناظرية يكون محدود بين 0v-5v .

يمكنك اضافة نص من خلال Static text، و تغير الخصائص المتعلقة بالخط ,و تغير لون خلفية الواجهة.

matlab-gui

قم بحفظ save الشكل  figure كملف،عندما تقوم بحفظه سيتم تقائيا توليد ملفين لهما نفس الإسم لكن ذو لاحقة مختلفة.
Fig file: يحتوي على الواجهة الرسومية  GUI التي قمت بإنشائها.
M-File : يحتوي code التعليمات البرمجية التي تتحكم بتنفيذ وسلوك الواجهة.

الكود البرمجي للواجهة

بعد بحفظ الواجهة الرسومية التي بنيتها بإستخدام الأداة GUIDE ،GUIDE سيقوم بتوليد الكود البرمجي لتعمل الواجهة، يتضمن التوابع الهيكلية التي يمكن للمبرمج أن يُعدّل عليها ويتحكم بتنفيذ وسلوك الواجهة الرسومية.

نقوم بفتح والتعديل على الكود البرمجي للواجهة (rgb.m) كما يلي :

function varargout = rgb(varargin)

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @rgb_OpeningFcn, ...
                   'gui_OutputFcn',  @rgb_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before rgb is made visible.
function rgb_OpeningFcn(hObject, eventdata, handles, varargin)
% Choose default command line output for rgb
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% --- Outputs from this function are returned to the command line.
function varargout = rgb_OutputFcn(hObject, eventdata, handles) 
varargout{1} = handles.output;
clear all;
global a;
a=arduino;


% --- Executes on slider movement.
function slider1_Callback(hObject, eventdata, handles)
b=get(hObject,'Value');
global a;
writePWMVoltage( a , 'D9' , 5-b );

% --- Executes during object creation, after setting all properties.
function slider1_CreateFcn(hObject, eventdata, handles)
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end


% --- Executes on slider movement.
function slider2_Callback(hObject, eventdata, handles)
c=get(hObject,'Value');
global a;
writePWMVoltage( a , 'D10' , 5-c );

% --- Executes during object creation, after setting all properties.
function slider2_CreateFcn(hObject, eventdata, handles)
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end


% --- Executes on slider movement.
function slider3_Callback(hObject, eventdata, handles)
d=get(hObject,'Value');
global a;
writePWMVoltage( a , 'D11' , 5-d );

function slider3_CreateFcn(hObject, eventdata, handles)

if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end

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

  إنشاء الاتصال

لإنشاء الاتصال بين الماتلاب ولوحة الاردوينو :

a = arduino;

او إذا كان لديك أكثر من لوحة ارديونو متصلة قم بتحديد المنفذ و نوع اللوحة كما يلي :

a = arduino('COM5', 'uno');

الكتابة على المنافذ :

لتعيين القيمة المتغيرة لكل منفذ( PWM pin) نستخدم الامر:

writePWMDutyCycle(a, pin, dutyCycle);

في هذا المشروع يتم تغير القيمة لكل منفذ اعتمادا على حركة ال Slider ، فتم اضافة الكود التالي لكل Slider كما يلي :

b=get(hObject,'Value');
global a;
writePWMVoltage( a , 'Pin' , 5-b );

يتم تغير الـ Pin لكل Slider اعتمادا على المدخل المرتبط به على لوحة الاردوينو

قم بحفظ و تشغيل الملف للتحكم بالـ RGB LED .

*يمكنك تنزيل واجهة المستخدم و الكود لهذا المشروع من هنـا.




التحكم التلقائي بالضوء

مقدمة

في هذا الدرس ستتعلم برمجة الأردوينو لتتمكن من التحكم التلقائي بالضوء بحيث تعمل مصابيح المحيط عند تواجد أشخاص ضمن المحيط وذلك عن طريق استخدام حساس الحركة (PIR Sensor) للكشف عن أي حركة في المحيط، وسيتم تشغيل المصابيح باستخدام المرحل (Relay) الذي يتحكم بمرور التيار الكهربائي.

التحكم التلقائي بالضوء

المواد والأدوات

المرحل (Relay)

X1 المرحل (5V Relay Module)

pir motion sensor - حساس الحركة

X1 حساس الحركة  (pir motion sensor)

small size breadboard 170 colors

X1  لوح تجارب صغير (small size breadboard)

اردوينو

X1أردوينو أونو

سلك اردوينو
X1 سلك الأردوينو
Female-Male Jumper Wires

 اسلاك توصيل أنثى/ذكر (Jumper Wires Female/male)

Jumper Wires Male/Male

 اسلاك توصيل ذكر/ذكر (Jumper Wires Male Male)

automatic-room-lights

Light Bulb Socket (غير متوفر بالمتجر)

لمبة 12 فولت

X1 لمبة 12 فولت (غير متوفر بالمتجر)*

X1 محول طاقة 12 فولت**

X1 وصلة تيار ثابت انثى

 

*يمكن استخدام 220 فولت (نحن لا نفضل ذلك)
** عند استخدام 220 فولت لن تحتاج لهذا المنتج

في المشاريع او التطبيقات العملية قد نود أن نتحكم بأحمال ذات قدرات عالية High Power باستخدام المتحكم الاصغر Microcontroller . فمثلاً أن نتحكم بإنارة مصباح يعمل على تيار متردد (AC) او تشغيل محركات كهربائية حثية مثل مضخات المياه.

من خلال الاردوينو ,لا يمكننا تشغيل اي حمل ذو استهلاك كبير للطاقة (220v,110v) لأن اقصى جهد يمكن توليده من الاردوينو هو 5 فولت فقط. احد الاجهزة التي لا يمكن للاكترونيات الاستغناء عنها والتي تلعب دور كبير في التحكم بالدرات الكهربائية هو المرحٌل -الريلي-(Relay) .

المرحٌلRelay

الوظيفة الأولية للمرحل هي فصل دوائر التحكم عن دوائر القدرة، لقيادة تيار مرتفع انطلاقا من إشارة تحكم ضعيفة نسبيا. وبالتالي عن طريق تطبيق تيار صغير يمكننا تشغيل المرحل للسماح بتدفق التيار الأكبر.

فالمرحل يعمل كعنصر وصل/فصل (ON-OFF switch) لتوصيل التيار الكهربائي للأحمال او فصلها.

automatic-room-lights

في هذا المشروع ,سنقوم باستخدام HL-52S  ريلي , يحتوي على ثلاث اقطاب يتم وصلها بمصدر الطاقة ذات الفولتية العالية. القطب الاوسط  يشير الحرف C الى كلمة Common  والتي تعني مشترك, يشير ان هذا القطب اما ان يكون موصولاً بالقطب (NC) تشير الى Normally Closed  والتي تعني مغلق عادةً او (NO) تشير الى  Normally Open والتي تعني مفتوح عادةً ،فلذلك سمي بالقطب المشترك.

automatic-room-lights

وعلى الجانب الآخر لدينا مجموعتين من الدبابيس، اول مجموعة تحتوي على 4 دبابيس، دبوس GND الأرض و دبوس الـ Vcc لتزويد الريلي بالطاقة ومدخلين IN1 ,IN2 . والمجموعة الثانية عبارة عن 3 دبابيس، Jumper  بين الـ JD-Vccو VCC  و دبوس الارض GND

automatic-room-lights

تحذير: يجب وضع الـ Relay على لوح عازل وعدم لمسه من اسفل اللوح الملحوم عليه لأنها قد تكون موصله للتيار الكهربائي بعد وصله بالجهد العالي.

 

انتبه:

قبل ان نبدأ بتوصيل الدائرة، ينبغي تحذيرك ، أن هذا المشروع يتطلب توصيل تيار متردد (AC – 220V) ،هذا التيار خطير و يجب التعامل معه بحذر شديد. لا تقم بالتوصيل مالم تكن على دراية كاملة بما تفعل او اطلب مساعدة من شخص ذو خبرة في هذا المجال.
اذا استخدم بطريقة غير صحيحة  او غير سليمة يمكن ان يؤدي إلى إصابات خطيرة أو وفاة. لذلك يجب الحذر جدا من ما تقومون به لأننا لا نتحمل اي مسؤولية من اي اجراءات تقوم به.

automatic-room-lights

تصميم لوحة التجارب:

قم بتوصيل الدائرة الكهربائية على لوحة التجارب كما هو موضح بالصورة:

قم بتوصيل سلك الطاقة الموجبة الخاص بالريلي بمنفذ ال 5v على لوحة التجارب،  وسلك الطاقة السالبة بمنفذ ال Gnd المتواجد على لوحة التجارب. قم بتوصيل سلك الاشارة (IN1) بمنفذ رقم 10 على لوحة الاردوينو.
يمكنك العودة الى الدرس الثامن عشر لمعرفة  طريقة التوصيل المتعلق في مستشعر الحركة (PIR Sensor) ،  قم بتوصيل سلك الاشارة  (Signal) للمستشعر بمنفذ رقم 9 على لوحة الاردوينو.

اذا كانت الإضاءة 12 فولت استخدم المحول اذا كانت الاضاءة 220 يمكن توصله مباشرة بدون محول

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

البرمجة:

يقوم الاردوينو بإنتظار إشارة من مستشعر الحركةMotion PIR sensor ، وفور حصولة على اشارة من المسشتعر تشير لوجود تحرك، يقوم بتفعيل الـ Relay  لفتح الإضاءة.

قم بتوصيل الاردوينو بالكمبيوتر، وقم بتحميل البرمجة التالي على الاردوينو:

int Relay=10;
int inputPin = 9; // choose the input pin (for PIR sensor)
int pirState = LOW; // we start, assuming no motion detected
int val = 0; // variable for reading the pin status
 
void setup() {
 pinMode(inputPin, INPUT); // declare sensor as input
 pinMode(Relay,OUTPUT);
 
 Serial.begin(9600);
}
 
void loop(){
 val = digitalRead(inputPin); // read input value
 // Serial.println(val);
 if (val == HIGH) { 
 digitalWrite(Relay,LOW); 
 Serial.println(val);// check if the input is HIGH
 if (pirState == LOW) {
 Serial.println("Motion detected!");
 pirState = HIGH;
 }
 delay(2000);
 } else {
 digitalWrite(Relay,HIGH);
 if (pirState == HIGH){
 Serial.println("Motion ended!");
 pirState = LOW;
 }
 delay(2000);
 }
}

لمحة سريعة عن الكود:

لفتح و اغلاق انارة AC يجب تفعيل الـ Relayعن طريق مدخل IN1 . يعمل مدخل IN1 في الـ Relay عكسيا، فيتم تفعيل المرحل (Relay) عند ادخال قيمة (LOW) الى مدخل (IN1)( حسب طريقة صنع الدارة على اللوحة الصغيرة التي يلحم عليها الريلي) .

 digitalWrite(Relay,LOW);

يمكنك العودة الى الدرس الثامن عشر لمعرفة شرح الكود المتعلق بحساس الحركة (Motion Sensor).