تعلم برمجة الأردوينو الأساسية - البرنامج التعليمي للقادمين الجدد

جرب أداة القضاء على المشاكل





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

مقدمة

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



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

سنعمل في هذا البرنامج التعليمي مع لوحة Arduino Uno لتعلم واختبار البرامج. من أجل اختبار ودمج تجميع الأجهزة ، سوف نستخدم لوح توصيل.



الآن دعنا نتحرك بسرعة ونتعلم كيفية البدء في برمجة Arduino.

1.2 تثبيت البرنامج (Windows)

لهذا ستحتاج إلى الوصول إلى الإنترنت ، والذي من الواضح أنك ستحصل عليه في جهاز الكمبيوتر الخاص بك. يرجى الانتقال إلى الرابط التالي وتنزيل برنامج IDE:

ملف Windows ZIP للتثبيت غير المسؤول

بعد التنزيل ، ستجد رمز إعداد Arduino في مجلد التنزيل ، والذي سيبدو كما يلي:

اردوينو تحميل أيقونة

بمجرد الحصول على هذا ، يمكنك ببساطة النقر فوقه نقرًا مزدوجًا وتثبيت Arduino بيئة التطوير المتكاملة (IDE) في جهاز الكمبيوتر الخاص بك. يمكن تصور العملية الكاملة في الفيديو التالي:

https://youtu.be/x7AMn1paCeU

1.4 بدءًا من دائرتنا الأولى

قبل أن نبدأ في تعلم تقنيات البرمجة الفعلية ، سيكون من المفيد لأي مبتدئ البدء بمكون أساسي مثل LED ، وفهم كيفية توصيله بـ Arduino.

كما نعلم ، فإن الصمام الثنائي الباعث للضوء هو الصمام الثنائي الباعث للضوء الذي له قطبية ولن يضيء إذا لم يكن متصلاً بأعمدة الإمداد الصحيحة.

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

كقاعدة عامة ، فإن 330 أوم 1/4 واط مثالية تمامًا لكل ارتفاع 5 فولت في مدخلات الإمداد للحد من التيار إلى المستوى الآمن المطلوب. لذلك ، بالنسبة إلى 5 فولت ، قد يكون 330 أوم ، وقد يكون 680 أوم بالنسبة إلى 10 فولت وما إلى ذلك.

استخدام اللوح للتجميع

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

يمكن رؤية إعداد اتصال LED الأساسي أدناه:

ال اي دي مع اردوينو

يمكنك أن ترى 3 مكونات أساسية أعلاه:

  1. 5 مم ، 20 مللي أمبير LED
  2. مقاومة 330 أوم 1/4 واط
  3. ان لوحة اردوينو

فقط قم بتجميع النظام حسب الرسم التخطيطي.

بعد ذلك ، قم بتوصيل 5V من الكمبيوتر USB إلى Arduino. بمجرد القيام بذلك ، سترى إضاءة LED.

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

1.5 التحكم في LED مع Arduino

الآن سوف نتعلم كيفية التحكم في LED باستخدام برنامج Arduino.

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

يمكن فهم الوظيفة على أنها سلسلة من عبارات البرمجة التي يمكن تعيين اسم لها ، كما هو موضح أدناه:

  1. يثبت() يتم استدعاء هذا أو تنفيذه أثناء بدء البرنامج.
  2. عقدة() يتم استدعاء هذا أو تنفيذه بشكل متكرر خلال فترة تشغيل Arduino بأكملها.

لذلك ، على الرغم من أنه قد لا يحتوي على وظائف عملية ، إلا أنه من الناحية الفنية يمكن كتابة أقصر برنامج شرعي من Arduino على النحو التالي:

أبسط برنامج

void setup()
{
}
void loop()
{
}

ربما لاحظت أنه في العديد من لغات البرمجة ، يبدأ النظام بإظهار طباعة بسيطة ، 'مرحبًا ، يا عالم' على شاشة العرض

المكافئ الإلكتروني لهذه العبارة في تفسير الميكروكونترولر هو وميض LED ON و OFF.

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

سنحاول تنفيذ وفهم الإجراء من خلال جزء الكود التالي:

قائمة 1.2: led1 / led1.pde

const int kPinLed = 13
void setup()
{
pinMode(kPinLed, OUTPUT)
}
void loop()
{
digitalWrite(kPinLed, HIGH)
delay(500)
digitalWrite(kPinLed, LOW)
delay(500)
}

حسنًا ، دعنا الآن نفهم معنى كل سطر من الكود وكيف يعمل لتنفيذ الوظيفة:

const int kPinLed = 13

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

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

void setup()
{
pinMode(kPinLed, OUTPUT)
}

يقوم هذا الرمز بتكوين الدبوس المحدد الذي يتم توصيل LED الخاص بنا به. بمعنى آخر ، يخبر الكود Arduino بالتحكم في جانب 'الكتابة' على هذا الدبوس ، بدلاً من 'قراءته'.

void loop()
{
digitalWrite(kPinLed, HIGH)
delay(500)
digitalWrite(kPinLed, LOW)
delay(500)
}

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

هنا ، المصطلح HIGH يعني ببساطة الحصول على + 5V على الدبوس المعني من Arduino. يشير المصطلح التكميلي LOW ببساطة إلى صفر أو 0 فولت على الدبوس المحدد.

بعد ذلك ، نسمي delay() وظيفتها هي إنشاء تأخير خلال مللي ثانية (1/1000 من الثانية). منذ إدخال الرقم 500 ، سيكون التأخير المنفذ لمدة 1/2 ثانية.

بمجرد انقضاء 1/2 ثانية ، يتم تنفيذ السطر التالي الذي يقوم بإيقاف تشغيل مؤشر LED مع المصطلح LOW على نفس الدبوس.

يولد السطر التالي مرة أخرى تأخيرًا قدره 1/2 ثانية ، من أجل السماح لمصباح LED بالبقاء مغلقًا لمدة 1/2 ثانية.

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

قبل الانتقال إلى المستوى التالي ، أوصيك ببرمجة الكود أعلاه والتحقق مما إذا كنت قادرًا على تنفيذ تسلسل LED ON / OF بشكل صحيح أم لا.

نظرًا لأن مؤشر LED الافتراضي في Arduino متصل بالدبوس رقم 13 ، فيجب أن يستجيب على الفور للبرنامج أعلاه ويبدأ في الوميض. ومع ذلك ، إذا وجدت أن مؤشر LED الخارجي الخاص بك لا يومض ، فقد يكون هناك خطأ في الاتصال بمؤشر LED الخاص بك ، يمكنك محاولة عكس قطبية مؤشر LED الخاص بك ونأمل أن تراه يومض أيضًا.

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

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

1.7 التعليقات

تم كتابة سطور الرموز التي فهمناها أعلاه خصيصًا لبرنامج الكمبيوتر.

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

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

تمت كتابة لغة هذه التعليقات بصيغتين:

  1. نمط كتلة التعليق ، حيث يتم وضع وصف التعليق تحت رمز البداية / * ورمز النهاية * /
  2. لا يلزم تقييد هذا في سطر واحد ، بل يمكن تمديده إلى الأسطر التالية التالية اعتمادًا على طول التعليق أو الوصف ، كما هو موضح في المثال التالي:

/ * هذا تعليق * /

/* هكذا هذا */

/* و
* هذه
* مثل
* حسنا */

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

// هذا تعليق ستتجاهله أجهزة الكمبيوتر.

فيما يلي مثال للرجوع إليه:

/*
* Program Name: Blink
* Author: Alan Smith
* Description:
* Turns an LED on for one half second, then off for one half second repeatedly.
*/

/* Pin Definitions */
const int kPinLed = 13
/*
* Function Name: setup
* Purpose: Run once when the system powers up.
*/
void setup()
{
pinMode(kPinLed, OUTPUT)
}
/*
* Function name: loop
* Purpose: Runs over and over again, as long as the Arduino has power
*/
void loop()
{
digitalWrite(kPinLed, HIGH)
delay(500)
digitalWrite(kPinLed, LOW)
delay(500)
}

1.8 استكشاف الأخطاء وإصلاحها

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

  1. ستكون لغة برنامجك حساسة لحالة الأحرف. على سبيل المثال التعبير myVar لا يمكن كتابتها كـ MyVar.
  2. جميع أنواع المساحات البيضاء التي قد يتم تنفيذها عن طريق الكتابة على لوحة المفاتيح ، يتم تقديمها في النهاية كمساحة واحدة ، وتكون مرئية أو مفهومة لك أنت فقط ، ولن يأخذ الكمبيوتر ذلك في الاعتبار. ببساطة ، لن يكون للمساحات الخالية من أي نوع أي تأثير على نتائج التعليمات البرمجية.
  3. يجب إرفاق كل كتلة من الكود بأقواس متعرجة على اليسار واليمين ، '{' و '}'
  4. يجب عدم فصل أرقام الأرقام بفاصلات. على سبيل المثال ، قد لا تتم كتابة 1000 كـ 1،000.
  5. يجب أن ينتهي كل سطر رمز محاط بين الأقواس المتعرجة بفاصلة منقوطة

إنشاء تسلسل إضاءة LED مثير للاهتمام باستخدام Arduino

في الفصل السابق ، تعلمنا كيفية وميض LED ON / OFF باستمرار بمعدل تأخير ثابت.

الآن سوف نتعلم كيف يمكن تنفيذ أنماط تأخير مختلفة على نفس LED عن طريق ترقية كود البرنامج.

لن نستخدم مؤشر LED خارجيًا ، بل نستخدم مؤشر LED الافتراضي المدمج في لوحة Arduino عند الطرف رقم 13. يمكنك العثور على SMD LED الصغير هذا خلف موصل USB مباشرة.

2.2 فهم عبارات IF

في هذا القسم سوف نتعلم كيف تمكننا هياكل التحكم من تشغيل الرموز الفردية ، وأحيانًا بشكل متكرر ، كما هو مطلوب.

البيان لو يصبح هيكل التحكم الأول. يوضح التنفيذ التالي كيفية استخدامه:

const int kPinLed = 13
void setup()
{
pinMode(kPinLed, OUTPUT)
}
int delayTime = 1000
void loop()
{
delayTime = delayTime - 100
if(delayTime <= 0){ // If the delay time is zero or less, reset it.
delayTime = 1000
}
digitalWrite(kPinLed, HIGH)
delay(delayTime)
digitalWrite(kPinLed, LOW)
delay(delayTime)
}

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

الرموز بين السطر الأول والسابع مشابهة تمامًا لبرنامجنا الأولي.

التعديل الأول يحدث بالفعل في السطر الثامن.

int delayTime = 1000

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

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

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

بدلاً من ذلك ، المتغيرات التي من المفترض أن تكون خارج الأقواس المتعرجة ، مثل المتغيرات التي نناقشها الآن ، يتم التعرف عليها على أنها 'عالمية' ، ويمكن تنفيذها في أي مكان داخل رمز البرنامج.

للمضي قدمًا ، يمكنك أن ترى أن الرموز بين السطر 9 و 11 تشبه أيضًا البرنامج الأول ، ومع ذلك تبدأ الأمور في أن تصبح مثيرة للاهتمام بعد السطر 11. دعونا نرى كيف!

delayTime = delayTime - 100

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

يتم خصم المعنى 100 من قيمته الأولية البالغة 1000 ، مما يمنحه قيمة جديدة قدرها 900.

من خلال الصورة التالية سنحاول فهم عدد قليل من عوامل الرياضيات المستخدمة في لغة Arduino.

رموز مشغل الرياضيات اردوينو

لنقم الآن بتقييم الرموز بين السطر 13 و 15.

if(delayTime <= 0){ // If the delay time is zero or less, reset it.
delayTime = 1000
}

الهدف الرئيسي من الكود أعلاه هو ضمان استمرار وميض LED دون أي انقطاع.

بسبب حقيقة أنه يتم خصم 100 من الأصل وقت التأخير ، يمنع وميض مؤشر LED من الوصول إلى الصفر ويسمح باستمرار الوميض باستمرار.

تُظهر الصورة التالية بعض عوامل المقارنة التي سنستخدمها في أكوادنا:

عامل المقارنة لرموز اردوينو

في الكود أعلاه ، كان بإمكاننا اختبار الكود ليكون if(delayTime == 0).

ومع ذلك ، نظرًا لأن الرقم السلبي يمكن أن يكون بنفس السوء ، فإننا لم نذهب إليه ، وهذه ممارسة موصى بها.

فكر في ما يمكن أن تكون النتيجة إذا حاولنا خصم 300 بدلاً من 100 من delayTime؟

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

digitalWrite(kPinLed, HIGH)
delay(delayTime)
digitalWrite(kPinLed, LOW)
delay(delayTime)

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

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

2.3 بيانات ELSE

هنا سوف نتعلم لماذا وكيف لو قد يكون للمصطلح بند آخر حتى تقرر الموقف في حالة لو البيان خاطئ.

أنا آسف إذا كان هذا يبدو محيرًا للغاية ، فلا تقلق ، سنحاول فهمه من خلال المثال التالي:

const int kPinLed = 13
void setup()
{
pinMode(kPinLed, OUTPUT)
}
int delayTime = 1000
void loop()
{
if(delayTime <= 100){ // If it is less than or equal to 100, reset it
delayTime = 1000
}
else{
delayTime = delayTime - 100
}
digitalWrite(kPinLed, HIGH)
delay(delayTime)
digitalWrite(kPinLed, LOW)
delay(delayTime)
}

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

ربما لاحظت أنه على عكس ما فعلناه في القسم السابق 2.2 ، لم نقارن هنا بـ 0 ، بدلاً من 100. هذا لأنه في هذا المثال مقارنة قبل طرحنا 100 ، على عكس القسم 2.2 ، قمنا بمقارنة ما بعد مطروح. هل يمكنك معرفة ما كان يمكن أن يحدث إذا قارنا 0 بدلاً من 100؟

2.4 بيانات بينما

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

سيساعدك المثال التالي على فهم هذا بشكل أفضل

const int kPinLed = 13
void setup()
{
pinMode(kPinLed, OUTPUT)
}
int delayTime = 1000
void loop()
{
while(delayTime > 0){ // while delayTime is greater than 0
digitalWrite(kPinLed, HIGH)
delay(delayTime)
digitalWrite(kPinLed, LOW)
delay(delayTime)
delayTime = delayTime - 100
}
while(delayTime <1000){ // while delayTime is less than 1000
delayTime = delayTime + 100 // do this first so we don’t have a loop with delayTime = 0
digitalWrite(kPinLed, HIGH)
delay(delayTime)
digitalWrite(kPinLed, LOW)
delay(delayTime)
}
}

هل يمكنك تخمين ما تمت برمجة الكود أعلاه للقيام به؟ حسنًا ، إنه مصمم ليومض LED بشكل أسرع ثم أبطأ.

2.5 ما هو الصواب والخطأ؟

في لغة البرمجة ، خاطئة يشير إلى صفر (0). في الواقع ، لا يتم استخدام 'true' ، بدلاً من ذلك يُفترض أنه عندما لا يوجد شيء خاطئ ، فإن كل ما يتم تضمينه يكون صحيحًا.

يبدو غريباً بعض الشيء ولكنه يقوم بالمهمة بشكل جيد.

سنحاول فهم الموقف من خلال المثال التالي.

قد تصادف أحيانًا رمزًا كما هو موضح أدناه:

while (1){
digitalWrite(kPinLed, HIGH)
delay(100)
digitalWrite(kPinLed, LOW)
delay(100)
}

يبدو هذا مشفرًا مثل تنفيذ LED سيستمر في ركوب الدراجات إلى الأبد ، طالما تتوفر الطاقة.

ومع ذلك ، يمكن أن يظهر جانب سلبي من هذا النوع من التعليمات البرمجية عندما يطبق المستخدم بطريق الخطأ = بدلاً من ==.

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

على سبيل المثال ، افترض أنك طلبت من مؤشر LED أن يومض بنمط تسريع متتابع وبشكل متكرر ، لكنك استخدمت بشكل غير صحيح = بدلاً من ==.

سيظهر الرمز بعد ذلك على النحو التالي:

int delayTime = 1000
void loop()
{
if(delayTime = 0){ // WRONG!!! the = should have been ==
delayTime = 1000
}
digitalWrite(kPinLed, HIGH)
delay(delayTime)
digitalWrite(kPinLed, LOW)
delay(delayTime)
delayTime = delayTime - 100
}

سيؤدي الخطأ إلى تعيين 0 لـ delayTime ، ويؤدي إلى لو بيان للتحقق مما إذا كان 0 صحيحًا أم لا. نظرًا لأن 0 يشير إلى خطأ ، فسوف يعتقد أنه ليس صحيحًا ، وسيوقف فرض delayTime = 1000 ، ولكن بدلاً من ذلك الوظيفة delayTime يتم الاحتفاظ به عند 0 خلال مسار الحلقة ().

هذا يبدو غير مرغوب فيه للغاية !!

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

2.6 مجموعات

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

يمكن تنفيذ مجموعات على المصطلحات المنطقية من خلال 3 طرق ، كما هو موضح في الجدول التالي:

جدول يوضح طرق الجمع بين اردوينو

سيكون من المثير للاهتمام معرفة أن عامل NOT يمكن أن يعمل كمحول لمتغير يمكن تعيينه ليكون أحدهما صحيح أو خاطئة (أو منخفض أو مرتفع).

يوضح المثال التالي الشرط:

int ledState = LOW
void loop()
{
ledState = !ledState // toggle value of ledState
digitalWrite(kPinLed, ledState)
delay(1000)
}

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

2.7 للبيانات

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

دعونا نفهم هذا بالمثال التالي:

const int kPinLed = 13
void setup()
{
pinMode(kPinLed, OUTPUT)
}
void loop()
{
for(int i = 0 i <4 i++){
digitalWrite(kPinLed, HIGH)
delay(200)
digitalWrite(kPinLed, LOW)
delay(200)
}
delay(1000) // 1 second
}

يمكنك العثور على شيء فريد من نوعه في السطر بالنسبة.

هذا هو الكود أنا ++؟ . هذا مفيد للمبرمجين الذين هم كسالى إلى حد ما ويريدون تنفيذ الترميز من خلال اختصارات مريحة

يُعرف المصطلح أعلاه بالعاملين المركبين ، حيث يقومون بمهمة الجمع بين عامل تعيين واحد ومشغل تعيين آخر. يمكن تصور أكثرها شيوعًا في الجدول التالي:

مشغلي مجمع اردوينو

ستجد أن هناك 3 عبارات فرعية في بيان for. وهي منظمة كما هو موضح أدناه:

for (statement1conditionstatement2){
// statements
}

العبارة # 1 تحدث في البداية ومرة ​​واحدة فقط. يتم اختبار الحالة في كل مرة خلال مسار الحلقة. أينما كان صحيح داخل الأقواس المتعرجة ، يتم فرض العبارة التالية # 2. في حالة وجود خاطئة، ينتقل النظام إلى الكتلة التالية من التعليمات البرمجية.

توصيل المزيد من المصابيح

حسنًا ، سنرى الآن كيف يمكننا توصيل عدد أكبر من LEds للحصول على تأثيرات أكثر إثارة للاهتمام.

يرجى توصيل مصابيح LED و Arduino كما هو موضح أدناه. السلك الأحمر ليس ضروريًا في الواقع ، ولكن نظرًا لأنه من الجيد دائمًا تضمين قضبان العرض في اللوح ، فإن الإعداد منطقي.

اردوينو وصلات LED متعددة

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

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

يساعد هذا في استكشاف الأخطاء وإصلاحها بسرعة.

يوفر مثال الكود أدناه LED 2 إلى 5 نمطًا محددًا عن طريق قلبها واحدة تلو الأخرى بطريقة دورية.

const int kPinLed1 = 2
const int kPinLed2 = 3
const int kPinLed3 = 4
const int kPinLed4 = 5
void setup()
{
pinMode(kPinLed1, OUTPUT)
pinMode(kPinLed2, OUTPUT)
pinMode(kPinLed3, OUTPUT)
pinMode(kPinLed4, OUTPUT)
}
void loop()
{
// turn on each of the LEDs in order
digitalWrite(kPinLed1, HIGH)
delay(100)
digitalWrite(kPinLed2, HIGH)
delay(100)
digitalWrite(kPinLed3, HIGH)
delay(100)
digitalWrite(kPinLed4, HIGH)
delay(100)
// turn off each of the LEDs in order
digitalWrite(kPinLed1, LOW)
delay(100)
digitalWrite(kPinLed2, LOW)
delay(100)
digitalWrite(kPinLed3, LOW)
delay(100)
digitalWrite(kPinLed4, LOW)
}

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

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

2.9 إدخال المصفوفات

يمكن أن تكون المصفوفات مجموعة من المتغيرات التي يمكن فهرستها بأرقام الفهرس. سيساعدنا المثال التالي على فهمه بشكل أفضل.

const int k_numLEDs = 4
const int kPinLeds[k_numLEDs] = {2,3,4,5} // LEDs connected to pins 2-5
void setup()
{
for(int i = 0 i pinMode(kPinLeds[i], OUTPUT)
}
}
void loop()
{
for(int i = 0 i digitalWrite(kPinLeds[i], HIGH)
delay(100)
}
for(int i = k_numLEDs - 1 i >= 0 i--){
digitalWrite(kPinLeds[i], LOW)
delay(100)
}
}

حسنًا ، دعنا الآن ننتقل إلى كل قسم ونفهم كيف تعمل بالفعل.

const int k_numLEDs = 4

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

const int kPinLeds[k_numLEDs] = {2,3,4,5} // LEDs connected to pins 2-5

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

عندما تجد مصفوفة مفهرسة بالرقم 0 ، يشير هذا إلى العنصر الأول في المصفوفة ، كما هو موضح في code: k_LEDPins is k_LEDPins[0].

وبالمثل ، سيظهر العنصر الأخير كـ k_LEDPins[3] ، نظرًا لأن العدد من 0 إلى 3 هو 4.

void setup()
{
for(int i = 0 i pinMode(kPinLeds[i], OUTPUT)
}
}

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

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

للمضي قدمًا ، دعنا نرى ما تفعله الكتلة التالية من التعليمات البرمجية:

for(int i = 0 i digitalWrite(kPinLeds[i], HIGH)
delay(100)
}

هنا يستمر الرمز من خلال كل مؤشر LED لتشغيله بالتتابع مع وجود فجوة أو تأخير قدره 100 مللي ثانية.

for(int i = k_numLEDs - 1 i >= 0 i--){
digitalWrite(kPinLeds[i], LOW)
delay(100)
}

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

يبدأ من k_numLEDs - 1 لأن المصفوفات مفهرسة صفرًا. لا نبدأ من k_LEDPins[4] لأن ذلك سيؤدي إلى عبور نهاية المصفوفة.

يستخدم الكود> = 0 للتحقق من أن العنصر الأول في الفهرس 0 لا يتم إغفاله أو تجاهله.

الفصل 3

ما هو المدخل

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

3.1 استخدام الأزرار الانضغاطية

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

3.1.1 زر واحد ومصباح LED

زر واجهة مع اردوينو

سنقوم بتوصيل Arduino بضغطة زر مع Arduino وفقًا للتفاصيل الموضحة أعلاه والتعرف على العمل الأساسي وتنفيذ الإعداد.

يحتوي زر الضغط المشار إليه والذي يسمى أيضًا زر ضغط المفتاح الصغير على 4 دبابيس (زوجان على كل جانب). عند الدفع ، يتم ربط كل زوج من المسامير داخليًا وتمكين الاتصال أو التوصيل عبرهما.

في هذا المثال ، نستخدم زوجًا واحدًا فقط من هذه المسامير أو جهات الاتصال ، والزوج الآخر غير ذي صلة وبالتالي يتم تجاهله.

دعنا نتابع تطبيق الكود التالي ونتحقق من أنه يعمل!

const int kPinButton1 = 2
const int kPinLed = 9
void setup()
{
pinMode(kPinButton1, INPUT)
digitalWrite(kPinButton1, HIGH) // turn on pull-up resistor
pinMode(kPinLed, OUTPUT)
}
void loop()
{
if(digitalRead(kPinButton1) == LOW){
digitalWrite(kPinLed, HIGH)
}
else{
digitalWrite(kPinLed, LOW)
}
}

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

void setup()
{
pinMode(kPinButton1, INPUT)
digitalWrite(kPinButton1, HIGH) // turn on pull-up resistor
pinMode(kPinLed, OUTPUT)
}

أول شيء نفعله هو إصلاح buttonPin مثل إدخال. حسنًا ، هذا أساسي تمامًا ، أعرف.

بعد ذلك ، نقوم بتعيين متوسط الى إدخال دبوس. أنت تتساءل ، كيف يمكن كتابة أي شيء عند الإدخال؟ بالتأكيد ، قد يكون هذا ممتعًا.

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

سؤال آخر قد يكون هو ما هو المقاوم الانسحاب. لقد غطيت منشورًا شاملاً عن مقاومات السحب التي قمت بها تعلمها هنا .

حسنًا ، المضي قدمًا ، فلنلقِ نظرة الآن على رمز الحلقة الرئيسية:

void loop()
{
if(digitalRead(kPinButton1) == LOW){
digitalWrite(kPinLed, HIGH)
}
else{
digitalWrite(kPinLed, LOW)
}
}

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

هنا نريد أن يضيء Arduino مؤشر LED عند الضغط على زر الضغط (LOW) ، لذلك نكتب HIGH للإخراج لكل استجابة منخفضة من زر الضغط ، أثناء الضغط عليه.

3.1.2 زرين ومصباح LED

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

حتى هذه النقطة ، درسنا كتابة الرموز إما للمفتاح ON (HIGH) أو إيقاف (LOW) LED.

الآن لنرى كيف يمكن التحكم في سطوع LED باستخدام Arduino.

يمكن أن يتم ذلك باستخدام طريقتين:

  1. عن طريق تقييد مقدار التيار على LED
  2. باستخدام PWM أو تعديل عرض النبضة ، حيث يتم تشغيل / إيقاف تشغيل LED عند بعض المعدل المطلوب بسرعة كبيرة ، مما ينتج عنه إضاءة متوسطة تعتمد شدتها على PWM.

في لوحة Arduino ، يتوفر دعم PWM على المسامير المميزة بعلامة التلدة (~) ، وهي دبابيس 3 و 4 و 5 و 9 و 10 و 11) عند 500 هرتز (500 مرة في الثانية). يمكن للمستخدم تقديم أي قيمة بين 0 و 255 ، حيث يشير 0 إلى عدم وجود HIGH أو لا + 5V ، و 255 يخبر Arduino بالحصول على HIGH أو + 5V طوال الوقت. لبدء هذه الأوامر ، يجب عليك الوصول إلى analogWrite () بالقيمة المطلوبة.

قد تفترض أن PWM هي x / 255 حيث x هي القيمة المطلوبة التي تريد إرسالها عبر analogWrite().

التحكم في Arduino PWM

قم بإعداد Arduino والمعلمات الأخرى كما هو موضح أعلاه.

const int kPinButton1 = 2
const int kPinButton2 = 3
const int kPinLed = 9
void setup()
{
pinMode(kPinButton1, INPUT)
pinMode(kPinButton2, INPUT)
pinMode(kPinLed, OUTPUT)
digitalWrite(kPinButton1, HIGH) // turn on pullup resistor
digitalWrite(kPinButton2, HIGH) // turn on pullup resistor
}
int ledBrightness = 128
void loop()
{
if(digitalRead(kPinButton1) == LOW){
ledBrightness--
}
else if(digitalRead(kPinButton2) == LOW){
ledBrightness++
}
ledBrightness = constrain(ledBrightness, 0, 255)
analogWrite(kPinLed, ledBrightness)
delay(20)
}

قد تجد هنا ثلاثة أسطر تحتاج إلى بعض الشرح.

ledBrightness = constrain(ledBrightness, 0, 255)
25 analogWrite(kPinLed, ledBrightness)
26 delay(20)

الخط: ledBrightness = constrain(ledBrightness, 0, 255) يوضح وظيفة فريدة داخل Arduino تُعرف باسم constrain ().

تتكون هذه الوظيفة الداخلية من رمز مشابه لما يلي:

تقييد int (قيمة int ، int min ، int max)
{
if(value > max){
value = max
}
if(value value = min
}
return value
}

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

صحيح ، هذا يعني أن الكود: ledBrightness = constrain(ledBrightness, 0, 255) يعين ledBrightness to be within the range of 0 and 255.

يستخدم السطر التالي analogWrite لأوامر Arduino لتطبيق PWM على الدبوس المحدد بالقيمة المطلوبة.

يخلق السطر التالي تأخيرًا قدره 20 مللي ثانية ، وهذا لضمان عدم ضبطنا للأكل أسرع من 50 هرتز أو 50 مرة في الثانية. هذا لأن البشر يمكن أن يكونوا أبطأ بكثير من Arduino. ومن ثم إذا لم يتم التأخير ، فقد يجعلنا البرنامج نشعر بأن الضغط على الزر الأول أدى إلى إيقاف تشغيل مؤشر LED والضغط على الزر الثاني لتشغيله (جربه بنفسك للتأكيد).

3.2 مقاييس فرق الجهد

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

لمعرفة كيفية عمل مقياس الجهد أو وعاء ، يمكنك قراءة هذا مقالة - سلعة .

باستخدام مقياس الجهد مع اردوينو

قم بتوصيل المعلمات الموضحة بـ Arduino كما هو موضح أعلاه.

سيكون للقدر 3 أطراف. سيتصل الطرف الأوسط بـ ANALOG IN 0 على Arduino. قد يتم توصيل المحطتين الخارجيتين الأخريين بقضبان تزويد + 5 فولت و 0 فولت.

لنبرمج ونتحقق من النتائج:

const int kPinPot = A0
const int kPinLed = 9
void setup()
{
pinMode(kPinPot, INPUT)
pinMode(kPinLed, OUTPUT)
}
void loop()
{
int ledBrightness
int sensorValue = 0
sensorValue = analogRead(kPinPot)
ledBrightness = map(sensorValue, 0, 1023, 0, 255)
analogWrite(kPinLed, ledBrightness)
}

ستجد بضعة أشياء قد تبدو جديدة تمامًا وليست مدرجة في أي من الرموز السابقة.

  1. الثابت kPinPot تم تعيينه كـ A0 ، حيث A هو الاختصار لوصف أحد المسامير التناظرية. ومع ذلك ، يشير A0 أيضًا إلى الدبوس رقم 14 ، و A1 إلى الدبوس رقم 15 وما إلى ذلك ، وهذه تتيح لك استخدامك كمدخلات / مخرجات رقمية في حالة نفاد الدبابيس للتجربة. لكن تذكر أنه لا يمكنك استخدام الدبابيس الرقمية كدبابيس تناظرية.
  2. الخط: ledBrightness = map(sensorValue, 0, 1023, 0, 255) يقدم وظيفة داخلية جديدة في Arduino تُعرف باسم خريطة(). تتم إعادة المعايرة هذه الميزة من نطاق معين إلى نطاق آخر ، يسمى الخريطة (القيمة ، من منخفض ، من مرتفع ، إلى منخفض ، إلى مرتفع). قد يصبح هذا أمرًا بالغ الأهمية منذ analogueRead يعطي قيمة في النطاق من 0-1023 ، لكن analogWrite قادر على قبول قيمة من 0-255.

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

لا توجد مشاكل ، الآن سنفعل شيئًا لا يمكن القيام به بدون Arduino.

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

ها هو البرنامج:

const int kPinPot = A0
const int kPinLed = 9
void setup()
{
pinMode(kPinLed, OUTPUT)
}
void loop()
{
int sensorValue
sensorValue = analogRead(kPinPot)
digitalWrite(kPinLed, HIGH)
delay(sensorValue)
digitalWrite(kPinLed, LOW)
delay(sensorValue)
}

3.2.3 تجنب التأخير ()

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

const int kPinPot = A0
const int kPinLed = 9
void setup()
{
pinMode(kPinLed, OUTPUT)
}
long lastTime = 0
int ledValue = LOW
void loop()
{
int sensorValue
sensorValue = analogRead(kPinPot)
if(millis() > lastTime + sensorValue){
if(ledValue == LOW){
ledValue = HIGH
}
else{
ledValue = LOW
}
lastTime = millis()
digitalWrite(kPinLed, ledValue)
}
}

إذن ما هو الاختلاف في الكود أعلاه؟ هذا هو السطر التالي الذي يصنع الفرق.

long lastTime = 0

حتى هذا القسم ، ناقشنا المتغير int. ومع ذلك ، قد يكون هناك العديد من أنواع المتغيرات التي يمكنك الوصول إليها. يمكن قراءة القائمة أدناه:

أنواع متغيرات الأردوينو

في الوقت الحالي ، قد يكون من المهم فقط معرفة ذلك لتخزين أعداد كبيرة نسبيًا لـ int متغير ، يمكنك استخدام المصطلح طويل أو أ كثافة العمليات طويلة.

هنا يمكنك أن ترى وظيفة أخرى مثيرة للاهتمام تسمى مللي ().

ينتج عن ذلك الفترة الزمنية بالمللي ثانية التي عمل بها Arduino في مسار عملها من البداية (سيتم إعادة تعيين هذا إلى 0 بعد كل 50 يومًا). هنا يعود طويلا لأنه إذا عاد int ، قد لا يكون العد لفترات طويلة ممكنًا. هل يمكنك الإجابة بالضبط إلى متى؟ الإجابة هي 32.767 ثانية.

لذلك ، بدلاً من استخدام التأخير () ، نتحقق من وجود ميلي () ، وبمجرد مرور عدد معين من الميلي ثانية ، نقوم بتغيير مؤشر LED. وبالتالي نقوم بتخزين الوقت الذي قمنا فيه بتغييره في آخر مرة آخر مرة متغير ، بحيث يسمح لنا بالتحقق منه مرة أخرى متى رغبت في ذلك.

3.3 RGB LEDs

حتى الآن لعبنا بمصباح LED أحادي اللون. على الرغم من أنه يمكن تغيير لون LED عن طريق استبدال LED بلون آخر ، ولكن ماذا عن استخدام RGB LEDs لتغيير ألوان LED دون تغيير المصابيح؟

إن RGB LED هو في الأساس مصباح LED به مصباح LED أحمر وأخضر وأزرق مدمج ومدمج في مصباح LED واحد. لها سلك مشترك واحد يذهب إلى الأرض أو سكة إمداد 0V بينما يتم تغذية الخيوط الثلاثة الأخرى بإشارات PWM الإيجابية المتنوعة لتنفيذ المقصود خلط الألوان .

يمكنك توصيل الإعداد كما هو موضح أدناه:

التحكم في RGB باستخدام Arduino

قد يبدو الأمر معقدًا بعض الشيء ، لكنه في الواقع نسخة طبق الأصل من تصميم تحكم LED السابق باستخدام PWM.

إليك رمز برنامج تدريبي:

const int kPinPot1 = A0
const int kPinPot2 = A1
const int kPinPot3 = A2
const int kPinLed_R = 6
const int kPinLed_G = 10
const int kPinLed_B = 11
void setup()
{
pinMode(kPinLed_R, OUTPUT)
pinMode(kPinLed_G, OUTPUT)
pinMode(kPinLed_B, OUTPUT)
}
void loop()
{
int potValue
int ledValue
potValue = analogRead(kPinPot1)
ledValue = map(potValue, 0, 1023, 0, 255)
analogWrite(kPinLed_R, ledValue)
potValue = analogRead(kPinPot2)
ledValue = map(potValue, 0, 1023, 0, 255)
analogWrite(kPinLed_G, ledValue)
potValue = analogRead(kPinPot3)
ledValue = map(potValue, 0, 1023, 0, 255)
analogWrite(kPinLed_B, ledValue)
}

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

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

الصوت مع اردوينو

سنتعلم في هذا القسم كيفية إضافة الصوت والموسيقى الأساسيين إلى إعداد Arduino.

سنرى كيفية تحويل الإشارة إلى مكبر صوت متصل بالتردد المطلوب.

لنكون أكثر دقة ، سيتم تجربة نغمة متوسطة ، وهي نغمة تردد 440 هرتز.

للقيام بذلك ، سنقوم ببساطة بتشغيل نغمة A متوسطة ، وتحسين إشارة الموجة الجيبية بموجة مربعة.

سنحسب أيضًا مقدار الوقت الذي قد يظل فيه مكبر الصوت قيد التشغيل عن طريق مقاضاة الصيغة:

التأخير الزمني = ثانية واحدة / 2 x نغمة التردد.

التأخير الزمني = 1 ثانية / 2 × 440

timeDelay = 1136 ميكروثانية

4.1 دعنا نربط لوحة Arduino

استخدام المؤثرات الصوتية في الأردوينو

4.2 إضافة ملاحظة بسيطة

لقد ناقشنا بالفعل حول الوظيفة تأخير() حيث تكون الوحدة بالمللي ثانية (ثانية / 1000) ، ومع ذلك ستجد دالة أخرى delayMicroseconds() حيث تكون الوحدة بالميكروثانية ، (مللي ثانية / 1000).

في الإعداد الحالي ، نقوم ببرمجة رمز للتبديل + 5V ON / OFF على الدبوس المحدد المرتبط بالسماعة ، بمعدل 440 نبضة في الثانية.

تذكر ، في المناقشة الأخيرة ، حددنا القيمة 1136 ميكروثانية للملاحظة الصوتية المقصودة.

إذن ، هذا هو البرنامج الخاص بهذا ، والذي سيسمح لك بسماع ملاحظة صوتية تبلغ 440 هرتز بمجرد برمجة اردوينو مع مكبر صوت متصل.

const int kPinSpeaker = 9
const int k_timeDelay = 1136
void setup()
{
pinMode(kPinSpeaker, OUTPUT)
}
void loop()
{
digitalWrite(kPinSpeaker, HIGH)
delayMicroseconds(k_timeDelay)
digitalWrite(kPinSpeaker, LOW)
delayMicroseconds(k_timeDelay)
}

باستخدام التطبيق أعلاه ، من الممكن تدوين ملاحظة صوتية ، مما يعني أيضًا أنه يمكننا إنشاء موسيقى حسب اختيارنا.

نفهم من الكود أن Arduino يتضمن وظيفتين متكاملتين تساهمان بشكل إضافي في إنشاء الموسيقى.

اول واحد هو نغمة، رنه() الذي يعمل مع عنصرين جنبًا إلى جنب مع عنصر اختياري ثالث ، تم تعيينه كـ نغمة (دبوس ، تردد ، مدة). أو نغمة (دبوس ، تردد)

تم تعيين كلاهما لتنفيذ كلٍ من الفترة الزمنية التي تحددها.

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

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

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

الوظيفة التالية ليس واحد () يتعامل مع معلمة واحدة ويوقف النغمة المحددة على دبوس معين معين.

تحذير غريب: في أي وقت عندما نغمة، رنه() تم تنفيذ الوظيفة ، ستتوقف وظيفة PWM على السن 3 و 11 عن العمل.

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

حسنًا ، هذا برنامج لتنفيذ الموسيقى على مكبر صوت ، على الرغم من أنها ليست موسيقى حقيقية بل هي عبارة عن ملاحظة على مقياس C الأساسي.

#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_A4 440
#define NOTE_B4 494
#define NOTE_C5 523
const int kPinSpeaker = 9
void setup()
{
pinMode(kPinSpeaker, OUTPUT)
}
void loop()
{
tone(kPinSpeaker, NOTE_C4, 500)
delay(500)
tone(kPinSpeaker, NOTE_D4, 500)
delay(500)
tone(kPinSpeaker, NOTE_E4, 500)
delay(500)
tone(kPinSpeaker, NOTE_F4, 500)
delay(500)
tone(kPinSpeaker, NOTE_G4, 500)
delay(500)
tone(kPinSpeaker, NOTE_A4, 500)
delay(500)
tone(kPinSpeaker, NOTE_B4, 500)
delay(500)
tone(kPinSpeaker, NOTE_C5, 500)
delay(500)
noTone(kPinSpeaker)
delay(2000)
}

في الكود أعلاه ربما لاحظت شيئًا جديدًا وهو #حدد .

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

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

حتى في هذا المثال عندما يرى الكمبيوتر NOTE_E4 تستبدله بسرعة بالكمية 330.

لمزيد من الملاحظات والتخصيص ، يمكنك الرجوع إلى ملف في محرك أقراص USB المسمى الملاعب ، حيث يمكن العثور على معظم الترددات التي تفضلها.

4.4 موسيقى بوظائف

يبدو الرمز أعلاه جيدًا ، ولكن يبدو أنه يحتوي على العديد من التكرارات ، يجب أن يكون هناك طريقة ما لتقصير هذه التكرارات ، أليس كذلك؟

لقد عملنا حتى الآن مع وظيفتين أساسيتين متضمنة في Arduino. الآن قد حان الوقت لإنشاء وظائفنا الخاصة.

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

وبالتالي ، فإن اسم الوظيفة المعين يحصل على قوس مفتوح '(' متبوعة بقائمة من المعلمات مفصولة بفواصل.

يكتسب كل معلمة نوعه مع الاسم ، وأخيراً الإغلاق ')' أقواس.

يمكن تطبيق هذه المعلمات داخل الوظيفة في شكل متغيرات.

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

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

#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_A4 440
#define NOTE_B4 494
#define NOTE_C5 523
const int kPinSpeaker = 9
void setup()
{
pinMode(kPinSpeaker, OUTPUT)
}
void loop()
{
tone(kPinSpeaker, NOTE_C4, 500)
delay(500)
tone(kPinSpeaker, NOTE_D4, 500)
delay(500)
tone(kPinSpeaker, NOTE_E4, 500)
delay(500)
tone(kPinSpeaker, NOTE_F4, 500)
delay(500)
tone(kPinSpeaker, NOTE_G4, 500)
delay(500)
tone(kPinSpeaker, NOTE_A4, 500)
delay(500)
tone(kPinSpeaker, NOTE_B4, 500)
delay(500)
tone(kPinSpeaker, NOTE_C5, 500)
delay(500)
noTone(kPinSpeaker)
delay(2000)
}
void ourTone(int freq, int duration)
{
tone(kPinSpeaker, freq, duration)
delay(duration)
}

يمكن أن تكون الوظائف مفيدة للغاية لتسهيل فهم البرنامج.

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

#include 'pitches.h'
int kPinSpeaker = 9
#define NUM_NOTES 15
const int notes[NUM_NOTES] = // a 0 represents a rest
{
NOTE_C4, NOTE_C4, NOTE_G4, NOTE_G4,
NOTE_A4, NOTE_A4, NOTE_G4, NOTE_F4,
NOTE_F4, NOTE_E4, NOTE_E4, NOTE_D4,
NOTE_D4, NOTE_C4, 0
}
const int beats[NUM_NOTES] = {
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4 }
const int beat_length = 300
void setup()
{
pinMode(kPinSpeaker, OUTPUT)
}
void loop()
{
for (int i = 0 i if (notes[i] == 0) {
delay(beats[i] * beat_length) // rest
}
else {
ourTone(notes[i], beats[i] * beat_length)
}
// pause between notes
noTone(kPinSpeaker)
delay(beat_length / 2)
}
}
void ourTone(int freq, int duration)
{
tone(kPinSpeaker, freq, duration)
delay(duration)
}

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

الفصل 5

قياس درجة الحرارة

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

5.1 الشاشة التسلسلية

حتى الآن ، لا تظهر الرموز التي ناقشناها بهذه السهولة لتمكين استكشاف الأخطاء وإصلاحها بسرعة. سنحاول هنا تسهيل الأمور للمراقبة وتسهيل حل مشكلة محتملة.

يتميز Arduino بميزة تمكنه من 'التحدث مرة أخرى' مع الكمبيوتر. قد تلاحظ أنه تم تمييز pin0 و pin1 على أنهما RX و TX بجانب بعضهما البعض. يتم تتبع هذه المسامير فعليًا بواسطة IC منفصل داخل Arduino والذي يقوم بترقيتها للقراءة عبر كبل USB أثناء توصيله بالكمبيوتر.

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

const int kPinLed = 13
void setup()
{
pinMode(kPinLed, OUTPUT)
Serial.begin(9600)
}
int delayTime = 1000
void loop()
{
delayTime = delayTime - 100
if(delayTime <= 0){ // If it would have been zero or less, reset it.
delayTime = 1000
}
Serial.print('delayTime = ')
Serial.println(delayTime)
digitalWrite(kPinLed, HIGH)
delay(delayTime)
digitalWrite(kPinLed, LOW)
delay(delayTime)
}

يمكنك تحديد شيئين جديدين هنا ، سطر جديد في يثبت() وظيفة.

Serial.begin(9600)

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

الإدخال الجديد الثاني على النحو التالي

Serial.print('delayTime = ')
Serial.println(delayTime)

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

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

حسنًا ، يمكننا الآن تحميل الكود أعلاه في Arduino ومعرفة ما سيحدث.

ماذا ، عفوًا ، لم يحدث شيء ، وميض مؤشر Arduino رقم 13 LED وتوقف ، بينما ظل مؤشر Tx يومض.

حسنًا ، هذا لأن نافذة Serial Monitor لم يتم إصلاحها بعد.

تحتاج إلى النقر فوق مربع Serial Monitor في IDE الخاص بك كما هو موضح أعلاه. لا تنس التحقق من معدل الباود الموجود في أسفل اليمين ، افتراضيًا يجب أن يكون 9600 وسيتطابق مع الرمز. إذا لم يكن تأكد من تحديد 9600.

يوضح مقطع الفيديو التالي كيف يتم ذلك.

https://youtu.be/ENg8CUyXm10

الآن دعنا نمضي قدمًا ونتعلم كيف يمكن لميزة Serial Monitor المذكورة أعلاه أن تساعد في معالجة ملف قياس درجة الحرارة باستخدام اردوينو

سنستخدم IC TMP36 كمستشعر درجة الحرارة ، بمدى يتراوح من -40 إلى 150 درجة مئوية.

يمكن رؤية الإعداد أدناه:

TMP36 مع الأردوينو لقياس درجة الحرارة

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

const int kPinTemp = A0
void setup()
{
Serial.begin(9600)
}
void loop()
{
float temperatureC = getTemperatureC()
Serial.print(temperatureC)
Serial.println(' degrees C')
// now convert to Fahrenheit
float temperatureF = convertToF(temperatureC)
Serial.print(temperatureF)
Serial.println(' degrees F')
delay(500)
}
float getTemperatureC()
{
int reading = analogRead(kPinTemp)
float voltage = (reading * 5.0) / 1024
// convert from 10 mv per degree with 500mV offset
// to degrees ((voltage - 500mV) * 100)
return (voltage - 0.5) * 100
}
float convertToF(float temperatureC)
{
return (temperatureC * 9.0 / 5.0) + 32.0
}

دعونا نفهم الكود من الأعلى.

float temperatureC = getTemperatureC()

هنا يمكنك أن ترى أننا قمنا بتضمين نوع المتغير يطفو.

هذا هو نوع المتغير الوحيد الذي يتميز بتخزين كل شيء باستثناء الأرقام الصحيحة (الأرقام بدون أجزاء عشرية أو كسرية).

يمكن أن تصل الدقة من متغير عائم إلى 6 إلى 7 أرقام.

الكود المجاور getTemperatureC() هي وظيفتنا الخاصة التي تحسب رياضيًا وتحول فرق الجهد المحسوس من مستشعر TMP36 إلى درجات مئوية.

float getTemperatureC()
{
int reading = analogRead(kPinTemp)
float voltage = (reading * 5.0) / 1024
// convert from 10 mv per degree with 500mV offset
// to degrees ((voltage - 500mV) * 100)
return (voltage - 0.5) * 100
}

في القسم التالي من الرموز ، منذ المصطلح analogIn() لإرجاع رقم بين 1 إلى 1023 ، يصبح من الممكن بالنسبة لنا تقييم الجهد من المستشعر بضرب قراءتنا في 5 ثم تقسيمها على 1024.

تم تحديد المستشعر TMP36 لتوليد 0.5 فولت عند 0 درجة مئوية ، وبالتالي يولد 10 مللي فولت لكل ارتفاع في درجة مئوية.

هذا هو التقريب الذي يمكننا الحصول عليه من خلال الحسابات:

معايرة درجة حرارة اردوينو

يمكنك اعتبار أن هذه هي وظيفتك الأولى التي تُرجع بعض القيمة (لاحظ أن جميع الوظائف المتبقية حتى الآن لم تُرجع أي قيمة لأنها كانت من النوع فارغ ).

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

عندما نقول إرجاع هذا يعني أن الوظيفة تقوم بإرجاع استجابة أو رد كلما تم استدعاؤها ، والتي يمكن تطبيقها على متغير.

عندما يتم إرسال هذا إلى Serial Monitor ، يتم تحويل القراءة إلى فهرنهايت من خلال تحويل إلى F ().

float convertToF(float temperatureC)
{
return (temperatureC * 9.0 / 5.0) + 32.0
}

تقوم هذه الوظيفة بالتقاط النطاق المئوي وتحويله إلى فهرنهايت.

لتحويل الفهرنهايت إلى مئوية ، نطبق الصيغة فهرنهايت = 9 / 5 (مئوية) + 32.

5.3 التواصل مع شاشة LCD

الآن دعنا ندرس كيفية إنشاء واجهة أو توصيل ملف عرض شاشات الكريستال السائل مع Arduino للحصول على عرض مرئي للمخرجات المطلوبة.

في تطبيقنا ، سنستخدم شاشة LCD رسومية مقاس 84 × 48 ، بها 84 بكسل أو نقطة أفقيًا ، ودقة 48 بكسل رأسية. نظرًا لأن وحدة التحكم المخصصة أصبحت ضرورية لجميع شاشات LCD ، فإن الجهاز الحالي يشتمل أيضًا على وحدة تحكم على شكل وحدة تحكم PCD8544.

في هذا البرنامج التعليمي ، سنقوم بتوصيل وحدة LCD المحددة أعلاه بـ Arduino ، وسنطبق إجراءات معينة لإنشاء رسائل نصية على الشاشة.

في الشكل التالي ، يمكنك العثور على تفاصيل تتعلق بواجهة شاشة LCD ، جنبًا إلى جنب مع شاشة صغيرة 3.3 فولت منظم الجهد . يعد هذا المنظم ضروريًا نظرًا لأن شاشة LCD مخصصة للعمل مع مصدر إمداد 3.3 فولت.

يمكنك أيضًا رؤية 8 pinouts من وحدة LCD ، ويمكن دراسة مواصفات pinout من الجدول التالي:

تفاصيل pinout LCD

الآن دعونا نرى كيف يمكننا توصيل شاشة LCD والمعلمات ذات الصلة بـ Arduino. يمكن تصور التفاصيل في الرسم التوضيحي الموضح أدناه:

تعلم أساسيات اردوينو

5.4 الاتصال بشاشة LCD

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

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

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

5.4.1 كيفية تثبيت المكتبة

لهذا سيتعين عليك إنشاء دليل يسمى مكتبات في جهاز الكمبيوتر الخاص بك Arduino IDE ، كما هو موضح هنا

5.4.2 تنفيذ عمليات LCD

تمامًا مثل نهجنا السابق ، سنقوم أولاً بفحص الكود بالكامل ثم نحاول فهم تفاصيل الأسطر الفردية.

#include
const int kPin_CLK = 5
const int kPin_DIN = 6
const int kPin_DC = 7
const int kPin_RESET = 8
PCD8544 lcd(kPin_CLK, kPin_DIN, kPin_DC, kPin_RESET)
void setup()
{
lcd.init()
lcd.setCursor(0,0)
lcd.print('Hello, World!')
}
void loop()
{
lcd.setCursor(0,1)
lcd.print(millis())
}

يتضمن السطر الكود #include

رمز #include يوجه الكمبيوتر لالتقاط الملف المذكور واستبدال عنصر #include بمحتويات الملف أثناء دورة تجميع البرنامج.

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

تعبر الأسطر التالية من التعليمات البرمجية عن نقاط توصيل LCD ، ثم نكتب شكلاً جديدًا من المتغيرات:

PCD8544 lcd(kPin_CLK, kPin_DIN, kPin_DC, kPin_RESET)

نحن هنا نعبر عن متغير بالاسم lcd به النوع PCD8544 ونوجه تعليمات للكمبيوتر الشخصي بإعادة تعيين pinouts الخاص به المرتبط بـ Arduino.

في هذه العملية ، نصف المتغير لجهاز الكمبيوتر عن طريق إرشادنا إلى كيفية تفاعل pin clk و din و dc و reset مع Arduino.

void setup()
{
lcd.init()
lcd.setCursor(0,0)
lcd.print('Hello, World!')
}

الخط lcd.init() تهيئة عملية LCD. بمجرد تنفيذ ذلك ، يقوم السطر التالي بفرض مؤشر على أعلى يسار الشاشة. والسطر التالي يبذل جهدًا لطباعة الرسالة 'Hello، World'.

يبدو هذا مطابقًا تمامًا للتقنية التي أرسلنا بها الرسائل عبر الشاشة التسلسلية. الاختلاف الوحيد هو استخدام الكود lcd.print بدلا من المسلسل.

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

void loop()
{
lcd.setCursor(0,1)
lcd.print(millis())
}

استخدام هذا الخط lcd.setCursor(0,1) نصلح المؤشر إلى العمود 0 في أقصى يسار الصف الأول ، فوق شاشة LCD.

يستخدم السطر التالي اختصارًا: lcd.print(millis())

إذا كنت تتذكر أننا عملنا مع millis() في رموزنا السابقة ، كان بإمكاننا تطبيق الشيء نفسه هنا أيضًا من خلال الرموز:

long numMillis = millis()
lcd.print(numMillis)

ولكن نظرًا لحقيقة عدم وجود فترات زمنية بالمللي ثانية ، فإننا ننجزها ببساطة عن طريق إرسال millis() تعمل مباشرة إلى lcd.print() .

5.5 الجمع بين كل شيء

حسنًا ، دعنا الآن نجمع جميع الرموز التي تعلمناها أعلاه لإنشاء دائرة درجة حرارة LCD ، ودعنا نرى كيف تبدو:

#include
const int kPin_CLK = 5
const int kPin_DIN = 6
const int kPin_DC = 7
const int kPin_RESET = 8
const int kPin_Temp = A0
PCD8544 lcd(kPin_CLK, kPin_DIN, kPin_DC, kPin_RESET)
void setup()
{
lcd.init()
lcd.setCursor(10,0)
lcd.print('Temperature:')
}
void loop()
{
float temperatureC = getTemperatureC()
// now convert to Fahrenheit
float temperatureF = convertToF(temperatureC)
lcd.setCursor(21,1)
lcd.print(temperatureC)
lcd.print(' C')
lcd.setCursor(21,2)
lcd.print(temperatureF)
lcd.print(' F')
delay(100)
}
float getTemperatureC()
{
int reading = analogRead(kPin_Temp)
float voltage = (reading * 5.0) / 1024
// convert from 10 mv per degree with 500mV offset
// to degrees ((voltage - 500mV) * 100)
return (voltage - 0.5) * 100
}
float convertToF(float temperatureC)
{
return (temperatureC * 9.0 / 5.0) + 32.0
}

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

رائعة! تهانينا ، لقد قمت للتو ببرمجة مؤشر درجة حرارة LCD الصغير الخاص بك باستخدام Arduino.

تطبيقات Arduino العملية

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

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

7.1 مقدمة إلى المستشعرات

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

سنبدأ مع التفاعل من مستشعر الضوء LDR مع Arduino ، كما هو موضح في الرسم البياني التالي:

استخدم LDR مع Arduino

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

تتناسب شدة الضوء عكسًا مع قراءة المقاومة لـ LDR.

هنا سوف نتعلم كيف يمكن دمج هذه الخاصية مع Arduino لتنفيذ تطبيق مفيد:

يمكن تصور رمز البرنامج الكامل كما هو موضح أدناه:

const int kPin_Photocell = A0
void setup()
{
Serial.begin(9600)
}
void loop()
{
int value = analogRead(kPin_Photocell)
Serial.print('Analog Reading = ')
Serial.print(value)
if(value <200){
Serial.println(' - Dark')
}else if(value <400){
Serial.println(' - Dim')
}
else if(value <600){
Serial.println(' - Light')
}
else if(value <800){
Serial.println(' - Bright')
}
else{
Serial.println(' - Very Bright')
}
delay(1000)
}

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

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

استشعار الخيمة

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

الآن دعونا نرى كيف أ استشعار الخيمة يمكن أن يكون الجهاز سلكيًا. تعطينا الصورة أدناه فكرة عن التكوين الكامل:

تثبيت مستشعر الإمالة مع اردوينو

const int kPin_Tilt = 3
const int kPin_LED = 13
void setup()
{
pinMode(kPin_Tilt, INPUT)
digitalWrite(kPin_Tilt, HIGH) // turn on built-in pull-up resistor
pinMode(kPin_LED, OUTPUT)
}
void loop()
{
if(digitalRead(kPin_Tilt) == HIGH){
digitalWrite(kPin_LED, LOW)
}
else{
digitalWrite(kPin_LED, HIGH)
}
}

في هذا المثال ، يتم استخدام مؤشر LED الافتراضي رقم 13 كمؤشر للإمالة.

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

7.4 مرحل تبديل ريد (مرحل مغناطيسي مصغر منشط)

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

هنا أيضًا نستخدم دبوس رقم 13 LED للإشارة إلى الاستجابة. يمكنك توصيل مصباح LED خارجي من هذا الدبوس إذا لزم الأمر وفقًا لتفسيراتنا السابقة.

const int kPinReedSwitch = 2
const int kPinLed = 13
void setup()
pinMode(kPinReedSwitch, INPUT)
digitalWrite(kPinReedSwitch, HIGH) // turn on pullup resistor
pinMode(kPinLed, OUTPUT)
}
void loop()
{
if(digitalRead(kPinReedSwitch) == LOW){
digitalWrite(kPinLed, HIGH)
}
else{
digitalWrite(kPinLed, LOW)
}
}

يجب أن تكون مصطلحات الكود مألوفة وتشرح نفسها بنفسها.

7.5 مستشعر الاهتزاز باستخدام محول الطاقة بيزو

في نموذج البرنامج التالي سنرى كيف أ محول بيزو يمكن استخدامها كمستشعر اهتزاز لإضاءة مؤشر LED من خلال Arduino.

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

قم بإعداد Arduino وعنصر بيزو كما هو موضح في الشكل التالي

باستخدام بيزو كمستشعر اهتزاز مع Arduino

const int kPinSensor = A5
const int kPinLed = 13
const int k_threshold = 100
int ledState = LOW // variable used to store the last LED status, to toggle the light
void setup()
{
pinMode(kPinLed, OUTPUT) // declare the ledPin as as OUTPUT
}
void loop()
{
int val = analogRead(kPinSensor)
if (val >= k_threshold) {
ledState = !ledState // toggle the value of ledState
digitalWrite(kPinLed, ledState)
delay(20) // for debouncing
}
}

يتم تقديم العتبة 100 فقط للتأكد من أن Arduino يستجيب فقط للاهتزازات الحقيقية من خلال الضربات ، وليس الاهتزازات الأخرى الأصغر مثل الأصوات العالية أو الأبواق.

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

باستخدام محرك سيرفو مع اردوينو

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

عادةً ما يحتوي محرك سيرفو على 3 أسلاك أو مدخلات. عادة ما تكون الأسلاك الموجبة حمراء اللون ، والسلك السالب أو الأرضي أسود ، ويكون سلك التوجيه أو سلك الإشارة عادة أبيض أو أصفر اللون.

تسهل Arduino التحكم في محرك سيرفو من خلال لغة دعم مدمجة تجعل التحكم مناسبًا جدًا ومثاليًا لمحركات المؤازرة.

سيوضح لنا المثال التالي برنامج الإعداد الأساسي لتنفيذ التحكم في محرك سيرفو من خلال Arduino:

التحكم في محرك سيرفو اردوينو

وفيما يلي التعليمات البرمجية:

#include
Servo servo1
const int kPinPot = A0
const int kPinServo1 = 9
void setup()
{
servo1.attach(kPinServo1)
}
void loop()
{
int val = analogRead(kPinPot)
val = map(val, 0, 1023, 0, 180)
servo1.write(val)
delay(15)
}

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

خاتمة

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

نأمل أن يتم تحديث المزيد من المعلومات من وقت لآخر هنا ، متى كانت متاحة.

في غضون ذلك ، استمتع بدورة البرمجة الخاصة بك ، سعيد Arduinoing لك !!




زوج من: دائرة مقياس كاشف الكحول باستخدام وحدة الاستشعار MQ-3 التالي: دائرة تغذية الكلب التي تسيطر عليها الهاتف المحمول