<?xml version="1.0"?>
<rss version="2.0"><channel><title>&#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629;: &#x627;&#x644;&#x623;&#x646;&#x638;&#x645;&#x629; &#x648;&#x627;&#x644;&#x623;&#x646;&#x638;&#x645;&#x629; &#x627;&#x644;&#x645;&#x62F;&#x645;&#x62C;&#x629;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/page/2/?d=2</link><description>&#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629;: &#x627;&#x644;&#x623;&#x646;&#x638;&#x645;&#x629; &#x648;&#x627;&#x644;&#x623;&#x646;&#x638;&#x645;&#x629; &#x627;&#x644;&#x645;&#x62F;&#x645;&#x62C;&#x629;</description><language>ar</language><item><title>&#x645;&#x641;&#x647;&#x648;&#x645; &#x627;&#x644;&#x631;&#x628;&#x637; &#x627;&#x644;&#x62F;&#x64A;&#x646;&#x627;&#x645;&#x64A;&#x643;&#x64A; Dynamic Linking &#x641;&#x64A; &#x645;&#x639;&#x645;&#x627;&#x631;&#x64A;&#x629; &#x627;&#x644;&#x62D;&#x627;&#x633;&#x648;&#x628;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D9%85%D9%81%D9%87%D9%88%D9%85-%D8%A7%D9%84%D8%B1%D8%A8%D8%B7-%D8%A7%D9%84%D8%AF%D9%8A%D9%86%D8%A7%D9%85%D9%8A%D9%83%D9%8A-dynamic-linking-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1965/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2023_04/--------.png.18f77f4f8054e7f4309206aac3e3fffd.png" /></p>
<p>
	تُعَد شيفرة نظام التشغيل البرمجية للقراءة فقط وتكون منفصلة عن البيانات، لذا إن لم تتمكن البرامج من تعديل الشيفرة البرمجية مع وجود كميات كبيرة من الشيفرة البرمجية المشتركة أمرًا منطقيًا، إذ يجب مشاركتها بين العديد من الملفات القابلة للتنفيذ بدلًا من تكرارها لكل ملف منها.
</p>

<p>
	يمكن تطبيق ذلك بسهولة باستخدام <a href="https://academy.hsoub.com/programming/general/%D8%A7%D9%84%D8%B0%D8%A7%D9%83%D8%B1%D8%A9-%D8%A7%D9%84%D9%88%D9%87%D9%85%D9%8A%D8%A9-%D9%88%D8%A7%D9%84%D8%B0%D8%A7%D9%83%D8%B1%D8%A9-%D8%A7%D9%84%D8%AD%D9%82%D9%8A%D9%82%D9%8A%D8%A9-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1918/" rel="">الذاكرة الوهمية</a>، إذ يمكن الرجوع بسهولة إلى صفحات الذاكرة الحقيقية التي جرى تحميل شيفرة المكتبة البرمجية إليها من خلال عدد من الصفحات الوهمية في عددٍ من فضاءات العناوين. لذا يمكن لكل عملية الوصول إلى شيفرة المكتبة البرمجية باستخدام أيّ عنوان وهمي تريده، بينما يكون لديك نسخة حقيقية واحدة فقط من هذه الشيفرة في ذاكرة النظام.
</p>

<p>
	وبذلك توصل المبرمجون بسرعة إلى فكرة المكتبة المشتركة Shared Library التي -كما يوحي الاسم- يمكن مشاركتها بين العديد من الملفات القابلة للتنفيذ. يحتوي كل ملف قابل للتنفيذ على مرجع يقول: "أحتاج مكتبة Foo مثلًا"، حيث يُترَك الأمر للنظام عند تحميل البرنامج للتحقق من وجود برنامج آخر حمّل شيفرة هذه المكتبة في الذاكرة ثم مشاركتها من خلال ربط صفحات <a href="https://academy.hsoub.com/programming/advanced/%D9%83%D9%8A%D9%81-%D8%AA%D9%86%D8%B4%D8%A6-%D9%85%D9%84%D9%81%D8%A7-%D9%82%D8%A7%D8%A8%D9%84%D8%A7-%D9%84%D9%84%D8%AA%D9%86%D9%81%D9%8A%D8%B0-executable-file-%D9%85%D9%86-%D8%B4%D9%8A%D9%81%D8%B1%D8%A9-%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A9-%D9%85%D8%B5%D8%AF%D8%B1%D9%8A%D8%A9-r1930/" rel="">الملف القابل للتنفيذ</a> مع الذاكرة الحقيقية، أو يمكنه تحميل المكتبة في ذاكرة الملف القابل للتنفيذ. تسمى هذه العملية بالربط الديناميكي Dynamic Linking، لأنها تطبّق جزءًا من عملية الربط مباشرةً عند تنفيذ البرامج في النظام.
</p>

<h2>
	تفاصيل المكتبة الديناميكية
</h2>

<p>
	تشبه المكتبات إلى حدٍ كبير برنامجًا لا يُشغَّل أبدًا، إذ لديها قسم الشيفرة البرمجية وقسم البيانات (الدوال والمتغيرات) تمامًا مثل الملفات القابل للتنفيذ، ولكن لا يمكن تشغيلها، فهي توفر فقط مكتبة من الدوال للمطورين لاستدعائها. لذا يمكن <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D9%84%D9%85%D9%84%D9%81%D8%A7%D8%AA-%D8%A7%D9%84%D9%82%D8%A7%D8%A8%D9%84%D8%A9-%D9%84%D9%84%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%88%D8%AA%D9%85%D8%AB%D9%8A%D9%84%D9%87%D8%A7-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D8%B5%D9%8A%D8%BA%D8%A9-elf-r1941/" rel="">ملف ELF</a> أن يمثل مكتبة ديناميكية تمامًا كما يمثل ملفًا قابلًا للتنفيذ مع وجود بعض الاختلافات الأساسية مثل عدم وجود مؤشر للمكان الذي يجب أن يبدأ فيه التنفيذ، ولكن تُعَد جميع المكتبات المشتركة مجرد كائنات <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D9%85%D9%81%D8%A7%D9%87%D9%8A%D9%85-%D9%85%D8%AA%D9%82%D8%AF%D9%85%D8%A9-%D9%85%D8%AA%D8%B9%D9%84%D9%82%D8%A9-%D8%A8%D8%B5%D9%8A%D8%BA%D8%A9-%D9%85%D9%84%D9%81%D8%A7%D8%AA-elf-%D8%A7%D9%84%D9%82%D8%A7%D8%A8%D9%84%D8%A9-%D9%84%D9%84%D8%AA%D9%86%D9%81%D9%8A%D8%B0-r1942/" rel="">بصيغة ELF</a> مثل أي ملف آخر قابل للتنفيذ.
</p>

<p>
	تحتوي ترويسة ملف ELF على رايتين حصريتين هما <code>ET_EXEC</code> و<code>ET_DYN</code> لتمييز ملف ELF بوصفه ملفًا قابلًا للتنفيذ أو ملفَ كائن مشترك.
</p>

<h2>
	تضمين المكتبات في ملف قابل للتنفيذ
</h2>

<p>
	يمكن تضمين المكتبات في ملف قابل للتنفيذ ولكن يجب أن نراعي مسألتين مهمتين متعلقتين بالمصرِّف والرابط الديناميكي كما سنوضح الآن.
</p>

<h3>
	التصريف Compilation
</h3>

<p>
	تمتلك ملفات الكائنات مراجعًا إلى دوال المكتبة تمامًا كما هو الحال مع أيّ مرجع خارجي آخر عندما تصرِّف برنامجك الذي يستخدم مكتبة ديناميكية. يجب تضمين ترويسة المكتبة ليعرف المصرِّف الأنواع المحددة للدوال التي تستدعيها، إذ يحتاج المصرِّف فقط معرفةَ الأنواع المرتبطة بالدالة (مثل أن تأخذ الدالة النوع <code>int</code> وتعيد النوع <code>char *‎</code>) بحيث يمكنه تخصيص مساحة لاستدعاء الدالة بصورة صحيحة.
</p>

<p>
	لم يكن هذا هو الحال دائمًا مع معايير لغة C، إذ افترضت المصِّرفات سابقًا أن أيّ دالة غير معروفة تعيد قيمة من النوع <code>int</code>. يكون لحجم المؤشر في نظام 32 بت حجم النوع <code>int</code> نفسه، لذلك لا توجد مشكلة في ذلك، ولكن يكون حجم المؤشر ضعف حجم <code>int</code> في نظام 64 بت، لذلك إذا أعادت الدالة مؤشرًا، فستُدمَّر قيمتها. يُعَد ذلك الأمر غير مقبول، لأن المؤشر لن يؤشّر إلى ذاكرة صالحة، ولكن تغيّر معيار C99 بحيث يُطلَب منك تحديد أنواع الدوال المُضمَّنة.
</p>

<h3>
	الربط Linking
</h3>

<p>
	يطبّق الرابط الديناميكي الكثير من العمل للمكتبات المشتركة، ولكن لا يزال الرابط التقليدي يلعب دورًا هامًا في إنشاء الملف القابل للتنفيذ، إذ يجب أن يضع الرابط التقليدي مؤشرًا في الملف القابل للتنفيذ حتى يعرف الرابط الديناميكي المكتبة التي ستحقّق الاعتماديات Dependencies في وقت التشغيل. يتطلب القسم <code>dynamic</code> من الملف القابل للتنفيذ مدخلة مطلوبة <code>NEEDED</code> لكل مكتبة مشتركة يعتمد عليها الملف القابل للتنفيذ.
</p>

<p>
	يمكننا فحص هذه الحقول باستخدام برنامج <code>readelf</code>. سنلقي فيما يلي نظرة على ملف ثنائي معياري <code>‎/bin/ls</code> يمثل تحديد المكتبات الديناميكية:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_2570_11" style=""><span class="pln">$ readelf </span><span class="pun">--</span><span class="pln">dynamic </span><span class="pun">/</span><span class="pln">bin</span><span class="pun">/</span><span class="pln">ls 

</span><span class="typ">Dynamic</span><span class="pln"> segment at offset </span><span class="lit">0x22f78</span><span class="pln"> contains </span><span class="lit">27</span><span class="pln"> entries</span><span class="pun">:</span><span class="pln">
  </span><span class="typ">Tag</span><span class="pln">        </span><span class="typ">Type</span><span class="pln">                         </span><span class="typ">Name</span><span class="pun">/</span><span class="typ">Value</span><span class="pln">
 </span><span class="lit">0x0000000000000001</span><span class="pln"> </span><span class="pun">(</span><span class="pln">NEEDED</span><span class="pun">)</span><span class="pln">             </span><span class="typ">Shared</span><span class="pln"> library</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">librt</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">1</span><span class="pun">]</span><span class="pln">
 </span><span class="lit">0x0000000000000001</span><span class="pln"> </span><span class="pun">(</span><span class="pln">NEEDED</span><span class="pun">)</span><span class="pln">             </span><span class="typ">Shared</span><span class="pln"> library</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">libacl</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">1</span><span class="pun">]</span><span class="pln">
 </span><span class="lit">0x0000000000000001</span><span class="pln"> </span><span class="pun">(</span><span class="pln">NEEDED</span><span class="pun">)</span><span class="pln">             </span><span class="typ">Shared</span><span class="pln"> library</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">libc</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">6.1</span><span class="pun">]</span><span class="pln">
 </span><span class="lit">0x000000000000000c</span><span class="pln"> </span><span class="pun">(</span><span class="pln">INIT</span><span class="pun">)</span><span class="pln">               </span><span class="lit">0x4000000000001e30</span><span class="pln">
 </span><span class="pun">...</span><span class="pln"> snip </span><span class="pun">...</span></pre>

<p>
	يمكنك أن ترى أن المثال السابق يحدد ثلاث مكتبات. المكتبة الأكثر شيوعًا التي تتشارك بها أغلبية البرامج الموجودة على النظام -إن لم تكن جميعها- هي مكتبة <code>libc</code>، وهناك بعض المكتبات الأخرى التي يحتاجها البرنامج ليعمل بصورة صحيحة.
</p>

<p>
	تكون قراءة ملف ELF المباشرة مفيدةً أحيانًا، ولكن الطريقة المعتادة لفحص ملف قابل للتنفيذ مرتبط ديناميكيًا هي باستخدام أداة <code>ldd</code> التي تمر على اعتماديات المكتبات، حيث ستظهِر لك إذا كانت المكتبة معتمدة على مكتبة أخرى كما يلي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_2570_13" style=""><span class="pln">$ ldd </span><span class="pun">/</span><span class="pln">bin</span><span class="pun">/</span><span class="pln">ls
        librt</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">1</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> </span><span class="pun">/</span><span class="pln">lib</span><span class="pun">/</span><span class="pln">tls</span><span class="pun">/</span><span class="pln">librt</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">1</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0x2000000000058000</span><span class="pun">)</span><span class="pln">
        libacl</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">1</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> </span><span class="pun">/</span><span class="pln">lib</span><span class="pun">/</span><span class="pln">libacl</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">1</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0x2000000000078000</span><span class="pun">)</span><span class="pln">
        libc</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">6.1</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> </span><span class="pun">/</span><span class="pln">lib</span><span class="pun">/</span><span class="pln">tls</span><span class="pun">/</span><span class="pln">libc</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">6.1</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0x2000000000098000</span><span class="pun">)</span><span class="pln">
        libpthread</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">0</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> </span><span class="pun">/</span><span class="pln">lib</span><span class="pun">/</span><span class="pln">tls</span><span class="pun">/</span><span class="pln">libpthread</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">0</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0x20000000002e0000</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">/</span><span class="pln">lib</span><span class="pun">/</span><span class="pln">ld</span><span class="pun">-</span><span class="pln">linux</span><span class="pun">-</span><span class="pln">ia64</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">2</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> </span><span class="pun">/</span><span class="pln">lib</span><span class="pun">/</span><span class="pln">ld</span><span class="pun">-</span><span class="pln">linux</span><span class="pun">-</span><span class="pln">ia64</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">2</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0x2000000000000000</span><span class="pun">)</span><span class="pln">
        libattr</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">1</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> </span><span class="pun">/</span><span class="pln">lib</span><span class="pun">/</span><span class="pln">libattr</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">1</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0x2000000000310000</span><span class="pun">)</span><span class="pln">
$ readelf </span><span class="pun">--</span><span class="pln">dynamic </span><span class="pun">/</span><span class="pln">lib</span><span class="pun">/</span><span class="pln">librt</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">1</span><span class="pln">

</span><span class="typ">Dynamic</span><span class="pln"> segment at offset </span><span class="lit">0xd600</span><span class="pln"> contains </span><span class="lit">30</span><span class="pln"> entries</span><span class="pun">:</span><span class="pln">
  </span><span class="typ">Tag</span><span class="pln">        </span><span class="typ">Type</span><span class="pln">                         </span><span class="typ">Name</span><span class="pun">/</span><span class="typ">Value</span><span class="pln">
 </span><span class="lit">0x0000000000000001</span><span class="pln"> </span><span class="pun">(</span><span class="pln">NEEDED</span><span class="pun">)</span><span class="pln">             </span><span class="typ">Shared</span><span class="pln"> library</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">libc</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">6.1</span><span class="pun">]</span><span class="pln">
 </span><span class="lit">0x0000000000000001</span><span class="pln"> </span><span class="pun">(</span><span class="pln">NEEDED</span><span class="pun">)</span><span class="pln">             </span><span class="typ">Shared</span><span class="pln"> library</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="pln">libpthread</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">0</span><span class="pun">]</span><span class="pln">
 </span><span class="pun">...</span><span class="pln"> snip </span><span class="pun">...</span></pre>

<p>
	يمكننا أن نرى في المثال السابق أن مكتبة <code>libpthread</code> مطلوبة من مكان ما، حيث إذا تعمّقنا قليلًا، فيمكننا أن نرى أنها مطلوبة من المكتبة <code>librt</code>.
</p>

<h2>
	الرابط الديناميكي Dynamic Linker
</h2>

<p>
	الرابط الديناميكي هو البرنامج الذي يدير المكتبات الديناميكية المشتركة بدلًا من الملف القابل للتنفيذ، ويعمل على تحميل المكتبات في الذاكرة وتعديل البرنامج في وقت التشغيل لاستدعاء الدوال الموجودة في المكتبة. يسمح ملف ELF للملفات القابلة للتنفيذ بتحديد المفسّر Interpreter الذي هو برنامج يجب استخدامه لتشغيل الملف القابل للتنفيذ. يضبط المصرِّف Compiler والرابط الساكن Static Linker مفسّر الملفات القابلة للتنفيذ الذي يعتمد على المكتبات الديناميكية ليكون الرابط الديناميكي.
</p>

<p>
	يوضَح المثال التالي كيفية التحقق من مفسّر البرنامج:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_2570_15" style=""><span class="pln">ianw@lime</span><span class="pun">:~/</span><span class="pln">programs</span><span class="pun">/</span><span class="pln">csbu$ readelf </span><span class="pun">--</span><span class="pln">headers </span><span class="pun">/</span><span class="pln">bin</span><span class="pun">/</span><span class="pln">ls

</span><span class="typ">Program</span><span class="pln"> </span><span class="typ">Headers</span><span class="pun">:</span><span class="pln">
  </span><span class="typ">Type</span><span class="pln">           </span><span class="typ">Offset</span><span class="pln">             </span><span class="typ">VirtAddr</span><span class="pln">           </span><span class="typ">PhysAddr</span><span class="pln">
                 </span><span class="typ">FileSiz</span><span class="pln">            </span><span class="typ">MemSiz</span><span class="pln">              </span><span class="typ">Flags</span><span class="pln">  </span><span class="typ">Align</span><span class="pln">
  PHDR           </span><span class="lit">0x0000000000000040</span><span class="pln"> </span><span class="lit">0x4000000000000040</span><span class="pln"> </span><span class="lit">0x4000000000000040</span><span class="pln">
                 </span><span class="lit">0x0000000000000188</span><span class="pln"> </span><span class="lit">0x0000000000000188</span><span class="pln">  R E    </span><span class="lit">8</span><span class="pln">
  INTERP         </span><span class="lit">0x00000000000001c8</span><span class="pln"> </span><span class="lit">0x40000000000001c8</span><span class="pln"> </span><span class="lit">0x40000000000001c8</span><span class="pln">
                 </span><span class="lit">0x0000000000000018</span><span class="pln"> </span><span class="lit">0x0000000000000018</span><span class="pln">  R      </span><span class="lit">1</span><span class="pln">
      </span><span class="pun">[</span><span class="typ">Requesting</span><span class="pln"> program interpreter</span><span class="pun">:</span><span class="pln"> </span><span class="pun">/</span><span class="pln">lib</span><span class="pun">/</span><span class="pln">ld</span><span class="pun">-</span><span class="pln">linux</span><span class="pun">-</span><span class="pln">ia64</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">2</span><span class="pun">]</span><span class="pln">
  LOAD           </span><span class="lit">0x0000000000000000</span><span class="pln"> </span><span class="lit">0x4000000000000000</span><span class="pln"> </span><span class="lit">0x4000000000000000</span><span class="pln">
                 </span><span class="lit">0x0000000000022e40</span><span class="pln"> </span><span class="lit">0x0000000000022e40</span><span class="pln">  R E    </span><span class="lit">10000</span><span class="pln">
  LOAD           </span><span class="lit">0x0000000000022e40</span><span class="pln"> </span><span class="lit">0x6000000000002e40</span><span class="pln"> </span><span class="lit">0x6000000000002e40</span><span class="pln">
                 </span><span class="lit">0x0000000000001138</span><span class="pln"> </span><span class="lit">0x00000000000017b8</span><span class="pln">  RW     </span><span class="lit">10000</span><span class="pln">
  DYNAMIC        </span><span class="lit">0x0000000000022f78</span><span class="pln"> </span><span class="lit">0x6000000000002f78</span><span class="pln"> </span><span class="lit">0x6000000000002f78</span><span class="pln">
                 </span><span class="lit">0x0000000000000200</span><span class="pln"> </span><span class="lit">0x0000000000000200</span><span class="pln">  RW     </span><span class="lit">8</span><span class="pln">
  NOTE           </span><span class="lit">0x00000000000001e0</span><span class="pln"> </span><span class="lit">0x40000000000001e0</span><span class="pln"> </span><span class="lit">0x40000000000001e0</span><span class="pln">
                 </span><span class="lit">0x0000000000000020</span><span class="pln"> </span><span class="lit">0x0000000000000020</span><span class="pln">  R      </span><span class="lit">4</span><span class="pln">
  IA_64_UNWIND   </span><span class="lit">0x0000000000022018</span><span class="pln"> </span><span class="lit">0x4000000000022018</span><span class="pln"> </span><span class="lit">0x4000000000022018</span><span class="pln">
                 </span><span class="lit">0x0000000000000e28</span><span class="pln"> </span><span class="lit">0x0000000000000e28</span><span class="pln">  R      </span><span class="lit">8</span></pre>

<p>
	يمكنك أن ترى في المثال السابق أن المفسّر مضبوط ليكون ‎/lib/ld-linux-ia64.so.2 أي يمثل الرابط الديناميكي. تتحقق النواة Kernel عندما تحمّل الملف الثنائي للتنفيذ مما إذا كان الحقل <code>PT_INTERP</code> موجودًا، حيث إذا كان موجودًا، فيجب تحميل ما يؤشّر إليه في الذاكرة وتشغيله.
</p>

<p>
	ذكرنا أن للملفات القابلة للتنفيذ المرتبطة ديناميكيًا مراجع يجب إصلاحها باستخدام معلومات غير متوفرة حتى وقت التشغيل مثل عنوان دالة موجودة في مكتبة مشتركة، وتسمَّى هذه المراجع بالانتقالات Relocations.
</p>

<h3>
	الانتقالات Relocations
</h3>

<p>
	يتمثل الجزء الأساسي من الرابط الديناميكي في إصلاح العناوين في وقت التشغيل الذي يُعَد المرة الوحيدة التي يمكنك أن تعرف فيها مكان تحميلك في الذاكرة بالضبط. يمكن التفكير في الانتقالات بأنها ملاحظة أن عنوانًا معينًا يجب إصلاحه في وقت التحميل، حيث يجب قراءة جميع الانتقالات وإصلاح العناوين التي تشير إليها للإشارة إلى المكان الصحيح قبل أن تصبح الشيفرة البرمجية جاهزة للتشغيل. إليك مثال عن عملية انتقال:
</p>

<table>
	<thead>
		<tr>
			<th>
				العنوان
			</th>
			<th>
				الحدث
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				0x123456
			</td>
			<td>
				عنوان الرمز "x"
			</td>
		</tr>
		<tr>
			<td>
				0x564773
			</td>
			<td>
				الدالة X
			</td>
		</tr>
	</tbody>
</table>

<p>
	هناك العديد من أنواع الانتقالات لكل معمارية، حيث يُوثَّق السلوك الدقيق لكل نوع بوصفه جزءًا من واجهة ABI الخاصة بالنظام. يُعَد تعريف الانتقالات واضحًا وسهلًا كما في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_2570_17" style=""><span class="kwd">typedef</span><span class="pln"> </span><span class="kwd">struct</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="typ">Elf32_Addr</span><span class="pln">    r_offset</span><span class="pun">;</span><span class="pln">  </span><span class="pun">&lt;---</span><span class="pln"> address to fix
  </span><span class="typ">Elf32_Word</span><span class="pln">    r_info</span><span class="pun">;</span><span class="pln">    </span><span class="pun">&lt;---</span><span class="pln"> symbol table pointer and relocation type
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">typedef</span><span class="pln"> </span><span class="kwd">struct</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="typ">Elf32_Addr</span><span class="pln">    r_offset</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Word</span><span class="pln">    r_info</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Sword</span><span class="pln">   r_addend</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span><span class="typ">Elf32_Rela</span></pre>

<p>
	يشير الحقل <code>r_offset</code> إلى الإزاحة في الملف التي يجب إصلاحها، ويحدد الحقل <code>r_info</code> نوع الانتقال الذي يصِف بالضبط ما يجب تطبيقه لإصلاح هذه الشيفرة البرمجية. تُعَد قيمة الرمز أبسط عملية انتقال مُعرَّفة لمعماريةٍ ما، حيث يمكنك ببساطة في هذه الحالة استبدال عنوان الرمز في الموقع المحدد، وبالتالي سيكتمل إصلاح عملية الانتقال.
</p>

<p>
	يوجد نوعان من الطرق المُستخدمة لتشغيل الانتقالات أحدهما مع قيمة مُضافة والآخر بدونها. القيمة المضافة هي ببساطة شيء يجب إضافته إلى العنوان الذي جرى إصلاحه للعثور على العنوان الصحيح، فمثلًا إذا كان الانتقال للرمز <code>i</code> مثلًا، فستُضبَط القيمة المُضافة على القيمة 8 لأن الشيفرة البرمجية الأصلية تطبّق شيئًا مثل <code>i[8]‎</code>، وهذا يعني العثور على عنوان <code>i</code> ثم تجاوزه بمقدار 8.
</p>

<p>
	يجب تخزين هذه القيمة المضافة في مكان ما، فمثلًا تُخزَّن في صيغة <code>REL</code> القيمة المُضافة في شيفرة البرنامج ضمن المكان الذي يجب أن يكون فيه العنوان الذي جرى إصلاحه. لذا يجب إصلاح العنوان بصورة صحيحة من خلال قراءة الذاكرة التي تريد إصلاحها للحصول على أيّ قيمة مضافة وتخزينها والعثور على العنوان الحقيقي وإضافة القيمة المضافة إليه ثم كتابته مرة أخرى فوق القيمة المضافة. بينما تحدد الصيغة <code>RELA</code> مكان القيمة المضافة في الانتقال مباشرةً.
</p>

<p>
	هناك بعض المقايضات لكلٍ من هاتين الصيغتين، إذ يجب في صيغة <code>REL</code> استخدام مرجع ذاكرة إضافي للعثور على القيمة المضافة قبل الإصلاح، لكنك لا تهدر مساحةً في الملف الثنائي لأنك تستخدم الذاكرة الهدف لعملية الانتقال. بينما يمكنك في صيغة <code>RELA</code> الاحتفاظ بالقيمة المضافة مع الانتقال، ولكنك تهدر هذه المساحة في ملف القرص الصلب الثنائي. تستخدم معظم الأنظمة الحديثة انتقالات <code>RELA</code>.
</p>

<h4>
	كيفية عمل الانتقالات
</h4>

<p>
	يوضح المثال التالي كيفية عمل الانتقالات، حيث سننشئ مكتبتين مشتركتين بسيطتين ونشير إلى إحدى المكتبتين من المكتبة الأخرى:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_2570_19" style=""><span class="pln">$ cat addendtest</span><span class="pun">.</span><span class="pln">c
</span><span class="kwd">extern</span><span class="pln"> </span><span class="typ">int</span><span class="pln"> i</span><span class="pun">[</span><span class="lit">4</span><span class="pun">];</span><span class="pln">
</span><span class="typ">int</span><span class="pln"> </span><span class="pun">*</span><span class="pln">j </span><span class="pun">=</span><span class="pln"> i </span><span class="pun">+</span><span class="pln"> </span><span class="lit">2</span><span class="pun">;</span><span class="pln">

$ cat addendtest2</span><span class="pun">.</span><span class="pln">c
</span><span class="typ">int</span><span class="pln"> i</span><span class="pun">[</span><span class="lit">4</span><span class="pun">];</span><span class="pln">

$ gcc </span><span class="pun">-</span><span class="pln">nostdlib </span><span class="pun">-</span><span class="pln">shared </span><span class="pun">-</span><span class="pln">fpic </span><span class="pun">-</span><span class="pln">s </span><span class="pun">-</span><span class="pln">o addendtest2</span><span class="pun">.</span><span class="pln">so addendtest2</span><span class="pun">.</span><span class="pln">c
$ gcc </span><span class="pun">-</span><span class="pln">nostdlib </span><span class="pun">-</span><span class="pln">shared </span><span class="pun">-</span><span class="pln">fpic </span><span class="pun">-</span><span class="pln">o addendtest</span><span class="pun">.</span><span class="pln">so addendtest</span><span class="pun">.</span><span class="pln">c </span><span class="pun">./</span><span class="pln">addendtest2</span><span class="pun">.</span><span class="pln">so

$ readelf </span><span class="pun">-</span><span class="pln">r </span><span class="pun">./</span><span class="pln">addendtest</span><span class="pun">.</span><span class="pln">so

</span><span class="typ">Relocation</span><span class="pln"> section </span><span class="str">'.rela.dyn'</span><span class="pln"> at offset </span><span class="lit">0x3b8</span><span class="pln"> contains </span><span class="lit">1</span><span class="pln"> entries</span><span class="pun">:</span><span class="pln">
  </span><span class="typ">Offset</span><span class="pln">          </span><span class="typ">Info</span><span class="pln">           </span><span class="typ">Type</span><span class="pln">           </span><span class="typ">Sym</span><span class="pun">.</span><span class="pln"> </span><span class="typ">Value</span><span class="pln">    </span><span class="typ">Sym</span><span class="pun">.</span><span class="pln"> </span><span class="typ">Name</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="typ">Addend</span><span class="pln">
</span><span class="lit">0000000104f8</span><span class="pln">  </span><span class="lit">000f00000027</span><span class="pln"> R_IA64_DIR64LSB   </span><span class="lit">0000000000000000</span><span class="pln"> i </span><span class="pun">+</span><span class="pln"> </span><span class="lit">8</span></pre>

<p>
	لدينا عملية انتقال واحدة في <code>addendtest.so</code> من النوع <code>R_IA64_DIR64LSB</code> الذي إن بحثت عنه في واجهة IA64 ABI، فيمكن تقسيمه إلى ما يلي:
</p>

<ol>
	<li>
		R_IA64: تبدأ جميع الانتقالات بهذه البادئة.
	</li>
	<li>
		DIR64: انتقال من النوع 64 بت المباشر.
	</li>
	<li>
		LSB: بما أن IA64 يمكن أن تعمل في أنماط Big Endian على تخزين البتات الأقل أهمية أولًا، و في أنماط Little Endian على تخزين البتات الأكثر أهمية أولًا، فسيكون هذا الانتقال Little Endian والذي يعني البايت الأقل أهميةً Least Significant Byte.
	</li>
</ol>

<p>
	تقول واجهة ABI أن هذا الانتقال يمثل قيمة الرمز الذي يؤشّر إليه مع أيّ قيمة مضافة. يمكننا أن نرى أن لدينا قيمة مضافة مقدارها 8 ، حيث أن حجم النوع <code>int</code> يساوي 4 أو <code>sizeof(int) == 4</code>، ونقلنا قيمتين من النوع <code>int</code> في المصفوفة أي <code>‎*j = i + 2</code>. لذا يمكن إصلاح هذا الانتقال في وقت التشغيل من خلال العثور على عنوان الرمز <code>i</code> ووضع قيمته بالإضافة إلى القيمة 8 في <code>0x104f8</code>.
</p>

<h3>
	استقلال المواقع
</h3>

<p>
	يُعطَى مقطع الشيفرة البرمجية ومقطع البيانات في ملف قابل للتنفيذ عنوانًا أساسيًا محددًا في الذاكرة الوهمية، لذا لا يمكن مشاركة شيفرة الملف القابل للتنفيذ الذي يحصل على فضاء عناوين جديد خاص به، وهذا يعني أن المصرِّف يعرف بالضبط مكان قسم البيانات ويمكنه الرجوع إليه مباشرةً.
</p>

<p>
	لا تمتلك المكتبات مثل هذا الضمان، إذ يمكنها معرفة أن قسم البيانات الخاص بها سيكون إزاحة محددة عن العنوان الأساسي، ولكن لا يمكن بالضبط معرفة مكان ذلك العنوان الأساسي إلّا في وقت التشغيل. لذا يجب إنشاء جميع المكتبات باستخدام شيفرة برمجية يمكن تنفيذها بغض النظر عن مكان وضعها في الذاكرة، ويُعرَف ذلك باسم الشيفرة المستقلة عن الموقع Position Independent Code، أو PIC اختصارًا. لاحظ أن قسم البيانات لا يزال يمثل إزاحة ثابتة عن قسم الشيفرة البرمجية، ولكن يجب إضافة الإزاحة إلى عنوان التحميل للعثور على عنوان البيانات.
</p>

<h2>
	جدول الإزاحة العام Global Offset Table
</h2>

<p>
	لا بد أنك لاحظت مشكلة خطيرة في الانتقالات Relocations عند التفكير في أهداف المكتبة المشتركة، حيث ذكرنا سابقًا أن ميزة المكتبة المشتركة مع الذاكرة الوهمية هي أن البرامج المتعددة يمكنها استخدام الشيفرة البرمجية الموجودة في الذاكرة من خلال مشاركة الصفحات.
</p>

<p>
	تنبع هذه المشكلة من حقيقة أن المكتبات ليس لديها أي ضمان حول مكان وضعها في الذاكرة، حيث سيجد الرابط الديناميكي المكان الأكثر ملاءمة في الذاكرة الوهمية لكل مكتبة مطلوبة ويضعها هناك. لكن إن لم يحدث ذلك، فستطلب كل مكتبة في النظام جزءها الخاص من الذاكرة الوهمية حتى لا تتداخل مع غيرها. تتطلب كل مكتبة جديدة في النظام تخصيصًا لها عند إضافتها، ويمكن كتابة مكتبة ضخمة لا تترك مساحةَ كافية للمكتبات الأخرى مع احتمالية ألّا يرغب برنامجك أبدًا في استخدام هذه المكتبة على أيّ حال. إذا عدّلتَ شيفرة مكتبة مشتركة لديها انتقال، فلن تصبح هذه الشيفرة البرمجية قابلةً للمشاركة، وبالتالي سنفقد ميزة المكتبة المشتركة.
</p>

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

<p>
	المنطقة المخصصة لهذه العناوين تسمى بجدول الإزاحة العام Global Offset Table -أو GOT اختصارًا- الذي يتواجد في القسم <code>‎.got</code> من ملف ELF.
</p>

<p>
	يوضح الشكل التالي كيفية الوصول إلى الذاكرة باستخدام جدول GOT:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="123886" href="https://academy.hsoub.com/uploads/monthly_2023_04/01_got-plt.png.9c64ec7d25629bf1f5514225399a7bd6.png" rel=""><img alt="كيفية الوصول إلى الذاكرة باستخدام جدول GOT في معمارية الحاسوب" class="ipsImage ipsImage_thumbnailed" data-fileid="123886" data-ratio="109.20" data-unique="dvoccaa8w" style="width: 500px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_04/01_got-plt.thumb.png.77b0a048034ba7128ab42fda5424580f.png"> </a>
</p>

<p>
	يُعَد جدول GOT خاصًا بكل عملية، ويجب أن يكون للعملية أذونات للكتابة خاصة بها. بينما يمكن مشاركة شيفرة المكتبة ويجب أن يكون للعملية فقط أذونات قراءة وتنفيذ الشيفرة البرمجية، وإلا فسيكون هناك خرق أمني خطير إذا تمكنت العملية من تعديل الشيفرة البرمجية.
</p>

<h3>
	كيفية عمل جدول GOT
</h3>

<p>
	يوضح المثال التالي كيفية استخدام جدول GOT:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2570_23" style=""><span class="pln">$ cat got</span><span class="pun">.</span><span class="pln">c
</span><span class="kwd">extern</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> i</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">void</span><span class="pln"> test</span><span class="pun">(</span><span class="kwd">void</span><span class="pun">)</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
  i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">100</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

$ gcc </span><span class="pun">-</span><span class="pln">nostdlib  </span><span class="pun">-</span><span class="pln">shared </span><span class="pun">-</span><span class="pln">o got</span><span class="pun">.</span><span class="pln">so </span><span class="pun">./</span><span class="pln">got</span><span class="pun">.</span><span class="pln">c

$ objdump </span><span class="pun">--</span><span class="pln">disassemble </span><span class="pun">./</span><span class="pln">got</span><span class="pun">.</span><span class="pln">so

</span><span class="pun">./</span><span class="pln">got</span><span class="pun">.</span><span class="pln">so</span><span class="pun">:</span><span class="pln">     file format elf64</span><span class="pun">-</span><span class="pln">ia64</span><span class="pun">-</span><span class="pln">little

</span><span class="typ">Disassembly</span><span class="pln"> </span><span class="kwd">of</span><span class="pln"> section </span><span class="pun">.</span><span class="pln">text</span><span class="pun">:</span><span class="pln">

</span><span class="lit">0000000000000410</span><span class="pln"> </span><span class="str">&lt;test&gt;</span><span class="pun">:</span><span class="pln">
 </span><span class="lit">410</span><span class="pun">:</span><span class="pln">   </span><span class="lit">0d</span><span class="pln"> </span><span class="lit">10</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">18</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">21</span><span class="pln">       </span><span class="pun">[</span><span class="pln">MFI</span><span class="pun">]</span><span class="pln">       mov r2</span><span class="pun">=</span><span class="pln">r12
 </span><span class="lit">416</span><span class="pun">:</span><span class="pln">   </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">02</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> c0                   nop</span><span class="pun">.</span><span class="pln">f </span><span class="lit">0x0</span><span class="pln">
 </span><span class="lit">41c</span><span class="pun">:</span><span class="pln">   </span><span class="lit">81</span><span class="pln"> </span><span class="lit">09</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">90</span><span class="pln">                         addl r14</span><span class="pun">=</span><span class="lit">24</span><span class="pun">,</span><span class="pln">r1</span><span class="pun">;;</span><span class="pln">
 </span><span class="lit">420</span><span class="pun">:</span><span class="pln">   </span><span class="lit">0d</span><span class="pln"> </span><span class="lit">78</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">1c</span><span class="pln"> </span><span class="lit">18</span><span class="pln"> </span><span class="lit">10</span><span class="pln">       </span><span class="pun">[</span><span class="pln">MFI</span><span class="pun">]</span><span class="pln">       ld8 r15</span><span class="pun">=[</span><span class="pln">r14</span><span class="pun">]</span><span class="pln">
 </span><span class="lit">426</span><span class="pun">:</span><span class="pln">   </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">02</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> c0                   nop</span><span class="pun">.</span><span class="pln">f </span><span class="lit">0x0</span><span class="pln">
 </span><span class="lit">42c</span><span class="pun">:</span><span class="pln">   </span><span class="lit">41</span><span class="pln"> </span><span class="lit">06</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">90</span><span class="pln">                         mov r14</span><span class="pun">=</span><span class="lit">100</span><span class="pun">;;</span><span class="pln">
 </span><span class="lit">430</span><span class="pun">:</span><span class="pln">   </span><span class="lit">11</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">38</span><span class="pln"> </span><span class="lit">1e</span><span class="pln"> </span><span class="lit">90</span><span class="pln"> </span><span class="lit">11</span><span class="pln">       </span><span class="pun">[</span><span class="pln">MIB</span><span class="pun">]</span><span class="pln">       st4 </span><span class="pun">[</span><span class="pln">r15</span><span class="pun">]=</span><span class="pln">r14
 </span><span class="lit">436</span><span class="pun">:</span><span class="pln">   c0 </span><span class="lit">00</span><span class="pln"> </span><span class="lit">08</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">42</span><span class="pln"> </span><span class="lit">80</span><span class="pln">                   mov r12</span><span class="pun">=</span><span class="pln">r2
 </span><span class="lit">43c</span><span class="pun">:</span><span class="pln">   </span><span class="lit">08</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">84</span><span class="pln"> </span><span class="lit">00</span><span class="pln">                         br</span><span class="pun">.</span><span class="pln">ret</span><span class="pun">.</span><span class="pln">sptk</span><span class="pun">.</span><span class="pln">many b0</span><span class="pun">;;</span><span class="pln">

$ readelf </span><span class="pun">--</span><span class="pln">sections </span><span class="pun">./</span><span class="pln">got</span><span class="pun">.</span><span class="pln">so
</span><span class="typ">There</span><span class="pln"> are </span><span class="lit">17</span><span class="pln"> section headers</span><span class="pun">,</span><span class="pln"> starting at offset </span><span class="lit">0x640</span><span class="pun">:</span><span class="pln">

</span><span class="typ">Section</span><span class="pln"> </span><span class="typ">Headers</span><span class="pun">:</span><span class="pln">
  </span><span class="pun">[</span><span class="typ">Nr</span><span class="pun">]</span><span class="pln"> </span><span class="typ">Name</span><span class="pln">              </span><span class="typ">Type</span><span class="pln">             </span><span class="typ">Address</span><span class="pln">           </span><span class="typ">Offset</span><span class="pln">
       </span><span class="typ">Size</span><span class="pln">              </span><span class="typ">EntSize</span><span class="pln">          </span><span class="typ">Flags</span><span class="pln">  </span><span class="typ">Link</span><span class="pln">  </span><span class="typ">Info</span><span class="pln">  </span><span class="typ">Align</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">0</span><span class="pun">]</span><span class="pln">                   NULL             </span><span class="lit">0000000000000000</span><span class="pln">  </span><span class="lit">00000000</span><span class="pln">
       </span><span class="lit">0000000000000000</span><span class="pln">  </span><span class="lit">0000000000000000</span><span class="pln">           </span><span class="lit">0</span><span class="pln">     </span><span class="lit">0</span><span class="pln">     </span><span class="lit">0</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">1</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">hash             HASH             </span><span class="lit">0000000000000120</span><span class="pln">  </span><span class="lit">00000120</span><span class="pln">
       </span><span class="lit">00000000000000a0</span><span class="pln">  </span><span class="lit">0000000000000004</span><span class="pln">   A       </span><span class="lit">2</span><span class="pln">     </span><span class="lit">0</span><span class="pln">     </span><span class="lit">8</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">2</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">dynsym           DYNSYM           </span><span class="lit">00000000000001c0</span><span class="pln">  </span><span class="lit">000001c0</span><span class="pln">
       </span><span class="lit">00000000000001f8</span><span class="pln">  </span><span class="lit">0000000000000018</span><span class="pln">   A       </span><span class="lit">3</span><span class="pln">     e     </span><span class="lit">8</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">3</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">dynstr           STRTAB           </span><span class="lit">00000000000003b8</span><span class="pln">  </span><span class="lit">000003b8</span><span class="pln">
       </span><span class="lit">000000000000003f</span><span class="pln">  </span><span class="lit">0000000000000000</span><span class="pln">   A       </span><span class="lit">0</span><span class="pln">     </span><span class="lit">0</span><span class="pln">     </span><span class="lit">1</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">4</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">rela</span><span class="pun">.</span><span class="pln">dyn         RELA             </span><span class="lit">00000000000003f8</span><span class="pln">  </span><span class="lit">000003f8</span><span class="pln">
       </span><span class="lit">0000000000000018</span><span class="pln">  </span><span class="lit">0000000000000018</span><span class="pln">   A       </span><span class="lit">2</span><span class="pln">     </span><span class="lit">0</span><span class="pln">     </span><span class="lit">8</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">5</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">text             PROGBITS         </span><span class="lit">0000000000000410</span><span class="pln">  </span><span class="lit">00000410</span><span class="pln">
       </span><span class="lit">0000000000000030</span><span class="pln">  </span><span class="lit">0000000000000000</span><span class="pln">  AX       </span><span class="lit">0</span><span class="pln">     </span><span class="lit">0</span><span class="pln">     </span><span class="lit">16</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">6</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">IA_64</span><span class="pun">.</span><span class="pln">unwind_inf PROGBITS         </span><span class="lit">0000000000000440</span><span class="pln">  </span><span class="lit">00000440</span><span class="pln">
       </span><span class="lit">0000000000000018</span><span class="pln">  </span><span class="lit">0000000000000000</span><span class="pln">   A       </span><span class="lit">0</span><span class="pln">     </span><span class="lit">0</span><span class="pln">     </span><span class="lit">8</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">7</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">IA_64</span><span class="pun">.</span><span class="pln">unwind     IA_64_UNWIND     </span><span class="lit">0000000000000458</span><span class="pln">  </span><span class="lit">00000458</span><span class="pln">
       </span><span class="lit">0000000000000018</span><span class="pln">  </span><span class="lit">0000000000000000</span><span class="pln">  AL       </span><span class="lit">5</span><span class="pln">     </span><span class="lit">5</span><span class="pln">     </span><span class="lit">8</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">8</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">data             PROGBITS         </span><span class="lit">0000000000010470</span><span class="pln">  </span><span class="lit">00000470</span><span class="pln">
       </span><span class="lit">0000000000000000</span><span class="pln">  </span><span class="lit">0000000000000000</span><span class="pln">  WA       </span><span class="lit">0</span><span class="pln">     </span><span class="lit">0</span><span class="pln">     </span><span class="lit">1</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">9</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="kwd">dynamic</span><span class="pln">          DYNAMIC          </span><span class="lit">0000000000010470</span><span class="pln">  </span><span class="lit">00000470</span><span class="pln">
       </span><span class="lit">0000000000000100</span><span class="pln">  </span><span class="lit">0000000000000010</span><span class="pln">  WA       </span><span class="lit">3</span><span class="pln">     </span><span class="lit">0</span><span class="pln">     </span><span class="lit">8</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">10</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">got              PROGBITS         </span><span class="lit">0000000000010570</span><span class="pln">  </span><span class="lit">00000570</span><span class="pln">
       </span><span class="lit">0000000000000020</span><span class="pln">  </span><span class="lit">0000000000000000</span><span class="pln"> </span><span class="typ">WAp</span><span class="pln">       </span><span class="lit">0</span><span class="pln">     </span><span class="lit">0</span><span class="pln">     </span><span class="lit">8</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">11</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">sbss             NOBITS           </span><span class="lit">0000000000010590</span><span class="pln">  </span><span class="lit">00000590</span><span class="pln">
       </span><span class="lit">0000000000000000</span><span class="pln">  </span><span class="lit">0000000000000000</span><span class="pln">   W       </span><span class="lit">0</span><span class="pln">     </span><span class="lit">0</span><span class="pln">     </span><span class="lit">1</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">12</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">bss              NOBITS           </span><span class="lit">0000000000010590</span><span class="pln">  </span><span class="lit">00000590</span><span class="pln">
       </span><span class="lit">0000000000000000</span><span class="pln">  </span><span class="lit">0000000000000000</span><span class="pln">  WA       </span><span class="lit">0</span><span class="pln">     </span><span class="lit">0</span><span class="pln">     </span><span class="lit">1</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">13</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">comment          PROGBITS         </span><span class="lit">0000000000000000</span><span class="pln">  </span><span class="lit">00000590</span><span class="pln">
       </span><span class="lit">0000000000000026</span><span class="pln">  </span><span class="lit">0000000000000000</span><span class="pln">           </span><span class="lit">0</span><span class="pln">     </span><span class="lit">0</span><span class="pln">     </span><span class="lit">1</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">14</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">shstrtab         STRTAB           </span><span class="lit">0000000000000000</span><span class="pln">  </span><span class="lit">000005b6</span><span class="pln">
       </span><span class="lit">000000000000008a</span><span class="pln">  </span><span class="lit">0000000000000000</span><span class="pln">           </span><span class="lit">0</span><span class="pln">     </span><span class="lit">0</span><span class="pln">     </span><span class="lit">1</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">15</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">symtab           SYMTAB           </span><span class="lit">0000000000000000</span><span class="pln">  </span><span class="lit">00000a80</span><span class="pln">
       </span><span class="lit">0000000000000258</span><span class="pln">  </span><span class="lit">0000000000000018</span><span class="pln">          </span><span class="lit">16</span><span class="pln">    </span><span class="lit">12</span><span class="pln">     </span><span class="lit">8</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">16</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">strtab           STRTAB           </span><span class="lit">0000000000000000</span><span class="pln">  </span><span class="lit">00000cd8</span><span class="pln">
       </span><span class="lit">0000000000000045</span><span class="pln">  </span><span class="lit">0000000000000000</span><span class="pln">           </span><span class="lit">0</span><span class="pln">     </span><span class="lit">0</span><span class="pln">     </span><span class="lit">1</span><span class="pln">
</span><span class="typ">Key</span><span class="pln"> to </span><span class="typ">Flags</span><span class="pun">:</span><span class="pln">
  W </span><span class="pun">(</span><span class="pln">write</span><span class="pun">),</span><span class="pln"> A </span><span class="pun">(</span><span class="pln">alloc</span><span class="pun">),</span><span class="pln"> X </span><span class="pun">(</span><span class="pln">execute</span><span class="pun">),</span><span class="pln"> M </span><span class="pun">(</span><span class="pln">merge</span><span class="pun">),</span><span class="pln"> S </span><span class="pun">(</span><span class="pln">strings</span><span class="pun">)</span><span class="pln">
  I </span><span class="pun">(</span><span class="pln">info</span><span class="pun">),</span><span class="pln"> L </span><span class="pun">(</span><span class="pln">link order</span><span class="pun">),</span><span class="pln"> G </span><span class="pun">(</span><span class="kwd">group</span><span class="pun">),</span><span class="pln"> x </span><span class="pun">(</span><span class="pln">unknown</span><span class="pun">)</span><span class="pln">
  O </span><span class="pun">(</span><span class="pln">extra OS processing required</span><span class="pun">)</span><span class="pln"> o </span><span class="pun">(</span><span class="pln">OS specific</span><span class="pun">),</span><span class="pln"> p </span><span class="pun">(</span><span class="pln">processor specific</span><span class="pun">)</span></pre>

<p>
	يوضّح المثال السابق كيفية إنشاء مكتبة مشتركة بسيطة تشير إلى رمز خارجي. لا نعرف عنوان هذا الرمز في وقت التصريف، لذلك نتركه للرابط الديناميكي لإصلاحه في وقت التشغيل. لكننا نريد أن تبقى الشيفرة البرمجية قابلةً للمشاركة في حالة رغبة العمليات الأخرى في استخدام هذه الشيفرة، حيث يوضّح التفكيك Disassembly كيفية تطبيق ذلك باستخدام القسم <code>‎.got</code>. يُعرف المسجّل <code>r1</code> في معمارية IA64 التي صُرِّفت المكتبة من أجلها بالمؤشر العام Global Pointer الذي يؤشّر دائمًا إلى مكان تحميل القسم <code>‎.got</code> في الذاكرة.
</p>

<p>
	إذا ألقينا نظرة على خرج الأداة <code>readelf</code>، فيمكننا أن نرى أن القسم <code>‎.got</code> يبدأ عند عنوان يبعد بمقدار 0x10570 بايت عن مكان تحميل المكتبة في الذاكرة. لذا إذا حُمِّلت المكتبة في الذاكرة عند العنوان 0x6000000000000000، فسيكون القسم <code>‎.got</code> موجودًا عند العنوان 0x6000000000010570، وسيؤشّر المسجّل <code>r1</code> دائمًا إلى هذا العنوان.
</p>

<p>
	كما يمكننا أن نرى أننا نخزن القيمة 100 في عنوان الذاكرة الموجود في المسجّل <code>r15</code> الذي يحتوي على قيمة عنوان الذاكرة المخزن في المسجل 14، حيث حمّلنا هذا العنوان من خلال إضافة عدد صغير إلى المسجّل 1. يُعَد جدول GOT مجرد قائمة طويلة من المدخلات، حيث تكون كل مدخلة خاصةً بمتغير خارجي، مما يعني أن مدخلة جدول GOT الخاصة بالمتغير الخارجي <code>i</code> تخزّن 24 بايتًا أو 3 عناوين بحجم 64 بتًا.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2570_25" style=""><span class="pln">$ readelf </span><span class="pun">--</span><span class="pln">relocs </span><span class="pun">./</span><span class="pln">got</span><span class="pun">.</span><span class="pln">so

</span><span class="typ">Relocation</span><span class="pln"> section </span><span class="str">'.rela.dyn'</span><span class="pln"> at offset </span><span class="lit">0x3f8</span><span class="pln"> contains </span><span class="lit">1</span><span class="pln"> entries</span><span class="pun">:</span><span class="pln">
  </span><span class="typ">Offset</span><span class="pln">          </span><span class="typ">Info</span><span class="pln">           </span><span class="typ">Type</span><span class="pln">           </span><span class="typ">Sym</span><span class="pun">.</span><span class="pln"> </span><span class="typ">Value</span><span class="pln">    </span><span class="typ">Sym</span><span class="pun">.</span><span class="pln"> </span><span class="typ">Name</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="typ">Addend</span><span class="pln">
</span><span class="lit">000000010588</span><span class="pln">  </span><span class="lit">000f00000027</span><span class="pln"> R_IA64_DIR64LSB   </span><span class="lit">0000000000000000</span><span class="pln"> i </span><span class="pun">+</span><span class="pln"> </span><span class="lit">0</span></pre>

<p>
	كما يمكننا التحقق من انتقال مدخلة جدول GOT، حيث يمثل الانتقالُ استبدالَ القيمة عند الإزاحة 10588 بموقع الذاكرة الذي خُزِّن فيه الرمز <code>i</code>.
</p>

<p>
	يبدأ القسم <code>‎.got</code> عند الإزاحة 0x10570 عن الخرج السابق، حيث رأينا كيف تحمّل الشيفرة البرمجية عنوانًا يبعد عن القسم <code>‎.got</code> بمقدار 0x18 (أو 24 في النظام العشري)، مما يمنحنا عنوانًا مقداره 0x10570 + 0x18 = 0x10588 يمثّل العنوان الذي طُبِّق الانتقال لأجله. لذا يجب أن يصلح الرابط الديناميكي الانتقال قبل أن يبدأ البرنامج للتأكد من أن قيمة الذاكرة عند الإزاحة 0x10588 هي عنوان المتغير العام <code>i</code>.
</p>

<p>
	ترجمة -وبتصرُّف- للأقسام <a href="https://bottomupcs.com/ch09.html" rel="external nofollow">Code Sharing</a> و <a href="https://bottomupcs.com/ch09s02.html" rel="external nofollow">The Dynamic Linker</a> و <a href="https://bottomupcs.com/ch09s03.html" rel="external nofollow">Global Offset Tables</a> من فصل <a href="https://bottomupcs.com/ch09.html" rel="external nofollow">Dynamic Linking</a> من كتاب <a href="https://www.bottomupcs.com/" rel="external nofollow">Computer Science from the Bottom Up</a> لصاحبه Ian Wienand.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال التالي:<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D9%84%D9%85%D9%83%D8%AA%D8%A8%D8%A7%D8%AA-%D9%88%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A7%D8%B3%D8%AA%D8%AF%D8%B9%D8%A7%D8%A1-%D8%AF%D9%88%D8%A7%D9%84%D9%87%D8%A7-%D8%AF%D9%8A%D9%86%D8%A7%D9%85%D9%8A%D9%83%D9%8A%D8%A7-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1966/" rel=""> المكتبات وكيفية استدعاء دوالها ديناميكيًا في معمارية الحاسوب</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D9%85%D9%81%D8%A7%D9%87%D9%8A%D9%85-%D9%85%D8%AA%D9%82%D8%AF%D9%85%D8%A9-%D9%85%D8%AA%D8%B9%D9%84%D9%82%D8%A9-%D8%A8%D8%B5%D9%8A%D8%BA%D8%A9-%D9%85%D9%84%D9%81%D8%A7%D8%AA-elf-%D8%A7%D9%84%D9%82%D8%A7%D8%A8%D9%84%D8%A9-%D9%84%D9%84%D8%AA%D9%86%D9%81%D9%8A%D8%B0-r1942/" rel="">مفاهيم متقدمة متعلقة بصيغة ملفات ELF القابلة للتنفيذ</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A7%D8%AA-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1722/" rel="">أنظمة المعالجات في معمارية الحاسوب</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA-%D9%88%D8%B9%D9%86%D8%A7%D8%B5%D8%B1%D9%87%D8%A7-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1758/" rel="">العمليات وعناصرها في نظام تشغيل الحاسوب</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1965</guid><pubDate>Wed, 26 Apr 2023 18:00:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x639;&#x645;&#x644;&#x64A;&#x627;&#x62A; &#x627;&#x644;&#x62A;&#x64A; &#x62A;&#x633;&#x628;&#x642; &#x628;&#x62F;&#x621; &#x62A;&#x646;&#x641;&#x64A;&#x630; &#x628;&#x631;&#x646;&#x627;&#x645;&#x62C; &#x641;&#x64A; &#x646;&#x638;&#x627;&#x645; &#x627;&#x644;&#x62A;&#x634;&#x63A;&#x64A;&#x644;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%AA%D9%8A-%D8%AA%D8%B3%D8%A8%D9%82-%D8%A8%D8%AF%D8%A1-%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D8%AC-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-r1943/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2023_03/------.png.0f358cfda7e81bf039a89f21865bf963.png" /></p>
<p>
	ذكرنا سابقًا أن البرنامج لا يبدأ بالدالة الرئيسية <code>main()‎</code>، حيث سنختبر في هذا المقال ما يحدث لبرنامج مرتبط ديناميكيًا عند تحميله وتشغيله.
</p>

<p>
	تخصّص النواة أولًا البنى لعملية جديدة وتقرأ <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D9%84%D9%85%D9%84%D9%81%D8%A7%D8%AA-%D8%A7%D9%84%D9%82%D8%A7%D8%A8%D9%84%D8%A9-%D9%84%D9%84%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%88%D8%AA%D9%85%D8%AB%D9%8A%D9%84%D9%87%D8%A7-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D8%B5%D9%8A%D8%BA%D8%A9-elf-r1941/" rel="">ملف ELF</a> المُحدَّد من القرص الصلب استجابةً <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B3%D9%84%D8%B3%D9%84-%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D9%87%D8%B1%D9%85%D9%8A-%D9%88%D8%A7%D8%B3%D8%AA%D8%AF%D8%B9%D8%A7%D8%A1%D8%A7%D8%AA-%D8%A7%D9%84%D9%86%D8%B8%D8%A7%D9%85-fork-%D9%88-exec-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1759/" rel="">لاستدعاء النظام <code>exec</code></a>. ذكرنا أن صيغة ELF لديها حقل لمفسّر Interpreter البرنامج هو <code>PT_INTERP</code> الذي يمكن ضبطه لتفسير البرنامج، حيث يكون المفسِّر بالنسبة للتطبيقات المرتبطة ديناميكيًا هو الرابط الديناميكي Dynamic Linker -أو ld.so- الذي يسمح بإجراء بعض عمليات الربط مباشرةً قبل بدء البرنامج.
</p>

<p>
	كما تقرأ النواة شيفرة الرابط الديناميكي، وتبدأ البرنامج من عنوان نقطة الدخول entry point الذي تحدده. سنختبر دور الرابط الديناميكي بالتفصيل لاحقًا، ولكن يكفي أن نقول أنه يضبط بعض الإعدادات مثل تحميل المكتبات التي يتطلبها التطبيق كما هو محدد في القسم الديناميكي من الملف الثنائي، ثم يبدأ تنفيذ البرنامج الثنائي عند عنوان نقطة الدخول أي الدالة <code>‎_init</code>.
</p>

<h2>
	اتصال النواة بالبرامج
</h2>

<p>
	تحتاج النواة Kernel إلى توصيل بعض الأشياء للبرامج عند بدء تشغيلها مثل وسائط البرنامج arguments ومتغيرات البيئة الحالية environment variables وبنية خاصة اسمها المتجه المساعد Auxiliary Vector أو <code>auxv</code> اختصارًا. يمكنك أن تطلب من الرابط الديناميكي أن يُظهر لك بعضًا من خرج تنقيح الأخطاء من البنية <code>auxv</code> من خلال تحديد قيمة البيئة كما يلي <code>LD_SHOW_AUXV=1</code>. تسمح الوسائط والبيئة والأشكال المختلفة من استدعاء النظام <code>exec</code> بتحديد هذه الأشياء للبرنامج التي يمكن للنواة توصيلها من خلال وضع جميع المعلومات المطلوبة في المكدس ليلتقطها البرنامج المُنشَأ حديثًا، وبالتالي يمكن للبرنامج عند بدء تشغيله استخدام مؤشر المكدس الخاص به للعثور على جميع معلومات بدء التشغيل المطلوبة.
</p>

<p>
	المتجه المساعد هو بنية خاصة لنقل المعلومات مباشرةً من النواة إلى البرنامج المُشغَّل حديثًا، ويحتوي على معلومات خاصة بالنظام يمكن أن تكون مطلوبة مثل الحجم الافتراضي لصفحة الذاكرة الوهمية على النظام أو إمكانات العتاد، وهذه هي الميزات التي تحددها النواة للعتاد الأساسي ويمكن أن تستفيد منها برامج مساحة المستخدمين.
</p>

<h3>
	مكتبة النواة Kernel Library
</h3>

<p>
	ذكرنا سابقًا أن استدعاءات النظام بطيئة وأن الأنظمة الحديثة لديها آليات لتجنب الحِمل الناتج عن استدعاء مصيدة Trap للمعالج، حيث يمكن تنفيذ ذلك في نظام لينكس من خلال استخدام حيلة بين المحمل الديناميكي والنواة المتصلَين ببنية <code>AUXV</code>، إذ تضيف النواة مكتبة مشتركة صغيرة إلى فضاء العناوين لكل عملية مُنشَأة حديثًا وتحتوي على دالة تجري استدعاءات النظام نيابة عنك. يكمن جمال هذا النظام في أنه إذا دعم العتاد الأساسي آلية استدعاء نظام سريعة، فيمكن للنواة استخدامها لكونها منشئة المكتبة، وإلّا فيمكنها استخدام النظام القديم لإنشاء مصيدة. تسمى هذه المكتبة <code>linux-gate.so.1</code> لأنها بوابة إلى عمل النواة الداخلي.
</p>

<p>
	تضيف النواة مدخلةً إلى البنية <code>auxv</code> تسمَّى <code>AT_SYSINFO_EHDR</code> عندما تبدأ الرابط الديناميكي، وهذه المدخلة هي العنوان الموجود في الذاكرة الذي توجد فيه مكتبة النواة الخاصة. يمكن للرابط الديناميكي عندما يبدأ البحثَ عن المؤشر <code>AT_SYSINFO_EHDR</code>، فإن وُجد، فستُحمَّل تلك المكتبة للبرنامج. لا يملك البرنامج أيّ فكرة عن وجود هذه المكتبة، لأنها تُعَد ترتيبًا خاصًا بين الرابط الديناميكي والنواة.
</p>

<p>
	ذكرنا أن المبرمجين يجرون استدعاءات النظام بطريقة غير مباشرة من خلال استدعاء الدوال في مكتبات النظام libc التي يمكنها التحقق مما إذا كان ملف النواة الثنائي الخاص محمَّلًا أم لا، فإذا كان الأمر كذلك، فيجب استخدام الدوال الموجودة ضمنه لإجراء استدعاءات النظام. إذا حددت النواة أن العتاد يمتلك القدرة المطلوبة، فيجب استخدام طريقة استدعاء النظام السريع.
</p>

<h3>
	بدء برنامج
</h3>

<p>
	تمرّر النواةُ المفسّرَ بعد تحميله إلى نقطة الدخول كما هو مذكور في ملف المفسّر (لاحظ عدم اختبار كيفية بدء الرابط الديناميكي). سيقفز الرابط الديناميكي إلى عنوان نقطة الدخول كما هو مذكور في ملف ELF الثنائي.
</p>

<p>
	يوضح المثال التالي نتيجة تفكيك Disassembley بدء تشغيل البرنامج:
</p>

<pre class="ipsCode">$ cat test.c

int main(void)
{
  return 0;
}

$ gcc -o test test.c

$ readelf --headers ./test | grep Entry
  Entry point address:               0x80482b0

$ objdump --disassemble ./test

[...]

080482b0 &lt;_start&gt;:
  80482b0:       31 ed                   xor    %ebp,%ebp
  80482b2:       5e                      pop    %esi
  80482b3:       89 e1                   mov    %esp,%ecx
  80482b5:       83 e4 f0                and    $0xfffffff0,%esp
  80482b8:       50                      push   %eax
  80482b9:       54                      push   %esp
  80482ba:       52                      push   %edx
  80482bb:       68 00 84 04 08          push   $0x8048400
  80482c0:       68 90 83 04 08          push   $0x8048390
  80482c5:       51                      push   %ecx
  80482c6:       56                      push   %esi
  80482c7:       68 68 83 04 08          push   $0x8048368
  80482cc:       e8 b3 ff ff ff          call   8048284 &lt;__libc_start_main@plt&gt;
  80482d1:       f4                      hlt
  80482d2:       90                      nop
  80482d3:       90                      nop

08048368 &lt;main&gt;:
  8048368:       55                      push   %ebp
  8048369:       89 e5                   mov    %esp,%ebp
  804836b:       83 ec 08                sub    $0x8,%esp
  804836e:       83 e4 f0                and    $0xfffffff0,%esp
  8048371:       b8 00 00 00 00          mov    $0x0,%eax
  8048376:       83 c0 0f                add    $0xf,%eax
  8048379:       83 c0 0f                add    $0xf,%eax
  804837c:       c1 e8 04                shr    $0x4,%eax
  804837f:       c1 e0 04                shl    $0x4,%eax
  8048382:       29 c4                   sub    %eax,%esp
  8048384:       b8 00 00 00 00          mov    $0x0,%eax
  8048389:       c9                      leave
  804838a:       c3                      ret
  804838b:       90                      nop
  804838c:       90                      nop
  804838d:       90                      nop
  804838e:       90                      nop
  804838f:       90                      nop

08048390 &lt;__libc_csu_init&gt;:
  8048390:       55                      push   %ebp
  8048391:       89 e5                   mov    %esp,%ebp
  [...]

08048400 &lt;__libc_csu_fini&gt;:
  8048400:       55                      push   %ebp
  [...]
</pre>

<p>
	يمكننا أن نرى في المثال البسيط السابق باستخدام أداة <code>readelf</code> أن نقطة الدخول هي الدالة <code>‎_start</code> في الملف الثنائي، ويمكننا أن نرى في عملية التفكيك دفع بعض القيم إلى المكدس. تمثل القيمة الأولى <code>0x8048400</code> الدالة <code>‎__libc_csu_fini</code>، وتمثل القيمة <code>0x8048390</code> الدالة <code>‎__libc_csu_init</code>، وتمثل القيمة <code>0x8048368</code> الدالة الرئيسية <code>main()‎</code>، ثم تُستدعَى قيمة الدالة <code>‎__libc_start_main</code>.
</p>

<p>
	الدالة <code>‎__libc_start_main</code> مُعرَّفة في مصادر مكتبة glibc ضمن <code>sysdeps/generic/libc-start.c</code>، وتُعَد معقدةً جدًا ومخفيةً بين عدد كبير من التعريفات، حيث يجب أن تكون قابلة للنقل عبر عدد كبير جدًا من الأنظمة والمعماريات التي يمكن لمكتبة glibc العمل عليها. تطبّق هذه الدالة عددًا من الأشياء المحدَّدة المتعلقة بإعداد مكتبة C والتي لا يحتاج المبرمج العادي للقلق بشأنها. النقطة التالية التي تستدعي فيها المكتبةُ البرنامجَ هي عند التعامل مع شيفرة <code>init</code>.
</p>

<p>
	تُعَد الدالتان <code>init</code> و<code>fini</code> مفهومين خاصين يستدعيان أجزاءً من الشيفرة البرمجية الموجودة في المكتبات المشتركة والتي يمكن أن تحتاج لاستدعائها قبل أن تبدأ المكتبة أو عند إلغاء تحميل المكتبة على التوالي. يمكنك أن ترى كيف يمكن أن يكون ذلك مفيدًا لمبرمجي المكتبات لإعداد المتغيرات عند بدء تشغيل المكتبة أو لتنظيفها في النهاية. كان البحث عن الدالتين <code>‎_init</code> و<code>‎_fini</code> في المكتبة ممكنًا سابقًا، ولكن أصبح ذلك مقيدًا إلى حد ما حيث كان كل شيء مطلوبًا في هاتين الدالتين. سنوضح فيما يلي كيفية عمل الدالتين <code>init</code> و<code>fini</code> فقط.
</p>

<p>
	يمكننا أن نرى الآن أن الدالة <code>‎__libc_start_main</code> ستتلقى عددًا من معاملات الدخل في المكدس stack، إذ سيكون بإمكانها أولًا الوصول إلى وسائط البرنامج ومتغيرات البيئة والمتجه المساعد من النواة، ثم ستدفع دالة التهيئة إلى عناوين المكدس الخاصة بالدوال للتعامل مع الدالتين <code>init</code> و<code>fini</code> ثم عنوان الدالة الرئيسية نفسها.
</p>

<p>
	نحتاج طريقةً ما للإشارة إلى أنه يجب استدعاء دالةٍ ما باستخدام <code>init</code> أو<code>fini</code> في الشيفرة المصدرية. نستخدم مع gcc سمات Attributes لتمييز دالتين بأنهما بانيتان Constructors أو ومدمرتان Destructors في برنامجنا الرئيسي. تُستخدَم هذه المصطلحات بصورة أكثر شيوعًا مع <a href="https://academy.hsoub.com/programming/general/%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-%D9%83%D8%A7%D8%A6%D9%86%D9%8A%D8%A9-%D8%A7%D9%84%D8%AA%D9%88%D8%AC%D9%87-r1375/" rel="">اللغات كائنية التوجه</a> لوصف دورات حياة الكائن.
</p>

<p>
	إليك مثال عن الباني والمدمر:
</p>

<pre class="ipsCode">$ cat test.c
#include &lt;stdio.h&gt;

void __attribute__((constructor)) program_init(void)  {
  printf("init\n");
}

void  __attribute__((destructor)) program_fini(void) {
  printf("fini\n");
}

int main(void)
{
  return 0;
}

$ gcc -Wall  -o test test.c

$ ./test
init
fini

$ objdump --disassemble ./test | grep program_init
08048398 &lt;program_init&gt;:

$ objdump --disassemble ./test | grep program_fini
080483b0 &lt;program_fini&gt;:

$ objdump --disassemble ./test 

[...]
08048280 &lt;_init&gt;:
  8048280:       55                      push   %ebp
  8048281:       89 e5                   mov    %esp,%ebp
  8048283:       83 ec 08                sub    $0x8,%esp
  8048286:       e8 79 00 00 00          call   8048304 &lt;call_gmon_start&gt;
  804828b:       e8 e0 00 00 00          call   8048370 &lt;frame_dummy&gt;
  8048290:       e8 2b 02 00 00          call   80484c0 &lt;__do_global_ctors_aux&gt;
  8048295:       c9                      leave
  8048296:       c3                      ret
[...]

080484c0 &lt;__do_global_ctors_aux&gt;:
  80484c0:       55                      push   %ebp
  80484c1:       89 e5                   mov    %esp,%ebp
  80484c3:       53                      push   %ebx
  80484c4:       52                      push   %edx
  80484c5:       a1 2c 95 04 08          mov    0x804952c,%eax
  80484ca:       83 f8 ff                cmp    $0xffffffff,%eax
  80484cd:       74 1e                   je     80484ed &lt;__do_global_ctors_aux+0x2d&gt;
  80484cf:       bb 2c 95 04 08          mov    $0x804952c,%ebx
  80484d4:       8d b6 00 00 00 00       lea    0x0(%esi),%esi
  80484da:       8d bf 00 00 00 00       lea    0x0(%edi),%edi
  80484e0:       ff d0                   call   *%eax
  80484e2:       8b 43 fc                mov    0xfffffffc(%ebx),%eax
  80484e5:       83 eb 04                sub    $0x4,%ebx
  80484e8:       83 f8 ff                cmp    $0xffffffff,%eax
  80484eb:       75 f3                   jne    80484e0 &lt;__do_global_ctors_aux+0x20&gt;
  80484ed:       58                      pop    %eax
  80484ee:       5b                      pop    %ebx
  80484ef:       5d                      pop    %ebp
  80484f0:       c3                      ret
  80484f1:       90                      nop
  80484f2:       90                      nop
  80484f3:       90                      nop


$ readelf --sections ./test
There are 34 section headers, starting at offset 0xfb0:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        08048114 000114 000013 00   A  0   0  1
  [ 2] .note.ABI-tag     NOTE            08048128 000128 000020 00   A  0   0  4
  [ 3] .hash             HASH            08048148 000148 00002c 04   A  4   0  4
  [ 4] .dynsym           DYNSYM          08048174 000174 000060 10   A  5   1  4
  [ 5] .dynstr           STRTAB          080481d4 0001d4 00005e 00   A  0   0  1
  [ 6] .gnu.version      VERSYM          08048232 000232 00000c 02   A  4   0  2
  [ 7] .gnu.version_r    VERNEED         08048240 000240 000020 00   A  5   1  4
  [ 8] .rel.dyn          REL             08048260 000260 000008 08   A  4   0  4
  [ 9] .rel.plt          REL             08048268 000268 000018 08   A  4  11  4
  [10] .init             PROGBITS        08048280 000280 000017 00  AX  0   0  4
  [11] .plt              PROGBITS        08048298 000298 000040 04  AX  0   0  4
  [12] .text             PROGBITS        080482e0 0002e0 000214 00  AX  0   0 16
  [13] .fini             PROGBITS        080484f4 0004f4 00001a 00  AX  0   0  4
  [14] .rodata           PROGBITS        08048510 000510 000012 00   A  0   0  4
  [15] .eh_frame         PROGBITS        08048524 000524 000004 00   A  0   0  4
  [16] .ctors            PROGBITS        08049528 000528 00000c 00  WA  0   0  4
  [17] .dtors            PROGBITS        08049534 000534 00000c 00  WA  0   0  4
  [18] .jcr              PROGBITS        08049540 000540 000004 00  WA  0   0  4
  [19] .dynamic          DYNAMIC         08049544 000544 0000c8 08  WA  5   0  4
  [20] .got              PROGBITS        0804960c 00060c 000004 04  WA  0   0  4
  [21] .got.plt          PROGBITS        08049610 000610 000018 04  WA  0   0  4
  [22] .data             PROGBITS        08049628 000628 00000c 00  WA  0   0  4
  [23] .bss              NOBITS          08049634 000634 000004 00  WA  0   0  4
  [24] .comment          PROGBITS        00000000 000634 00018f 00      0   0  1
  [25] .debug_aranges    PROGBITS        00000000 0007c8 000078 00      0   0  8
  [26] .debug_pubnames   PROGBITS        00000000 000840 000025 00      0   0  1
  [27] .debug_info       PROGBITS        00000000 000865 0002e1 00      0   0  1
  [28] .debug_abbrev     PROGBITS        00000000 000b46 000076 00      0   0  1
  [29] .debug_line       PROGBITS        00000000 000bbc 0001da 00      0   0  1
  [30] .debug_str        PROGBITS        00000000 000d96 0000f3 01  MS  0   0  1
  [31] .shstrtab         STRTAB          00000000 000e89 000127 00      0   0  1
  [32] .symtab           SYMTAB          00000000 001500 000490 10     33  53  4
  [33] .strtab           STRTAB          00000000 001990 000218 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

$ objdump --disassemble-all --section .ctors ./test

./test:     file format elf32-i386

Contents of section .ctors:
  8049528 ffffffff 98830408 00000000           ............    
</pre>

<p>
	كانت دالة التهيئة <code>‎__libc_csu_init</code> هي القيمة الأخيرة المدفوعة إلى المكدس من أجل الدالة <code>‎__libc_start_main</code>. إذا اتبعنا سلسلة الاستدعاءات ابتداءً من <code>‎__libc_csu_init</code>، فيمكننا أن نرى أنها تجري بعض الإعدادات ثم تستدعي الدالة <code>‎_init</code> في الملف القابل للتنفيذ. تستدعي الدالة <code>‎_init</code> في النهاية دالة تسمى <code>‎__do_global_ctors_aux</code>، حيث إذا نظرنا إلى تفكيك هذه الدالة، فيمكننا أن نرى أنها تبدأ من العنوان <code>0x804952c</code> ثم تتكرر وتقرأ قيمة وتستدعيها. هذا العنوان الذي يمثل البداية موجود في القسم <code>‎.ctors</code> من الملف، حيث إذا ألقينا نظرة عليه، فسنرى أنه يحتوي على القيمة الأولى ‎-1 وعنوان الدالة بصيغة Big Endian أي تخزين البتات الأقل أهمية أولًا والقيمة صفر.
</p>

<p>
	العنوان بصيغة Big Endian هو <code>0x08048398</code> أو عنوان الدالة <code>program_init</code>، لذا فإن صيغة القسم <code>‎.ctors</code> هي ‎-1 أولًا ثم عنوان الدوال المطلوب استدعاؤها عند التهيئة، وأخيرًا القيمة صفر للإشارة إلى اكتمال القائمة. ستُستدعَى كل مدخلة، ولدينا في هذه الحالة دالة واحدة فقط.
</p>

<p>
	أخيرًا، تستدعي الدالة <code>‎__libc_start_main</code> الدالةَ الرئيسية <code>main()‎</code> بمجرد اكتمالها باستدعاء الدالة <code>‎_init</code>. تذكر أن هذه الدالة تمتلك إعداد المكدس الأولي باستخدام الوسائط ومؤشرات البيئة من النواة، وهذه هي الطريقة التي تحصل بها الدالة الرئيسية على الوسائط <code>argc, argv[], envp[]‎</code>. تعمل العملية بعد ذلك وتكتمل مرحلة الإعداد.
</p>

<p>
	تحدث عملية مماثلة مع القسم <code>‎.dtors</code> للمدمرين Destructors عند إنهاء البرنامج، حيث تستدعيها الدالة <code>‎__libc_start_main</code> عند اكتمال الدالة الرئيسية <code>main()‎</code>.
</p>

<p>
	لاحظ تطبيق الكثير من العمل قبل أن يبدأ البرنامج وحتى بعد أن تعتقد أنه انتهى بقليل.
</p>

<p>
	ترجمة -وبتصرُّف- للقسم <a href="https://www.bottomupcs.com/starting_a_process.xhtml" rel="external nofollow">Starting a process</a> من فصل <a href="https://www.bottomupcs.com/chapter07.xhtml" rel="external nofollow">Behind the process</a> من كتاب <a href="https://www.bottomupcs.com/" rel="external nofollow">Computer Science from the Bottom Up</a> لصاحبه Ian Wienand.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D9%85%D9%81%D8%A7%D9%87%D9%8A%D9%85-%D9%85%D8%AA%D9%82%D8%AF%D9%85%D8%A9-%D9%85%D8%AA%D8%B9%D9%84%D9%82%D8%A9-%D8%A8%D8%B5%D9%8A%D8%BA%D8%A9-%D9%85%D9%84%D9%81%D8%A7%D8%AA-elf-%D8%A7%D9%84%D9%82%D8%A7%D8%A8%D9%84%D8%A9-%D9%84%D9%84%D8%AA%D9%86%D9%81%D9%8A%D8%B0-r1942/" rel="">مفاهيم متقدمة متعلقة بصيغة ملفات ELF القابلة للتنفيذ</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/advanced/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D9%84%D9%81-%D9%82%D8%A7%D8%A8%D9%84-%D9%84%D9%84%D8%AA%D9%86%D9%81%D9%8A%D8%B0-executable-file-%D9%85%D9%86-%D8%B4%D9%8A%D9%81%D8%B1%D8%A9-%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A9-%D9%85%D8%B5%D8%AF%D8%B1%D9%8A%D8%A9-source-code-r1930/" rel="">كيفية إنشاء ملف قابل للتنفيذ Executable File من شيفرة برمجية مصدرية Source Code</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1943</guid><pubDate>Fri, 14 Apr 2023 15:00:00 +0000</pubDate></item><item><title>&#x645;&#x641;&#x627;&#x647;&#x64A;&#x645; &#x645;&#x62A;&#x642;&#x62F;&#x645;&#x629; &#x645;&#x62A;&#x639;&#x644;&#x642;&#x629; &#x628;&#x635;&#x64A;&#x63A;&#x629; &#x645;&#x644;&#x641;&#x627;&#x62A; ELF &#x627;&#x644;&#x642;&#x627;&#x628;&#x644;&#x629; &#x644;&#x644;&#x62A;&#x646;&#x641;&#x64A;&#x630;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D9%85%D9%81%D8%A7%D9%87%D9%8A%D9%85-%D9%85%D8%AA%D9%82%D8%AF%D9%85%D8%A9-%D9%85%D8%AA%D8%B9%D9%84%D9%82%D8%A9-%D8%A8%D8%B5%D9%8A%D8%BA%D8%A9-%D9%85%D9%84%D9%81%D8%A7%D8%AA-elf-%D8%A7%D9%84%D9%82%D8%A7%D8%A8%D9%84%D8%A9-%D9%84%D9%84%D8%AA%D9%86%D9%81%D9%8A%D8%B0-r1942/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2023_03/------ELF.png.148921e30cd931ffba926c022b8c8969.png" /></p>
<p>
	تعرفنا في المقال السابق على <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D9%84%D9%85%D9%84%D9%81%D8%A7%D8%AA-%D8%A7%D9%84%D9%82%D8%A7%D8%A8%D9%84%D8%A9-%D9%84%D9%84%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%88%D8%AA%D9%85%D8%AB%D9%8A%D9%84%D9%87%D8%A7-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D8%B5%D9%8A%D8%BA%D8%A9-elf-r1941/" rel="">الملفات القابلة للتنفيذ في نظام التشغيل وتمثيلها باستخدام الصيغة ELF</a> وسنوضح في هذا المقال بعض المفاهيم المتعلقة بصيغة ملفات ELF مثل تنقيح الأخطاء Debugging وكيفية إنشاء أقسام مخصصة فيها وسكربتات الرابط Linker Scripts التي يستخدمها الرابط لبناء الأقسام Sections المُكوِّنة للمقاطع Segments، ولكن لنتعرّف أولًا على مفهوم ملفات ELF القابلة للتنفيذ.
</p>

<h2>
	ملفات ELF القابلة للتنفيذ
</h2>

<p>
	تُعَد الملفات القابلة للتنفيذ أحد الاستخدامات الأساسية لصيغة ELF. يحتوي الملف الثنائي على كل ما هو مطلوب لنظام التشغيل لتنفيذ الشيفرة البرمجية بالطريقة المطلوبة، حيث صُمِّم الملف التنفيذي لتشغيله في عملية ذات فضاء عناوين فريد، لذا يمكن للشيفرة البرمجية وضع افتراضات حول مكان تحميل أجزاء البرنامج المختلفة في الذاكرة.
</p>

<p>
	يوضح المثال الآتي اختبار أجزاء ملفٍ قابل للتنفيذ باستخدام أداة <code>readelf</code>. يمكننا أن نرى العناوين الوهمية التي يجب وضع مقاطع <code>LOAD</code> فيها، حيث يمكننا أن نرى أنّ أحد هذه المقاطع مخصصٌ للشيفرة البرمجية ويمتلك أذونات القراءة والتنفيذ فقط، وهناك مقطع آخر مخصصٌ للبيانات ولديه أذونات القراءة والكتابة دون وجود أذونات التنفيذ، فبدونها لن تُميَّز الصفحات التي تدعم خطأ ما بأن لها أذونات التنفيذ حتى إن سمح هذا الخطأ للمهاجم بإدخال بيانات عشوائية، وبالتالي لن تسمح معظم المعالجات بأيّ تنفيذ للشيفرة البرمجية في تلك الصفحات.
</p>

<pre class="ipsCode" id="ips_uid_4581_14">$ readelf --segments /bin/ls

Elf file type is EXEC (Executable file)
Entry point 0x4046d4
There are 8 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x00000000000001c0 0x00000000000001c0  R E    8
  INTERP         0x0000000000000200 0x0000000000400200 0x0000000000400200
                 0x000000000000001c 0x000000000000001c  R      1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x0000000000019ef4 0x0000000000019ef4  R E    200000
  LOAD           0x000000000001a000 0x000000000061a000 0x000000000061a000
                 0x000000000000077c 0x0000000000001500  RW     200000
  DYNAMIC        0x000000000001a028 0x000000000061a028 0x000000000061a028
                 0x00000000000001d0 0x00000000000001d0  RW     8
  NOTE           0x000000000000021c 0x000000000040021c 0x000000000040021c
                 0x0000000000000044 0x0000000000000044  R      4
  GNU_EH_FRAME   0x0000000000017768 0x0000000000417768 0x0000000000417768
                 0x00000000000006fc 0x00000000000006fc  R      4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     8

Section to Segment mapping:
  Segment Sections...
    00     
    01     .interp 
    02     .interp .note.ABI-tag .note.gnu.build-id .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 
    03     .ctors .dtors .jcr .dynamic .got .got.plt .data .bss 
    04     .dynamic 
    05     .note.ABI-tag .note.gnu.build-id 
    06     .eh_frame_hdr 
    07</pre>

<p>
	يجب تحميل مقاطع البرنامج على هذه العناوين، حيث تتمثل الخطوة الأخيرة للرابط Linker في تحليل معظم المنقولات Relocations وتصحيحها باستخدام العناوين المطلقة المُفترَضة، ثم تجاهل البيانات التي تصف الانتقال في الملف الثنائي النهائي دون وجود طريقة لإيجاد هذه المعلومات بعد الآن.
</p>

<p>
	تحتوي الملفات القابلة للتنفيذ عمومًا على اعتماديات Dependencies خارجية للمكتبات المشتركة Shared Libraries أو أجزاء من الشيفرة البرمجية المشتركة يمكن تجريدها ومشاركتها بين أجزاء النظام بأكمله، حيث تتعلق جميع الأجزاء الغريبة في المثال السابق باستخدام المكتبات المشتركة التي سنوضّحها لاحقًا.
</p>

<h2>
	تنقيح الأخطاء Debugging
</h2>

<p>
	يُشار تقليديًا إلى الطريقة الأساسية لتنقيح أخطاء ما بعد التعطل باسم التفريغ الأساسي Core Dump، حيث يأتي مصطلح الأساسي Core من الخصائص الفيزيائية الأصلية للذاكرة المغناطيسية الأساسية التي تستخدم اتجاه الحلقات المغناطيسية الصغيرة لتخزين الحالة. يُعَد التفريغ الأساسي لقطة كاملة للبرنامج عند عمله في وقت معين، ويمكن بعد ذلك استخدام منقح أخطاء Debugger لفحص هذا التفريغ وإعادة بناء حالة البرنامج. يوضح المثال التالي نموذجًا لبرنامج يكتب في موقع ذاكرة عشوائية لغرض التعطل، حيث ستتوقف العمليات ويُسجَّل تفريغ للحالة الحالية:
</p>

<pre class="ipsCode" id="ips_uid_4581_16">$ cat coredump.c
int main(void) {
  char *foo = (char*)0x12345;
  *foo = 'a';

  return 0;
}

$ gcc -Wall -g -o coredump coredump.c

$ ./coredump
Segmentation fault (core dumped)

$ file ./core
./core: ELF 32-bit LSB core file Intel 80386, version 1 (SYSV), SVR4-style, from './coredump'

$ gdb ./coredump
...
(gdb) core core
[New LWP 31614]
Core was generated by `./coredump'.
Program terminated with signal 11, Segmentation fault.
#0  0x080483c4 in main () at coredump.c:3
3        *foo = 'a';
(gdb)</pre>

<p>
	وبالتالي فإن ملف التفريغ الأساسي هو مجرد ملف ELF يحتوي على مجموعة من الأقسام التي يفهمها منقح الأخطاء لتمثيل أجزاء من البرنامج المُشغَّل.
</p>

<h3>
	الرموز ومعلومات تنقيح الأخطاء
</h3>

<p>
	يتطلب منقح الأخطاء gdb الملف القابل للتنفيذ الأصلي وملف التفريغ الأساسي لإعادة بناء بيئة جلسة تنقيح الأخطاء. لاحظ أن الملف القابل للتنفيذ الأصلي أُنشئ باستخدام الراية <code>‎-g</code> التي توجه <a href="https://academy.hsoub.com/programming/advanced/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D9%84%D9%81-%D9%82%D8%A7%D8%A8%D9%84-%D9%84%D9%84%D8%AA%D9%86%D9%81%D9%8A%D8%B0-executable-file-%D9%85%D9%86-%D8%B4%D9%8A%D9%81%D8%B1%D8%A9-%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A9-%D9%85%D8%B5%D8%AF%D8%B1%D9%8A%D8%A9-source-code-r1930/" rel="">المصرِّف Compiler</a> لتضمين جميع معلومات الأخطاء، حيث يجري الاحتفاظ بالمعلومات المتعلقة بعملية تنقيح الأخطاء الإضافية في أقسام خاصة من ملف ELF، إذ تصف هذه المعلومات بالتفصيل أشياءً مثل قيم المسجّل التي تحتوي حاليًا على المتغيرات المستخدمة في الشيفرة البرمجية وحجم المتغيرات وطول المصفوفات وغير ذلك. تكون هذه المعلومات بصيغة DWARF المعيارية التي تُعَد مرادفًا لصيغة ELF تقريبًا.
</p>

<p>
	يمكن أن يؤدي تضمين معلومات تنقيح الأخطاء إلى جعل الملفات والمكتبات القابلة للتنفيذ كبيرة جدًا، إذ لا تزال تشغل مساحة كبيرة على القرص الصلب بالرغم من أنها ليست مطلوبة في الذاكرة للتشغيل الفعلي، وبالتالي يجب إزالة هذه المعلومات من ملف ELF. يمكن نقل كل من الملفات التي أًزيلت منها هذه المعلومات والملفات التي لم تًُزال منها هذه المعلومات، ولكن توفّر معظم طرق توزيع أو نشر الملفات الثنائية binary distribution الحالية معلومات لتنقيح الأخطاء في ملفات منفصلة. يمكن استخدام أداة objcopy لاستخراج معلومات تنقيح الأخطاء (<code>‎--only-keep-debug</code>) ثم إضافة رابط في الملف القابل للتنفيذ الأصلي إلى هذه المعلومات المُزالَة (<code>‎--add-gnu-debuglink</code>)، ثم سيكون هناك قسم خاص بالاسم <code>‎.gnu_debuglink</code> موجود في الملف القابل للتنفيذ الأصلي ويحتوي على قيمة فريدة بحيث يمكن لمنقح الأخطاء عند بدء جلسات تنقيح الأخطاء التأكدَ من أنه يربط معلومات تنقيح الأخطاء الصحيحة بالملف التنفيذي الصحيح.
</p>

<p>
	يوضح المثال التالي إزالة معلومات تنقيح الأخطاء إلى ملفات منفصلة باستخدام الأداة objcopy:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_4581_10" style=""><span class="pln">$ gcc </span><span class="pun">-</span><span class="pln">g </span><span class="pun">-</span><span class="pln">shared </span><span class="pun">-</span><span class="pln">o libtest</span><span class="pun">.</span><span class="pln">so libtest</span><span class="pun">.</span><span class="pln">c
$ objcopy </span><span class="pun">--</span><span class="pln">only</span><span class="pun">-</span><span class="pln">keep</span><span class="pun">-</span><span class="pln">debug libtest</span><span class="pun">.</span><span class="pln">so libtest</span><span class="pun">.</span><span class="pln">debug
$ objcopy </span><span class="pun">--</span><span class="pln">add</span><span class="pun">-</span><span class="pln">gnu</span><span class="pun">-</span><span class="pln">debuglink</span><span class="pun">=</span><span class="pln">libtest</span><span class="pun">.</span><span class="pln">debug libtest</span><span class="pun">.</span><span class="pln">so
$ objdump </span><span class="pun">-</span><span class="pln">s </span><span class="pun">-</span><span class="pln">j </span><span class="pun">.</span><span class="pln">gnu_debuglink libtest</span><span class="pun">.</span><span class="pln">so

libtest</span><span class="pun">.</span><span class="pln">so</span><span class="pun">:</span><span class="pln">     file format elf32</span><span class="pun">-</span><span class="pln">i386

</span><span class="typ">Contents</span><span class="pln"> of section </span><span class="pun">.</span><span class="pln">gnu_debuglink</span><span class="pun">:</span><span class="pln">
 </span><span class="lit">0000</span><span class="pln"> </span><span class="lit">6c696274</span><span class="pln"> </span><span class="lit">6573742e</span><span class="pln"> </span><span class="lit">64656275</span><span class="pln"> </span><span class="lit">67000000</span><span class="pln">  libtest</span><span class="pun">.</span><span class="pln">debug</span><span class="pun">...</span><span class="pln">
 </span><span class="lit">0010</span><span class="pln"> </span><span class="lit">52a7fd0a</span><span class="pln">                             R</span><span class="pun">...</span></pre>

<p>
	تشغل الرموز مساحة أقل بكثير، ولكنها تُعَد هدفًا للإزالة من الخرج النهائي، إذ لن تكون هناك حاجة لبقاء معظم الرموز بمجرد ربط ملفات التعليمات المُصرَّفة object files لملف قابل للتنفيذ بالصورة النهائية. تُعَد الرموز مطلوبة لإصلاح مدخلات المنقولات Relocation، ولكن لن تكون الرموز بعد ذلك ضرورية تمامًا لتشغيل البرنامج النهائي. توفر سلسلة أدوات GNU لتجريد البرنامج في نظام لينكس خياراتٍ لإزالة الرموز. لاحظ أنه يجب تحليل بعض الرموز في وقت التشغيل (للربط الديناميكي Dynamic Linking)، ولكنها تُوضَع في جداول رموز ديناميكية منفصلة حتى لا تُزال وتجعل الخرج النهائي عديم الفائدة.
</p>

<h3>
	التفريغ الأساسي Coredump
</h3>

<p>
	يُعَد التفريغ الأساسي مجرد ملف ELF. يوضح المثال التالي مرونة صيغة ELF بوصفها صيغة ثنائية:
</p>

<pre class="ipsCode" id="ips_uid_4581_12">$ readelf --all ./core
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              CORE (Core file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          52 (bytes into file)
  Start of section headers:          0 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         15
  Size of section headers:           0 (bytes)
  Number of section headers:         0
  Section header string table index: 0

There are no sections in this file.

There are no sections to group in this file.

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  NOTE           0x000214 0x00000000 0x00000000 0x0022c 0x00000     0
  LOAD           0x001000 0x08048000 0x00000000 0x01000 0x01000 R E 0x1000
  LOAD           0x002000 0x08049000 0x00000000 0x01000 0x01000 RW  0x1000
  LOAD           0x003000 0x489fc000 0x00000000 0x01000 0x1b000 R E 0x1000
  LOAD           0x004000 0x48a17000 0x00000000 0x01000 0x01000 R   0x1000
  LOAD           0x005000 0x48a18000 0x00000000 0x01000 0x01000 RW  0x1000
  LOAD           0x006000 0x48a1f000 0x00000000 0x01000 0x153000 R E 0x1000
  LOAD           0x007000 0x48b72000 0x00000000 0x00000 0x01000     0x1000
  LOAD           0x007000 0x48b73000 0x00000000 0x02000 0x02000 R   0x1000
  LOAD           0x009000 0x48b75000 0x00000000 0x01000 0x01000 RW  0x1000
  LOAD           0x00a000 0x48b76000 0x00000000 0x03000 0x03000 RW  0x1000
  LOAD           0x00d000 0xb771c000 0x00000000 0x01000 0x01000 RW  0x1000
  LOAD           0x00e000 0xb774d000 0x00000000 0x02000 0x02000 RW  0x1000
  LOAD           0x010000 0xb774f000 0x00000000 0x01000 0x01000 R E 0x1000
  LOAD           0x011000 0xbfeac000 0x00000000 0x22000 0x22000 RW  0x1000

There is no dynamic section in this file.

There are no relocations in this file.

There are no unwind sections in this file.

No version information found in this file.

Notes at offset 0x00000214 with length 0x0000022c:
  Owner                 Data size    Description
  CORE                 0x00000090    NT_PRSTATUS (prstatus structure)
  CORE                 0x0000007c    NT_PRPSINFO (prpsinfo structure)
  CORE                 0x000000a0    NT_AUXV (auxiliary vector)
  LINUX                0x00000030    Unknown note type: (0x00000200)

$ eu-readelf -n ./core

Note segment of 556 bytes at offset 0x214:
  Owner          Data size  Type
  CORE                 144  PRSTATUS
    info.si_signo: 11, info.si_code: 0, info.si_errno: 0, cursig: 11
    sigpend: &lt;&gt;
    sighold: &lt;&gt;
    pid: 31614, ppid: 31544, pgrp: 31614, sid: 31544
    utime: 0.000000, stime: 0.000000, cutime: 0.000000, cstime: 0.000000
    orig_eax: -1, fpvalid: 0
    ebx:     1219973108  ecx:     1243440144  edx:              1
    esi:              0  edi:              0  ebp:     0xbfecb828
    eax:          74565  eip:     0x080483c4  eflags:  0x00010286
    esp:     0xbfecb818
    ds: 0x007b  es: 0x007b  fs: 0x0000  gs: 0x0033  cs: 0x0073  ss: 0x007b
  CORE                 124  PRPSINFO
    state: 0, sname: R, zomb: 0, nice: 0, flag: 0x00400400
    uid: 1000, gid: 1000, pid: 31614, ppid: 31544, pgrp: 31614, sid: 31544
    fname: coredump, psargs: ./coredump 
  CORE                 160  AUXV
    SYSINFO: 0xb774f414
    SYSINFO_EHDR: 0xb774f000
    HWCAP: 0xafe8fbff  &lt;fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov clflush dts acpi mmx fxsr sse sse2 ss tm pbe&gt;
    PAGESZ: 4096
    CLKTCK: 100
    PHDR: 0x8048034
    PHENT: 32
    PHNUM: 8
    BASE: 0
    FLAGS: 0
    ENTRY: 0x8048300
    UID: 1000
    EUID: 1000
    GID: 1000
    EGID: 1000
    SECURE: 0
    RANDOM: 0xbfecba1b
    EXECFN: 0xbfecdff1
    PLATFORM: 0xbfecba2b
    NULL
  LINUX                 48  386_TLS
    index: 6, base: 0xb771c8d0, limit: 0x000fffff, flags: 0x00000051
    index: 7, base: 0x00000000, limit: 0x00000000, flags: 0x00000028
    index: 8, base: 0x00000000, limit: 0x00000000, flags: 0x00000028
</pre>

<p>
	يمكننا أن نرى في المثال السابق اختبارًا باستخدام أداة <code>readelf</code> أولًا للملف الأساسي الناتج عن مثال إنشاء ملف تفريغ أساسي واستخدامه باستخدام منقح الأخطاء gdb. لا توجد أقسام أو منقولات أو معلومات أخرى غريبة في هذا الملف يمكن أن تكون مطلوبة لتحميل ملف قابل للتنفيذ أو مكتبة، إذ يتكون من سلسلة من ترويسات البرامج التي تمثل مقاطع <code>LOAD</code> التي هي عمليات تفريغ بيانات أولية أنشأتها النواة Kernel لتخصيصات الذاكرة الحالية.
</p>

<p>
	المكون الآخر لملف التفريغ الأساسي هو أقسام الملاحظات <code>NOTE</code> التي تحتوي على البيانات الضرورية لتنقيح الأخطاء ولكن ليس بالضرورة أن تُلتقَط في لقطة مباشرة لتخصيصات الذاكرة. يوفّر برنامج <code>eu-readelf</code> المُستخدَم في الجزء الثاني من المثال السابق رؤيةً أكثر اكتمالًا للبيانات من خلال فك تشفيرها.
</p>

<p>
	تقدّم الملاحظة <code>PRSTATUS</code> مجموعة من المعلومات حول العملية أثناء تشغيلها، فمثلًا يمكننا أن نرى من قيمة <code>cursig</code> أن البرنامج تلقى إشارة قيمتها 11 تمثل خطأ تقطيع segmentation fault. كما تتضمن بالإضافة إلى معلومات رقم العملية ملف تفريغ لجميع المسجلات الحالية. يمكن لمنقح الأخطاء بالنظر إلى قيم المسجّل إعادة بناء حالة المكدس وبالتالي توفير تعقب خلفي Backtrace، حيث يمكن لمنقح الأخطاء جنبًا إلى جنب مع الرمز ومعلومات تنقيح الأخطاء من الملف الثنائي الأصلي إظهار كيفية الوصول إلى نقطة التنفيذ الحالية.
</p>

<p>
	من المخرجات الأخرى المتجه المساعد الحالي Auxiliary Vector أو <code>AUXV</code> اختصارًا. تصف <code>386_TLS</code> مدخلات جدول الواصفات العام المستخدمة في تقديم Implementation معمارية x86 لمخزن محلي قائم على الخيوط thread-local storage. سيكون هناك مدخلات مكررة لكل خيط قيد التشغيل بالنسبة للتطبيق متعدد الخيوط، حيث سيفهم منقح الأخطاء ذلك وهذه هي الطريقة التي يطبّق بها منقح الأخطاء gdb الأمر <code>thread</code> لإظهار الخيوط والتبديل بينها.
</p>

<p>
	تنشئ النواة ملف التفريغ الأساسي ضمن حدود إعدادات <code>ulimit</code> الحالية، إذ يمكن أن يؤدي البرنامج الذي يستخدم قدرًا كبيرًا من الذاكرة إلى وجود ملف تفريغ كبير جدًا، ويُحتمَل أن يملأ القرص الصلب ويزيد المشاكل سوءًا، ويُضبَط <code>ulimit</code> على مستوى منخفض أو حتى على القيمة الصفر لأن معظم الأشخاص الذين ليسوا مطورين لديهم استخدام ضئيل لملف التفريغ الأساسي. لكن يظل التفريغ الأساسي هو الطريقة الأكثر فائدة لتنقيح أخطاء حالة غير متوقعة بعد التعطل.
</p>

<h2>
	إنشاء أقسام مخصصة
</h2>

<p>
	يُعَد تنظيم الشيفرة والبيانات والرموز شيئًا يمكن للمبرمج ترك إعدادات سلسلة أدواته الافتراضية كما هي، ولكن يمكن في بعض الأحيان توسيع أو تخصيص الأقسام ومحتوياتها مثل وحدات نواة لينكس التي تُستخدَم لتحميل المشغّلات والميزات الأخرى ديناميكيًا في نواة التشغيل. تُعَد هذه الوحدات غير قابلة للنقل، فهي تعمل فقط مع إصدار بناء نواة ثابت واحد، لذلك يمكن أن تكون الواجهة بين الوحدات والنواة مرنةً وغير مرتبطة بمعايير معينة، وبالتالي يمكن تعريف طرق تخزين مثل تخزين معلومات الترخيص والتأليف والاعتماديات والمعاملات الخاصة بالوحدات بصورة فريدة وكاملة باستخدام النواة.
</p>

<p>
	يمكن لأداة <code>modinfo</code> فحص هذه المعلومات في وحدةٍ ما وتقديمها للمستخدم. يوضح المثال التالي استخدام مثال عن وحدة نواة لينكس <code>fuse</code> التي تسمح لمكتبات مساحة المستخدم بتوفير تقديمات نظام الملفات للنواة:
</p>

<pre class="ipsCode">$ cd /lib/modules/$(uname -r)

$ sudo modinfo ./kernel/fs/fuse/fuse.ko 
filename:       /lib/modules/3.2.0-4-amd64/./kernel/fs/fuse/fuse.ko
alias:          devname:fuse
alias:          char-major-10-229
license:        GPL
description:    Filesystem in Userspace
author:         Miklos Szeredi &lt;miklos@szeredi.hu&gt;
depends:        
intree:         Y
vermagic:       3.2.0-4-amd64 SMP mod_unload modversions 
parm:           max_user_bgreq:Global limit for the maximum number of backgrounded requests an unprivileged user can set (uint)
parm:           max_user_congthresh:Global limit for the maximum congestion threshold an unprivileged user can set (uint)

$ objdump -s -j .modinfo ./kernel/fs/fuse/fuse.ko 

./kernel/fs/fuse/fuse.ko:     file format elf64-x86-64

Contents of section .modinfo:
 0000 616c6961 733d6465 766e616d 653a6675  alias=devname:fu
 0010 73650061 6c696173 3d636861 722d6d61  se.alias=char-ma
 0020 6a6f722d 31302d32 32390070 61726d3d  jor-10-229.parm=
 0030 6d61785f 75736572 5f636f6e 67746872  max_user_congthr
 0040 6573683a 476c6f62 616c206c 696d6974  esh:Global limit
 0050 20666f72 20746865 206d6178 696d756d   for the maximum
 0060 20636f6e 67657374 696f6e20 74687265   congestion thre
 0070 73686f6c 6420616e 20756e70 72697669  shold an unprivi
 0080 6c656765 64207573 65722063 616e2073  leged user can s
 0090 65740070 61726d74 7970653d 6d61785f  et.parmtype=max_
 00a0 75736572 5f636f6e 67746872 6573683a  user_congthresh:
 00b0 75696e74 00706172 6d3d6d61 785f7573  uint.parm=max_us
 00c0 65725f62 67726571 3a476c6f 62616c20  er_bgreq:Global 
 00d0 6c696d69 7420666f 72207468 65206d61  limit for the ma
 00e0 78696d75 6d206e75 6d626572 206f6620  ximum number of 
 00f0 6261636b 67726f75 6e646564 20726571  backgrounded req
 0100 75657374 7320616e 20756e70 72697669  uests an unprivi
 0110 6c656765 64207573 65722063 616e2073  leged user can s
 0120 65740070 61726d74 7970653d 6d61785f  et.parmtype=max_
 0130 75736572 5f626772 65713a75 696e7400  user_bgreq:uint.
 0140 6c696365 6e73653d 47504c00 64657363  license=GPL.desc
 0150 72697074 696f6e3d 46696c65 73797374  ription=Filesyst
 0160 656d2069 6e205573 65727370 61636500  em in Userspace.
 0170 61757468 6f723d4d 696b6c6f 7320537a  author=Miklos Sz
 0180 65726564 69203c6d 696b6c6f 7340737a  eredi &lt;miklos@sz
 0190 65726564 692e6875 3e000000 00000000  eredi.hu&gt;.......
 01a0 64657065 6e64733d 00696e74 7265653d  depends=.intree=
 01b0 59007665 726d6167 69633d33 2e322e30  Y.vermagic=3.2.0
 01c0 2d342d61 6d643634 20534d50 206d6f64  -4-amd64 SMP mod
 01d0 5f756e6c 6f616420 6d6f6476 65727369  _unload modversi
 01e0 6f6e7320 00                          ons .     
</pre>

<p>
	تحلّل الأداة <code>modinfo</code> القسم <code>‎.modinfo</code> المُضمَّن في ملف الوحدة لتقديم تفاصيلها. يوضح المثال التالي كيفية وضع حقل "المؤلف Author" في الوحدة، حيث تأتي هذه الشيفرة البرمجية غالبًا من <code>include/linux/module.h</code>:
</p>

<pre class="ipsCode">/*
 * ابدأ من الأسفل ثم انتقل إلى الأعلى
 */

 ‫/* وحدات الماكرو غير المباشرة مطلوبة للصق الوسيط المُوسَّع مثل الماكرو‫ __LINE__ */
#define ___PASTE(a,b) a##b
#define __PASTE(a,b) ___PASTE(a,b)


#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)

/* تحويل الماكرو غير المباشر إلى سلسلة نصية. يسمح إنشاء مستويين للمعامل بأن يكون ماكرو بحد ذاته، حيث يتحوّل‫ __stringify(FOO)‎ مثلًا إلى السلسلة "bar" عند التصريف باستخدام ‎-DFOO=bar.  */

#define __stringify_1(x...)     #x
#define __stringify(x...)       __stringify_1(x)

#define __MODULE_INFO(tag, name, info)                                    \
static const char __UNIQUE_ID(name)[]                                     \
  __used __attribute__((section(".modinfo"), unused, aligned(1)))         \
  = __stringify(tag) "=" info

‫/* معلومات عامة للصيغة‫ tag = "info"‎ */
#define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)

/*
* ‫استخدم للمؤلفين المتعددين الذين يستخدمون "Name &lt;email&gt;‎" أو "Name" فقط 
‫تعليمات أو سطور MODULE_AUTHOR()‎ متعددة *  
*/
#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author)

/* ---- */

MODULE_AUTHOR("Your Name &lt;your@name.com&gt;");
</pre>

<p>
	لنبدأ من الجزء السفلي حيث نرى أن الوحدة <code>MODULE_AUTHOR</code> تغلّف الماكرو الأعم <code>‎__MODULE_INFO</code>، ويمكننا أن نرى أننا نبني متغيرًا من النوع <code>static const char []‎</code> ليحتوي على السلسلة النصية <code>"author=Your Name &lt;your@name.com&gt;‎"</code>. لاحظ أن المتغير لديه معامل إضافي <code>‎__attribute__((section(".modinfo")))‎</code> يخبر المصرّف بعدم وضع هذا المتغير في قسم البيانات <code>data</code> مع المتغيرات الأخرى، ولكن يمكن إخفاؤه في قسم ELF الخاص به الذي اسمه <code>‎.modinfo</code>. توقِف المعاملات الأخرى المتغير الذي يجري تحسينه لأنه يبدو غير مُستخدَم وللتأكد من أننا نضع المتغيرات بجانب بعضها بعضًا من خلال تحديد المحاذاة.
</p>

<p>
	هناك استخدام واسع النطاق لتحويل وحدات الماكرو إلى سلاسل نصية Stringification Macros، وهي حيل تُستخدَم في معالج لغة C المسبق لضمان أن السلاسل النصية والتعاريف يمكن أن تكون مع بعضها البعض. يوفّر المصرِّف gcc التعريف الخاص <code>__COUNTER__</code> الذي يوفر قيمة فريدة ومتزايدة في كل استدعاء، مما يسمح باستدعاءات وحدة <code>MODULE_AUTHOR</code> متعددة في ملف واحد دون استخدام اسم المتغير نفسه.
</p>

<p>
	يمكننا فحص الرموز الموضوعة في الوحدة النهائية لمعرفة النتيجة النهائية كما يلي:
</p>

<pre class="ipsCode">$ objdump --syms ./fuse.ko | grep modinfo

0000000000000000 l    d  .modinfo    0000000000000000 .modinfo
0000000000000000 l     O .modinfo    0000000000000013 __UNIQUE_ID_alias1
0000000000000013 l     O .modinfo    0000000000000018 __UNIQUE_ID_alias0
000000000000002b l     O .modinfo    0000000000000011 __UNIQUE_ID_alias8
000000000000003c l     O .modinfo    000000000000000e __UNIQUE_ID_alias7
000000000000004a l     O .modinfo    0000000000000068 __UNIQUE_ID_max_user_congthresh6
00000000000000b2 l     O .modinfo    0000000000000022 __UNIQUE_ID_max_user_congthreshtype5
00000000000000d4 l     O .modinfo    000000000000006e __UNIQUE_ID_max_user_bgreq4
0000000000000142 l     O .modinfo    000000000000001d __UNIQUE_ID_max_user_bgreqtype3
000000000000015f l     O .modinfo    000000000000000c __UNIQUE_ID_license2
000000000000016b l     O .modinfo    0000000000000024 __UNIQUE_ID_description1
000000000000018f l     O .modinfo    000000000000002a __UNIQUE_ID_author0
00000000000001b9 l     O .modinfo    0000000000000011 __UNIQUE_ID_alias0
00000000000001d0 l     O .modinfo    0000000000000009 __module_depends
00000000000001d9 l     O .modinfo    0000000000000009 __UNIQUE_ID_intree1
00000000000001e2 l     O .modinfo    000000000000002f __UNIQUE_ID_vermagic0
</pre>

<h2>
	سكربتات الرابط Linker Scripts
</h2>

<p>
	تتمثل وظيفة الرابط في بناء الأقسام Sections لتشكيل المقاطع Segments من خلال استخدام سكربت الرابط الذي يصِف مكان بدء المقاطع والأقسام الموجودة فيها ويحدد المعاملات الأخرى.
</p>

<p>
	يوضح المثال الآتي مقتطفًا من سكربت الرابط الافتراضي الذي سيعرضه الرابط عند إعطاء الراية التفصيلية Verbose باستخدام الرايتين <code>‎-Wl</code> و<code>‎--verbose</code> مع gcc. السكربت الافتراضي مُضمَّنٌ في الرابط ويعتمد على تعريفات <a href="https://academy.hsoub.com/programming/general/%D9%85%D8%A7-%D9%87%D9%8A-%D9%88%D8%A7%D8%AC%D9%87%D8%A9-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A9-%D9%84%D9%84%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-api%D8%9F-r1512/" rel="">واجهة <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr></a> المعيارية لإنشاء برامج عاملة لمساحة مستخدمٍ خاصة بمنصة البناء.
</p>

<pre class="ipsCode">$ gcc -Wl,--verbose -o test test.c
GNU ld (GNU Binutils for Debian) 2.26
...
using internal linker script:
==================================================
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
          "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu"); ...
SECTIONS
{
  ‫/* أقسام للقراءة فقط مُدمَجة في مقطع النص‫ text segment: */
  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
  .interp         : { *(.interp) }
  .note.gnu.build-id : { *(.note.gnu.build-id) }
  .hash           : { *(.hash) }
  .gnu.hash       : { *(.gnu.hash) }
  .dynsym         : { *(.dynsym) }
  .dynstr         : { *(.dynstr) }
  .gnu.version    : { *(.gnu.version) }
  .gnu.version_d  : { *(.gnu.version_d) }
  .gnu.version_r  : { *(.gnu.version_r) }
  .rela.dyn       :
    {
    ...
    }
  PROVIDE (etext = .);
  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
  .rodata1        : { *(.rodata1) }
...
</pre>

<p>
	يمكنك أن ترى في المثال السابق كيف يحدد سكربت الرابط أمورًا متعددة مثل مواقع البدء والأقسام المراد تجميعها في مقاطع مختلفة. تُستخدَم الراية <code>‎-Wl</code> لتمرير الراية <code>‎--verbose</code> إلى الرابط عبر gcc، إذ يمكن توفير سكربتات مخصصة للرابط باستخدام الرايات. ليس مُحتمًلًا أن يحتاج مطورو مساحة المستخدم العادية إلى تجاوز سكربت الرابط الافتراضي، ولكن تتطلب التطبيقات المخصَّصة جدًا مثل عمليات بناء النواة سكربتات مخصصة للرابط في أغلب الأحيان.
</p>

<p>
	ترجمة -وبتصرُّف- للقسمين <a href="https://www.bottomupcs.com/executables.xhtml" rel="external nofollow">ELF Executables</a> و <a href="https://www.bottomupcs.com/elf-sections-others.xhtml" rel="external nofollow">Extending ELF concepts</a> من فصل <a href="https://www.bottomupcs.com/chapter07.xhtml" rel="external nofollow">Behind the process</a> من كتاب <a href="https://www.bottomupcs.com/" rel="external nofollow">Computer Science from the Bottom Up</a> لصاحبه Ian Wienand.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D9%85%D9%81%D9%87%D9%88%D9%85-%D8%A7%D9%84%D8%B1%D8%A8%D8%B7-%D8%A7%D9%84%D8%AF%D9%8A%D9%86%D8%A7%D9%85%D9%8A%D9%83%D9%8A-dynamic-linking-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1965/" rel="">مفهوم الربط الديناميكي Dynamic Linking في معمارية الحاسوب</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D9%84%D9%85%D9%84%D9%81%D8%A7%D8%AA-%D8%A7%D9%84%D9%82%D8%A7%D8%A8%D9%84%D8%A9-%D9%84%D9%84%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%88%D8%AA%D9%85%D8%AB%D9%8A%D9%84%D9%87%D8%A7-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D8%B5%D9%8A%D8%BA%D8%A9-elf-r1941/" rel="">الملفات القابلة للتنفيذ في نظام التشغيل وتمثيلها باستخدام الصيغة ELF</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/c/%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D8%B9%D9%85%D9%84%D9%8A-%D9%84%D8%A8%D9%86%D8%A7%D8%A1-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D8%AC-%D8%AA%D9%86%D9%81%D9%8A%D8%B0%D9%8A-%D9%85%D9%86-%D8%B4%D9%8A%D9%81%D8%B1%D8%A9-%D9%85%D8%B5%D8%AF%D8%B1%D9%8A%D8%A9-%D8%A8%D9%84%D8%BA%D8%A9-c-r1931/" rel="">تطبيق عملي لبناء برنامج تنفيذي من شيفرة مصدرية بلغة C</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1942</guid><pubDate>Fri, 07 Apr 2023 15:07:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x645;&#x644;&#x641;&#x627;&#x62A; &#x627;&#x644;&#x642;&#x627;&#x628;&#x644;&#x629; &#x644;&#x644;&#x62A;&#x646;&#x641;&#x64A;&#x630; &#x641;&#x64A; &#x646;&#x638;&#x627;&#x645; &#x627;&#x644;&#x62A;&#x634;&#x63A;&#x64A;&#x644; &#x648;&#x62A;&#x645;&#x62B;&#x64A;&#x644;&#x647;&#x627; &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x627;&#x644;&#x635;&#x64A;&#x63A;&#x629; ELF</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D9%84%D9%85%D9%84%D9%81%D8%A7%D8%AA-%D8%A7%D9%84%D9%82%D8%A7%D8%A8%D9%84%D8%A9-%D9%84%D9%84%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%88%D8%AA%D9%85%D8%AB%D9%8A%D9%84%D9%87%D8%A7-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D8%B5%D9%8A%D8%BA%D8%A9-elf-r1941/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2023_03/--------ELF.png.eebac4a1eab3a97caf437efe4a4d392c.png" /></p>
<p>
	يحتوي البرنامج الذي يعمل في الذاكرة على مكونين رئيسيين هما: الشيفرة البرمجية Code المعروفة أيضًا باسم النص Text والبيانات Data. لا يبقى الملف القابل للتنفيذ في الذاكرة، ولكنه يقضي معظم وقته بوصفه ملفًا على القرص الصلب ينتظر تحميله عند التشغيل. يُعَد الملف مجرد مصفوفة متجاورة من البتات، لذا تبتكر جميع الأنظمة طرقًا لتنظيم الشيفرة البرمجية والبيانات ضمن الملفات للتنفيذ عند الطلب، حيث يشار إلى هذه الصيغة من الملفات باسم ملف ثنائي Binary أو ملف قابل للتنفيذ Executable، وتكون البتات والبايتات الخاصة بالملف بصيغة جاهزة لوضعها في الذاكرة وتفسيرها مباشرةً بواسطة عتاد المعالج.
</p>

<h2>
	تمثيل الملفات القابلة للتنفيذ
</h2>

<p>
	يجب أن تحدّد أيّ صيغة لملفٍ قابل للتنفيذ executable file مكانَ وجود الشيفرة البرمجية والبيانات في الملف الثنائي، حيث تُعَد الشيفرة البرمجية والبيانات القسمين الأساسيين لملفٍ قابل للتنفيذ، وأحد المكونات الإضافية التي لم نذكرها حتى الآن هو مساحة تخزين المتغيرات العامة غير المُهيَّأة uninitialised global variables.
</p>

<p>
	إذا صرّحنا عن متغير وأعطيناه قيمة أولية، فيجب تخزين هذه القيمة في ملف قابل للتنفيذ بحيث يمكن تهيئته بالقيمة الصحيحة عند بدء البرنامج، ولكن هناك العديد من المتغيرات غير المهيأة أو التي قيمتها صفر عند تنفيذ البرنامج لأول مرة. يُعَد حجز مساحة لهذه المتغيرات في الملف القابل للتنفيذ ثم تخزين قيم صفرية أو فارغة NULL هدرًا للمساحة، مما يؤدي إلى تضخّم حجم الملف القابل للتنفيذ على القرص الصلب دون داع لذلك. تُعرِّف معظم الصيغ الثنائية مفهوم القسم <code>BSS</code> الإضافي بوصفه حجمًا بديلًا للبيانات الصفرية غير المُهيَّأة. يمكن تخصيص الذاكرة الإضافية التي يحدّدها القسم BSS وضبطها على القيمة صفر عند تحميل البرنامج. يرمز الاختصار BSS إلى العبارة Block Started by Symbol، وهو أمر بلغة تجميع حاسوب IBM القديم، ولكن يُرجَّح أن الاشتقاق الدقيق له ضاع مع الوقت.
</p>

<h3>
	الصيغة الثنائية Binary Format
</h3>

<p>
	يُنشَأ الملف القابل بالتنفيذ باستخدام سلسلة أدوات من الشيفرة المصدرية، حيث يجب أن يكون هذا الملف بصيغة محددة وواضحة بحيث يمكن للمصرِّف إنشاؤه ويمكن لنظام التشغيل تحديده وتحميله في الذاكرة وتحويله إلى عملية مُشغَّلة يمكن لنظام التشغيل إدارتها. يمكن أن تكون هذه الصيغة من الملفات القابلة للتنفيذ خاصة بنظام التشغيل، إذ لا نتوقع تنفيذ برنامج مُصرَّف لنظامٍ ما على نظام آخر مثل أن تعمل برامج ويندوز على نظام لينكس أو أن تعمل برامج لينكس على نظام macOS.
</p>

<p>
	لكن خيط المعالجة Thread المشترك بين جميع صيغ الملفات القابلة للتنفيذ هو أنها تتضمن ترويسة معيارية مُعرَّفة مسبقًا توضّح كيفية تخزين شيفرة وبيانات البرنامج في بقية الملف، حيث يمكن أن تشرح ذلك بالكلمات مثل أن نقول: "تبدأ شيفرة البرنامج من 20 بايت في هذا الملف، ويبلغ طولها 50 كيلوبايت، وتتبعها بيانات البرنامج ويبلغ طولها 20 كيلوبايت".
</p>

<p>
	هناك صيغة معينة أصبحت في الآونة الأخيرة معيارًا لتمثيل الملفات القابلة للتنفيذ في الأنظمة الحديثة القائمة على نظام يونكس، ويطلَق على هذا التنسيق بصيغة الرابط والملفات القابلة للتنفيذ Executable and Linker Format -أو ELF اختصارًا، حيث سنشرحها بمزيد من التفصيل لاحقًا.
</p>

<h3>
	تاريخ الصيغة الثنائية
</h3>

<p>
	سنوضح فيما يلي صيغتين للملفات الثنائية سبقت ظهور صيغة ملفات ELF هما a.out و COFF.
</p>

<h4>
	a.out
</h4>

<p>
	لم تكن صيغة ملفات ELF المعيار دائمًا، إذ استخدمت أنظمة يونكس الأصلية صيغة ملف بالاسم <code>a.out</code>. يمكننا أن نرى آثار ذلك عند تصريف برنامج بدون الخيار <code>‎-o</code> لتحديد اسم ملف الخرج، حيث سينشأ الملف القابل للتنفيذ بالاسم الافتراضي <code>a.out</code> الذي يُعَد اسم ملف الخرج الافتراضي الناتج عن الرابط Linker. يستخدم المصرِّف Compiler أسماء الملفات المُنشَأة عشوائيًا بوصفها ملفات وسيطة لشيفرة التجميع والشيفرة المُصرَّفة.
</p>

<p>
	a.out هو صيغة ترويسة بسيطة تسمح فقط بقسم واحد للبيانات والشيفرة وBSS، وهذا غير كافٍ للأنظمة الحديثة ذات المكتبات الديناميكية.
</p>

<h4>
	COFF
</h4>

<p>
	كانت صيغة ملف التعليمات المُصرَّفة المشترك Common Object File Format -أو COFF اختصارًا- مقدمة لظهور صيغة ملفات ELF، حيث كانت صيغة ترويستها أكثر مرونة، مما يسمح بمزيد -ولكن محدود- من الأقسام في الملف.
</p>

<p>
	تواجه صيغة COFF صعوبات في دعم المكتبات المشتركة، لذا اختيرت صيغة ELF بوصفها تقديمًا Implementation بديلًا على نظام لينكس. لكن توجد صيغة COFF في مايكروسوفت ويندوز بوصفها صيغة ملفات قابلة للتنفيذ والنقل Portable Executable -أو PE اختصارًا- التي تُعَد بالنسبة إلى ويندوز مثل صيغة ملفات ELF في لينكس.
</p>

<h2>
	صيغة ملفات ELF
</h2>

<p>
	تُعَد صيغة ملفات ELF صيغةً مرنة لتمثيل الشيفرة الثنائية في النظام، حيث يمكنك باتباع معيار ELF تمثيل النواة Kernel ثنائيًا بسهولة مثل تمثيل ملف قابل للتنفيذ أو مكتبة نظام عادية. يمكن استخدام الأدوات نفسها لفحص وتشغيل جميع ملفات ELF ويمكن للمطورين الذين يفهمون صيغة ملفات ELF الاستفادة من مهاراتهم في معظم الأنظمة الحديثة المبنية على يونكس.
</p>

<p>
	توسّع الصيغة ELF صيغة الملفات COFF وتمنح الترويسة مرونة كافية لتحديد عدد عشوائي من الأقسام، بحيث يكون لكل منها خاصياته الخاصة، مما يسهّل الربط الديناميكي وتنقيح الأخطاء Debugging.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122495" href="https://academy.hsoub.com/uploads/monthly_2023_03/01_elf-overview.png.7d0c68b288c65caabb5d6262245060c7.png" rel=""><img alt="01_elf-overview.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122495" data-unique="ltqqzog2l" src="https://academy.hsoub.com/uploads/monthly_2023_03/01_elf-overview.png.7d0c68b288c65caabb5d6262245060c7.png"> </a>
</p>

<h3>
	ترويسة ملفات ELF
</h3>

<p>
	يحتوي الملف على ترويسة ملف File Header تصِف الملف، ثم يحتوي على مؤشرات لكل قسم من الأقسام التي يتكون منها الملف. يوضح المثال التالي الوصف على النحو الوارد في توثيق واجهة برمجة تطبيقات ELF32 (نموذج 32 بت من صيغة ملفات ELF)، وهو تخطيط لبنية <a href="https://academy.hsoub.com/programming/c/" rel="">لغة C</a> الذي يعرّف ترويسة ELF:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3603_8" style=""><span class="kwd">typedef</span><span class="pln"> </span><span class="kwd">struct</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">char</span><span class="pln"> e_ident</span><span class="pun">[</span><span class="pln">EI_NIDENT</span><span class="pun">];</span><span class="pln">
  </span><span class="typ">Elf32_Half</span><span class="pln">    e_type</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Half</span><span class="pln">    e_machine</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Word</span><span class="pln">    e_version</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Addr</span><span class="pln">    e_entry</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Off</span><span class="pln">     e_phoff</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Off</span><span class="pln">     e_shoff</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Word</span><span class="pln">    e_flags</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Half</span><span class="pln">    e_ehsize</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Half</span><span class="pln">    e_phentsize</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Half</span><span class="pln">    e_phnum</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Half</span><span class="pln">    e_shentsize</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Half</span><span class="pln">    e_shnum</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Half</span><span class="pln">    e_shstrndx</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span><span class="typ">Elf32_Ehdr</span><span class="pun">;</span></pre>

<p>
	إليك مثال عن ترويسة ELF كما هو موضح باستخدام الأداة <code>readelf</code>:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3603_10" style=""><span class="pln">$ readelf </span><span class="pun">--</span><span class="pln">header </span><span class="pun">/</span><span class="pln">bin</span><span class="pun">/</span><span class="pln">ls

ELF </span><span class="typ">Header</span><span class="pun">:</span><span class="pln">
  </span><span class="typ">Magic</span><span class="pun">:</span><span class="pln">   </span><span class="lit">7f</span><span class="pln"> </span><span class="lit">45</span><span class="pln"> </span><span class="lit">4c</span><span class="pln"> </span><span class="lit">46</span><span class="pln"> </span><span class="lit">01</span><span class="pln"> </span><span class="lit">02</span><span class="pln"> </span><span class="lit">01</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> 
  </span><span class="typ">Class</span><span class="pun">:</span><span class="pln">                             ELF32
  </span><span class="typ">Data</span><span class="pun">:</span><span class="pln">                              </span><span class="lit">2</span><span class="str">'</span><span class="pln">s complement</span><span class="pun">,</span><span class="pln"> big endian
  </span><span class="typ">Version</span><span class="pun">:</span><span class="pln">                           </span><span class="lit">1</span><span class="pln"> </span><span class="pun">(</span><span class="pln">current</span><span class="pun">)</span><span class="pln">
  OS</span><span class="pun">/</span><span class="pln">ABI</span><span class="pun">:</span><span class="pln">                            UNIX </span><span class="pun">-</span><span class="pln"> </span><span class="typ">System</span><span class="pln"> V
  ABI </span><span class="typ">Version</span><span class="pun">:</span><span class="pln">                       </span><span class="lit">0</span><span class="pln">
  </span><span class="typ">Type</span><span class="pun">:</span><span class="pln">                              EXEC </span><span class="pun">(</span><span class="typ">Executable</span><span class="pln"> file</span><span class="pun">)</span><span class="pln">
  </span><span class="typ">Machine</span><span class="pun">:</span><span class="pln">                           </span><span class="typ">PowerPC</span><span class="pln">
  </span><span class="typ">Version</span><span class="pun">:</span><span class="pln">                           </span><span class="lit">0x1</span><span class="pln">
  </span><span class="typ">Entry</span><span class="pln"> point address</span><span class="pun">:</span><span class="pln">               </span><span class="lit">0x10002640</span><span class="pln">
  </span><span class="typ">Start</span><span class="pln"> of program headers</span><span class="pun">:</span><span class="pln">          </span><span class="lit">52</span><span class="pln"> </span><span class="pun">(</span><span class="pln">bytes into file</span><span class="pun">)</span><span class="pln">
  </span><span class="typ">Start</span><span class="pln"> of section headers</span><span class="pun">:</span><span class="pln">          </span><span class="lit">87460</span><span class="pln"> </span><span class="pun">(</span><span class="pln">bytes into file</span><span class="pun">)</span><span class="pln">
  </span><span class="typ">Flags</span><span class="pun">:</span><span class="pln">                             </span><span class="lit">0x0</span><span class="pln">
  </span><span class="typ">Size</span><span class="pln"> of </span><span class="kwd">this</span><span class="pln"> header</span><span class="pun">:</span><span class="pln">               </span><span class="lit">52</span><span class="pln"> </span><span class="pun">(</span><span class="pln">bytes</span><span class="pun">)</span><span class="pln">
  </span><span class="typ">Size</span><span class="pln"> of program headers</span><span class="pun">:</span><span class="pln">           </span><span class="lit">32</span><span class="pln"> </span><span class="pun">(</span><span class="pln">bytes</span><span class="pun">)</span><span class="pln">
  </span><span class="typ">Number</span><span class="pln"> of program headers</span><span class="pun">:</span><span class="pln">         </span><span class="lit">8</span><span class="pln">
  </span><span class="typ">Size</span><span class="pln"> of section headers</span><span class="pun">:</span><span class="pln">           </span><span class="lit">40</span><span class="pln"> </span><span class="pun">(</span><span class="pln">bytes</span><span class="pun">)</span><span class="pln">
  </span><span class="typ">Number</span><span class="pln"> of section headers</span><span class="pun">:</span><span class="pln">         </span><span class="lit">29</span><span class="pln">
  </span><span class="typ">Section</span><span class="pln"> header string table index</span><span class="pun">:</span><span class="pln"> </span><span class="lit">28</span><span class="pln">

  </span><span class="pun">[...]</span></pre>

<p>
	يوضّح المثال السابق نموذجًا سهل القراءة على الإنسان كما مولدًا باستخدام برنامج <code>readelf</code>، وهو جزء من أدوات Binutils في GNU.
</p>

<p>
	تُوجَد المصفوفة <code>e_ident</code> في بداية أيّ ملف ELF، وتبدأ دائمًا بمجموعة بايتات سحرية. البايت الأول هو <code>0x7F</code> ثم الثلاثة بايتات التالية هي "ELF". يمكنك فحص ملف ELF الثنائي لترى ذلك بنفسك باستخدام الأمر <code>hexdump</code>.
</p>

<p>
	يفحص المثال التالي عدد ELF السحري:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3603_12" style=""><span class="pln">ianw@mingus</span><span class="pun">:~</span><span class="pln">$ hexdump </span><span class="pun">-</span><span class="pln">C </span><span class="pun">/</span><span class="pln">bin</span><span class="pun">/</span><span class="pln">ls </span><span class="pun">|</span><span class="pln"> more
</span><span class="lit">00000000</span><span class="pln">  </span><span class="lit">7f</span><span class="pln"> </span><span class="lit">45</span><span class="pln"> </span><span class="lit">4c</span><span class="pln"> </span><span class="lit">46</span><span class="pln"> </span><span class="lit">01</span><span class="pln"> </span><span class="lit">02</span><span class="pln"> </span><span class="lit">01</span><span class="pln"> </span><span class="lit">00</span><span class="pln">  </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> </span><span class="lit">00</span><span class="pln">  </span><span class="pun">|.</span><span class="pln">ELF</span><span class="pun">............|</span><span class="pln">

</span><span class="pun">...</span><span class="pln"> </span><span class="pun">(يتبع</span><span class="pln"> </span><span class="pun">ذلك</span><span class="pln"> </span><span class="pun">بقية</span><span class="pln"> </span><span class="pun">البرنامج)</span><span class="pln"> </span><span class="pun">…</span></pre>

<p>
	لاحظ وجود البت <code>0x7F</code> في البداية ثم سلسلة آسكي ASCII المُشفَّرة "ELF". ألقِ نظرة على المعيار وشاهد ما تعرّفه بقية المصفوفة وما هي القيم الموجودة في الملف الثنائي. لدينا بعد ذلك بعض الرايات Flags لنوع الجهاز الذي اُنشِئ هذا الملف الثنائي من أجله. لاحظ أن صيغة ELF تعرّف إصدارات مختلفة من الأحجام مثل إصدارات 32 بت و64 بت، حيث سنشرح هنا الإصدار 32 بت. يكمن الاختلاف في أنه يجب الاحتفاظ بالعناوين على أجهزة 64 بت في متغيرات بحجم 64 بتًا. يمكننا أن نرى أن الملف الثنائي أُنشِئ للجهاز الذي يستخدم صيغة Big Endian (تخزين البتات الأقل أهمية أولًا)، حيث يستخدم هذا الجهاز المكمل الثنائي لتمثيل الأعداد السالبة. لاحظ بعد ذلك أن الخاصية <code>Machine</code> تخبرنا أنه جهاز PowerPC الثنائي.
</p>

<p>
	يبدو أن عنوان نقطة الدخول واضح وصريح بدرجة كافية، وهو العنوان الموجود في الذاكرة الذي تبدأ منه شيفرة البرنامج. يُقال لمبرمجي لغة C المبتدئين أن الدالة الرئيسية <code>main()‎</code> هي أول برنامج يُستدعَى في برامجهم، ولكن يمكننا التحقق من أنه ليس كذلك باستخدام عنوان نقطة الدخول كما يلي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3603_14" style=""><span class="pln">$ cat test</span><span class="pun">.</span><span class="pln">c
</span><span class="com">#include</span><span class="pln"> </span><span class="str">&lt;stdio.h&gt;</span><span class="pln">

</span><span class="typ">int</span><span class="pln"> main</span><span class="pun">(</span><span class="kwd">void</span><span class="pun">)</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
  printf</span><span class="pun">(</span><span class="str">"main is : %p\n"</span><span class="pun">,</span><span class="pln"> </span><span class="pun">&amp;</span><span class="pln">main</span><span class="pun">);</span><span class="pln">
  </span><span class="kwd">return</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

$ gcc </span><span class="pun">-</span><span class="typ">Wall</span><span class="pln"> </span><span class="pun">-</span><span class="pln">o test test</span><span class="pun">.</span><span class="pln">c

$ </span><span class="pun">./</span><span class="pln">test
main is </span><span class="pun">:</span><span class="pln"> </span><span class="lit">0x10000430</span><span class="pln">

$ readelf </span><span class="pun">--</span><span class="pln">headers </span><span class="pun">./</span><span class="pln">test </span><span class="pun">|</span><span class="pln"> grep </span><span class="str">'Entry point'</span><span class="pln">
  </span><span class="typ">Entry</span><span class="pln"> point address</span><span class="pun">:</span><span class="pln">               </span><span class="lit">0x100002b0</span><span class="pln">

$ objdump </span><span class="pun">--</span><span class="pln">disassemble </span><span class="pun">./</span><span class="pln">test </span><span class="pun">|</span><span class="pln"> grep </span><span class="lit">100002b0</span><span class="pln">
</span><span class="lit">100002b0</span><span class="pln"> </span><span class="pun">&lt;</span><span class="pln">_start</span><span class="pun">&gt;:</span><span class="pln">
</span><span class="lit">100002b0</span><span class="pun">:</span><span class="pln">       </span><span class="lit">7c</span><span class="pln"> </span><span class="lit">29</span><span class="pln"> </span><span class="lit">0b</span><span class="pln"> </span><span class="lit">78</span><span class="pln">     mr      r9</span><span class="pun">,</span><span class="pln">r1</span></pre>

<p>
	لاحظ في المثال السابق أنه يمكننا أن نرى أن نقطة الدخول هي دالة تسمى <code>‎_start</code>. لم يعرّف برنامجنا هذه الدالة على الإطلاق، ويشير الخط السفلي في بداية اسم الدالة إلى أنها موجودة في فضاء أسماء منفصل. سنشرح لاحقًا كيفية بدء البرنامج بالتفصيل.
</p>

<p>
	تحتوي الترويسة بعد ذلك على مؤشرات إلى المكان الموجود في الملف الذي تبدأ فيه الأجزاء المهمة الأخرى من ملف ELF مثل جدول المحتويات.
</p>

<h3>
	الرموز Symbols 3 والمنقولات Relocation
</h3>

<p>
	توفر مواصفات ملف ELF جداول رموز Symbol Tables تربط بين السلاسل النصية أو الرموز ومواقع في الملف. تُعَد الرموز مطلوبة للربط Linking، فمثلًا يمكن أن يتطلب إسنادُ قيمة للمتغير <code>foo</code> المُصرَّح عنه بالشكل <code>extern int foo</code> رابطًا للعثور على عنوان المتغير <code>foo</code>، والذي يمكن أن يتضمن البحث عن الكلمة "foo" في جدول الرموز وإيجاد العنوان.
</p>

<p>
	ترتبط المنقولات Relocations ارتباطًا وثيقًا بالرموز، حيث يُعَد الانتقال مساحةً فارغة تُترَك لإصلاحها لاحقًا، إذ لا يمكن استخدام المتغير <code>foo</code> في المثال السابق حتى معرفة عنوانه، ولكن نعلم في نظام 32 بت أن عنوان المتغير <code>foo</code> يجب أن يكون بقيمة 4 بايتات، لذلك يمكن للمصرِّف ببساطة ترك مساحة فارغة بمقدار 4 بايتات والاحتفاظ بانتقالٍ Relocation يخبر الرابط بأن يضع القيمة الحقيقية للمتغير <code>foo</code> في هذه المساحة التي مقدارها 4 بايتات في هذا العنوان في أيّ وقت يحتاج فيه المصرِّف استخدامَ هذا العنوان لإسناد قيمة مثلًا، ولكن يتطلب ذلك تحليل الرمز "foo".
</p>

<h3>
	المقاطع Segments والأقسام Sections
</h3>

<p>
	تحدد صيغة ELF عرضين لملف ELF، حيث يُستخدَم أحدهما للربط والآخر للتنفيذ، مما يوفر مرونة كبيرة لمصممي الأنظمة. سنتحدث عن الأقسام الموجودة في شيفرة الكائن التي تنتظر أن تُربَط بملف قابل للتنفيذ، ويُربَط قسم واحد أو أكثر مع مقطعٍ ما في الملف القابل للتنفيذ.
</p>

<h4>
	المقاطع Segments
</h4>

<p>
	من الأسهل في بعض الأحيان النظر إلى المستوى الأعلى من التجريد abstraction المتمثل بالمقاطع قبل فحص الطبقات السفلية. يحتوي ملف ELF على ترويسة تصف تخطيط الملف العام، حيث تشير ترويسة ELF إلى مجموعة أخرى من الترويسات تسمى ترويسات البرامج Program Headers، حيث تصِف هذه الترويسات لنظام التشغيل أيّ شيء يمكن أن يكون مطلوبًا لتحميل الملف الثنائي في الذاكرة وتنفيذه. كما تصف ترويسات البرامج المقاطع، ولكن هناك بعض الأشياء الأخرى المطلوبة لتشغيل الملف القابل للتنفيذ.
</p>

<p>
	إليك مثال عن ترويسة برنامج:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3603_16" style=""><span class="kwd">typedef</span><span class="pln"> </span><span class="kwd">struct</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="typ">Elf32_Word</span><span class="pln"> p_type</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Off</span><span class="pln">  p_offset</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Addr</span><span class="pln"> p_vaddr</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Addr</span><span class="pln"> p_paddr</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Word</span><span class="pln"> p_filesz</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Word</span><span class="pln"> p_memsz</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Word</span><span class="pln"> p_flags</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Word</span><span class="pln"> p_align</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	يوضح المثال السابق تعريف ترويسة البرنامج. لا بد أنك لاحظت من تعريف ترويسة ELF سابقًا وجود الحقول <code>e_phoff</code> و<code>e_phnum</code> و<code>e_phentsize</code> التي تمثّل الإزاحة في الملف حيث تبدأ ترويسات البرامج وعدد ترويسات البرامج الموجودة وحجم كل ترويسة برنامج، وبالتالي يمكنك العثور على ترويسات البرامج وقراءتها بسهولة باستخدام هذه الأجزاء الثلاثة من المعلومات.
</p>

<p>
	تُعَد ترويسات البرامج أكثر من مجرد مقاطع، حيث يعرّف الحقل <code>p_type</code> ما تعرّفه ترويسة البرنامج، فمثلًا إذا كان هذا الحقل هو <code>PT_INTERP</code>، فستُعرَّف الترويسة بأنها مؤشر سلسلة نصية يؤشّر إلى مفسّر Interpreter الملف الثنائي. ناقشنا سابقًا <a href="https://academy.hsoub.com/programming/advanced/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D9%84%D9%81-%D9%82%D8%A7%D8%A8%D9%84-%D9%84%D9%84%D8%AA%D9%86%D9%81%D9%8A%D8%B0-executable-file-%D9%85%D9%86-%D8%B4%D9%8A%D9%81%D8%B1%D8%A9-%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A9-%D9%85%D8%B5%D8%AF%D8%B1%D9%8A%D8%A9-source-code-r1930/" rel="">الفرق بين اللغات المُصرَّفة Compiled واللغات المُفسَّرة Interpreted</a> وميّزنا المُصرِّف بأنه ينشئ ملفًا ثنائيًا يمكن تشغيله بطريقة مستقلة. لكن لا بد أنك تتساءل عن سبب حاجتنا لمفسّر! حسنًا، ترغب الأنظمة الحديثة في المرونة عند تحميل الملفات القابلة للتنفيذ، لذا لا يمكن الحصول على بعض المعلومات بصورة كافية إلّا في الوقت الفعلي الذي يُعَد فيه البرنامج للتشغيل، وهذا ما يسمى بالربط الديناميكي Dynamic Linking الذي سنتحدث عنه لاحقًا، وبالتالي يجب إجراء بعض التغييرات الطفيفة على البرنامج الثنائي للسماح له بالعمل بصورة صحيحة في وقت التشغيل. لذا يُعَد مفسّر الملف الثنائي المعتاد هو المحمّل الديناميكي Dynamic Loader، لأنه يأخذ الخطوات النهائية لإكمال تحميل الملف القابل للتنفيذ وإعداد الصورة الثنائية للتشغيل.
</p>

<p>
	تصف القيمة <code>PT_LOAD</code> في الحقل <code>p_type</code> المقاطع، ثم تصف الحقول الأخرى في ترويسة البرنامج كلّ مقطع منها. يخبرك الحقل <code>p_offset</code> بمقدار بُعد بيانات المقطع عن الملف الموجود على القرص الصلب. بينما يخبرك الحقل <code>p_vaddr</code> بالعنوان الذي يجب أن توجد عنده البيانات في الذاكرة الوهمية Virtual Memory، حيث يصف الحقل <code>p_addr</code> العنوان الحقيقي Physical Address الذي يُعَد مفيدًا للأنظمة المدمَجة الصغيرة التي لا تطبّق الذاكرة الوهمية. تخبرك الرايتان <code>p_filesz</code> و<code>p_memsz</code> بحجم المقطع الموجود على القرص الصلب وكم يجب أن يكون حجمه في الذاكرة. إذا كان حجم الذاكرة أكبر من حجم القرص الصلب، فيجب ملء التداخل بينهما بالأصفار، وبالتالي يمكنك توفير مساحة كبيرة في ملفاتك الثنائية من خلال عدم الاضطرار إلى هدر مساحة للمتغيرات العامة الفارغة. أخيرًا، يشير الحقل <code>p_flags</code> إلى أذونات المقطع، حيث يمكن تحديد أذونات التنفيذ والقراءة والكتابة، فمثلًا يجب تمييز مقاطع الشيفرة البرمجية بأنها للقراءة والتنفيذ فقط، وتمييز أقسام البيانات للقراءة والكتابة فقط بدون تنفيذ.
</p>

<p>
	هناك عدد من أنواع المقاطع الأخرى المُعرَّفة في ترويسات البرامج الموصوفة كاملةً في مواصفات المعايير.
</p>

<h4>
	الأقسام Sections
</h4>

<p>
	تشكّل الأقسام مقاطعًا، حيث تُعَد الأقسام طريقة لتنظيم الملف الثنائي في مناطق منطقية لتوصيل المعلومات بين المصرِّف والرابط. تُستخدَم الأقسام في بعض الملفات الثنائية الخاصة مثل <a href="https://academy.hsoub.com/devops/linux/%D9%85%D8%A7-%D9%87%D9%88-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%8A%D9%86%D9%83%D8%B3%D8%9F-r451/" rel="">نواة لينكس</a> Linux Kernel بطرق أكثر تحديدًا سنوضحها لاحقًا.
</p>

<p>
	رأينا كيف تصل المقاطع في النهاية إلى كتلة بيانات في ملف على القرص الصلب مع بعض المواصفات حول المكان الذي يجب تحميلها فيه والأذونات التي تمتلكها. تمتلك الأقسام ترويسةً مماثلة لترويسة المقاطع كما هو موضح في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3603_18" style=""><span class="kwd">typedef</span><span class="pln"> </span><span class="kwd">struct</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="typ">Elf32_Word</span><span class="pln"> sh_name</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Word</span><span class="pln"> sh_type</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Word</span><span class="pln"> sh_flags</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Addr</span><span class="pln"> sh_addr</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Off</span><span class="pln">  sh_offset</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Word</span><span class="pln"> sh_size</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Word</span><span class="pln"> sh_link</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Word</span><span class="pln"> sh_info</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Word</span><span class="pln"> sh_addralign</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Elf32_Word</span><span class="pln"> sh_entsize</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	تحتوي الأقسام على عدد من الأنواع المُعرَّفة للحقل <code>sh_type</code> مثل تعريف قسم من النوع <code>SH_PROGBITS</code> بوصفه قسمًا يحتوي على بيانات ثنائية يستخدمها البرنامج. تشير الرايات الأخرى إلى ما إذا كان هذا القسم جدولَ رموز يستخدمه الرابط أو منقح الأخطاء مثلًا أو يمكن أن يكون شيئًا ما خاصًا بالمحمّل الديناميكي. كما توجد سمات إضافية مثل سمة التخصيص Allocate التي تشير إلى أن هذا القسم سيحتاج إلى ذاكرة مخصصة له.
</p>

<p>
	سنختبر الآن البرنامج الموضح في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3603_20" style=""><span class="com">#include</span><span class="pln"> </span><span class="str">&lt;stdio.h&gt;</span><span class="pln">

</span><span class="typ">int</span><span class="pln"> big_big_array</span><span class="pun">[</span><span class="lit">10</span><span class="pun">*</span><span class="lit">1024</span><span class="pun">*</span><span class="lit">1024</span><span class="pun">];</span><span class="pln">

</span><span class="kwd">char</span><span class="pln"> </span><span class="pun">*</span><span class="pln">a_string </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Hello, World!"</span><span class="pun">;</span><span class="pln">

</span><span class="typ">int</span><span class="pln"> a_var_with_value </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0x100</span><span class="pun">;</span><span class="pln">

</span><span class="typ">int</span><span class="pln"> main</span><span class="pun">(</span><span class="kwd">void</span><span class="pun">)</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
  big_big_array</span><span class="pun">[</span><span class="lit">0</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">100</span><span class="pun">;</span><span class="pln">
  printf</span><span class="pun">(</span><span class="str">"%s\n"</span><span class="pun">,</span><span class="pln"> a_string</span><span class="pun">);</span><span class="pln">
  a_var_with_value </span><span class="pun">+=</span><span class="pln"> </span><span class="lit">20</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	يوضح المثال التالي خرج الأداة <code>readelf</code> مع بعض الأجزاء الأخرى، حيث يمكننا باستخدام هذا الخرج تحليل كل جزء من برنامجنا البسيط السابق ومعرفة ما سيحدث به في خرج الملف الثنائي النهائي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3603_22" style=""><span class="pln">$ readelf </span><span class="pun">--</span><span class="pln">all </span><span class="pun">./</span><span class="pln">sections
ELF </span><span class="typ">Header</span><span class="pun">:</span><span class="pln">
  </span><span class="pun">...</span><span class="pln">
    </span><span class="typ">Size</span><span class="pln"> of section headers</span><span class="pun">:</span><span class="pln">           </span><span class="lit">40</span><span class="pln"> </span><span class="pun">(</span><span class="pln">bytes</span><span class="pun">)</span><span class="pln">
    </span><span class="typ">Number</span><span class="pln"> of section headers</span><span class="pun">:</span><span class="pln">         </span><span class="lit">37</span><span class="pln">
    </span><span class="typ">Section</span><span class="pln"> header string table index</span><span class="pun">:</span><span class="pln"> </span><span class="lit">34</span><span class="pln">

</span><span class="typ">Section</span><span class="pln"> </span><span class="typ">Headers</span><span class="pun">:</span><span class="pln">
  </span><span class="pun">[</span><span class="typ">Nr</span><span class="pun">]</span><span class="pln"> </span><span class="typ">Name</span><span class="pln">              </span><span class="typ">Type</span><span class="pln">            </span><span class="typ">Addr</span><span class="pln">     </span><span class="typ">Off</span><span class="pln">    </span><span class="typ">Size</span><span class="pln">   ES </span><span class="typ">Flg</span><span class="pln"> </span><span class="typ">Lk</span><span class="pln"> </span><span class="typ">Inf</span><span class="pln"> </span><span class="typ">Al</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">0</span><span class="pun">]</span><span class="pln">                   NULL            </span><span class="lit">00000000</span><span class="pln"> </span><span class="lit">000000</span><span class="pln"> </span><span class="lit">000000</span><span class="pln"> </span><span class="lit">00</span><span class="pln">      </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">0</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">1</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">interp           PROGBITS        </span><span class="lit">10000114</span><span class="pln"> </span><span class="lit">000114</span><span class="pln"> </span><span class="lit">00000d</span><span class="pln"> </span><span class="lit">00</span><span class="pln">   A  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">1</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">2</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">note</span><span class="pun">.</span><span class="pln">ABI</span><span class="pun">-</span><span class="pln">tag     NOTE            </span><span class="lit">10000124</span><span class="pln"> </span><span class="lit">000124</span><span class="pln"> </span><span class="lit">000020</span><span class="pln"> </span><span class="lit">00</span><span class="pln">   A  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">3</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">hash             HASH            </span><span class="lit">10000144</span><span class="pln"> </span><span class="lit">000144</span><span class="pln"> </span><span class="lit">00002c</span><span class="pln"> </span><span class="lit">04</span><span class="pln">   A  </span><span class="lit">4</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">4</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">dynsym           DYNSYM          </span><span class="lit">10000170</span><span class="pln"> </span><span class="lit">000170</span><span class="pln"> </span><span class="lit">000060</span><span class="pln"> </span><span class="lit">10</span><span class="pln">   A  </span><span class="lit">5</span><span class="pln">   </span><span class="lit">1</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">5</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">dynstr           STRTAB          </span><span class="lit">100001d0</span><span class="pln"> </span><span class="lit">0001d0</span><span class="pln"> </span><span class="lit">00005e</span><span class="pln"> </span><span class="lit">00</span><span class="pln">   A  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">1</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">6</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">gnu</span><span class="pun">.</span><span class="pln">version      VERSYM          </span><span class="lit">1000022e</span><span class="pln"> </span><span class="lit">00022e</span><span class="pln"> </span><span class="lit">00000c</span><span class="pln"> </span><span class="lit">02</span><span class="pln">   A  </span><span class="lit">4</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">2</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">7</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">gnu</span><span class="pun">.</span><span class="pln">version_r    VERNEED         </span><span class="lit">1000023c</span><span class="pln"> </span><span class="lit">00023c</span><span class="pln"> </span><span class="lit">000020</span><span class="pln"> </span><span class="lit">00</span><span class="pln">   A  </span><span class="lit">5</span><span class="pln">   </span><span class="lit">1</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">8</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">rela</span><span class="pun">.</span><span class="pln">dyn         RELA            </span><span class="lit">1000025c</span><span class="pln"> </span><span class="lit">00025c</span><span class="pln"> </span><span class="lit">00000c</span><span class="pln"> </span><span class="lit">0c</span><span class="pln">   A  </span><span class="lit">4</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="pln"> </span><span class="lit">9</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">rela</span><span class="pun">.</span><span class="pln">plt         RELA            </span><span class="lit">10000268</span><span class="pln"> </span><span class="lit">000268</span><span class="pln"> </span><span class="lit">000018</span><span class="pln"> </span><span class="lit">0c</span><span class="pln">   A  </span><span class="lit">4</span><span class="pln">  </span><span class="lit">25</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">10</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">init             PROGBITS        </span><span class="lit">10000280</span><span class="pln"> </span><span class="lit">000280</span><span class="pln"> </span><span class="lit">000028</span><span class="pln"> </span><span class="lit">00</span><span class="pln">  AX  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">11</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">text             PROGBITS        </span><span class="lit">100002b0</span><span class="pln"> </span><span class="lit">0002b0</span><span class="pln"> </span><span class="lit">000560</span><span class="pln"> </span><span class="lit">00</span><span class="pln">  AX  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln"> </span><span class="lit">16</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">12</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">fini             PROGBITS        </span><span class="lit">10000810</span><span class="pln"> </span><span class="lit">000810</span><span class="pln"> </span><span class="lit">000020</span><span class="pln"> </span><span class="lit">00</span><span class="pln">  AX  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">13</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">rodata           PROGBITS        </span><span class="lit">10000830</span><span class="pln"> </span><span class="lit">000830</span><span class="pln"> </span><span class="lit">000024</span><span class="pln"> </span><span class="lit">00</span><span class="pln">   A  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">14</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">sdata2           PROGBITS        </span><span class="lit">10000854</span><span class="pln"> </span><span class="lit">000854</span><span class="pln"> </span><span class="lit">000000</span><span class="pln"> </span><span class="lit">00</span><span class="pln">   A  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">15</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">eh_frame         PROGBITS        </span><span class="lit">10000854</span><span class="pln"> </span><span class="lit">000854</span><span class="pln"> </span><span class="lit">000004</span><span class="pln"> </span><span class="lit">00</span><span class="pln">   A  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">16</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">ctors            PROGBITS        </span><span class="lit">10010858</span><span class="pln"> </span><span class="lit">000858</span><span class="pln"> </span><span class="lit">000008</span><span class="pln"> </span><span class="lit">00</span><span class="pln">  WA  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">17</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">dtors            PROGBITS        </span><span class="lit">10010860</span><span class="pln"> </span><span class="lit">000860</span><span class="pln"> </span><span class="lit">000008</span><span class="pln"> </span><span class="lit">00</span><span class="pln">  WA  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">18</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">jcr              PROGBITS        </span><span class="lit">10010868</span><span class="pln"> </span><span class="lit">000868</span><span class="pln"> </span><span class="lit">000004</span><span class="pln"> </span><span class="lit">00</span><span class="pln">  WA  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">19</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">got2             PROGBITS        </span><span class="lit">1001086c</span><span class="pln"> </span><span class="lit">00086c</span><span class="pln"> </span><span class="lit">000010</span><span class="pln"> </span><span class="lit">00</span><span class="pln">  WA  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">1</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">20</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">dynamic          DYNAMIC         </span><span class="lit">1001087c</span><span class="pln"> </span><span class="lit">00087c</span><span class="pln"> </span><span class="lit">0000c8</span><span class="pln"> </span><span class="lit">08</span><span class="pln">  WA  </span><span class="lit">5</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">21</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">data             PROGBITS        </span><span class="lit">10010944</span><span class="pln"> </span><span class="lit">000944</span><span class="pln"> </span><span class="lit">000008</span><span class="pln"> </span><span class="lit">00</span><span class="pln">  WA  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">22</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">got              PROGBITS        </span><span class="lit">1001094c</span><span class="pln"> </span><span class="lit">00094c</span><span class="pln"> </span><span class="lit">000014</span><span class="pln"> </span><span class="lit">04</span><span class="pln"> WAX  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">23</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">sdata            PROGBITS        </span><span class="lit">10010960</span><span class="pln"> </span><span class="lit">000960</span><span class="pln"> </span><span class="lit">000008</span><span class="pln"> </span><span class="lit">00</span><span class="pln">  WA  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">24</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">sbss             NOBITS          </span><span class="lit">10010968</span><span class="pln"> </span><span class="lit">000968</span><span class="pln"> </span><span class="lit">000000</span><span class="pln"> </span><span class="lit">00</span><span class="pln">  WA  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">1</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">25</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">plt              NOBITS          </span><span class="lit">10010968</span><span class="pln"> </span><span class="lit">000968</span><span class="pln"> </span><span class="lit">000060</span><span class="pln"> </span><span class="lit">00</span><span class="pln"> WAX  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">26</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">bss              NOBITS          </span><span class="lit">100109c8</span><span class="pln"> </span><span class="lit">000968</span><span class="pln"> </span><span class="lit">2800004</span><span class="pln"> </span><span class="lit">00</span><span class="pln">  WA  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">27</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">comment          PROGBITS        </span><span class="lit">00000000</span><span class="pln"> </span><span class="lit">000968</span><span class="pln"> </span><span class="lit">00018f</span><span class="pln"> </span><span class="lit">00</span><span class="pln">      </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">1</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">28</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">debug_aranges    PROGBITS        </span><span class="lit">00000000</span><span class="pln"> </span><span class="lit">000af8</span><span class="pln"> </span><span class="lit">000078</span><span class="pln"> </span><span class="lit">00</span><span class="pln">      </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">8</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">29</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">debug_pubnames   PROGBITS        </span><span class="lit">00000000</span><span class="pln"> </span><span class="lit">000b70</span><span class="pln"> </span><span class="lit">000025</span><span class="pln"> </span><span class="lit">00</span><span class="pln">      </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">1</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">30</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">debug_info       PROGBITS        </span><span class="lit">00000000</span><span class="pln"> </span><span class="lit">000b95</span><span class="pln"> </span><span class="lit">0002e5</span><span class="pln"> </span><span class="lit">00</span><span class="pln">      </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">1</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">31</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">debug_abbrev     PROGBITS        </span><span class="lit">00000000</span><span class="pln"> </span><span class="lit">000e7a</span><span class="pln"> </span><span class="lit">000076</span><span class="pln"> </span><span class="lit">00</span><span class="pln">      </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">1</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">32</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">debug_line       PROGBITS        </span><span class="lit">00000000</span><span class="pln"> </span><span class="lit">000ef0</span><span class="pln"> </span><span class="lit">0001de</span><span class="pln"> </span><span class="lit">00</span><span class="pln">      </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">1</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">33</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">debug_str        PROGBITS        </span><span class="lit">00000000</span><span class="pln"> </span><span class="lit">0010ce</span><span class="pln"> </span><span class="lit">0000f0</span><span class="pln"> </span><span class="lit">01</span><span class="pln">  MS  </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">1</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">34</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">shstrtab         STRTAB          </span><span class="lit">00000000</span><span class="pln"> </span><span class="lit">0011be</span><span class="pln"> </span><span class="lit">00013b</span><span class="pln"> </span><span class="lit">00</span><span class="pln">      </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">1</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">35</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">symtab           SYMTAB          </span><span class="lit">00000000</span><span class="pln"> </span><span class="lit">0018c4</span><span class="pln"> </span><span class="lit">000c90</span><span class="pln"> </span><span class="lit">10</span><span class="pln">     </span><span class="lit">36</span><span class="pln">  </span><span class="lit">65</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
  </span><span class="pun">[</span><span class="lit">36</span><span class="pun">]</span><span class="pln"> </span><span class="pun">.</span><span class="pln">strtab           STRTAB          </span><span class="lit">00000000</span><span class="pln"> </span><span class="lit">002554</span><span class="pln"> </span><span class="lit">000909</span><span class="pln"> </span><span class="lit">00</span><span class="pln">      </span><span class="lit">0</span><span class="pln">   </span><span class="lit">0</span><span class="pln">  </span><span class="lit">1</span><span class="pln">
</span><span class="typ">Key</span><span class="pln"> to </span><span class="typ">Flags</span><span class="pun">:</span><span class="pln">
  W </span><span class="pun">(</span><span class="pln">write</span><span class="pun">),</span><span class="pln"> A </span><span class="pun">(</span><span class="pln">alloc</span><span class="pun">),</span><span class="pln"> X </span><span class="pun">(</span><span class="pln">execute</span><span class="pun">),</span><span class="pln"> M </span><span class="pun">(</span><span class="pln">merge</span><span class="pun">),</span><span class="pln"> S </span><span class="pun">(</span><span class="pln">strings</span><span class="pun">)</span><span class="pln">
  I </span><span class="pun">(</span><span class="pln">info</span><span class="pun">),</span><span class="pln"> L </span><span class="pun">(</span><span class="pln">link order</span><span class="pun">),</span><span class="pln"> G </span><span class="pun">(</span><span class="pln">group</span><span class="pun">),</span><span class="pln"> x </span><span class="pun">(</span><span class="pln">unknown</span><span class="pun">)</span><span class="pln">
  O </span><span class="pun">(</span><span class="pln">extra OS processing required</span><span class="pun">)</span><span class="pln"> o </span><span class="pun">(</span><span class="pln">OS specific</span><span class="pun">),</span><span class="pln"> p </span><span class="pun">(</span><span class="pln">processor specific</span><span class="pun">)</span><span class="pln">

</span><span class="typ">There</span><span class="pln"> are no section groups in </span><span class="kwd">this</span><span class="pln"> file</span><span class="pun">.</span><span class="pln">
 </span><span class="pun">...</span><span class="pln">

</span><span class="typ">Symbol</span><span class="pln"> table </span><span class="str">'.symtab'</span><span class="pln"> contains </span><span class="lit">201</span><span class="pln"> entries</span><span class="pun">:</span><span class="pln">
  </span><span class="typ">Num</span><span class="pun">:</span><span class="pln">    </span><span class="typ">Value</span><span class="pln">  </span><span class="typ">Size</span><span class="pln"> </span><span class="typ">Type</span><span class="pln">    </span><span class="typ">Bind</span><span class="pln">   </span><span class="typ">Vis</span><span class="pln">      </span><span class="typ">Ndx</span><span class="pln"> </span><span class="typ">Name</span><span class="pln">
</span><span class="pun">...</span><span class="pln">
    </span><span class="lit">99</span><span class="pun">:</span><span class="pln"> </span><span class="lit">100109cc</span><span class="pln"> </span><span class="lit">0x2800000</span><span class="pln"> OBJECT  GLOBAL DEFAULT   </span><span class="lit">26</span><span class="pln"> big_big_array
</span><span class="pun">...</span><span class="pln">
   </span><span class="lit">110</span><span class="pun">:</span><span class="pln"> </span><span class="lit">10010960</span><span class="pln">     </span><span class="lit">4</span><span class="pln"> OBJECT  GLOBAL DEFAULT   </span><span class="lit">23</span><span class="pln"> a_string
</span><span class="pun">...</span><span class="pln">
   </span><span class="lit">130</span><span class="pun">:</span><span class="pln"> </span><span class="lit">10010964</span><span class="pln">     </span><span class="lit">4</span><span class="pln"> OBJECT  GLOBAL DEFAULT   </span><span class="lit">23</span><span class="pln"> a_var_with_value
</span><span class="pun">...</span><span class="pln">
   </span><span class="lit">144</span><span class="pun">:</span><span class="pln"> </span><span class="lit">10000430</span><span class="pln">    </span><span class="lit">96</span><span class="pln"> FUNC    GLOBAL DEFAULT   </span><span class="lit">11</span><span class="pln"> main</span></pre>

<p>
	لنلقِ أولًا نظرة على المتغير <code>big_big_array</code> الذي -كما يوحي الاسم- هو مصفوفة عامة كبيرة إلى حد ما، وإذا انتقلنا إلى جدول الرموز، فيمكننا أن نرى أن هذا المتغير موجود في الموقع <code>0x100109cc</code> الذي يمكننا ربطه بالقسم <code>‎.bss</code> في قائمة الأقسام لأنه يبدأ تحته مباشرةً عند الموقع <code>0x100109c8</code>، ولاحظ حجمه الكبير جدًا.
</p>

<p>
	ذكرنا أن القسم BSS هو جزء معياري من صورة ثنائية، لأنه ليس منطقيًا أن تطلب أن يكون لملفٍ ثنائي على القرص الصلب 10 ميجابايتات من المساحة المخصَّصة له عندما تكون كل هذه المساحة قيمًا صفرية. لاحظ أن هذا القسم يحتوي على النوع <code>NOBITS</code>، مما يعني أنه لا يحتوي على أيّ بايت على القرص الصلب. لذا يُعرَّف القسم <code>‎.bss</code> للمتغيرات العامة التي يجب أن تكون قيمتها صفرًا عند بدء البرنامج. رأينا كيف يمكن أن يختلف حجم الذاكرة عن حجم القرص الصلب عند مناقشتنا للمقاطع، فوجود المتغيرات في القسم <code>‎.bss</code> دليل على أنها ستُعطَى قيمة صفرية عند بدء البرنامج.
</p>

<p>
	يوجد المتغير <code>a_string</code> في القسم <code>‎.sdata</code> الذي يمثّل البيانات الصغيرة Small Data، حيث يُعَد هذا القسم وقسم <code>‎.sbss</code> المقابل له أقسامًا متوفرة في بعض المعماريات حيث يمكن الوصول إلى البيانات باستخدام الإزاحة عن بعض المؤشرات المعروفة، وهذا يعني أنه يمكن إضافة قيمة ثابتة إلى العنوان الأساسي، مما يجعل الوصول إلى البيانات في الأقسام أسرع نظرًا لعدم وجود عمليات بحث مطلوبة إضافية وتحميل للعناوين في الذاكرة. تقتصر معظم المعماريات على حجم القيم الفورية Immediate Value التي يمكنك إضافتها إلى المسجل مثل القيمة الفورية 70 عند تطبيق التعليمة <code>r1 = add r2, 70;‎</code> على عكس جمع قيمتين مخزنتين في مسجلين <code>r1 = add r2,r3</code>، وبالتالي يمكن تطبيق إزاحة بمقدار مسافة صغيرة معينة عن العنوان. يمكننا أيضًا أن نرى أن المتغير <code>a_var_with_value</code> يوجد في المكان نفسه.
</p>

<p>
	بينما توجد الدالة الرئيسية <code>main</code> في القسم <code>‎.text</code>. تذكر أن "النص Text" و"الشيفرة Code" يُستخدَمان للإشارة إلى برنامج في الذاكرة.
</p>

<h4>
	الأقسام والمقاطع مع بعضها البعض
</h4>

<p>
	إليك مثال يحتوي على الأقسام والمقاطع مع بعضها البعض:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3603_24" style=""><span class="pln">$ readelf </span><span class="pun">--</span><span class="pln">segments </span><span class="pun">/</span><span class="pln">bin</span><span class="pun">/</span><span class="pln">ls

</span><span class="typ">Elf</span><span class="pln"> file type is EXEC </span><span class="pun">(</span><span class="typ">Executable</span><span class="pln"> file</span><span class="pun">)</span><span class="pln">
</span><span class="typ">Entry</span><span class="pln"> point </span><span class="lit">0x100026c0</span><span class="pln">
</span><span class="typ">There</span><span class="pln"> are </span><span class="lit">8</span><span class="pln"> program headers</span><span class="pun">,</span><span class="pln"> starting at offset </span><span class="lit">52</span><span class="pln">

</span><span class="typ">Program</span><span class="pln"> </span><span class="typ">Headers</span><span class="pun">:</span><span class="pln">
  </span><span class="typ">Type</span><span class="pln">           </span><span class="typ">Offset</span><span class="pln">   </span><span class="typ">VirtAddr</span><span class="pln">   </span><span class="typ">PhysAddr</span><span class="pln">   </span><span class="typ">FileSiz</span><span class="pln"> </span><span class="typ">MemSiz</span><span class="pln">  </span><span class="typ">Flg</span><span class="pln"> </span><span class="typ">Align</span><span class="pln">
  PHDR           </span><span class="lit">0x000034</span><span class="pln"> </span><span class="lit">0x10000034</span><span class="pln"> </span><span class="lit">0x10000034</span><span class="pln"> </span><span class="lit">0x00100</span><span class="pln"> </span><span class="lit">0x00100</span><span class="pln"> R E </span><span class="lit">0x4</span><span class="pln">
  INTERP         </span><span class="lit">0x000154</span><span class="pln"> </span><span class="lit">0x10000154</span><span class="pln"> </span><span class="lit">0x10000154</span><span class="pln"> </span><span class="lit">0x0000d</span><span class="pln"> </span><span class="lit">0x0000d</span><span class="pln"> R   </span><span class="lit">0x1</span><span class="pln">
    </span><span class="pun">[</span><span class="typ">Requesting</span><span class="pln"> program interpreter</span><span class="pun">:</span><span class="pln"> </span><span class="pun">/</span><span class="pln">lib</span><span class="pun">/</span><span class="pln">ld</span><span class="pun">.</span><span class="pln">so</span><span class="pun">.</span><span class="lit">1</span><span class="pun">]</span><span class="pln">
  LOAD           </span><span class="lit">0x000000</span><span class="pln"> </span><span class="lit">0x10000000</span><span class="pln"> </span><span class="lit">0x10000000</span><span class="pln"> </span><span class="lit">0x14d5c</span><span class="pln"> </span><span class="lit">0x14d5c</span><span class="pln"> R E </span><span class="lit">0x10000</span><span class="pln">
  LOAD           </span><span class="lit">0x014d60</span><span class="pln"> </span><span class="lit">0x10024d60</span><span class="pln"> </span><span class="lit">0x10024d60</span><span class="pln"> </span><span class="lit">0x002b0</span><span class="pln"> </span><span class="lit">0x00b7c</span><span class="pln"> RWE </span><span class="lit">0x10000</span><span class="pln">
  DYNAMIC        </span><span class="lit">0x014f00</span><span class="pln"> </span><span class="lit">0x10024f00</span><span class="pln"> </span><span class="lit">0x10024f00</span><span class="pln"> </span><span class="lit">0x000d8</span><span class="pln"> </span><span class="lit">0x000d8</span><span class="pln"> RW  </span><span class="lit">0x4</span><span class="pln">
  NOTE           </span><span class="lit">0x000164</span><span class="pln"> </span><span class="lit">0x10000164</span><span class="pln"> </span><span class="lit">0x10000164</span><span class="pln"> </span><span class="lit">0x00020</span><span class="pln"> </span><span class="lit">0x00020</span><span class="pln"> R   </span><span class="lit">0x4</span><span class="pln">
  GNU_EH_FRAME   </span><span class="lit">0x014d30</span><span class="pln"> </span><span class="lit">0x10014d30</span><span class="pln"> </span><span class="lit">0x10014d30</span><span class="pln"> </span><span class="lit">0x0002c</span><span class="pln"> </span><span class="lit">0x0002c</span><span class="pln"> R   </span><span class="lit">0x4</span><span class="pln">
  GNU_STACK      </span><span class="lit">0x000000</span><span class="pln"> </span><span class="lit">0x00000000</span><span class="pln"> </span><span class="lit">0x00000000</span><span class="pln"> </span><span class="lit">0x00000</span><span class="pln"> </span><span class="lit">0x00000</span><span class="pln"> RWE </span><span class="lit">0x4</span><span class="pln">

 </span><span class="typ">Section</span><span class="pln"> to </span><span class="typ">Segment</span><span class="pln"> mapping</span><span class="pun">:</span><span class="pln">
  </span><span class="typ">Segment</span><span class="pln"> </span><span class="typ">Sections</span><span class="pun">...</span><span class="pln">
    </span><span class="lit">00</span><span class="pln">
    </span><span class="lit">01</span><span class="pln">     </span><span class="pun">.</span><span class="pln">interp
    </span><span class="lit">02</span><span class="pln">     </span><span class="pun">.</span><span class="pln">interp </span><span class="pun">.</span><span class="pln">note</span><span class="pun">.</span><span class="pln">ABI</span><span class="pun">-</span><span class="pln">tag </span><span class="pun">.</span><span class="pln">hash </span><span class="pun">.</span><span class="pln">dynsym </span><span class="pun">.</span><span class="pln">dynstr </span><span class="pun">.</span><span class="pln">gnu</span><span class="pun">.</span><span class="pln">version </span><span class="pun">.</span><span class="pln">gnu</span><span class="pun">.</span><span class="pln">version_ r </span><span class="pun">.</span><span class="pln">rela</span><span class="pun">.</span><span class="pln">dyn </span><span class="pun">.</span><span class="pln">rela</span><span class="pun">.</span><span class="pln">plt </span><span class="pun">.</span><span class="pln">init </span><span class="pun">.</span><span class="pln">text </span><span class="pun">.</span><span class="pln">fini </span><span class="pun">.</span><span class="pln">rodata </span><span class="pun">.</span><span class="pln">eh_frame_hdr
    </span><span class="lit">03</span><span class="pln">     </span><span class="pun">.</span><span class="pln">data </span><span class="pun">.</span><span class="pln">eh_frame </span><span class="pun">.</span><span class="pln">got2 </span><span class="pun">.</span><span class="pln">dynamic </span><span class="pun">.</span><span class="pln">ctors </span><span class="pun">.</span><span class="pln">dtors </span><span class="pun">.</span><span class="pln">jcr </span><span class="pun">.</span><span class="pln">got </span><span class="pun">.</span><span class="pln">sdata </span><span class="pun">.</span><span class="pln">sbss </span><span class="pun">.</span><span class="pln">p lt </span><span class="pun">.</span><span class="pln">bss
    </span><span class="lit">04</span><span class="pln">     </span><span class="pun">.</span><span class="pln">dynamic
    </span><span class="lit">05</span><span class="pln">     </span><span class="pun">.</span><span class="pln">note</span><span class="pun">.</span><span class="pln">ABI</span><span class="pun">-</span><span class="pln">tag
    </span><span class="lit">06</span><span class="pln">     </span><span class="pun">.</span><span class="pln">eh_frame_hdr
    </span><span class="lit">07</span></pre>

<p>
	يوضح المثال السابق كيف تظهِر الأداة <code>readelf</code> ربط المقاطع والأقسام في ملف ELF مع الملف الثنائي <code>‎/bin/ls</code>.
</p>

<p>
	انتقل إلى نهاية الخرج حيث يمكننا أن نرى الأقسام المنقولة إلى المقاطع، فمثلًا يُوضَع القسم <code>‎.interp</code> في المقطع الذي له الراية <code>INTERP</code>. لاحظ أن الأداة <code>readelf</code> تخبرنا بطلب المفسّر <code>‎/lib/ld.so.1</code>، وهو الرابط الديناميكي الذي يُشغَّل لإعداد الملف الثنائي للتنفيذ.
</p>

<p>
	يمكننا أن نرى الفرق بين النص والبيانات بالنظر إلى مقطعي <code>LOAD</code>. لاحظ أن المقطع الأول لديه أذونات القراءة والتنفيذ فقط، بينما يكون للمقطع الآخر أذونات القراءة والكتابة والتنفيذ، أي أن مقطع الشيفرة له أذونات القراءة والكتابة (r/w) ومقطع البيانات له أذونات القراءة والكتابة والتنفيذ (r/w/e)، ولكن لا يجب أن تكون البيانات قابلة للتنفيذ. لن يُميَّز قسم البيانات في معظم المعماريات مثل المعمارية x86 الأكثر شيوعًا على أنه يحتوي على قسم بيانات قابل للتنفيذ. لكن المثال السابق مأخوذ من معمارية PowerPC التي لها نموذج برمجة مختلف قليلًا وهو واجهة التطبيق الثنائية Application Binary Interface -أو ABI اختصارًا- التي تتطلب أن يكون قسم البيانات قابلًا للتنفيذ. هذه هي حياة مبرمج الأنظمة، إذ وُضِعت القواعد لكسرها.
</p>

<p>
	تستدعي واجهة ABI في معمارية PowerPC شيفرات اختبارية Stubs للدوال في المكتبات الديناميكية مباشرةً في جدول الإزاحة العام Global Offset Table -أو GOT اختصارًا- بدلًا من جعلها ترتد بين مدخلات منفصلة من جدول PLT، وبالتالي يحتاج المعالج إلى أذونات تنفيذ للقسم GOT الذي يمكنك رؤيته مضمَّنًا في مقطع البيانات.
</p>

<p>
	الشيء الآخر الذي يجب ملاحظته هو أن حجم الملف هو حجم الذاكرة نفسه لمقطع الشيفرة، ولكن حجم الذاكرة أكبر من حجم ملف مقطع البيانات، ويأتي ذلك من القسم BSS الذي يحتوي على متغيرات عامة صفرية.
</p>

<h2>
	واجهات ABI
</h2>

<p>
	تُعَد واجهة ABI مصطلحًا ستسمع عنه كثيرًا عند العمل مع <a href="https://academy.hsoub.com/programming/general/%D9%85%D8%AC%D8%A7%D9%84%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9/" rel="">برمجة الأنظمة</a>، وهو مختلف عن مصطلح <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr> الذي يُعَد واجهات يراها المبرمج في شيفرته البرمجية. تشير ABI إلى واجهات المستوى الأدنى التي يجب أن يتفق عليها المصرِّف ونظام التشغيل والمعالج إلى حد ما للتواصل مع بعضها البعض. سنقدم فيما يلي عددًا من المفاهيم المهمة لفهم واجهات ABI.
</p>

<h3>
	ترتيب البايتات
</h3>

<p>
	تُرتَّب البايتات باستخدام ترتيب Endianess الذي يحتوي على نوعين هما: Big-endian أي تخزين البتات الأقل أهمية أولًا، و Little-endian أي تخزين البتات الأكثر أهمية أولًا.
</p>

<h3>
	العرف المتبع في الاستدعاءات
</h3>

<p>
	يمكن تنفيذ الاستدعاءات بطريقتين هما: تمرير المعاملات باستخدام المسجلات registers أو المكدس stack وواصفات الدوال.
</p>

<p>
	بخصوص واصفات الدوال، لا تُستدعَى الدالة في العديد من المعماريات مباشرةً، بل تُستدعَى عبر واصف دالة Function Descriptor. يتكون واصف الدالة في المعمارية IA64 مثلًا من مكونين هما: عنوان الدالة (يُمثَّل بقيمة مقدارها 64 بتًا أو 8 بايتات) وعنوان المؤشر العام Global Pointer أو gp اختصارًا. تحدد واجهة ABI أن المسجل r1 يجب أن يحتوي دائمًا على قيمة المؤشر gp الخاص بالدالة، وهذا يعني أن مهمة المستدعي عند استدعاء دالة هي حفظ قيمة المؤشر gp الخاصة به وضبط المسجل r1 على القيمة الجديدة من واصف الدالة ثم استدعاء هذه الدالة.
</p>

<p>
	تُعَد واصفات الدوال مفيدة للغاية كما سترى لاحقًا. يمكن أن تأخذ تعليمة الجمع <code>add</code> في المعالج IA64 قيمة فورية ذات حجم بحد أقصى 22 بتًا بسبب الطريقة التي يحزُم بها المعالج IA64 التعليمات، حيث تُوضَع ثلاثة تعليمات في كل حزمة، ولا يوجد سوى مساحة كافية للاحتفاظ بقيمة 22 بتًا للحفاظ على الحزمة مع بعضها البعض. القيمة الفورية Immediate Value هي القيمة المحددة مباشرةً وليس القيمة الموجودة في المسجل، إذ تُعَد القيمة 100 في التعليمة <code>add r1 + 100</code> هي القيمة الفورية.
</p>

<p>
	يمكن أن تتمكن 22 بتًا من تمثيل 4194304 بايت أو 4 ميجابايتات، وبالتالي يمكن إزاحة كل دالة مباشرة في حيّز ذاكرة كبير مقداره 4 ميجابايتات دون الحاجة إلى تحمل عناء تحميل أيّ قيمٍ في المسجل. إذا اتفق المصرِّف والرابط والمحمِّل على ما يشير إليه المؤشر العام كما هو محدد في واجهة ABI، فيمكن تحسين الأداء من خلال تقليل عمليات التحميل.
</p>

<p>
	ترجمة -وبتصرُّف- للأقسام <a href="https://www.bottomupcs.com/chapter07.xhtml#executable_files" rel="external nofollow">Review of executable files</a> و <a href="https://www.bottomupcs.com/representing_executables.xhtml" rel="external nofollow">Representing executable files</a> و <a href="https://www.bottomupcs.com/elf.xhtml" rel="external nofollow">ELF</a> و <a href="https://www.bottomupcs.com/abi.xhtml" rel="external nofollow">ABIs</a> من فصل <a href="https://www.bottomupcs.com/chapter07.xhtml" rel="external nofollow">Behind the process</a> من كتاب <a href="https://www.bottomupcs.com/" rel="external nofollow">Computer Science from the Bottom Up</a> لصاحبه Ian Wienand.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D9%85%D9%81%D8%A7%D9%87%D9%8A%D9%85-%D9%85%D8%AA%D9%82%D8%AF%D9%85%D8%A9-%D9%85%D8%AA%D8%B9%D9%84%D9%82%D8%A9-%D8%A8%D8%B5%D9%8A%D8%BA%D8%A9-%D9%85%D9%84%D9%81%D8%A7%D8%AA-elf-%D8%A7%D9%84%D9%82%D8%A7%D8%A8%D9%84%D8%A9-%D9%84%D9%84%D8%AA%D9%86%D9%81%D9%8A%D8%B0-r1942/" rel="">مفاهيم متقدمة متعلقة بصيغة ملفات ELF القابلة للتنفيذ</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/c/%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D8%B9%D9%85%D9%84%D9%8A-%D9%84%D8%A8%D9%86%D8%A7%D8%A1-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D8%AC-%D8%AA%D9%86%D9%81%D9%8A%D8%B0%D9%8A-%D9%85%D9%86-%D8%B4%D9%8A%D9%81%D8%B1%D8%A9-%D9%85%D8%B5%D8%AF%D8%B1%D9%8A%D8%A9-%D8%A8%D9%84%D8%BA%D8%A9-c-r1931/" rel="">تطبيق عملي لبناء برنامج تنفيذي من شيفرة مصدرية بلغة C</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA-%D9%88%D8%B9%D9%86%D8%A7%D8%B5%D8%B1%D9%87%D8%A7-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1758/" rel="">العمليات وعناصرها في نظام تشغيل الحاسوب</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D9%85%D8%AB%D9%8A%D9%84-%D8%A7%D9%84%D8%A3%D9%86%D9%88%D8%A7%D8%B9-%D9%88%D8%A7%D9%84%D8%A3%D8%B9%D8%AF%D8%A7%D8%AF-%D9%81%D9%8A-%D8%A7%D9%84%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8%D9%8A%D8%A9-r1659/" rel="">تمثيل الأنواع والأعداد في الأنظمة الحاسوبية</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1941</guid><pubDate>Fri, 31 Mar 2023 15:07:00 +0000</pubDate></item><item><title>&#x62A;&#x635;&#x645;&#x64A;&#x645; &#x648;&#x62A;&#x646;&#x641;&#x64A;&#x630; &#x644;&#x639;&#x628;&#x629; &#x62D;&#x633;&#x64A;&#x629; &#x62A;&#x641;&#x627;&#x639;&#x644;&#x64A;&#x629; &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x644;&#x648;&#x62D;&#x629; &#x631;&#x627;&#x633;&#x628;&#x64A;&#x631;&#x64A; &#x628;&#x627;&#x64A; &#x628;&#x64A;&#x643;&#x648;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%88%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D9%84%D8%B9%D8%A8%D8%A9-%D8%AD%D8%B3%D9%8A%D8%A9-%D8%AA%D9%81%D8%A7%D8%B9%D9%84%D9%8A%D8%A9-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1934/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2023_03/---------.jpg.41b7930050ae42aa0149ce1a926ab16c.jpg" /></p>
<p>
	ستتعلم في هذا المقال كيفية إنشاء لعبة حسية تفاعلية، لتخفيف التوتر وتحسين مستوى تركيز الفرد، أو لتوفير وسيلة للتواصل مع الآخرين.
</p>

<p>
	ستعمل في هذا المشروع على:
</p>

<ul>
	<li>
		توظيف مهاراتك لتصميم وتنفيذ آلة حسية يتفاعل معها المستخدم.
	</li>
	<li>
		استخدام عناصر دخل إلكترونية، مثل الأزرار buttons والمقاومات المتغيرة potentiometers للتحكم بعمل عناصر خرج، مثل مصابيح الليد LED والأجراس buzzers.
	</li>
	<li>
		تحسين آلتك بناءً على ملاحظات المستخدمين.
	</li>
</ul>

<p>
	<strong>معلومة:</strong> تدفع الألعاب الحسية المستخدمين على الاستمرار في استخدامها والتفاعل معها، ومنها ألعاب النقر المتكرر fidget toys التي تساعد في تخفيف التوتر وتحسين مستوى تركيز الفرد، وأيضًا الألعاب الحسية التكيُّفية التي توفر وسيلة للأشخاص ذوي الإعاقات الجسدية للتواصل مع الآخرين. قد تحفز الألعاب الحسية جميع الحواس أو تركز فقط على إحداها.
</p>

<p>
	سيعتمد المقال على ملف المشروع <a data-fileext="zip" data-fileid="122039" href="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=122039&amp;key=cef26817b88d0e81081f3d2b301bd3fe" rel="">codes.zip</a> لذا يمكنك تحميله وبدء العمل.
</p>

<h2>
	الدليل الموجز لإنشاء لعبة إلكترونية تفاعلية تحفز الحواس
</h2>

<p>
	إليك شرحًا مختصرًا عن أهداف هذا المشروع:
</p>

<ul>
	<li>
		استخدام عناصر دخل وخرج إلكترونية متنوعة.
	</li>
	<li>
		إنشاء لعبة تفاعلية متينة تشد المستخدمين.
	</li>
	<li>
		توفير بيئة عمل وتجربة استخدام مريحة.
	</li>
	<li>
		تصفير الإعدادات بناءً على مدخلات المستخدمين، أو بعد مدة زمنية معينة.
	</li>
	<li>
		تصميم اللعبة وفق نمط أو موضوع معين.
	</li>
</ul>

<p>
	<strong>معلومة:</strong> يُعنى علم الهندسة البشرية Ergonomics بتحسين الطريقة التي يتفاعل فيها البشر مع البيئة المحيطة بهم وإيجاد حلول للمشكلات التي قد تواجههم، وسنحصل عند تطبيقه على أدوات سهلة الاستخدام ومريحة.
</p>

<h2>
	متطلبات المشروع
</h2>

<p>
	يتطلب المشروع توفر العتاد الآتي:
</p>

<ul>
	<li>
		لوحة حاسوب راسبيري باي بيكو Raspberry Pi Pico مع أرجل مثبتة عليها.
	</li>
	<li>
		كبل USB لنقل البيانات ذو نهايات من النوع USB A و micro USB.
	</li>
	<li>
		عناصر إلكترونية وأسلاك توصيل.
	</li>
</ul>

<p>
	أما من ناحية البرمجيات، فلا بد من توفر الآتي:
</p>

<ul>
	<li>
		برنامج ثوني Thonny: وهو البيئة البرمجية التي سنستخدمها لكتابة الشيفرة <a href="https://academy.hsoub.com/programming/python/%D8%A7%D9%84%D9%85%D8%B1%D8%AC%D8%B9-%D8%A7%D9%84%D8%B4%D8%A7%D9%85%D9%84-%D8%A5%D9%84%D9%89-%D8%AA%D8%B9%D9%84%D9%85-%D9%84%D8%BA%D8%A9-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-r735/" rel="">بلغة بايثون</a>.
	</li>
</ul>

<h2>
	تثبيت برنامج Thonny
</h2>

<p>
	سنعرض في الآتي طريقة تثبيت برنامج ثوني Thonny في أنظمة التشغيل المختلفة.
</p>

<h3>
	تثبيت برنامج Thonny على نظام تشغيل راسبيري باي
</h3>

<p>
	يأتي برنامج ثوني Thonny مثبتًا مع <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AC%D9%88%D9%84%D8%A9-%D9%81%D9%8A-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%A7%D9%86-%D9%86%D8%B8%D8%A7%D9%85-%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-r1371/" rel="">نظام تشغيل راسبيري باي</a>، المعروف سابقًا براسبيان Raspbian، لكن قد تحتاج إلى تحديثه. انقر على الأيقونة في الزاوية العلوية اليسرى من الشاشة لفتح نافذة الطرفية Terminal، أو اضغط المفاتيح التالية معًا <strong>Ctrl+Alt+T</strong>. ثم اكتب الأمر التالي لتحديث <a href="https://academy.hsoub.com/files/24-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%84%D9%85%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D9%86/" rel="">نظام التشغيل</a> وبرنامج Thonny:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8043_6" style=""><span class="pln">sudo apt update </span><span class="pun">&amp;&amp;</span><span class="pln"> sudo apt upgrade </span><span class="pun">-</span><span class="pln">y</span></pre>

<h3>
	تثبيت برنامج Thonny على أنظمة التشغيل الأخرى
</h3>

<p>
	يمكنك تثبيت ثوني Thonny على الحواسيب العاملة <a href="https://academy.hsoub.com/devops/linux/%D9%85%D8%A7-%D9%87%D9%88-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%8A%D9%86%D9%83%D8%B3%D8%9F-r451/" rel="">بنظام تشغيل لينكس</a>، أو ويندوز، أو ماك، وذلك من الموقع الرسمي <a href="https://thonny.org/" rel="external nofollow">thonny.org</a>. انقر على رابط التنزيل الموافق لنظام تشغيل حاسوبك من الزاوية العلوية اليمنى في الموقع، ثم انقر على الملفات بعد تنزيلها، وقد تظهر لك الرسالة التالية على نظام ويندوز:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122145" href="https://academy.hsoub.com/uploads/monthly_2023_03/thonny-site.png.954ffc6fb1376e39daa83f8bb7fdb3e6.png" rel=""><img alt="thonny-site.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122145" data-unique="mtgmjcxvg" src="https://academy.hsoub.com/uploads/monthly_2023_03/thonny-site.png.954ffc6fb1376e39daa83f8bb7fdb3e6.png"> </a>
</p>

<p>
	انقر على خيار المزيد من المعلومات "More info" ثم على التشغيل على أي حال "Run anyway".
</p>

<h2>
	التعرف على واجهة برنامج Thonny
</h2>

<p>
	عند فتح Thonny ستظهر لك الواجهة التالية:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122144" href="https://academy.hsoub.com/uploads/monthly_2023_03/thonny-editor.png.087fe74da20f21288908a0737baf7eb2.png" rel=""><img alt=" واجهة برنامج ثوني" class="ipsImage ipsImage_thumbnailed" data-fileid="122144" data-unique="bypzi6jpe" style="width: 700px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_03/thonny-editor.thumb.png.d5e51fc473f64870bc629b7e967fe02a.png"> </a>
</p>

<p>
	يمكنك الكتابة <a href="https://wiki.hsoub.com/Python" rel="external">بلغة بايثون</a> في النافذة الرئيسية الكبيرة، ثم النقر على زر التشغيل الأخضر <strong>Run</strong> للتنفيذ، ستظهر لك رسالة لحفظ الملف قبل تشغيله.
</p>

<p>
	اكتب الأمر التالي وشغّله:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8043_11" style=""><span class="kwd">print</span><span class="pun">(</span><span class="str">'Hello World!'</span><span class="pun">)</span></pre>

<h3>
	تغيير السمة والخط
</h3>

<p>
	يمكنك التحكم بلون الخط وحجمه وتغيير السمة المُستخدمة في واجهة البرنامج، وذلك بالنقر على قائمة الأدوات <strong>Tools</strong> من الشريط أعلى الشاشة، ثم النقر على خيارات <strong>Options</strong>، ثم انقر بعدها على نافذة الخط والسمة <strong>Theme &amp; Font</strong> واختر نوع الخط والسمة التي تفضلها من النافذة المنسدلة ثم انقر على زر موافق <strong>OK</strong> عند الانتهاء.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122143" href="https://academy.hsoub.com/uploads/monthly_2023_03/theme-tab.png.6e938dbf236d933840501adf6b8cae60.png" rel=""><img alt="تغيير السمة والخط المستخدمين في البرنامج" class="ipsImage ipsImage_thumbnailed" data-fileid="122143" data-unique="u4mz6jiue" style="width: 500px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_03/theme-tab.png.6e938dbf236d933840501adf6b8cae60.png"> </a>
</p>

<p>
	ننصحك باختيار الخطوط البسيطة الواضحة والابتعاد عن الخطوط المزخرفة أو المشابهة لخط اليد لأنها قد تجعل القراءة أصعب.
</p>

<h3>
	إعداد مكتبة picozero
</h3>

<p>
	سنعمل في هذه الخطوة على إعداد مكتبة picozero وتوصيل لوحة راسبيري باي بيكو وإعداد برنامج مايكرو بايثون.
</p>

<p>
	أولًا، صِل الطرف الصغير لكبل USB إلى لوحة <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D9%85%D8%A7-%D9%87%D9%88-%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-raspberry-pi%D8%9F-r1578/" rel="">راسبيري باي</a> والطرف الآخر إلى حاسوبك لتتمكن من برمجة اللوحة عن طريقه.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122119" href="https://academy.hsoub.com/uploads/monthly_2023_03/pico-top-plug.png.64bc044a2493b57cb44e48a04c32bd5f.png" rel=""><img alt="pico-top-plug.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122119" data-unique="r60z520ak" src="https://academy.hsoub.com/uploads/monthly_2023_03/pico-top-plug.png.64bc044a2493b57cb44e48a04c32bd5f.png"> </a>
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122123" href="https://academy.hsoub.com/uploads/monthly_2023_03/plug-in-pico.png.f0894ccd28100c5655b60bbe0ee0d68b.png" rel=""><img alt="plug-in-pico.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122123" data-unique="fqw9mid4q" src="https://academy.hsoub.com/uploads/monthly_2023_03/plug-in-pico.png.f0894ccd28100c5655b60bbe0ee0d68b.png"> </a>
</p>

<p>
	ثانيًا، افتح محرر Thonny، ولاحظ ما هو الإصدار المستخدم من <a href="https://academy.hsoub.com/programming/python/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-%D8%A8%D9%84%D8%BA%D8%A9-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-r1815/" rel="">بايثون</a> بقراءة النص الموجود في الزاوية السفلية اليمنى من الشاشة، انقر على النص واختر "MicroPython (Raspberry Pi Pico)‎"، إذا لم يكن هذا الخيار محددًا. سيطالبك Thonny بتثبيت برنامج MicroPython على حاسوب راسبيري باي بيكو إذا لم تستخدمه مسبقًا، فقط انقر على زر التثبيت <strong>Install</strong>.
</p>

<p>
	ثالثًا، أضف حزمة بيكو زيرو picozero من خلال النقر على قائمة الأدوات <strong>Tools</strong> من شريط القوائم في برنامج Thonny، ثم النقر على خيار إدارة الحزم <strong>Manage Packages</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122147" href="https://academy.hsoub.com/uploads/monthly_2023_03/tools-manage-packages.png.fb83d8fc11a2e7747ba98e63b0711bbf.png" rel=""><img alt="tools-manage-packages.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122147" data-unique="tua9phhvv" src="https://academy.hsoub.com/uploads/monthly_2023_03/tools-manage-packages.png.fb83d8fc11a2e7747ba98e63b0711bbf.png"> </a>
</p>

<p>
	ثالثًا، اكتب "picozero"، ثم انقر على زر البحث <strong>Search on PyPi</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122130" href="https://academy.hsoub.com/uploads/monthly_2023_03/search-picozero.png.9492fe53fb3b4ee1384b9eac49a71aee.png" rel=""><img alt="search-picozero.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122130" data-unique="8icggh3ug" src="https://academy.hsoub.com/uploads/monthly_2023_03/search-picozero.png.9492fe53fb3b4ee1384b9eac49a71aee.png"> </a>
</p>

<p>
	رابعًا، انقر على <strong>picozero</strong> من نتائج البحث ثم انقر على زر التثبيت <strong>Install</strong>.
</p>

<h2>
	استلهم أفكارك
</h2>

<p>
	اطلع على المشاريع التالية واستلهم منها بعض الأفكار لصنع آلتك التفاعلية:
</p>

<h3>
	مشروع الأضواء الليلية
</h3>

<div class="ipsEmbeddedVideo" contenteditable="false">
	<div>
		<iframe allowfullscreen="" frameborder="0" height="506" src="https://player.vimeo.com/video/795266293?autoplay=0&amp;color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="900"></iframe>
	</div>
</div>

<p>
	شغّل الفيديو، وشاهد كيف أحدثنا ثقوبًا صغيرةً في ورقة سوداء اللون للحصول على سماء مرصّعة بالنجوم داخل غرفتك. استخدم مصباح الليد متعدد الألوان RGB LED للحصول على تأثير الوميض، واستخدم الأزرار buttons لتشغيل وإطفاء الأضواء. يمكنك الاطلاع على الشيفرة اللازمة لتنفيذ هذا المشروع والموجودة باسم "night_sky.py" من ملف المشروع <a data-fileext="zip" data-fileid="122039" href="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=122039&amp;key=cef26817b88d0e81081f3d2b301bd3fe" rel="">codes.zip</a>.
</p>

<h3>
	مشروع النحلة الطنانة
</h3>

<div class="ipsEmbeddedVideo" contenteditable="false">
	<div>
		<iframe allowfullscreen="" frameborder="0" height="506" src="https://player.vimeo.com/video/795266253?autoplay=0&amp;color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="900"></iframe>
	</div>
</div>

<p>
	شغّل الفيديو ولاحظ أنه عند الضغط على أجنحة النحلة يصدر صوت طنين، إذ وضعنا ورق قصدير تحت الأجنحة وعند الضغط عليها تلامس قطعةً أخرى من القصدير، وهذا يجعل الجرس يصدر نغمةً ما، إذ يُصدر كل جناح صوتًا مختلفًا؛ كما أضفنا مقاومةً متغيرة للتحكم في مصباح ليد أزرق. يمكنك الاطلاع على الشيفرة اللازمة لتنفيذ هذا المشروع والموجودة باسم "The buzzy bee.py" من ملف المشروع <a data-fileext="zip" data-fileid="122039" href="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=122039&amp;key=cef26817b88d0e81081f3d2b301bd3fe" rel="">codes.zip</a>.
</p>

<h3>
	مشروع السيف المضيئ
</h3>

<div class="ipsEmbeddedVideo" contenteditable="false">
	<div>
		<iframe allowfullscreen="" frameborder="0" height="506" src="https://player.vimeo.com/video/795266203?autoplay=0&amp;color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="900"></iframe>
	</div>
</div>

<p>
	شغّل الفيديو ولاحظ كيف يضيء نصل السيف عند الضغط على الزر ويصدر الجرس الإلكتروني صوت طنين خافت، وعند تدوير قرص المقاومة المتغيرة يتغير لون النصل وحِدّة الطنين؛ ولإطفاء السيف علينا تدوير قرص المقاومة بالاتجاه المعاكس. يمكنك الاطلاع على الشيفرة اللازمة لتنفيذ هذا المشروع والموجودة باسم "saber.py" من ملف المشروع <a data-fileext="zip" data-fileid="122039" href="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=122039&amp;key=cef26817b88d0e81081f3d2b301bd3fe" rel="">codes.zip</a>.
</p>

<h3>
	مشروع الشمعة الإلكترونية
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="122096" href="https://academy.hsoub.com/uploads/monthly_2023_03/candle.gif.883cd9d29daca5dea13136e1021c8d72.gif" rel=""><img alt="candle.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="122096" data-ratio="56.33" data-unique="ygmm5hm4g" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_03/candle.gif.883cd9d29daca5dea13136e1021c8d72.gif"> </a>
</p>

<p>
	استخدمنا في هذا المشروع مصباح ليد متعدد الألوان RGB LED يضيء باستمرار، وعند النفخ على الشمعة ينطفئ المصباح كما شعلة اللهب الحقيقية؛ حيث يؤدي النفخ إلى تلامس قطعتين من ورق القصدير فتنطفئ الشعلة مدةً قصيرةً، ثم تعود للعمل بعدها. يمكنك الاطلاع على الشيفرة اللازمة لتنفيذ هذا المشروع والموجودة باسم "candle.py" من ملف المشروع <a data-fileext="zip" data-fileid="122039" href="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=122039&amp;key=cef26817b88d0e81081f3d2b301bd3fe" rel="">codes.zip</a>.
</p>

<h2>
	إعداد فكرة اللعبة
</h2>

<p>
	يجب عليك وضع خطة للعبتك وكيف سيتفاعل اللاعب معها، لذلك خطط عن طريق التفكير، أو الكتابة والرسم، أو عن طريق التعديل وإصلاح بعض أجزاء اللعبة، فالخيار متروك لك.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="122095" href="https://academy.hsoub.com/uploads/monthly_2023_03/buzy-bee.jpg.7f9a5d2738686d0085e050a0feafe3ae.jpg" rel=""><img alt="buzy-bee.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="122095" data-ratio="93.17" data-unique="drad34ecn" style="width: 550px; height: auto;" width="644" src="https://academy.hsoub.com/uploads/monthly_2023_03/buzy-bee.thumb.jpg.3c5abe3ee5b2a6155f0fead8ef64abef.jpg"> </a>
</p>

<h3>
	تحديد غرض اللعبة
</h3>

<p>
	فكر مليًّا في الهدف من اللعبة التي ستصممها، ما الغرض منها، هل تود تعريف طفل ما على الأصوات والأشكال؟ أم تريدها وسيلةً لتخفيف التوتر عن طريق الضغط على الأزرار وسماع الأصوات الموافقة لكل زر؟ أم تود تصميم أداة لمساعدة الأشخاص على التواصل والتعبير عن احتياجاتهم؟
</p>

<h3>
	تحديد الجمهور
</h3>

<p>
	فكر مليًا في الجمهور المستهدف من اللعبة، من هم؟ هل تود تصميم اللعبة لتناسب احتياجات صديق ما، أو أحد أفراد العائلة، أو أحد الصفوف الدراسية، أو الأشخاص الذين يمارسون هواية ما؟ كما يمكنك استهداف جمهور أحد الموسيقيين، أو أن تصمم اللعبة لنفسك.
</p>

<h3>
	تحديد مميزات اللعبة
</h3>

<p>
	فكر مليًا في العناصر التي تود استخدامها في لعبتك؛ إذ تحتوي لوحة راسبيري باي بيكو على ثمانية أرجل أرضية <strong>GND</strong>، لذا يمكنك توصيل ثمانية عناصر فقط، وقد تستطيع توصيل أكثر من ثمانية عناصر إذا كان من الممكن أن يشترك بعضها برجل الأرض <strong>GND</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122111" href="https://academy.hsoub.com/uploads/monthly_2023_03/gnd-pins.png.3cc6504a18f3838d79c2d6873e9e96b2.png" rel=""><img alt="gnd-pins.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122111" data-unique="zdzlnorti" src="https://academy.hsoub.com/uploads/monthly_2023_03/gnd-pins.thumb.png.dec51ca4a1457a21ff02129dcb01fb78.png"> </a>
</p>

<p>
	عليك أخذ النقاط التالية في الحسبان عند التخطيط للعبتك:
</p>

<ul>
	<li>
		تُشَغّل مكبرات الصوت Speakers كل نغمة على حدى، لذلك ستحتاج لعدة مكبرات صوت لتشغيل عدة نغمات في نفس الوقت.
	</li>
	<li>
		توجد رجل تغذية واحدة ذات جهد 3 فولت على لوحة بيكو؛ أي يمكنك استخدام مقاومة متغيرة واحدة، كما أنه يوجد حدٌّ لقيمة التيار الذي توفره لوحة بيكو.
	</li>
</ul>

<p>
	إليك بعض الاقتراحات لعناصر الدخل والخرج التي يمكنك استخدامها معًا:
</p>

<ul>
	<li>
		مقاومة متغيرة واحدة وجرس إلكتروني واحد.
	</li>
	<li>
		أربعة أزرار جاهزة وجرس إلكتروني واحد.
	</li>
	<li>
		ثمانية مبدلات يدوية الصنع وجرس إلكتروني واحد.
	</li>
	<li>
		مقاومة متغيرة واحدة وجرسان، وزران.
	</li>
	<li>
		عدة أزرار وأجراس لعزف عدة نغمات في نفس الوقت.
	</li>
</ul>

<p>
	يمكنك استخدام ما يزيد عن ثمانية عناصر، ولكن عليك حينها استخدام رجل أرضية مشتركة <strong>GND</strong>.
</p>

<p>
	حدد هل تود استخدام الأزرار ومقاومة متغيرةً كعناصر دخل؟ أم تريد استخدام قواطع يدوية الصنع؟ وهل تريد عزف صوت معين، أم لحنًا ما أو عدة ألحان؟ هل تريد استخدام مصباح ليد ذو لون واحد؟ أم تفضل استخدام المصباح متعدد الألوان؟
</p>

<h3>
	اعتماد التصميم الخارجي للعبة
</h3>

<p>
	حدد كيف تريد أن يبدو الشكل الخارجي للعبة:
</p>

<ul>
	<li>
		هل تريد اعتماد تصميم موجود مسبقًا، مثل شكل المكعب أو المفرقعات؟
	</li>
	<li>
		هل تفضل اعتماد موضوع برنامجك التلفزيوني أو سلسلتك المفضلة من القصص المصورة، أو حتى أغنيتك المفضلة؟
	</li>
	<li>
		هل تريد صنع غلاف خارجي للعبة من صناديق الورق المقوى، أو من القماش، أو البلاستيك؟
	</li>
</ul>

<p>
	الآن، حضّر العناصر التي ستحتاجها لتنفيذ لعبتك قبل البدء، من عناصر دخل وخرج إلكترونية، وأسلاك توصيل، ولوحة بيكو، واختبر سلامة اللوحة عن طريق توصيلها بحاسوبك والتحقق من عمل مصباح الليد الموجود على اللوحة، باستخدام الشيفرة التالية:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8043_18" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> pico_led
</span><span class="kwd">from</span><span class="pln"> time </span><span class="kwd">import</span><span class="pln"> sleep

pico_led</span><span class="pun">.</span><span class="pln">on</span><span class="pun">()</span><span class="pln">
sleep</span><span class="pun">(</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
pico_led</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span></pre>

<h2>
	تنفيذ اللعبة واختبارها
</h2>

<p>
	حان الآن وقت إعداد لعبتك وتنفيذها.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122099" href="https://academy.hsoub.com/uploads/monthly_2023_03/communication-tool.png.916e923c8cf28436502dc0b5dc2af312.png" rel=""><img alt="communication-tool.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122099" data-ratio="66.00" data-unique="3qb2d65n6" style="width: 550px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2023_03/communication-tool.thumb.png.6d42bda3805bd11fa246a633a02f7170.png"> </a>
</p>

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

<p>
	إليك تذكرةً ببعض المهارات التي تعلمناها والتي ستفيدك في إنشاء لعبتك:
</p>

<h3>
	توصيل عناصر الخرج
</h3>

<h4>
	استخدام رجل أرضية مشتركة
</h4>

<p>
	تحتوي لوحة بيكو على ثمانية أرجل أرضية <strong>GND</strong>، لذلك لاستخدام ما يزيد عن ثمانية عناصر إلكترونية عليك إعادة استخدام إحدى الأرجل الأرضية، وستحتاج لما يلي:
</p>

<ul>
	<li>
		سلك توصيل نوع دبوس- مقبس.
	</li>
	<li>
		رقائق قصدير، وشريط لاصق ناقل، أو أي مادة ناقلة للتيار الكهربائي.
	</li>
	<li>
		شريط لاصق.
	</li>
</ul>

<p>
	أولًا، أنشئ شريطًا من ورق القصدير، أو من أي مادة ناقلة.
</p>

<p>
	ثانيًا، استخدم الشريط اللاصق لتوصيل سلك أحد الأرجل الأرضية مع شريط القصدير، كما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpeg" data-fileid="122135" href="https://academy.hsoub.com/uploads/monthly_2023_03/step-one.jpeg.fbd3d0c4bf43bee118a561bd3d1ff6af.jpeg" rel=""><img alt="step-one.jpeg" class="ipsImage ipsImage_thumbnailed" data-fileid="122135" data-unique="idsz74sly" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_03/step-one.thumb.jpeg.aa75179d64a86217216878dde9f13156.jpeg"> </a>
</p>

<p>
	ثالثًا، صِل القطب الموجب للعنصر الأول مع أحد الأرجل العامة <strong>GP</strong> على لوحة بيكو، والقطب السالب للعنصر مع شريط القصدير.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpeg" data-fileid="122136" href="https://academy.hsoub.com/uploads/monthly_2023_03/step-three.jpeg.30611d2e706685da3ae8496876196426.jpeg" rel=""><img alt="step-three.jpeg" class="ipsImage ipsImage_thumbnailed" data-fileid="122136" data-ratio="66.67" data-unique="78a5dshes" style="width: 550px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2023_03/step-three.thumb.jpeg.c57ffb6a8b4a0e3f33e29f9fa0710f3d.jpeg"> </a>
</p>

<p>
	رابعًا، لتوصيل المزيد من العناصر، صِل القطب الموجب للعنصر مع إحدى أرجل الأغراض العامة <strong>GP</strong>، والقطب السالب مع شريط القصدير.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpeg" data-fileid="122134" href="https://academy.hsoub.com/uploads/monthly_2023_03/step-four.jpeg.945d4e92719390d0297b1f747377278a.jpeg" rel=""><img alt="step-four.jpeg" class="ipsImage ipsImage_thumbnailed" data-fileid="122134" data-ratio="66.67" data-unique="38y70926q" style="width: 550px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2023_03/step-four.thumb.jpeg.eb49b7e13c230e5940060b4e40c4bab5.jpeg"> </a>
</p>

<h4>
	توصيل مصابيح الليد ذات اللون الواحد
</h4>

<p>
	لتوصيل مصباح ليد واحد ستحتاج إلى ما يلي:
</p>

<ul>
	<li>
		لوحة راسبيري باي بيكو.
	</li>
	<li>
		مصباح ليد باللون الذي تفضله.
	</li>
	<li>
		مقاومة.
	</li>
	<li>
		سلكي توصيل نوع مقبس- مقبس.
	</li>
</ul>

<p>
	يجب توصيل مقاومة مع الرجل الموجبة الطويلة لمصباح الليد، وتوصيلها مع الرجل <strong>GP13</strong> على لوحة بيكو. وتوصيل الرجل السالبة للمصباح مع أقرب رجل أرضية، كما هو موضح في المخطط التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122120" href="https://academy.hsoub.com/uploads/monthly_2023_03/pico_led_13_bb.png.4fd00ba2e08119c7169900b0a8b93e2e.png" rel=""><img alt="pico_led_13_bb.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122120" data-unique="g5nipjyuu" src="https://academy.hsoub.com/uploads/monthly_2023_03/pico_led_13_bb.thumb.png.ad03e0bd318b747000c17bc4dab29f9f.png"> </a>
</p>

<p>
	أما لتوصيل عدة مصابيح ليد ذات اللون الواحد، ستحتاج إلى ما يلي:
</p>

<ul>
	<li>
		لوحة راسبيري باي بيكو.
	</li>
	<li>
		عدة مصابيح ليد باللون الذي تفضله.
	</li>
	<li>
		مقاومة لكل مصباح.
	</li>
	<li>
		سلكي توصيل نوع مقبس- مقبس لكل مصباح.
	</li>
</ul>

<p>
	يجب توصيل مقاومة مع الرجل الموجبة الطويلة لكل مصباح ليد؛ وتوصيل الرجل الموجبة للمصباح الأول مع الرجل <strong>GP13</strong> على لوحة بيكو والسالبة مع أقرب رجل أرضية <strong>GND</strong>؛ وتوصيل الرجل الموجبة للمصباح الثاني مع الرجل <strong>GP8</strong>، والسالبة مع أقرب رجل أرضية <strong>GND</strong>؛ وتوصيل الرجل الموجبة للمصباح الثالث مع الرجل <strong>GP5</strong>، والسالبة مع أقرب رجل أرضية <strong>GND</strong>، كما هو موضح في المخطط التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122117" href="https://academy.hsoub.com/uploads/monthly_2023_03/multiple-leds.png.5839df55cf221933d9b4d5ca9c2df17a.png" rel=""><img alt="multiple-leds.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122117" data-unique="89vpjai26" src="https://academy.hsoub.com/uploads/monthly_2023_03/multiple-leds.thumb.png.b77b46b5f8bcdfc35dc4cd02c67b54bf.png"> </a>
</p>

<h4>
	إسناد مصابيح ليد إلى رجل معينة أو عدة أرجل على اللوحة
</h4>

<p>
	استخدم الشيفرة التالية لإسناد مصباح وحيد إلى الرجل الموصول معها على لوحة بيكو:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8043_24" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> LED
led </span><span class="pun">=</span><span class="pln"> LED</span><span class="pun">(</span><span class="lit">13</span><span class="pun">)</span></pre>

<p>
	أما لإسناد عدة مصابيح ليد إلى أرجل لوحة بيكو: استورد تابع المصباح <code>LED</code> من مكتبة <code>picozero</code>، ثم استخدم الشيفرة التالية لإسناد المصابيح إلى الأرجل الموصولة معها على لوحة بيكو:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8043_26" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> LED
led_1 </span><span class="pun">=</span><span class="pln"> LED</span><span class="pun">(</span><span class="lit">13</span><span class="pun">)</span><span class="pln">
led_2 </span><span class="pun">=</span><span class="pln"> LED</span><span class="pun">(</span><span class="lit">8</span><span class="pun">)</span><span class="pln">
led_2 </span><span class="pun">=</span><span class="pln"> LED</span><span class="pun">(</span><span class="lit">5</span><span class="pun">)</span></pre>

<p>
	ننصحك بتسمية المتغيرات بأسماء تدل على عملها، كأن تسمّي المصباح المسؤول عن تشغيل المصباح باللون المسؤول عنه، كما يلي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8043_28" style=""><span class="pln">red_led </span><span class="pun">=</span><span class="pln"> LED</span><span class="pun">(</span><span class="lit">13</span><span class="pun">)</span><span class="pln">
green_led </span><span class="pun">=</span><span class="pln"> LED</span><span class="pun">(</span><span class="lit">8</span><span class="pun">)</span><span class="pln">
pink_led </span><span class="pun">=</span><span class="pln"> LED</span><span class="pun">(</span><span class="lit">5</span><span class="pun">)</span></pre>

<h4>
	إضافة الشيفرة اللازمة لتشغيل مصباح ليد واحد أو عدة مصابيح
</h4>

<p>
	إليك الدالة اللازمة لتشغيل المصباح:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8043_30" style=""><span class="kwd">def</span><span class="pln"> excited</span><span class="pun">():</span><span class="pln"> </span><span class="com"># دالة تشغل اللون الموافق لمزاجك</span><span class="pln">
    purple</span><span class="pun">.</span><span class="pln">on</span><span class="pun">()</span><span class="pln"> </span><span class="com"># شغّل اللون البنفسجي</span></pre>

<p>
	أما الشيفرة اللازمة لتشغيل عدة مصابيح فهي على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8043_32" style=""><span class="kwd">def</span><span class="pln"> excited</span><span class="pun">():</span><span class="pln"> </span><span class="com">#  شغّل اللون الموافق لشعورك بالحماس</span><span class="pln">
    purple</span><span class="pun">.</span><span class="pln">on</span><span class="pun">()</span><span class="pln"> </span><span class="com">#  شغّل المصباح البنفسجي</span><span class="pln">
    blue</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln"> </span><span class="com">#  أطفئ المصباح الأزرق</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> worried</span><span class="pun">():</span><span class="pln"> </span><span class="com"># شغّل اللون الموافق لشعورك بالقلق</span><span class="pln">
    purple</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln"> </span><span class="com">#  أطفئ المصباح البنفسجي</span><span class="pln">
    blue</span><span class="pun">.</span><span class="pln">on</span><span class="pun">()</span><span class="pln"> </span><span class="com"># شغّل المصباح الأزرق</span></pre>

<h4>
	توصيل مصابيح الليد متعددة الألوان
</h4>

<p>
	ستحتاج لتوصيل مصباح ليد متعدد الألوان إلى ما يلي:
</p>

<ul>
	<li>
		لوحة راسبيري باي بيكو.
	</li>
	<li>
		مصباح ليد متعدد الألوان ذو مهبط مشترك.
	</li>
	<li>
		ثلاث مقاومات.
	</li>
	<li>
		أسلاك توصيل نوع مقبس- مقبس (عدد 8).
	</li>
</ul>

<p>
	يجب عليك توصيل مقاومة مع الأرجل الثلاثة الطويلة لمصباح الليد، أما الرجل الطويلة فهي رجل الأرضية ولا تحتاج إلى مقاومة.
</p>

<p>
	<strong>معلومة:</strong> لاحظ أنه لمصباح الليد متعدد الألوان أربعة أرجل، لذلك أمسك المصباح بحيث تكون الرجل الأرضية هي ثاني رجل من اليسار، وبحيث يصبح ترتيب الأرجل على النحو التالي: الرجل المسؤولة عن اللون الأحمر<strong>R</strong>ed، ثم الرجل الأرضية <strong>GND</strong>، ثم الرجل المسؤولة عن اللون الأخضر<strong>G</strong>reen، فالأزرق <strong>B</strong>lue، وذلك ليسهُل عليك تذكر وظيفة كل رجل.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122128" href="https://academy.hsoub.com/uploads/monthly_2023_03/rgb-led-legs.png.876e215fbec07d2d7ad6b5432b045e21.png" rel=""><img alt="rgb-led-legs.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122128" data-unique="faxtws7xj" src="https://academy.hsoub.com/uploads/monthly_2023_03/rgb-led-legs.png.876e215fbec07d2d7ad6b5432b045e21.png"> </a>
</p>

<p>
	صِل أرجل مصباح الليد وفقًا لما يلي:
</p>

<ul>
	<li>
		صِل الرجل المسؤولة عن اللون الأحمر<strong>R</strong> مع الرجل <strong>GP1</strong> على لوحة بيكو.
	</li>
	<li>
		صِل الرجل الأرضية <strong>GND</strong> مع رجل الأرض <strong>GND</strong> على لوحة بيكو.
	</li>
	<li>
		صِل الرجل المسؤولة عن اللون الأخضر<strong>G</strong> مع الرجل <strong>GP2</strong> على لوحة بيكو.
	</li>
	<li>
		صِل الرجل المسؤولة عن اللون الأزرق <strong>B</strong> مع الرجل <strong>GP3</strong> على لوحة بيكو.
	</li>
</ul>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122127" href="https://academy.hsoub.com/uploads/monthly_2023_03/rgb-led-diagram.png.67f4cc5f2091ea8f31ca50e0e1d9d775.png" rel=""><img alt="rgb-led-diagram.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122127" data-unique="6yys7y05t" src="https://academy.hsoub.com/uploads/monthly_2023_03/rgb-led-diagram.thumb.png.564217c1eaea0c86ee492e598c7fd57c.png"> </a>
</p>

<p>
	لإسناد مصباح الليد متعدد الألوان إلى أرجل لوحة بيكو: استورد تابع المصباح متعدد الألوان <code>RGBLED</code> من مكتبة <code>picozero</code>، ثم استخدم الشيفرة التالية لإسناد المصباح إلى الأرجل الموصول معها على لوحة بيكو:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8043_34" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> RGBLED

rgb </span><span class="pun">=</span><span class="pln"> RGBLED</span><span class="pun">(</span><span class="pln">red </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> green </span><span class="pun">=</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> blue </span><span class="pun">=</span><span class="pln"> </span><span class="lit">3</span><span class="pun">)</span></pre>

<p>
	استخدم الدالة اللازمة لتشغيل مصباح متعدد الألوان كما هو موضح في الشيفرة التالية:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8043_36" style=""><span class="kwd">def</span><span class="pln"> happy</span><span class="pun">():</span><span class="pln"> </span><span class="com"># الشعور بالسعادة</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">color </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="com"># شغّل اللون الموافق لشعورك بالسعادة</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> sad</span><span class="pun">():</span><span class="pln"> </span><span class="com"># الشعور بالحزن</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">color </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="com"># شغّل اللون الموافق لشعورك بالحزن</span></pre>

<h4>
	تمثيل الألوان بصيغة RGB:
</h4>

<p>
	يمكننا تمثيل الألوان بصيغة يفهمها الحاسوب وذلك بالتعبير عن نسبة ما يحتويه اللون من اللون الأحمر والأخضر والأزرق، إذ تخزن هذه القيم في <strong>بايت</strong> (ثمانية بتات) وتكون قيمتها من 0 إلى 255.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="122129" href="https://academy.hsoub.com/uploads/monthly_2023_03/RGB.gif.9d89cfaba36fa1605f28c06d6cbf19d1.gif" rel=""><img alt="RGB.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="122129" data-ratio="59.84" data-unique="cvh3rkb63" width="498" src="https://academy.hsoub.com/uploads/monthly_2023_03/RGB.gif.9d89cfaba36fa1605f28c06d6cbf19d1.gif"> </a>
</p>

<p>
	إليك جدولًا يوضح بعض القيم اللونية:
</p>

<table>
	<thead>
		<tr>
			<th>
				اللون
			</th>
			<th>
				الأحمر
			</th>
			<th>
				الأخضر
			</th>
			<th>
				الأزرق
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				أحمر
			</td>
			<td>
				255
			</td>
			<td>
				0
			</td>
			<td>
				0
			</td>
		</tr>
		<tr>
			<td>
				أخضر
			</td>
			<td>
				0
			</td>
			<td>
				255
			</td>
			<td>
				0
			</td>
		</tr>
		<tr>
			<td>
				أزرق
			</td>
			<td>
				0
			</td>
			<td>
				0
			</td>
			<td>
				255
			</td>
		</tr>
		<tr>
			<td>
				أصفر
			</td>
			<td>
				255
			</td>
			<td>
				255
			</td>
			<td>
				0
			</td>
		</tr>
		<tr>
			<td>
				أرجواني
			</td>
			<td>
				255
			</td>
			<td>
				0
			</td>
			<td>
				255
			</td>
		</tr>
		<tr>
			<td>
				سماوي
			</td>
			<td>
				0
			</td>
			<td>
				255
			</td>
			<td>
				255
			</td>
		</tr>
	</tbody>
</table>

<p>
	كما يمكنك الاستعانة <a href="https://www.w3schools.com/colors/colors_rgb.asp" rel="external nofollow">بمنتقي الألوان</a> من موقع w3schools للحصول على القيم الموافقة للون الذي تريده.
</p>

<h4>
	توصيل مكبرات الصوت والأجراس الإلكترونية
</h4>

<p>
	ستحتاج لتوصيل جرس إلكتروني واحد مع لوحة بيكو إلى سلكي توصيل نوع مقبس- مقبس. ابدأ بوصل الرجل الطويلة الموجبة للجرس مع الرجل <strong>GP5</strong> على لوحة بيكو، وصِل الرجل السالبة مع أقرب رجل تأريض <strong>GND</strong>.
</p>

<p>
	لمعرفة الرجل الموجبة للجرس، ابحث عن الرجل الأطول، أو عن إشارة الموجب <strong>+</strong> أعلى الجرس.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122133" href="https://academy.hsoub.com/uploads/monthly_2023_03/single-buzzer-wiring.png.de1b8867a072f938c05c09c60428d526.png" rel=""><img alt="single-buzzer-wiring.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122133" data-ratio="105.08" data-unique="pifs31t33" width="571" src="https://academy.hsoub.com/uploads/monthly_2023_03/single-buzzer-wiring.thumb.png.f053f833ce8ea342bb413f90b2e6d9f8.png"> </a>
</p>

<p>
	وتكون الشيفرة اللازمة لتوصيل جرس واحد على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8043_38" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pln">

speaker </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pun">(</span><span class="lit">5</span><span class="pun">)</span></pre>

<p>
	أما لتوصيل جرسين إلكترونيين مع لوحة بيكو لخلق تأثير الصوت المجسم ستحتاج إلى أربعة أسلاك توصيل نوع مقبس- مقبس.
</p>

<p>
	أولًا، صِل الرجل الطويلة الموجبة للجرس الأول مع الرجل <strong>GP5</strong> على لوحة بيكو، وصِل الرجل السالبة مع أقرب رجل تأريض <strong>GND</strong>، ثم صِل الرجل الموجبة للجرس الثاني مع الرجل <strong>GP10</strong> على لوحة بيكو، والرجل السالبة مع أقرب رجل تأريض <strong>GND</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122137" href="https://academy.hsoub.com/uploads/monthly_2023_03/stereo-buzzer-wiring.png.7617f565450e26813d9e329772fa758a.png" rel=""><img alt="stereo-buzzer-wiring.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122137" data-ratio="105.08" data-unique="rxkq691pn" style="width: 550px; height: auto;" width="571" src="https://academy.hsoub.com/uploads/monthly_2023_03/stereo-buzzer-wiring.thumb.png.4b972c8411e5749ada9241ca113c60fb.png"> </a>
</p>

<p>
	وتكون الشيفرة اللازمة لتوصيل جرسين على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_7" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pln">

speaker_1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pun">(</span><span class="lit">5</span><span class="pun">)</span><span class="pln">
speaker_2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pun">(</span><span class="lit">10</span><span class="pun">)</span></pre>

<p>
	ننصحك بتسمية المتغيرات Variables بأسماء تدل على وظيفتها، مثلًا عند إسناد صوت الطبل للمتغير <code>Speaker_1</code> فسمّه <code>drum_beat</code>.
</p>

<p>
	ستحتاج لتوصيل السمّاعات مع لوحة بيكو إلى وصلة ذات نهاية بقطر 3 أو 5 <strong>مم</strong> (وليس وصلة USB)، وثلاثة مشابك تثبيت، وإلى اتباع الخطوات التالية:
</p>

<p>
	1.صِل أحد المشابك مع أحد أرجل الأرض <strong>GND</strong> القريبة، وصِل المشبكين الآخرين مع الرجل <strong>GP5</strong> والرجل <strong>GP10</strong>، كما هو موضح في الصورة أدناه.
</p>

<ol start="2">
	<li>
		صِل نهاية المشبك الأول الموصول مع الرجل <strong>GP5</strong>، مع نهاية وصلة السمّاعات.
	</li>
	<li>
		صِل نهاية المشبك الثاني الموصول مع الرجل <strong>GP10</strong>،مع منتصف وصلة السمّاعات.
	</li>
	<li>
		صِل نهاية المشبك الموصول مع رجل الأرض <strong>GND</strong> مع جذر وصلة السمّاعات.
	</li>
</ol>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122105" href="https://academy.hsoub.com/uploads/monthly_2023_03/earphones-wiring.png.0c17f0618c1f5392d0bad45e6b96a138.png" rel=""><img alt="earphones-wiring.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122105" data-ratio="93.60" data-unique="jrdwzrmr3" style="width: 550px; height: auto;" width="641" src="https://academy.hsoub.com/uploads/monthly_2023_03/earphones-wiring.thumb.png.41cc190a500a884c9fc5679564514c2f.png"> </a>
</p>

<h4>
	معلومات مفيدة يجب معرفتها عن الصوت
</h4>

<p>
	دعنا نطلع على بعض المعلومات المفيدة عن الأصوات قبل كتابة الشيفرة.
</p>

<p>
	<strong>النغمات المتاحة</strong>: تُوفر لنا مكتبة picozero ثمان وثمانين علامةً موسيقية، تتبع التدوين الغربي للموسيقا وتشمل جميع العلامات الموجودة في لوحة مفاتيح موسيقية كاملة الحجم.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122112" href="https://academy.hsoub.com/uploads/monthly_2023_03/keyboard.png.7ed913a0426177f622bfb8fbf39f940b.png" rel=""><img alt="keyboard.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122112" data-unique="psa6wr7ri" src="https://academy.hsoub.com/uploads/monthly_2023_03/keyboard.thumb.png.a13e6696e24a143d97645ca26d9fed36.png"> </a>
</p>

<p>
	إليك بعض العلامات المُتاحة:
</p>

<ul>
	<li>
		b0
	</li>
	<li>
		c1
	</li>
	<li>
		c#1
	</li>
	<li>
		d1
	</li>
	<li>
		d#1
	</li>
	<li>
		e1
	</li>
	<li>
		f1
	</li>
	<li>
		f#1
	</li>
</ul>

<p>
	<strong>طول النغمة</strong>: توجد عدة طرق لتحديد طول النغمة: أولًا، تحديد طول نغمة واحدة باستخدام القيم، إذ يمكنك تحديد مدة النغمة الواحدة بإدخال قيمة في حقل الوسيط الثاني في دالة العزف:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_12" style=""><span class="pln">speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">c_note</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اعزف النغمة لمدة 0.1 ثانية</span></pre>

<p>
	ستُعزَف النغمة <strong>C</strong> في مثالنا لمدة 0.1 ثانية.
</p>

<p>
	ثانيًا، تحديد طول نغمة واحدة باستخدام الثوابت، إذ يمكنك تحديد مدة النغمة الواحدة بالتصريح عن أحد الثوابت في حقل الوسيط الثاني في دالة العزف بدلًا عن القيمة، وتعريف هذا الثابت كما يلي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_14" style=""><span class="pln">BEAT </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span class="com"># BEAT تعريف الثابت</span><span class="pln">

speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">c_note</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">)</span><span class="pln"> </span><span class="com">#  اعزف النغمة لمدة ثانية واحدة</span></pre>

<p>
	لاحظ أنه يمكننا استخدام الثابت <code>BEAT</code> لتحديد طول أي نغمة.
</p>

<p>
	ثالثًا، تحديد طول مجموعة من النغمات باستخدام القيم؛ فعند عزف لحن ما، يُفضل تخزين النغمات وطول كل منها في قائمة list، كما في مثالنا التالي، إذ خزّنا كل نغمة مع طولها في قائمة، وجمعنا النغمات الثلاث في قائمة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_16" style=""><span class="pln">my_tune </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.5</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1.2</span><span class="pun">]]</span><span class="pln"> </span><span class="com"># قائمة بالنغمات وطول كل منها</span></pre>

<p>
	احرص على كتابة النغمة ضمن علامتي اقتباس <code>' '</code>.
</p>

<p>
	رابعًا، تحديد طول مجموعة من النغمات باستخدام الثوابت: ابدأ أولًا بتحديد طول النغمة الذي تريده باستخدام الثابت <code>BEAT</code>، اخترنا في مثالنا القيمة 0.4، ثم صرّح عن النغمات التي تود عزفها في قائمة ضمن علامتي <code>' '</code> واستخدم الثابت <code>BEAT</code> لتحديد طول النغمات:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_18" style=""><span class="pln">BEAT </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0.4</span><span class="pln"> </span><span class="com"># طول النغمة الواحدة</span><span class="pln">

my_tune </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">*</span><span class="pln"> </span><span class="lit">1.5</span><span class="pun">]]</span><span class="pln"> </span><span class="com"># قائمة بالنغمات وطول كل منها</span></pre>

<p>
	يمكنك التحكم بعدد النغمات في الدقيقة <strong>BPM</strong> عن طريق تقسيم الثابت <code>BEAT</code> على عدد ما للحصول على نغمات أقصر، مثلًا <code>2 / BEAT</code>، أو مضاعفته بضربه بعدد ما للحصول على نغمات أطول، مثلًا <code>BEAT * 1.5</code>
</p>

<ul>
	<li>
		<strong>استخدام الأرقام عوضا عن النغمات</strong>: يمكنك الاستعاضة عن النغمات باستخدام قيم الترددات الموافقة لها، والتي تتراوح بين القيمة <strong>150</strong> إلى <strong>10000</strong>، إليك المثال التالي لعزف نغمة ذات التردد 523 لثانية واحدة:
	</li>
</ul>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_20" style=""><span class="pln">speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="lit">523</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اعزف النغمة ذات التردد 523 لثانية واحدة</span></pre>

<ul>
	<li>
		<p>
			<strong>تحويل المقطوعات الموسيقية إلى نغمات</strong>: تُتيح لنا مكتبة "picozero" عزف المقطوعات الموسيقية الشهيرة واستخدامها في مشاريعنا، إذ تُستخدم الأحرف الإنجليزية للتعبير عن العلامات الموسيقية، وتستخدم الأرقام للتعبير عن موقع العلامة في السلم الموسيقي الكبير.
		</p>
	</li>
</ul>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122113" href="https://academy.hsoub.com/uploads/monthly_2023_03/middle-c.png.f192189ae9c757c6e7320a151e1f01d2.png" rel=""><img alt="middle-c.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122113" data-unique="vm8u15ft8" style="width: 280px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_03/middle-c.png.f192189ae9c757c6e7320a151e1f01d2.png"> </a>
</p>

<p>
	على سبيل المثال، توجد العلامة <strong>C</strong> الوسطى في منتصف السلم الموسيقي ويعبر عنها بالرمز <strong>C4</strong>، وتزداد الأرقام المعبرة عن العلامة كلما صعدنا في السلم الكبير، وتنقص عند النزول.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122097" href="https://academy.hsoub.com/uploads/monthly_2023_03/cdef-cdef.png.fa6fe43b679f2b0538f031f3a5d4dc4e.png" rel=""><img alt="cdef-cdef.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122097" data-unique="4qxejk0zq" style="width: 500px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_03/cdef-cdef.png.fa6fe43b679f2b0538f031f3a5d4dc4e.png"> </a>
</p>

<p>
	تحتوي المقطوعة الموسيقية علامات حادة يُعَبر عنها بالرمز <strong>#</strong> وتدعى "دييز". في مثالنا أدناه، توجد عدة علامات موسيقية حادة، أولها العلامة <strong>C</strong> الحادة والتي يرمز لها <strong>c#4</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122131" href="https://academy.hsoub.com/uploads/monthly_2023_03/sharp-notes.png.3af8b613671d4b8d8346f3a8f88dab6a.png" rel=""><img alt="sharp-notes.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122131" data-unique="w23ey3dq4" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_03/sharp-notes.png.3af8b613671d4b8d8346f3a8f88dab6a.png"> </a>
</p>

<p>
	وقد تحتوي المقطوعة الموسيقية على علامات بسيطة يُشار إليها بالرمز <strong>♭</strong> وتدعى "بيمول"، لكن سنشير إليها في مشروعنا بالرمز <strong>#</strong> لعدم احتواء مكتبة <code>picozero</code> على شيفرة خاصة للتعبير عن العلامات البسيطة، وعلينا النزول نصف درجة في السلم الموسيقي للتحويل من علامة بسيطة إلى حادة.
</p>

<p>
	إليك الأمثلة التالية:
</p>

<ul>
	<li>
		تتحوّل العلامة البسيطة <strong>D</strong> إلى <strong>C</strong> حادة أو <strong>c#4</strong>.
	</li>
	<li>
		تتحوّل العلامة البسيطة <strong>E</strong> إلى <strong>D</strong> حادة أو <strong>d#4</strong>.
	</li>
	<li>
		تتحوّل العلامة البسيطة <strong>G</strong> إلى <strong>F</strong> حادة أو <strong>f#4</strong>.
	</li>
	<li>
		تتحوّل العلامة البسيطة <strong>A</strong> إلى <strong>G</strong> حادة أو <strong>g#4</strong>.
	</li>
</ul>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122106" href="https://academy.hsoub.com/uploads/monthly_2023_03/flat-notes.png.23ab4f92746ce3788b90682d4b98ef25.png" rel=""><img alt="flat-notes.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122106" data-unique="kd1aqx3u8" style="width: 500px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_03/flat-notes.png.23ab4f92746ce3788b90682d4b98ef25.png"> </a>
</p>

<h3>
	أمثلة عن بعض الشيفرات الموسيقية
</h3>

<h4>
	الشيفرة اللازمة لعزف علامة موسيقية واحدة
</h4>

<p>
	إليك مثالًا عن الشيفرة اللازمة لعزف العلامة <strong>C</strong> الوسطى لمدة نصف ثانية:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_33" style=""><span class="kwd">def</span><span class="pln"> c_note</span><span class="pun">():</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="str">'c4'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.5</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اعزف العلامة لمدة نصف ثانية</span></pre>

<h4>
	الشيفرة اللازمة لعزف لحن موسيقي
</h4>

<p>
	خزّن النغمات وطول كل منها في قائمة للحصول على لحن ما ، ثم شغّل اللحن باستخدام الدالة <code>play</code>:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_35" style=""><span class="pln">BEAT </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0.4</span><span class="pln">

liten_mus </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">''</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'b5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">*</span><span class="pln"> </span><span class="lit">1.5</span><span class="pun">]</span><span class="pln"> </span><span class="pun">]</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> play_liten_mus</span><span class="pun">():</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">liten_mus</span><span class="pun">)</span></pre>

<h4>
	الشيفرة اللازمة لتوليد تأثيرات صوتية مختلفة باستخدام الترددات
</h4>

<p>
	يمكننا توليد تأثيرات صوتية ممتعة، أو مزعجة، وذلك بعزف نغمات قصيرة ذات ترددات مختلفة، إذ أنه كلما تغير التردد تختلف العلامة الموسيقية التي نسمعها وتختلف نغمتها.
</p>

<p>
	إليك الشيفرة التالية التي ترتفع فيها الترددات تدريجيًا لخلق صوت مبهج:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_37" style=""><span class="kwd">def</span><span class="pln"> win</span><span class="pun">():</span><span class="pln"> </span><span class="com"># ترددات متزايدة</span><span class="pln">
    </span><span class="kwd">for</span><span class="pln"> i </span><span class="kwd">in</span><span class="pln"> range</span><span class="pun">(</span><span class="lit">2000</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5000</span><span class="pun">,</span><span class="pln"> </span><span class="lit">100</span><span class="pun">):</span><span class="pln">
        speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">i</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.05</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اعزف النغمة لمدة قصيرة جدًا</span></pre>

<p>
	أما المثال التالي فخفضنا فيه الترددات تدريجيًا لتوليد صوت زقزقة العصافير:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_39" style=""><span class="kwd">def</span><span class="pln"> chirp</span><span class="pun">():</span><span class="pln"> </span><span class="com"># توليد صوت زقزقة العصافير</span><span class="pln">
    </span><span class="kwd">for</span><span class="pln"> _ </span><span class="kwd">in</span><span class="pln"> range</span><span class="pun">(</span><span class="lit">2</span><span class="pun">):</span><span class="pln"> </span><span class="com"># ترددات متناقصة</span><span class="pln">
        </span><span class="kwd">for</span><span class="pln"> i </span><span class="kwd">in</span><span class="pln"> range</span><span class="pun">(</span><span class="lit">5000</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2999</span><span class="pun">,</span><span class="pln"> </span><span class="pun">-</span><span class="lit">100</span><span class="pun">):</span><span class="pln">
            speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">i</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.02</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اعزف النغمة لمدة قصيرة جدًا</span><span class="pln">
        sleep</span><span class="pun">(</span><span class="lit">0.2</span><span class="pun">)</span></pre>

<p>
	غَيّر الترددات المستخدمة في حلقة التكرار <code>for</code> واستخدم الترددات ضمن المجال من <strong>150</strong> إلى <strong>10000</strong>.
</p>

<h4>
	الشيفرة اللازمة لتوليد ضجيج أبيض من صوت قرع الطبل
</h4>

<p>
	إليك الشيفرة التالية:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_41" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> time </span><span class="kwd">import</span><span class="pln"> sleep
</span><span class="kwd">from</span><span class="pln"> random </span><span class="kwd">import</span><span class="pln"> randint

speaker </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pun">(</span><span class="lit">5</span><span class="pun">)</span><span class="pln">

</span><span class="kwd">for</span><span class="pln"> i </span><span class="kwd">in</span><span class="pln"> range</span><span class="pun">(</span><span class="lit">100</span><span class="pun">):</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">randint</span><span class="pun">(</span><span class="lit">500</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5000</span><span class="pun">),</span><span class="pln"> duration</span><span class="pun">=</span><span class="kwd">None</span><span class="pun">)</span><span class="pln">
    sleep</span><span class="pun">(</span><span class="lit">0.001</span><span class="pun">)</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">stop</span><span class="pun">()</span><span class="pln">
    sleep</span><span class="pun">(</span><span class="lit">0.5</span><span class="pun">)</span></pre>

<h4>
	الشيفرة اللازمة لعزف النغمات بصورة متكررة
</h4>

<p>
	أنشئ قائمةً بالنغمات التي تريد عزفها وطول كل منها للحصول على لحن ما، ثم استخدم حلقة تكرار <code>for</code> لتشغيل اللحن نغمةً نغمة، أو علامةً علامة باستخدام الدالة <code>play</code>:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_44" style=""><span class="pln">BEAT </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0.4</span><span class="pln">

liten_mus </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">''</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'b5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">*</span><span class="pln"> </span><span class="lit">1.5</span><span class="pun">]</span><span class="pln"> </span><span class="pun">]</span><span class="pln">

</span><span class="kwd">for</span><span class="pln"> note </span><span class="kwd">in</span><span class="pln"> liten_mus</span><span class="pun">:</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">note</span><span class="pun">)</span></pre>

<h4>
	الشيفرة اللازمة لعزف عدة نغمات متزامنة
</h4>

<p>
	إذا أردت عزف لحن ما مثلًا، وتشغيل لحن أو تأثير صوتي آخر بالتزامن معه، فيمكنك ذلك بوضع <code>wait=False</code> في حقل الوسيط الثاني للدالة <code>play</code> .
</p>

<p>
	في مثالنا التالي، أنشأنا قائمةً بالنغمات التي نريد عزفها وطول كل منها، ثم عرّفنا اللحن الآخر المزعج، الذي سينطلق بالتزامن مع اللحن الأول عند الضغط على الزر، وسيتوقف معه عند إيقاف الشيفرة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_46" style=""><span class="pln">BEAT </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0.4</span><span class="pln">

liten_mus </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">''</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'b5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">*</span><span class="pln"> </span><span class="lit">1.5</span><span class="pun">]</span><span class="pln"> </span><span class="pun">]</span><span class="pln">

sound </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="pun">[</span><span class="lit">523</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="kwd">None</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="lit">523</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.4</span><span class="pun">]</span><span class="pln"> </span><span class="pun">]</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> annoying_sound</span><span class="pun">():</span><span class="pln">
    speaker2</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">sound</span><span class="pun">,</span><span class="pln"> wait</span><span class="pun">=</span><span class="kwd">False</span><span class="pun">)</span><span class="pln"> </span><span class="com"># شغّل بالتزامن مع اللحن الأول</span><span class="pln">

button</span><span class="pun">.</span><span class="pln">when_pressed </span><span class="pun">=</span><span class="pln"> annoying_sound

</span><span class="kwd">try</span><span class="pun">:</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">liten_mus</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">finally</span><span class="pun">:</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln"> </span><span class="com">#أطفئ مكبر الصوت الأول عند إيقاف البرنامج</span><span class="pln">
    speaker2</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln"> </span><span class="com"># أطفئ مكبر الصوت الثاني عند إيقاف البرنامج</span></pre>

<h3>
	توصيل عناصر الدخل
</h3>

<h4>
	توصيل الأزرار مع لوحة بيكو
</h4>

<p>
	ستحتاج لتوصيل زر واحد مع لوحة بيكو إلى ما يلي:
</p>

<ul>
	<li>
		لوحة راسبيري بيكو.
	</li>
	<li>
		زر إلكتروني.
	</li>
	<li>
		سلكي توصيل نوع مقبس-مقبس.
	</li>
</ul>

<p>
	صِل سلكي التوصيل مع أرجل الزر واستخدم الشريط اللاصق لتثبيتهما إن لزم الأمر، ثم صِل أحد السلكين مع الرجل <strong>GP18</strong> والسلك الآخر مع أقرب رجل أرضية، لا يهمنا ترتيب توصيل الأسلاك إذ إنه لا توجد قطبية للزر.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122132" href="https://academy.hsoub.com/uploads/monthly_2023_03/single-button-wiring.png.795c58a7b1cf855e463d2149ec626287.png" rel=""><img alt="single-button-wiring.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122132" data-ratio="134.53" data-unique="h2lac6p46" width="446" src="https://academy.hsoub.com/uploads/monthly_2023_03/single-button-wiring.thumb.png.85a04b387d4d6b8dd99313639340b41e.png"> </a>
</p>

<p>
	لتوصيل عدة أزرار إلكترونية مع لوحة بيكو ستحتاج إلى ما يلي:
</p>

<ul>
	<li>
		لوحة راسبيري بيكو.
	</li>
	<li>
		أزرار إلكترونية.
	</li>
	<li>
		سلكي توصيل نوع دبوس-مقبس لكل زر.
	</li>
</ul>

<p>
	توضح الصورة التالية طريقة توصيل ثلاثة أزرار مع لوحة بيكو، وإذا أردت توصيل زر رابع فما عليك سوى توصيله مع إحدى أرجل الأغراض العامة <strong>GP</strong> ورجل أرضية.
</p>

<p>
	استخدم سلكي توصيل نوع دبوس- مقبس لتوصيل الزر الأول مع الرجل <strong>GP18</strong> ومع أقرب رجل أرضية <strong>GND</strong>، ثم صِل الزر الثاني مع الرجل <strong>GP22</strong>، والثالث مع الرجل <strong>GP28</strong> بنفس الطريقة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122115" href="https://academy.hsoub.com/uploads/monthly_2023_03/multiple-button-wiring.png.5f3a027ad6ca1be786fce7bd9ee56122.png" rel=""><img alt="multiple-button-wiring.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122115" data-ratio="134.53" data-unique="lqk29em16" width="446" src="https://academy.hsoub.com/uploads/monthly_2023_03/multiple-button-wiring.thumb.png.1c64fa3dcd6536969299f767f2d87b4d.png"> </a>
</p>

<ul>
	<li>
		<p>
			<strong>استيراد تابع الزر Button من مكتبة picozero</strong>: إليك الشيفرة اللازمة لاستيراد تابع الزر <code>Button</code> من مكتبة <code>picozero</code>:
		</p>
	</li>
</ul>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_49" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Button</span></pre>

<ul>
	<li>
		<p>
			<strong>الشيفرة اللازمة لتوصيل زر إلكتروني واحد</strong>: لتوصيل زر إلكتروني علينا إسناده إلى الرجل الموصول معها على لوحة بيكو، كما يلي:
		</p>
	</li>
</ul>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_51" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">

button </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Button</span><span class="pun">(</span><span class="lit">18</span><span class="pun">)</span></pre>

<ul>
	<li>
		<p>
			<strong>الشيفرة اللازمة لتوصيل عدة أزرار إلكترونية</strong>: استورد تابع الزر <code>Button</code> من مكتبة <code>picozero</code>، ثم استخدم الشيفرة التالية لإسناد عدة أزرار إلى الأرجل الموصولة معها على لوحة بيكو:
		</p>
	</li>
</ul>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_53" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">

button_1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Button</span><span class="pun">(</span><span class="lit">18</span><span class="pun">)</span><span class="pln">
button_2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Button</span><span class="pun">(</span><span class="lit">22</span><span class="pun">)</span><span class="pln">
button_3 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Button</span><span class="pun">(</span><span class="lit">28</span><span class="pun">)</span></pre>

<p>
	ننصحك بتسمية المتغيرات بأسماء تدل على عملها، كأن تسمّي الزر المسؤول عن تشغيل المصباح الأحمر <code>red_button</code> أو أي اسم آخر تراه مناسبًا.
</p>

<ul>
	<li>
		<p>
			<strong>تشغيل نغمة معينة عند الضغط على كل زر</strong>: يمكنك إضافة عدة أزرار يستدعي كل منها دالة صوتية مختلفة عند الضغط عليها، وذلك باستدعاء الدالة الموافقة عند الضغط على الزر عن طريق ذكر اسمها بدون استخدام الأقواس. كما في المثال التالي:
		</p>
	</li>
</ul>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_55" style=""><span class="pln">happy_button</span><span class="pun">.</span><span class="pln">when_pressed </span><span class="pun">=</span><span class="pln"> happy
sad_button</span><span class="pun">.</span><span class="pln">when_pressed </span><span class="pun">=</span><span class="pln"> sad
angry_button</span><span class="pun">.</span><span class="pln">when_pressed </span><span class="pun">=</span><span class="pln"> angry</span></pre>

<ul>
	<li>
		<p>
			<strong>تشغيل النغمة التالية عند الضغط على الزر</strong>: عرّف متغيرًا ما، وليكن <code>option</code>، لتخزين النغمة الحالية فيه واستدعاء الدالة التالية، واحرص على مطابقة أسماء الدوال في الشيفرة للدوال التي استخدمتها في الفقرة السابقة:
		</p>
	</li>
</ul>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_57" style=""><span class="pln">option </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="com"># خزّن النغمة الحالية في هذا المتغير</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> choice</span><span class="pun">():</span><span class="pln"> </span><span class="com"># استدعي الدالة الصوتية التالية وعدّل قيمة متغير التخزين</span><span class="pln">
    </span><span class="kwd">global</span><span class="pln"> option
    </span><span class="kwd">if</span><span class="pln"> option </span><span class="pun">==</span><span class="pln"> </span><span class="lit">0</span><span class="pun">:</span><span class="pln">
        energised</span><span class="pun">()</span><span class="pln"> </span><span class="com"># دالة النغمة الأولى</span><span class="pln">
    </span><span class="kwd">elif</span><span class="pln"> option </span><span class="pun">==</span><span class="pln"> </span><span class="lit">1</span><span class="pun">:</span><span class="pln">
        calm</span><span class="pun">()</span><span class="pln"> </span><span class="com"># دالة النغمة الثانية</span><span class="pln">
    </span><span class="kwd">elif</span><span class="pln"> option </span><span class="pun">==</span><span class="pln"> </span><span class="lit">2</span><span class="pun">:</span><span class="pln">
        focused</span><span class="pun">()</span><span class="pln"> </span><span class="com"># دالة النغمة الثالثة</span><span class="pln">
    </span><span class="kwd">elif</span><span class="pln"> option </span><span class="pun">==</span><span class="pln"> </span><span class="lit">3</span><span class="pun">:</span><span class="pln">
        rgb</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln">

    </span><span class="com"># انتقل إلى الخيار الثاني</span><span class="pln">
    </span><span class="kwd">if</span><span class="pln"> option </span><span class="pun">==</span><span class="pln"> </span><span class="lit">3</span><span class="pun">:</span><span class="pln">
        option </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pln">
    </span><span class="kwd">else</span><span class="pun">:</span><span class="pln">
        option </span><span class="pun">=</span><span class="pln"> option </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pln">

button</span><span class="pun">.</span><span class="pln">when_pressed </span><span class="pun">=</span><span class="pln"> choice </span><span class="com"># استدعي الدالة التالية عند الضغط على الزر</span></pre>

<h4>
	توصيل المبدل مع لوحة بيكو والشيفرة اللازمة لذلك
</h4>

<ul>
	<li>
		<p>
			<strong>توصيل مبدل يدوي الصنع أو زر مع لوحة بيكو</strong>: ستحتاج إلى سلكي توصيل نوع دبوس-مقبس. صِل أحدهما مع الرجل <strong>GP18</strong> والسلك الآخر مع أقرب رجل أرضية، كما يلي:
		</p>
	</li>
</ul>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122101" href="https://academy.hsoub.com/uploads/monthly_2023_03/crafted-switch-wiring.png.7c7a6993236a0829d5145799382824eb.png" rel=""><img alt="crafted-switch-wiring.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122101" data-ratio="134.53" data-unique="k97gae4ml" style="width: 400px; height: auto;" width="446" src="https://academy.hsoub.com/uploads/monthly_2023_03/crafted-switch-wiring.thumb.png.7627d10879a82da2ae15bde9e56d20e4.png"> </a>
</p>

<p>
	ثم يمكنك صنع مبدّل يدوي، كما تعلمنا في <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%85%D8%AD%D8%A7%D9%83%D8%A7%D8%A9-%D9%84%D9%85%D9%81%D8%B1%D9%82%D8%B9%D8%A7%D8%AA-%D8%A7%D9%84%D8%AD%D9%81%D9%84%D8%A7%D8%AA-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1861/" rel="">مشروع سابق</a>، وتوصيلها مع اللوحة وذلك بتوصيل النهاية الحرة للأسلاك مع الجزء الناقل من المبدّل، مثل النحاس أو ورق القصدير.
</p>

<ul>
	<li>
		<p>
			<strong>توصيل عدة قواطع يدوية أو أزرار مع لوحة بيكو</strong>: ستحتاج إلى سلكي توصيل نوع دبوس-مقبس لكل قاطعة تود توصيلها مع لوحة بيكو.
		</p>
	</li>
</ul>

<p>
	استخدم سلكي توصيل نوع دبوس- مقبس لتوصيل المبدّل الأول مع الرجل <strong>GP18</strong> ومع أقرب رجل أرضية <strong>GND</strong>، ثم صِل المبدّل الثاني مع الرجل <strong>GP22</strong> ومع أقرب رجل أرضية، والثالث مع الرجل <strong>GP28</strong> ورجل الأرضية بنفس الطريقة، كما هو موضح في المخطط التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122116" href="https://academy.hsoub.com/uploads/monthly_2023_03/multiple-crafted-switch-wiring.png.c93d40db1ade819537a518c9e4e40497.png" rel=""><img alt="multiple-crafted-switch-wiring.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122116" data-ratio="134.53" data-unique="72o97fjl5" style="width: 400px; height: auto;" width="446" src="https://academy.hsoub.com/uploads/monthly_2023_03/multiple-crafted-switch-wiring.thumb.png.ae018bb8840e9d664b5cdfcc8ef5220d.png"> </a>
</p>

<p>
	لكتابة الشيفرة اللازمة لتوصيل المبدّل لا بُد من استيراد تابع المبدل <code>Switch</code> من مكتبة <code>picozero</code> كما هو موضح في الشيفرة التالية:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_61" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Switch</span></pre>

<p>
	استورد تابع المبدّل <code>Switch</code> من مكتبة <code>picozero</code>، ثم استخدم الشيفرة التالية لإسناد المبدّل إلى الرجل الموصولة معه على لوحة بيكو:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_63" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Switch</span><span class="pln">

switch </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Switch</span><span class="pun">(</span><span class="lit">18</span><span class="pun">)</span></pre>

<p>
	ولتوصيل عدة مبدّلات: استورد تابع المبدّل <code>Switch</code> من مكتبة <code>picozero</code>، ثم استخدم الشيفرة التالية لإسناد عدة مبدّلات إلى الأرجل الموصولة معها على لوحة بيكو:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_65" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Switch</span><span class="pln">

switch_1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Switch</span><span class="pun">(</span><span class="lit">18</span><span class="pun">)</span><span class="pln">
switch_2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Switch</span><span class="pun">(</span><span class="lit">22</span><span class="pun">)</span><span class="pln">
switch_3 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Switch</span><span class="pun">(</span><span class="lit">28</span><span class="pun">)</span></pre>

<p>
	ننصحك بتسمية المتغيرات بأسماء تدل على عملها، كأن تسمّي القاطعة المسؤولة عن تشغيل المصباح الأحمر <code>red_switch</code> أو أي اسم آخر تراه مناسبًا.
</p>

<h4>
	توصيل المقاومات المتغيرة مع لوحة بيكو
</h4>

<p>
	ستحتاج لتوصيل مقاومة متغيرة مع اللوحة إلى ما يلي:
</p>

<ul>
	<li>
		لوحة راسبيري بيكو.
	</li>
	<li>
		مقاومة متغيرة.
	</li>
	<li>
		أسلاك توصيل نوع مقبس-مقبس (عدد 3).
	</li>
</ul>

<p>
	توجد للمقاومة المتغيرة ثلاثة أرجل: رجل الأرضية <strong>GND</strong>، ورجل تشابهية Analogue، ورجل التغذية <strong>3V3</strong>، وعند تدوير قرص المقاومة المتغيرة إلى أقصى اليسار سيشير السهم إلى الرجل الأرضية <strong>GND</strong>، وعند تدويره إلى أقصى اليمين سيشير السهم إلى رجل التغذية <strong>3V3</strong>، أما الرجل الوسطى للمقاومة فهي الرجل التشابهية التي تستمد منها لوحة بيكو القيم لقراءتها.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122125" href="https://academy.hsoub.com/uploads/monthly_2023_03/potentiometer-illustration.png.017107f4be40aafd29d0ac6c2a7bb3ea.png" rel=""><img alt="potentiometer-illustration.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122125" data-unique="lbnlbyh2h" style="width: 350px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_03/potentiometer-illustration.thumb.png.b229417fbbaed5a862335778d88066ca.png"> </a>
</p>

<ul>
	<li>
		صِل سلك توصيل ذو نهايات مقبس-مقبس مع كل من أرجل المقاومة الثلاث، ثبت التوصيلات بالشريط اللاصق إن لزم الأمر.
	</li>
	<li>
		صِل النهاية الحرة للسلك الموصول مع رجل المقاومة ذات الرقم <strong>1</strong> مع رجل الأرض <strong>GND</strong> الموجودة بين الرجلين <strong>GP21</strong> و<strong>GP22</strong>.
	</li>
	<li>
		صِل رجل المقاومة الوسطى مع الرجل <strong>GP26_A0</strong> على لوحة بيكو.
	</li>
	<li>
		صِل رجل المقاومة ذات الرقم <strong>3</strong> مع رجل التغذية <strong>3V3</strong>.
	</li>
</ul>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="122124" href="https://academy.hsoub.com/uploads/monthly_2023_03/pot-diagram.png.7afba1312a236f9b423ad66b70e0e76d.png" rel=""><img alt="pot-diagram.png" class="ipsImage ipsImage_thumbnailed" data-fileid="122124" data-unique="52rj3n2tk" src="https://academy.hsoub.com/uploads/monthly_2023_03/pot-diagram.thumb.png.262bebc942193eba65195ff3dff98733.png"> </a>
</p>

<ul>
	<li>
		<p>
			<strong>استيراد تابع المقاومة المتغيرة Pot من مكتبة picozero</strong>: إليك الشيفرة اللازمة لاستيراد تابع المقاومة المتغيرة <code>Pot</code> من مكتبة <code>picozero</code>:
		</p>
	</li>
</ul>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_69" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Pot</span></pre>

<p>
	وتكون الشيفرة اللازمة لتوصيل مقاومة متغيرة على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_71" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Pot</span><span class="pln">

dial </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Pot</span><span class="pun">(</span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="com"># Connected to pin A0 (GP_26)</span></pre>

<p>
	عند استخدام مقاومة متغيرة للتحكم في الخرج، سنحتاج إلى تقسيم قيم المقاومة إلى أجزاء متساوية. كأن نستخدم التابع <code>dial.value</code> للحصول على قيم تتراوح بين <strong>0</strong> و <strong>1</strong>، كما يمكننا ضرب القيمة ب <strong>100</strong> للحصول على نسبة مئوية؛ فإذا كان لديك خمس قيم يمكنك التحقق ما إذا كانت القيمة أقل من 20 أو 40 أو 60 أو 80 أو 100؛ أما إذا كان لديك ثلاث قيم يمكنك تقسيم القراءات للتحقق ما إذا كانت القيمة أقل من 33 أو 66 أو 100.
</p>

<p>
	إليك المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_73" style=""><span class="kwd">while</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">:</span><span class="pln">
    mood </span><span class="pun">=</span><span class="pln"> dial</span><span class="pun">.</span><span class="pln">value </span><span class="pun">*</span><span class="pln"> </span><span class="lit">100</span><span class="pln"> </span><span class="com"># تحويل إلى نسبة مئوية</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">mood</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">if</span><span class="pln"> mood </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">20</span><span class="pun">:</span><span class="pln">
        happy</span><span class="pun">()</span><span class="pln">
    </span><span class="kwd">elif</span><span class="pln"> mood </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">40</span><span class="pun">:</span><span class="pln">
        good</span><span class="pun">()</span><span class="pln">
    </span><span class="kwd">elif</span><span class="pln"> mood </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">60</span><span class="pun">:</span><span class="pln">
        okay</span><span class="pun">()</span><span class="pln">
    </span><span class="kwd">elif</span><span class="pln"> mood </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">80</span><span class="pun">:</span><span class="pln">
        unsure</span><span class="pun">()</span><span class="pln">
    </span><span class="kwd">else</span><span class="pun">:</span><span class="pln">
        unhappy</span><span class="pun">()</span><span class="pln">
    sleep</span><span class="pun">(</span><span class="lit">0.1</span><span class="pun">)</span></pre>

<p>
	الآن، شغّل دارتك وتحقق أن جميع عناصر الدخل والخرج تعمل كما يجب، واستعن بفقرة تصحيح الأخطاء أدناه إذا واجهتك أي مشكلة.
</p>

<h4>
	تصميم الهيكل الخارجي
</h4>

<h5>
	تثبيت العناصر داخل الورق المقوى أو البلاستيك
</h5>

<p>
	بإمكانك تثبيت مصابيح الليد أو الأجراس أو المقاومات المتغيرة داخل قطع من الورق المقوى أو البلاستيك، وذلك بصنع ثقوب وإدخال العناصر وأسلاك التوصيل فيها، كما هو موضح:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="122126" href="https://academy.hsoub.com/uploads/monthly_2023_03/pre-soldered-mount.jpg.d10dcbd6d5cfee69836c2f31e5c488e0.jpg" rel=""><img alt="pre-soldered-mount.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="122126" data-ratio="127.12" data-unique="6oy802kxy" style="width: 450px; height: auto;" width="472" src="https://academy.hsoub.com/uploads/monthly_2023_03/pre-soldered-mount.thumb.jpg.50e115464b2bc2c55b727b1945fc1bcc.jpg"></a>
</p>

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

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="122118" href="https://academy.hsoub.com/uploads/monthly_2023_03/non-soldered-mount.jpg.99f623b565427bfe8b8a23d2cbcb53a5.jpg" rel=""><img alt="non-soldered-mount.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="122118" data-ratio="94.04" data-unique="b6ccq9tft" style="width: 450px; height: auto;" width="638" src="https://academy.hsoub.com/uploads/monthly_2023_03/non-soldered-mount.thumb.jpg.88f1cea804c39da24a8089395eeecf93.jpg"></a>
</p>

<p>
	استخدم الشريط اللاصق لتثبيت العناصر في مكانها.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="122141" href="https://academy.hsoub.com/uploads/monthly_2023_03/taped-mount.jpg.4f0c73063f79e74a90223890661e0aef.jpg" rel=""><img alt="taped-mount.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="122141" data-ratio="97.09" data-unique="qzz3rmril" style="width: 450px; height: auto;" width="618" src="https://academy.hsoub.com/uploads/monthly_2023_03/taped-mount.thumb.jpg.464511e9fc5b8f9a7b7f8656f4526784.jpg"></a>
</p>

<h5>
	تبديد الضوء المنبعث من مصباح الليد
</h5>

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

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="122114" href="https://academy.hsoub.com/uploads/monthly_2023_03/mood-lamp.gif.a8c96758cb7eccbd90a1ddea256226fd.gif" rel=""><img alt="mood-lamp.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="122114" data-ratio="65.38" data-unique="uwp6djak4" style="width: 500px; height: auto;" width="517" src="https://academy.hsoub.com/uploads/monthly_2023_03/mood-lamp.gif.a8c96758cb7eccbd90a1ddea256226fd.gif"> </a>
</p>

<p>
	كما يمكنك توجيه الضوء في اتجاه معين باستخدام ورقة بيضاء، وذلك لتحصل على أكبر قدر ممكن من الضوء.
</p>

<h5>
	تثبيت أسلاك التوصيل باستخدام الشريط اللاصق
</h5>

<p>
	يمكنك تثبيت أسلاك التوصيل باستخدام الشريط اللاصق، وإزالة الشريط اللاصق فيما بعد بكل سهولة لإعادة استخدام العناصر عند الحاجة.
</p>

<h5>
	استخدام سكين الحرف
</h5>

<p>
	تُعد سكاكين الحرف Crafts مفيدةً عند صنع الحرف اليدوية، لكن يجب أن تكون حذرًا جدًا عند استخدامها لأنها حادة جدًا ويمكن أن تسبب جروحًا وإصابات. احرص على وجود شخص بالغ عند استخدامك للسكاكين، أو اطلب منه استخدامها عوضًا عنك، كما ننصحك باستخدام لوح القص لحماية الأسطح، أو باستخدام لوح التقطيع الخشبي المتوفر في كل المطابخ.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="122094" href="https://academy.hsoub.com/uploads/monthly_2023_03/Box-cutter.jpg.293367772a8176096c2a6bbb1b1c628c.jpg" rel=""><img alt="Box-cutter.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="122094" data-unique="k8me2ne7t" style="width: 380px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_03/Box-cutter.thumb.jpg.afe8d4fe91654de287e89b6adafe7714.jpg"> </a>
</p>

<h5>
	توصيل الأسلاك ببعضها
</h5>

<p>
	قد تحتاج إلى أسلاك توصيل طويلة جدًا لتوصيل مصابيح الليد مع أرجل لوحة بيكو، أو يمكنك وصل الأسلاك ببعضها للحصول على سلك طويل، وذلك عبر توصيل سلك ذو نهايات دبوس-مقبس مع سلك ذو نهايات مقبس-مقبس للحصول على سلك مقبس-مقبس طويل جدًا، ويُطلق على هذه الطريقة اسم سلسلة الأقحوان daisy chaining.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="122102" href="https://academy.hsoub.com/uploads/monthly_2023_03/daisy-chain.jpg.9e2466a5656f9a98799c5455ef210b57.jpg" rel=""><img alt="daisy-chain.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="122102" data-unique="4o0dqkpnw" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_03/daisy-chain.thumb.jpg.5a0f5f1eff631e13441b434030dfb260.jpg"> </a>
</p>

<p>
	ننصحك باستخدام سلكين لهما اللون نفسه ليسهل تتبع السلك ومعرفة العنصر الموصول معه.
</p>

<p>
	تكمن مشكلة هذه الطريقة في أن الأسلاك قد تنفصل عن بعضها، ولذلك ينصح بلصقها بقطعة صغيرة من الشريط اللاصق.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="122139" href="https://academy.hsoub.com/uploads/monthly_2023_03/tape-daisy-chain.jpg.e19297faa154abcaeeefa2ae67ade9fc.jpg" rel=""><img alt="tape-daisy-chain.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="122139" data-unique="12vfj287b" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_03/tape-daisy-chain.thumb.jpg.af14561ed4b4000e81c6ae48256adcc4.jpg"> </a>
</p>

<h5>
	إنشاء مبدل فوري يعمل عند الإسقاط
</h5>

<p>
	ستحتاج لإنشاء مبدّل فوري Drop switch ما يلي:
</p>

<ul>
	<li>
		لوحة راسبيري بيكو.
	</li>
	<li>
		سلكي توصيل نوع دبوس-مقبس.
	</li>
	<li>
		ورق قصدير.
	</li>
	<li>
		شريط لاصق.
	</li>
</ul>

<p>
	أولًا، أنشئ شريطين من ورق القصدير، أو من أي مادة ناقلة.
</p>

<p>
	ثانيًا، ثبت سلكي التوصيل مع شريطي القصدير باستخدام الشريط اللاصق، كما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpeg" data-fileid="122100" href="https://academy.hsoub.com/uploads/monthly_2023_03/connect-pins.jpeg.208b2e951597eeaebaba7d018c1bad06.jpeg" rel=""><img alt="connect-pins.jpeg" class="ipsImage ipsImage_thumbnailed" data-fileid="122100" data-unique="wiecab2mg" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_03/connect-pins.thumb.jpeg.5d1cfae5ff5ca2e21e4492333d81b41c.jpeg"> </a>
</p>

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

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpeg" data-fileid="122108" href="https://academy.hsoub.com/uploads/monthly_2023_03/foil-to-base.jpeg.582f915815030dadfbf5ba79f2d3a223.jpeg" rel=""><img alt="foil-to-base.jpeg" class="ipsImage ipsImage_thumbnailed" data-fileid="122108" data-unique="zv9m6gu18" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_03/foil-to-base.thumb.jpeg.c5766ad0dbc501088158cec1012a4357.jpeg"> </a>
</p>

<p>
	رابعًا، صِل النهايات الحرة للسلكين مع لوحة بيكو وأسقط المجسم لإغلاق المبدّل.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="122103" href="https://academy.hsoub.com/uploads/monthly_2023_03/drop-switch.gif.25a202e91752e8244f13e8a69b22b424.gif" rel=""><img alt="drop-switch.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="122103" data-ratio="56.33" data-unique="eyo8pfbx9" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_03/drop-switch.gif.25a202e91752e8244f13e8a69b22b424.gif"> </a>
</p>

<h5>
	إنشاء قاطعة يدوية تعمل عند السحب
</h5>

<p>
	إليك ما سنحتاج إليه:
</p>

<ul>
	<li>
		مقص.
	</li>
	<li>
		ورق مقوى.
	</li>
	<li>
		رقائق القصدير.
	</li>
	<li>
		غراء وشريط لاصق.
	</li>
	<li>
		شرائط ملونة وورق ملون.
	</li>
	<li>
		قلم رصاص ومسطرة (اختياري).
	</li>
</ul>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpeg" data-fileid="122138" href="https://academy.hsoub.com/uploads/monthly_2023_03/switch-gather-materials.jpeg.8b72def573d7a3a6a3c20b7413d4ef19.jpeg" rel=""><img alt="switch-gather-materials.jpeg" class="ipsImage ipsImage_thumbnailed" data-fileid="122138" data-ratio="66.67" data-unique="2e5b43ujj" style="width: 600px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2023_03/switch-gather-materials.thumb.jpeg.caf3021f2c235bacece809ef9f250278.jpeg"></a>
</p>

<p>
	أولًا، قُصَّ الورق المقوى إلى ثلاثة مستطيلات متساوية الحجم.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="122146" href="https://academy.hsoub.com/uploads/monthly_2023_03/three-rectangles.jpg.ebb698876bd21320aa65cb4a26e12cfd.jpg" rel=""><img alt="three-rectangles.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="122146" data-ratio="66.67" data-unique="ly8re0azh" style="width: 600px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2023_03/three-rectangles.thumb.jpg.0d8b48acd9465f4ea01b227421581e75.jpg"></a>
</p>

<p>
	ثانيًا، قُصَّ مستطيلًا صغيرًا في منتصف المستطيل الأول، واحتفظ به لاستخدامه لاحقًا.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="122098" href="https://academy.hsoub.com/uploads/monthly_2023_03/centre-cut.jpg.1ecd27bc2ed9b3fa7c263ec1cab862ba.jpg" rel=""><img alt="centre-cut.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="122098" data-unique="pdzo3ovc0" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_03/centre-cut.thumb.jpg.4154f3c8268a4be86c99e4c484d03614.jpg"> </a>
</p>

<p>
	ثالثًا، قُصَّ قطعًا من ورق القصدير بحجم المستطيلات الكبيرة، ثم الصقها عليها باستخدام الغراء، واحرص على عدم وضع الغراء على الوجه الخارجي لورق القصدير حتى لا تتأثر التوصيلات لاحقًا.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="122093" href="https://academy.hsoub.com/uploads/monthly_2023_03/add-foil.jpg.21a396af7af697d969689a25ee0741d6.jpg" rel=""><img alt="add-foil.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="122093" data-unique="pmahflkqu" src="https://academy.hsoub.com/uploads/monthly_2023_03/add-foil.thumb.jpg.08f1e141f4237e258a8e96fb3dc81dea.jpg"> </a>
</p>

<p>
	رابعًا، قُصَّ أطراف المستطيل الصغير للحصول على شكل مدبب أو بشكل حرف V، ثم قلّم الأطراف بمقدار بضع ملميترات كي يتسع المستطيل الصغير في الفتحة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="122148" href="https://academy.hsoub.com/uploads/monthly_2023_03/trim-piece.jpg.a22a7cbb0f395573957bb8f5df4b298b.jpg" rel=""><img alt="trim-piece.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="122148" data-unique="3s02uqdic" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_03/trim-piece.thumb.jpg.875f2437bdacea3fad6c695f1a0a2fca.jpg"> </a>
</p>

<p>
	خامسًا، غلّف المستطيل الصغير بكامله بورق القصدير، واحرص على استخدام ورقة قصدير واحدة، إذ ستسمح هذه القطعة بمرور التيار عند إغلاق المبدّل.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="122107" href="https://academy.hsoub.com/uploads/monthly_2023_03/foil-cover.gif.165476712471a3aa8a13447a94c65fce.gif" rel=""><img alt="foil-cover.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="122107" data-ratio="56.33" data-unique="7bwtnh3t4" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_03/foil-cover.gif.165476712471a3aa8a13447a94c65fce.gif"> </a>
</p>

<p>
	سادسًا، استخدم الشريط اللاصق لتثبيت على الوجه العلوي للمستطيلات.
</p>

<p>
	احرص على أن يكون الدبوس المعدني للسلك ملامسًا لورق القصدير، وأن يكون الجزء البلاستيكي الأسود ملامسًا لحافة المستطيل.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="122121" href="https://academy.hsoub.com/uploads/monthly_2023_03/pin-sticky-tape-1.jpg.b8c8a356cb21fd02703c0791dc1b6556.jpg" rel=""><img alt="pin-sticky-tape-1.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="122121" data-unique="ex1z5z9oo" src="https://academy.hsoub.com/uploads/monthly_2023_03/pin-sticky-tape-1.jpg.b8c8a356cb21fd02703c0791dc1b6556.jpg"> </a>
</p>

<p>
	سابعًا، أضف مزيدًا من الشريط اللاصق لتثبيت السلك ومنع انفكاكه عن طريق الخطأ.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="122122" href="https://academy.hsoub.com/uploads/monthly_2023_03/pin-sticky-tape-2.jpg.224515bcac4d877ce06e441fd06d8244.jpg" rel=""><img alt="pin-sticky-tape-2.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="122122" data-unique="jlqejeplg" src="https://academy.hsoub.com/uploads/monthly_2023_03/pin-sticky-tape-2.jpg.224515bcac4d877ce06e441fd06d8244.jpg"> </a>
</p>

<p>
	ثامنًا، ادهن بعض الغراء على المستطيل الذي فرّغنا منتصفه (الموجود في يسار الصورة) والصقه مع المستطيل المغطى بالقصدير (يمين الصورة)، واحرص على ألا تتلامس طبقتي القصدير الموجودة على حواف المستطيلات، قُصّها إذا لزم الأمر:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="122109" href="https://academy.hsoub.com/uploads/monthly_2023_03/glue-left.jpg.96add5331dbbc6474dd1e7bb725f31c6.jpg" rel=""><img alt="glue-left.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="122109" data-unique="dedcshf5b" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_03/glue-left.thumb.jpg.b6f23606ce84b239559bde984cf6b77d.jpg"> </a>
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="122110" href="https://academy.hsoub.com/uploads/monthly_2023_03/glue-right.jpg.0744fd619580c83dd496342239804afa.jpg" rel=""><img alt="glue-right.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="122110" data-unique="4zwo04cv0" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_03/glue-right.thumb.jpg.044202e5801d56afa270ef54ce3ac4d0.jpg"> </a>
</p>

<p>
	أصبح المبدّل جاهزًا للاستخدام في مشروعك.
</p>

<h5>
	تثبيت الأسلاك والعناصر باستخدام الشريط اللاصق
</h5>

<p>
	يمكنك تثبيت العناصر مع أسلاك التوصيل، أو تثبيتها في مكانها باستخدام الشريط اللاصق، وإزالة الشريط اللاصق بكل سهولة لإعادة استخدام العناصر فيما بعد:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="122142" href="https://academy.hsoub.com/uploads/monthly_2023_03/taped-wires.jpg.c01527094a023b19fabde053dbc5849f.jpg" rel=""><img alt="taped-wires.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="122142" data-ratio="49.67" data-unique="vp2s8o2s6" style="width: 500px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2023_03/taped-wires.thumb.jpg.a7c9954e9100409ced6dd398cbe927f9.jpg"></a>
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="122140" href="https://academy.hsoub.com/uploads/monthly_2023_03/taped-component.jpg.e5c8ae67ba00d7d0a1a0410c154bd2c3.jpg" rel=""><img alt="taped-component.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="122140" data-ratio="66.67" data-unique="8whnkfje7" style="width: 500px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2023_03/taped-component.thumb.jpg.61c25d6baf5136edaa45f7373ad9cb4e.jpg"></a>
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="122141" href="https://academy.hsoub.com/uploads/monthly_2023_03/taped-mount.jpg.4f0c73063f79e74a90223890661e0aef.jpg" rel=""><img alt="taped-mount.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="122141" data-ratio="97.09" data-unique="tis00ahcq" style="width: 500px; height: auto;" width="618" src="https://academy.hsoub.com/uploads/monthly_2023_03/taped-mount.thumb.jpg.464511e9fc5b8f9a7b7f8656f4526784.jpg"></a>
</p>

<p>
	أخيرًا، اختبر المشروع بعد انتهائك من تنفيذ التصميم الخارجي، واعرضه على أفراد العائلة أو الأصدقاء للحصول على ملاحظاتهم، وقرر هل تود إجراء أي تعديل؟
</p>

<h3>
	تصحيح الأخطاء
</h3>

<p>
	قبل التعرف على المشاكل التي قد تواجهك عند تنفيذ المشروع وكيفية إصلاحها، عليك أولًا التحقق من سلامة لوحة بيكو:
</p>

<h4>
	التحقق من سلامة لوحة بيكو باستخدام مصباح الليد
</h4>

<p>
	استخدم مصباح الليد الموجود على لوحة بيكو للتحقق من سلامة اللوحة، وذلك بجعل المصباح يومض عند تشغيل الشيفرة بإضافة الشيفرة التالية في البداية:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_103" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> pico_led
</span><span class="kwd">from</span><span class="pln"> time </span><span class="kwd">import</span><span class="pln"> sleep

pico_led</span><span class="pun">.</span><span class="pln">on</span><span class="pun">()</span><span class="pln">
sleep</span><span class="pun">(</span><span class="lit">2</span><span class="pun">)</span><span class="pln">
pico_led</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span></pre>

<h4>
	تصحيح الأخطاء الموجودة في الشيفرة
</h4>

<ul>
	<li>
		تحقق من وجود أي رسائل خطأ في نافذة صدفة Thonny وتحقق من محتواها، إن وجدت.
	</li>
	<li>
		راجع الشيفرة التي كتبتها وتحقق من خلوها من الأخطاء، مثل نسيان علامة <strong>:</strong> مثلًا، أو وجود مسافة بادئة دون الحاجة لها.
	</li>
	<li>
		تأكد من استيراد توابع العناصر التي ستستخدمها في مشروعك من مكتبة <code>picozero</code> مثل تابع مصباح الليد <code>RGBLED</code> أو الزر <code>Button</code>.
	</li>
	<li>
		استخدم تعليمة الطباعة <code>print</code> لإضافة شرح مختصر عند كل خطوة، مثل <code>(البدء)print</code> أو <code>(ضبط المصباح على اللون الأخضر)print</code>.
	</li>
</ul>

<h4>
	لا تعمل بعض العناصر الإلكترونية كما يجب
</h4>

<ul>
	<li>
		تأكد أن جميع العناصر متصلة ببعضها جيدًا، وتحقق من ثبات نقاط توصيل الأسلاك مع اللوحة ومع العناصر.
	</li>
	<li>
		تأكد أن أرقام الأرجل المستخدمة في الشيفرة مطابقة لأرقام الأرجل الموصولة مع مصباح الليد، وتأكد من إعادة وصل الأرجل في حال فصلتها عند العمل على تصميم شكل الآلة الموسيقية.
	</li>
	<li>
		تحقق من وصل العناصر وفق القطبية الصحيحة، إذ قد تحتوي بعض العناصر على قطب موجب <strong>+</strong> وآخر سالب <strong>-</strong>.
	</li>
	<li>
		في حال تحققت من جميع النقاط السابقة ولا زالت آلتك لا تعمل، فجرّب تبديل العناصر الإلكترونية بأخرى جديدة.
	</li>
</ul>

<h4>
	لا يحدث شيء عند تشغيل الشيفرة
</h4>

<ul>
	<li>
		تأكد أن جميع العناصر متصلة ببعضها جيدًا، وأنها موصولة مع الأرجل الصحيحة على اللوحة.
	</li>
	<li>
		تحقق من صدفة Thonny عند تشغيل الشيفرة؛ لربما نسيت نسيت تعريف بعض الدوال أو المتغيرات، أو قد تكون نسيت تعديل الشيفرة لتتناسب مع مشروعك.
	</li>
	<li>
		تحقق من صحة الشيفرة التي كتبتها، واستخدم تابع الطباعة <code>print</code> لإيضاح عمل الشيفرة.
	</li>
	<li>
		تحقق أنك استدعيت الدوال في الشيفرة.
	</li>
</ul>

<p>
	إليك مثالًا عن طريقة استدعاء الدالة، إذا عرفنا الدالة <code>happy</code> أولًا، ثم استدعيناها عن طريق التصريح عن اسمها (بدون وسطاء داخل الأقواس):
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_105" style=""><span class="kwd">def</span><span class="pln"> happy</span><span class="pun">():</span><span class="pln"> </span><span class="com"># الدالة الأولى</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">color </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اللون الموافق للدالة الأولى</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> sad</span><span class="pun">():</span><span class="pln"> </span><span class="com"># الدالة الثانية</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">color </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اللون الموافق للدالة الثانية</span><span class="pln">

happy</span><span class="pun">()</span></pre>

<h4>
	لا يضيء مصباح الليد عند استدعاء الدالة المسؤولة عن تشغيله
</h4>

<p>
	تأكد من مطابقة الأرجل الموصول معها المصباح على لوحة بيكو للأرجل المسند إليها في الشيفرة.
</p>

<h4>
	لا يضيء مصباح الليد باللون الصحيح
</h4>

<p>
	تحقق من الشيفرة التي كتبتها وأن القيم اللونية مطابقة للون المستخدم، واستخدم <a href="https://www.w3schools.com/colors/colors_rgb.asp" rel="external nofollow">منتقي الألوان التالي</a> للتحقق من اللون المستخدم.
</p>

<h4>
	لا تصدر النغمات أو أن صوتها مختلف عن الصوت المطلوب
</h4>

<p>
	من غير المرجح أن تكون المشكلة في الشيفرة التي كتبتها، بما أنها كانت سليمةً قبل تنفيذ التصميم الخارجي للعبة، لذا عليك التحقق من التوصيلات والعناصر.
</p>

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

<p>
	وذلك للمشاكل الآتية:
</p>

<ul>
	<li>
		<p>
			<strong>يتأخر عزف النغمة عند الضغط على زر ما</strong>: عند استخدام أحد الأحداث events مثل حدث الضغط <code>when_pressed</code> لتشغيل دالة ما، فإن هذه الدالة ستُنفَذ حتى انتهائها وستمنع تشغيل أي شيء آخر في الشيفرة.
		</p>
	</li>
</ul>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3912_107" style=""><span class="pln">sound </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="pun">[</span><span class="lit">523</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="kwd">None</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="lit">523</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.4</span><span class="pun">]</span><span class="pln"> </span><span class="pun">]</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> annoying_sound</span><span class="pun">():</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">sound</span><span class="pun">,</span><span class="pln"> wait</span><span class="pun">=</span><span class="kwd">False</span><span class="pun">)</span><span class="pln"> </span><span class="com"># لا تؤخر تشغيل الشيفرة</span><span class="pln">

button</span><span class="pun">.</span><span class="pln">when_pressed </span><span class="pun">=</span><span class="pln"> annoying_sound</span></pre>

<ul>
	<li>
		<strong>طول الأسلاك غير مناسب</strong>: إذا وجدت أن الأسلاك التي استخدمتها لا تفي بالغرض المطلوب بسبب قصر طولها، فما عليك إلا زيادة طولها، وفقًا لما تعلمناه في فقرة توصيل الأسلاك ببعضها.
	</li>
	<li>
		<strong>لا تثبُت الأسلاك والعناصر في مكانها</strong>: قد تكون بعض التوصيلات أمتن من غيرها، لذا ننصحك باستخدام الشريط اللاصق لإحكام تثبيت الأسلاك.
	</li>
</ul>

<p>
	حاول حل المشاكل الأخرى التي قد تواجهك عند التنفيذ وشاركنا طريقة الحل في <a href="https://io.hsoub.com/" rel="external">منصة حسوب IO</a> أو في <a href="https://academy.hsoub.com/search/" rel="">أكاديمية حسوب</a>.
</p>

<h2>
	ترقية المشروع
</h2>

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

<p>
	استخدمنا في النسخة الأصلية لمشروع الأضواء الليلية مصباح ليد متعدد الألوان وأحدثنا ثقوبًا صغيرةً في ورقة ليخرج منها الضوء ونحصل على تأثير مشابه لسماء مرصّعة بالنجوم، وأضفنا زرًا تشغيل وإطفاء المصباح.
</p>

<div class="ipsEmbeddedVideo" contenteditable="false">
	<div>
		       <iframe allowfullscreen="" frameborder="0" height="506" src="https://player.vimeo.com/video/795266019?autoplay=0&amp;color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="900"></iframe>
	</div>
</div>

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

<h2>
	الخاتمة
</h2>

<p>
	تهانينا، فقد أتممت مشروع تصميم وتنفيذ لعبة حسية تفاعلية باستخدام لوحة راسبيري باي بيكو.
</p>

<p>
	إذا واجهت مشاكلًا عند تنفيذ هذا المشروع فيمكنك الحصول على الدعم والمساعدة عبر إضافة سؤالك في قسم الأسئلة والأجوبة في <a href="https://academy.hsoub.com/questions/" rel="">أكاديمية حسوب</a>.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://projects.raspberrypi.org/en/projects/sensory-gadget/" rel="external nofollow">Sensory gadget</a> من <a href="https://raspberrypi.org/" rel="external nofollow">الموقع الرسمي لراسبيري باي</a>.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%88%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D8%A2%D9%84%D8%A9-%D9%85%D9%88%D8%B3%D9%8A%D9%82%D9%8A%D8%A9-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1910/" rel="">تصميم وتنفيذ آلة موسيقية باستخدام لوحة راسبيري باي بيكو</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%B5%D9%86%D8%B9-%D8%AC%D9%87%D8%A7%D8%B2-%D9%84%D8%B9%D8%B1%D8%B6-%D8%A7%D9%84%D8%AD%D8%A7%D9%84%D8%A9-%D8%A7%D9%84%D9%85%D8%B2%D8%A7%D8%AC%D9%8A%D8%A9-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1893/" rel="">صنع جهاز لعرض الحالة المزاجية باستخدام لوحة راسبيري باي بيكو</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%B5%D9%86%D8%B9-%D9%82%D9%84%D8%A8-%D9%86%D8%A7%D8%A8%D8%B6-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1862/" rel="">صنع قلب نابض باستخدام لوحة راسبيري باي بيكو</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1934</guid><pubDate>Sat, 25 Mar 2023 15:06:00 +0000</pubDate></item><item><title>&#x62A;&#x635;&#x645;&#x64A;&#x645; &#x648;&#x62A;&#x646;&#x641;&#x64A;&#x630; &#x622;&#x644;&#x629; &#x645;&#x648;&#x633;&#x64A;&#x642;&#x64A;&#x629; &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x644;&#x648;&#x62D;&#x629; &#x631;&#x627;&#x633;&#x628;&#x64A;&#x631;&#x64A; &#x628;&#x627;&#x64A; &#x628;&#x64A;&#x643;&#x648;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%88%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D8%A2%D9%84%D8%A9-%D9%85%D9%88%D8%B3%D9%8A%D9%82%D9%8A%D8%A9-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1910/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2023_02/795781754_--------.jpg.7ebe79ca5e912848ce6cbd72c6c83a82.jpg" /></p>
<p>
	سنعمل في هذا المشروع على إنشاء آلة تصدر أصواتًا وموسيقى مختلفة باستخدام الأزرار buttons، والمبدّلات الإلكترونية switches، والمقاومات المتغيرة potentiometer.
</p>
<p>
	لنحصل على آلة مشابهة لما يلي:
</p>
<div class="ipsEmbeddedVideo" contenteditable="false">
	<div>
		<iframe allowfullscreen="" frameborder="0" height="506" src="https://player.vimeo.com/video/795266504?autoplay=0&amp;color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="900"></iframe>
	</div>
</div>

<p>
	اصنع لوحة تصدر تأثيراتٍ صوتيةً مختلفةً عند الضغط عليها، وذلك باستخدام الورق المقوى ورقائق القصدير، ويمكنك الاطلاع على الشيفرة اللازمة لتنفيذ هذا المشروع من ملف <a data-fileext="zip" data-fileid="118836" href="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=118836&amp;key=7109b5e65c562a86c657eb901b18c01f" rel="">codes.zip</a>.
</p>

<p>
	ستتعلم في هذا المشروع ما يلي:
</p>

<ul>
	<li>
		كيفية تصميم جهاز صوتي يعمل وفق غرضٍ معين.
	</li>
	<li>
		برمجة الجرس الإلكتروني buzzer لتشغيل تأثيرات صوتية وموسيقى.
	</li>
	<li>
		إنشاء واجهة تتيح للمستخدم التحكم بالأصوات.
	</li>
</ul>

<p>
	<strong>معلومة:</strong> تملك الأصوات تأثيرًا على حالتنا النفسية، فقد تكون مهدئةً، أو مزعجةً، أو منشِطة، فعلى سبيل المثال، يجد بعض الأطفال الرُضع لآلة الضجيج الأبيض Whitenoise تأثيرًا مهدئًا يساعدهم على الاسترخاء والنوم؛ بينما يستخدم منسقو الأغاني DJs أجهزةً محمولة لتوليد النغمات، ويستخدم محبو الدُعابة أجهزةً تصدر تأثيرات صوتية لإضحاك الناس. ماذا عنك؟ هل توجد آلة صوتية تستخدمها يوميًا؟
</p>

<h2>
	متطلبات المشروع
</h2>

<h3>
	عتاد:
</h3>

<ol>
	<li>
		لوحة حاسوب راسبيري باي بيكو Raspberry Pi Pico مع أرجل مثبتة عليها.
	</li>
	<li>
		كبل USB لنقل البيانات ذو نهايات من النوع USB A و micro USB.
	</li>
	<li>
		مقاومات متغيرة potentiometer وأزرار buttons.
	</li>
	<li>
		جرس إلكتروني غير فعّال passive.
	</li>
	<li>
		أسلاك توصيل.
	</li>
	<li>
		بعض مستلزمات الأشغال اليدوية، مثل الورق المقوى، ورقائق القصدير، وشريط لاصق.
	</li>
	<li>
		مصباح ليد عادي أو متعدد الألوان RGB LED ذو مهبط مشترك common cathode، ومقاومات وأسلاك توصيل. (اختياري)
	</li>
	<li>
		جرس إلكتروني إضافي غير فعّال لخلق تأثير الصوت المجسم stereo. (اختياري)
	</li>
</ol>

<h3>
	برمجيات
</h3>

<ol>
	<li>
		برنامج ثوني Thonny: وهو البيئة البرمجية التي سنستخدمها لكتابة الشيفرة <a href="https://wiki.hsoub.com/Python" rel="external">بلغة بايثون</a>.
	</li>
</ol>

<h4>
	تثبيت برنامج ثوني على نظام تشغيل راسبيري باي
</h4>

<p>
	يأتي برنامج ثوني مثبتًا مع <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AC%D9%88%D9%84%D8%A9-%D9%81%D9%8A-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%A7%D9%86-%D9%86%D8%B8%D8%A7%D9%85-%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-r1371/" rel="">نظام تشغيل راسبيري باي</a>، المعروف سابقًا براسبيان Raspbian، لكن قد تحتاج إلى تحديثه. انقر على الأيقونة في الزاوية العلوية اليسرى من الشاشة لفتح نافذة الطرفية Terminal، أو اضغط المفاتيح التالية معًا <strong>Ctrl+Alt+T</strong>. ثم اكتب الأمر التالي لتحديث <a href="https://academy.hsoub.com/files/24-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%84%D9%85%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D9%86/" rel="">نظام التشغيل</a> وبرنامج ثوني:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_17" style=""><span class="pln">sudo apt update </span><span class="pun">&amp;&amp;</span><span class="pln"> sudo apt upgrade </span><span class="pun">-</span><span class="pln">y</span></pre>

<h4>
	تثبيت برنامج ثوني على أنظمة التشغيل الأخرى
</h4>

<p>
	يمكنك تثبيت ثوني على الحواسيب العاملة بنظام تشغيل لينكس، أو ويندوز، أو ماك، وذلك من الموقع الرسمي <a href="https://thonny.org/" rel="external nofollow">thonny.org</a> انقر على رابط التنزيل الموافق لنظام تشغيل حاسوبك من الزاوية العلوية اليمنى في الموقع، ثم انقر على الملفات بعد تنزيلها، قد تظهر لك الرسالة التالية على نظام ويندوز:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118831" href="https://academy.hsoub.com/uploads/monthly_2023_02/thonny-site.png.d48f2cc83aaff61b40147f94f1fe14a2.png" rel=""><img alt="تثبيت برنامج ثوني على أنظمة التشغيل" class="ipsImage ipsImage_thumbnailed" data-fileid="118831" data-ratio="67.34" data-unique="npf5muemw" style="width: 297px; height: auto;" width="297" src="https://academy.hsoub.com/uploads/monthly_2023_02/thonny-site.png.d48f2cc83aaff61b40147f94f1fe14a2.png"> </a>
</p>

<p>
	انقر على خيار المزيد من المعلومات "More info" ثم على التشغيل على أي حال "Run anyway".
</p>

<h4>
	التعرف على واجهة برنامج ثوني
</h4>

<p>
	ستظهر لك الواجهة التالية عند فتح ثوني:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118830" href="https://academy.hsoub.com/uploads/monthly_2023_02/thonny-editor.png.5fcc8c6a9885f78da220d095729e2ae4.png" rel=""><img alt="واجهة برنامج ثوني" class="ipsImage ipsImage_thumbnailed" data-fileid="118830" data-ratio="72.92" data-unique="ama3a08xe" style="width: 650px; height: auto;" width="650" src="https://academy.hsoub.com/uploads/monthly_2023_02/thonny-editor.thumb.png.14cd3cfaf4cb7232dd6149dbd4c97f9c.png"> </a>
</p>

<p>
	يمكنك الكتابة <a href="https://academy.hsoub.com/" rel="">بلغة بايثون</a> في النافذة الرئيسية الكبيرة، ثم النقر على زر التشغيل الأخضر <strong>Run</strong> للتنفيذ، ستظهر لك رسالة لحفظ الملف قبل تشغيله.
</p>

<p>
	اكتب الأمر التالي وشغّله:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_21" style=""><span class="kwd">print</span><span class="pun">(</span><span class="str">'Hello World!'</span><span class="pun">)</span></pre>

<h4>
	تغيير السمة والخط
</h4>

<p>
	يمكنك التحكم بلون الخط وحجمه وتغيير السمة المُستخدمة في واجهة البرنامج، وذلك بالنقر على قائمة الأدوات <strong>Tools</strong> من الشريط أعلى الشاشة، ثم النقر على خيارات <strong>Options</strong>، ثم انقر بعدها على نافذة الخط والسمة <strong>Theme &amp; Font</strong> واختر نوع الخط والسمة التي تفضلها من النافذة المنسدلة ثم انقر على زر موافق <strong>OK</strong> عند الانتهاء.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118829" href="https://academy.hsoub.com/uploads/monthly_2023_02/theme-tab.png.ba3d25fd4050a3ff6be1d82e34927f7b.png" rel=""><img alt="تغيير السمة والخط" class="ipsImage ipsImage_thumbnailed" data-fileid="118829" data-ratio="77.11" data-unique="qvvv2gohj" style="width: 450px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_02/theme-tab.png.ba3d25fd4050a3ff6be1d82e34927f7b.png"> </a>
</p>

<p>
	ننصحك باختيار الخطوط البسيطة الواضحة والابتعاد عن الخطوط المزخرفة أو المشابهة لخط اليد لأنه قد تجعل القراءة أصعب.
</p>

<h4>
	إعداد مكتبة picozero
</h4>

<p>
	سنعمل في هذه الخطوة على إعداد مكتبة picozero وتوصيل لوحة راسبيري باي بيكو وإعداد برنامج مايكرو بايثون.
</p>

<p>
	أولًا، صِل الطرف الصغير لكبل USB إلى لوحة <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D9%85%D8%A7-%D9%87%D9%88-%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-raspberry-pi%D8%9F-r1578/" rel="">راسبيري باي</a> والطرف الآخر إلى حاسوبك لتتمكن من برمجة اللوحة عن طريقه.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118805" href="https://academy.hsoub.com/uploads/monthly_2023_02/pico-top-plug.png.5ab3981d1bf06cf43120ffe740be8eee.png" rel=""><img alt="إعداد مكتبة picozero" class="ipsImage ipsImage_thumbnailed" data-fileid="118805" data-ratio="93.14" data-unique="3tjtdjh5m" style="width: 204px; height: auto;" width="204" src="https://academy.hsoub.com/uploads/monthly_2023_02/pico-top-plug.png.5ab3981d1bf06cf43120ffe740be8eee.png"> </a>
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118808" href="https://academy.hsoub.com/uploads/monthly_2023_02/plug-in-pico.png.cd04d09d9f5ff5938b7088ee0f507e39.png" rel=""><img alt="plug-in-pico.png" class="ipsImage ipsImage_thumbnailed" data-fileid="118808" data-unique="plqbs0gq8" src="https://academy.hsoub.com/uploads/monthly_2023_02/plug-in-pico.png.cd04d09d9f5ff5938b7088ee0f507e39.png"> </a>
</p>

<p>
	ثانيًا، افتح محرر ثوني، ولاحظ ما هو الإصدار المستخدم من <a href="https://academy.hsoub.com/programming/python/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-%D8%A8%D9%84%D8%BA%D8%A9-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-r1815/" rel="">بايثون</a> بقراءة النص الموجود في الزاوية السفلية اليمنى من الشاشة، انقر على النص واختر "MicroPython (Raspberry Pi Pico)‎"، إذا لم يكن هذا الخيار محددًا. سيطالبك ثوني بتثبيت برنامج MicroPython على حاسوب راسبيري باي بيكو إذا لم تستخدمه مسبقًا، فقط انقر على زر التثبيت <strong>Install</strong>.
</p>

<p>
	ثالثًا، أضف حزمة بيكو زيرو picozero من خلال النقر على قائمة الأدوات <strong>Tools</strong> من شريط القوائم في برنامج ثوني، ثم النقر على خيار إدارة الحزم <strong>Manage Packages</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118833" href="https://academy.hsoub.com/uploads/monthly_2023_02/tools-manage-packages.png.cf7be9ccca73ddf52f77d64feaed57d7.png" rel=""><img alt="خيار إدارة الحزم Manage Packages في برنامج ثوني" class="ipsImage ipsImage_thumbnailed" data-fileid="118833" data-ratio="87.12" data-unique="sjyxuilfl" style="width: 233px; height: auto;" width="200" src="https://academy.hsoub.com/uploads/monthly_2023_02/tools-manage-packages.png.cf7be9ccca73ddf52f77d64feaed57d7.png"> </a>
</p>

<p>
	ثالثًا، اكتب "picozero"، ثم انقر على زر البحث <strong>Search on PyPi</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118813" href="https://academy.hsoub.com/uploads/monthly_2023_02/search-picozero.png.c853d81cd8f01050cfd963b3eeb16a15.png" rel=""><img alt="زر البحث Search on PyPi في برنامج ثوني" class="ipsImage ipsImage_thumbnailed" data-fileid="118813" data-ratio="94.44" data-unique="hggshnqt5" style="width: 324px; height: auto;" width="324" src="https://academy.hsoub.com/uploads/monthly_2023_02/search-picozero.png.c853d81cd8f01050cfd963b3eeb16a15.png"> </a>
</p>

<p>
	رابعًا، انقر على <strong>picozero</strong> من نتائج البحث ثم انقر على زر التثبيت <strong>Install</strong>.
</p>

<h3>
	استلهم أفكارك
</h3>

<p>
	اطلع على المشاريع التالية واستلهم منها بعض الأفكار لصنع آلتك الموسيقية:
</p>

<ul>
	<li>
		لوحة العزف السحرية
	</li>
</ul>

<div class="ipsEmbeddedVideo" contenteditable="false">
	   
	<div>
		       <iframe allowfullscreen="" frameborder="0" height="506" src="https://player.vimeo.com/video/795266475?autoplay=0&amp;color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="900"></iframe>    
	</div>
</div>

<p>
	باستخدام مبدّل فوري أنشئ مبدّلًا فوريًا drop switch بلصق قطعة قصدير على مجسم شخصية ما وضعها فوق ورق القصدير ليبدأ العزف السحري.
</p>

<p>
	يمكنك الاطلاع على الشيفرة اللازمة لتنفيذ هذا المشروع باسم drop_switch_player.py ضمن الملف المرفق <a data-fileext="zip" data-fileid="118836" href="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=118836&amp;key=7109b5e65c562a86c657eb901b18c01f" rel="">codes.zip</a>.
</p>

<ul>
	<li>
		آلة الإنذار
	</li>
</ul>

<div class="ipsEmbeddedVideo" contenteditable="false">
	   
	<div>
		       <iframe allowfullscreen="" frameborder="0" height="506" src="https://player.vimeo.com/video/795266324?autoplay=0&amp;color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="900"></iframe>    
	</div>
</div>

<p>
	شغّل الفيديو ولاحظ أنه عند سحب قطعة الورق المقوى، كما في مشروع مفرقعات الحفلات، ستتلامس قطعتا القصدير (الملصقتان على مشبك الملابس) وتغلق المبدّل، مما سيؤدي إلى تشغيل سلسلة من الأضواء والأصوات المزعجة.
</p>

<p>
	يمكنك الاطلاع على الشيفرة اللازمة لتنفيذ هذا المشروع باسم soundalarm.py ضمن الملف المرفق الذكور سابقًا والمتاح بنهاية المقال.
</p>

<ul>
	<li>
		آلة موسيقية بسيطة
	</li>
</ul>

<div class="ipsEmbeddedVideo" contenteditable="false">
	   
	<div>
		       <iframe allowfullscreen="" frameborder="0" height="506" src="https://player.vimeo.com/video/795266415?autoplay=0&amp;color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="900"></iframe>    
	</div>
</div>

<p>
	شغّل الفيديو ولاحظ كيف تتحكم المقاومة المتغيرة بسرعة عزف النغمة من الجرس الأول، أما عند الضغط على الزر فتَصدُر عدة نغمات قصيرة من الجرس الثاني.
</p>

<p>
	يمكنك الاطلاع على الشيفرة اللازمة لتنفيذ هذا المشروع باسم dj_desk.py ضمن الملف المرفق.
</p>

<h2>
	تصميم الآلة الموسيقية
</h2>

<p>
	فكِّر في الغرض من آلتك الموسيقية؟ وما هي الآلية التي سيتبعها المستخدم للتحكم بأصوات الآلة؟
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpeg" data-fileid="118835" href="https://academy.hsoub.com/uploads/monthly_2023_02/wicked-player.jpeg.c8efbed14bad1d6ac36d8bd1d82c1d54.jpeg" rel=""><img alt="تصميم الآلة الموسيقية" class="ipsImage ipsImage_thumbnailed" data-fileid="118835" data-unique="9f73rigjg" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_02/wicked-player.thumb.jpeg.acbd4d711f610e2b83912fc23f78cf54.jpeg"> </a>
</p>

<p>
	أولًا، يجب عليك اختيار الآلة التي تود صنعها واختيار الغرض منها، ثم اختيار طريقة العزف، واختيار الجمهور المناسب لها، ويمكنك اختيار إحدى الاقتراحات التالية:
</p>

<ul>
	<li>
		صنع محاكاة لآلة موسيقية ما.
	</li>
	<li>
		صنع مشغل موسيقى.
	</li>
	<li>
		صنع آلة لتوليد التأثيرات الصوتية. *صنع آلةٍ تولّد أنغامًا مهدئةً، أو مزعجة.
	</li>
</ul>

<p>
	ثانيًا، عليك اختيار نوع الصوت الذي ستصدره الآلة، هل تريد:
</p>

<ul>
	<li>
		تشغيل نغمات موسيقية محددة، أو أغانٍ كاملة.
	</li>
	<li>
		تشغيل أصوات من الطبيعة، مثل صوت الرعد أو زقزقة العصافير.
	</li>
	<li>
		تشغيل الصوت حتى انتهائه، أم مقاطعة الصوت عند تشغيل صوت آخر.
	</li>
	<li>
		استخدام مقاومة متغيرة للتحكم بطبقة الصوت وسرعته.
	</li>
</ul>

<h3>
	عدد العناصر التي يمكن توصيلها مع لوحة راسبيري باي بيكو
</h3>

<p>
	تحتوي لوحة راسبيري باي بيكو على ثمانية أرجل أرضية <strong>GND</strong>، لذا يمكنك توصيل ثمانية عناصر فقط، وقد تستطيع توصيل أكثر من ثمانية عناصر إذا كان من الممكن أن يشترك بعضها برجل الأرض <strong>GND</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118797" href="https://academy.hsoub.com/uploads/monthly_2023_02/gnd-pins.png.2d6378ef851e17573f37bfacef29db02.png" rel=""><img alt="عدد العناصر التي يمكن توصيلها مع لوحة راسبيري باي بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="118797" data-ratio="153.85" data-unique="5kmqtyrr1" style="width: 390px; height: auto;" width="300" src="https://academy.hsoub.com/uploads/monthly_2023_02/gnd-pins.thumb.png.72659f7d23fa43367888a9d0702483b1.png"> </a>
</p>

<p>
	عليك أخذ النقاط التالية في الحسبان عند التخطيط لآلتك:
</p>

<ul>
	<li>
		تُشَغّل مكبرات الصوت Speakers كل نغمة على حدى، لذلك ستحتاج لعدة مكبرات صوت لتشغيل عدة نغمات في نفس الوقت.
	</li>
	<li>
		توجد رجل تغذية واحدة ذات جهد 3 فولت على لوحة بيكو؛ أي يمكنك استخدام مقاومة متغيرة potentiometer واحدة، كما أنه يوجد حدٌّ لقيمة التيار الذي توفره لوحة بيكو.
	</li>
</ul>

<p>
	إليك بعض الاقتراحات لعناصر الدخل والخرج التي يمكنك استخدامها معًا:
</p>

<ul>
	<li>
		مقاومة متغيرة واحدة وجرس إلكتروني واحد.
	</li>
	<li>
		أربعة أزرار جاهزة وجرس إلكتروني واحد.
	</li>
	<li>
		ثمانية أزرار يدوية الصنع وجرس إلكتروني واحد.
	</li>
	<li>
		مقاومة متغيرة واحدة وجرسان، وزران.
	</li>
	<li>
		عدة أزرار وأجراس لعزف عدة نغمات في نفس الوقت.
	</li>
</ul>

<p>
	ثالثًا، قرر ما هو عدد الأزرار والأجراس التي تريد استخدامها عند تصميم آلتك؟
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118804" href="https://academy.hsoub.com/uploads/monthly_2023_02/output-components.png.06dec0711ccb682f63524c2321a9b818.png" rel=""><img alt="العناصر التي يمكن توصيلها مع لوحة راسبيري باي بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="118804" data-ratio="92.81" data-unique="ik901lk01" style="width: 292px; height: auto;" width="292" src="https://academy.hsoub.com/uploads/monthly_2023_02/output-components.png.06dec0711ccb682f63524c2321a9b818.png"> </a>
</p>

<p>
	يمكن لآلتك أن تحتوي على:
</p>

<ul>
	<li>
		جرس إلكتروني واحد.
	</li>
	<li>
		جرسان لخلق تأثير الصوت المجسم، أو عزف النغمة وإيقاعها.
	</li>
	<li>
		سمّاعات، وستحتاج حينها إلى ثلاثة دبابيس تثبيت أو ما يُعرف بمشابك التمساح Alligator Clips لتوصيل السمّاعات.
	</li>
	<li>
		عدة أجراس إلكترونية.
	</li>
</ul>

<p>
	رابعًا، اختر ما هي العناصر التي تريد استخدامها؟
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118798" href="https://academy.hsoub.com/uploads/monthly_2023_02/input-components.png.e09b2ac9d8270e9d55b0e489efdcd2b8.png" rel=""><img alt="العناصر المراد استخدامها في لوحة راسبيري باي بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="118798" data-ratio="98.07" data-unique="pxyjdmjzd" style="width: 207px; height: auto;" width="207" src="https://academy.hsoub.com/uploads/monthly_2023_02/input-components.png.e09b2ac9d8270e9d55b0e489efdcd2b8.png"> </a>
</p>

<p>
	إليك بعض الاقتراحات:
</p>

<ul>
	<li>
		زر أو عدة أزرار.
	</li>
	<li>
		مقاومة متغيرة للتحكم بنغمة صوت الجرس وسرعة إيقاعه.
	</li>
	<li>
		أزرار أو مبدّلات يدوية الصنع.
	</li>
</ul>

<p>
	خامسًا، عليك اختيار الشكل الخارجي للآلة، وتحديد آلية توصيل عناصر الدخل والخرج معها.
</p>

<p>
	تساعدك الإجابة على الأسئلة التالية في اختيار التصميم الخارجي:
</p>

<ul>
	<li>
		هل تريد اعتماد تصميم مماثل لآلة موسيقية تقليدية، مثل البيانو مثلًا؟
	</li>
	<li>
		صنع أزرار أو مبدّلات يدوية؟ وصنع هيكل خارجي للآلة؟
	</li>
	<li>
		رسم مشهد ما واستخدام الأزرار لتوليد الأصوات.
	</li>
</ul>

<p>
	لا بأس إذا لم يكن لديك تصورٌ واضحٌ لتصميم الآلة في ذهنك، إذ يمكنك التعديل على تصميمك عند البدء بصنعه.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118823" href="https://academy.hsoub.com/uploads/monthly_2023_02/strip-examples.png.fdca06d20e5e6ca16adb4a262865c22f.png" rel=""><img alt="إمكانية التعديل على التصميم عند البدء في تصنيعه" class="ipsImage ipsImage_thumbnailed" data-fileid="118823" data-ratio="67.05" data-unique="ymivmilma" style="width: 352px; height: auto;" width="352" src="https://academy.hsoub.com/uploads/monthly_2023_02/strip-examples.png.fdca06d20e5e6ca16adb4a262865c22f.png"> </a>
</p>

<h2>
	إضافة الأصوات
</h2>

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

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118818" href="https://academy.hsoub.com/uploads/monthly_2023_02/sound-bomb.png.e0035657d70a393be853550b2ce2bcd1.png" rel=""><img alt="إضافة الصوت إلى مشروع راسبيري باي بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="118818" data-ratio="70.37" data-unique="kcrwo6lcf" style="width: 405px; height: auto;" width="405" src="https://academy.hsoub.com/uploads/monthly_2023_02/sound-bomb.png.e0035657d70a393be853550b2ce2bcd1.png"> </a>
</p>

<h3>
	توصيل الأجراس الإلكترونية والسماعات مع لوحة بيكو
</h3>

<p>
	سنعرض فيما يلي كيفية توصيل الأجراس الإلكترونية والسماعات مع لوحة بيكو.
</p>

<h4>
	توصيل جرس إلكتروني واحد مع لوحة بيكو
</h4>

<p>
	ستحتاج إلى سلكي توصيل نوع مقبس- مقبس socket-socket. صِل الرجل الطويلة،الموجبة للجرس الإلكتروني غير الفعّال مع الرجل <strong>GP5</strong> على لوحة بيكو، وصِل الرجل السالبة مع أقرب رجل تأريض <strong>GND</strong>.
</p>

<p>
	لمعرفة الرجل الموجبة للجرس، ابحث عن الرجل الأطول، أو عن إشارة الموجب <strong>+</strong> أعلى الجرس.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118816" href="https://academy.hsoub.com/uploads/monthly_2023_02/single-buzzer-wiring.png.3121bc4c15e266f51b9b2d2699b385ab.png" rel=""><img alt="توصيل جرس إلكتروني واحد مع لوحة بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="118816" data-ratio="105.00" data-unique="1ul45m0pp" style="width: 500px; height: auto;" width="571" src="https://academy.hsoub.com/uploads/monthly_2023_02/single-buzzer-wiring.thumb.png.7ca31a46ecac22885cbe9927961522b6.png"> </a>
</p>

<h4>
	توصيل جرسين لخلق تأثير الصوت المجسم stereo
</h4>

<p>
	ستحتاج لتوصيل جرسين إلكترونيين غير فعّالين مع لوحة بيكو إلى أربعة أسلاك توصيل نوع مقبس- مقبس.
</p>

<p>
	أولًا، صِل الرجل الطويلة الموجبة للجرس الأول مع الرجل <strong>GP5</strong> على لوحة بيكو، وصِل الرجل السالبة مع أقرب رجل تأريض <strong>GND</strong>، ثم صِل الرجل الموجبة للجرس الثاني مع الرجل <strong>GP10</strong> على لوحة بيكو، والرجل السالبة مع أقرب رجل تأريض <strong>GND</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118822" href="https://academy.hsoub.com/uploads/monthly_2023_02/stereo-buzzer-wiring.png.46694a1c1e228ace5ed6fe48c737cf26.png" rel=""><img alt="توصيل جرسين لخلق تأثير الصوت المجسم stereo" class="ipsImage ipsImage_thumbnailed" data-fileid="118822" data-ratio="105.00" data-unique="czw5ccie8" style="width: 500px; height: auto;" width="571" src="https://academy.hsoub.com/uploads/monthly_2023_02/stereo-buzzer-wiring.thumb.png.d5ba30218d5aba0c5e1f643e0bb5e2c3.png"> </a>
</p>

<h4>
	توصيل السماعات مع لوحة بيكو
</h4>

<p>
	ستحتاج لتوصيل السمّاعات مع لوحة بيكو إلى وصلة ذات نهاية بقطر 3 أو 5 <strong>مم</strong> (وليس وصلة USB)، وثلاثة مشابك تثبيت، وإلى اتباع الخطوات التالية:
</p>

<p>
	1.صِل أحد المشابك مع أحد أرجل الأرض <strong>GND</strong> القريبة، وصِل المشبكين الآخرين مع الرجل <strong>GP5</strong> والرجل <strong>GP10</strong>، كما هو موضح في الصورة أدناه.
</p>

<ol start="2">
	<li>
		صِل نهاية المشبك الأول، الموصول مع الرجل <strong>GP5</strong>، مع نهاية وصلة السمّاعات.
	</li>
	<li>
		صِل نهاية المشبك الثاني، الموصول مع الرجل <strong>GP10</strong>،مع منتصف وصلة السمّاعات.
	</li>
	<li>
		صِل نهاية المشبك الموصول مع رجل الأرض <strong>GND</strong> مع جذر وصلة السمّاعات.
	</li>
</ol>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118791" href="https://academy.hsoub.com/uploads/monthly_2023_02/earphones-wiring.png.c390d7255fd9e70d415034361c24cbf6.png" rel=""><img alt="توصيل السماعات مع لوحة بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="118791" data-ratio="93.62" data-unique="tk1vqrvf2" style="width: 580px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_02/earphones-wiring.thumb.png.846bf1cf27cb6f64ca80612dd91d2c9c.png"> </a>
</p>

<h4>
	استخدام رجل أرضية مشتركة
</h4>

<p>
	تحتوي لوحة بيكو على ثمانية أرجل أرضية <strong>GND</strong>، لذلك لاستخدام ما يزيد عن ثمانية عناصر إلكترونية عليك إعادة استخدام إحدى الأرجل الأرضية، وستحتاج لما يلي:
</p>

<ul>
	<li>
		سلك توصيل دبوس- مقبس.
	</li>
	<li>
		رقائق قصدير، وشريط لاصق ناقل، أو أي مادة ناقلة للتيار الكهربائي.
	</li>
	<li>
		شريط لاصق.
	</li>
</ul>

<p>
	أولًا، أنشئ شريطًا من ورق القصدير، أو من أي مادة ناقلة.
</p>

<p>
	ثانيًا، استخدم الشريط اللاصق لتوصيل سلك أحد الأرجل الأرضية مع شريط القصدير كما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpeg" data-fileid="118820" href="https://academy.hsoub.com/uploads/monthly_2023_02/step-one.jpeg.cd5434c30f5c41312d17e21dd5c9aa37.jpeg" rel=""><img alt="استخدام رجل أرضية مشتركة" class="ipsImage ipsImage_thumbnailed" data-fileid="118820" data-ratio="75.09" data-unique="5pse0f4i8" style="width: 550px; height: auto;" width="700" src="https://academy.hsoub.com/uploads/monthly_2023_02/step-one.thumb.jpeg.e1b062910230b8d33efe0786db994c4b.jpeg"> </a>
</p>

<p>
	ثالثًا،صِل القطب الموجب للعنصر الأول مع أحد الأرجل العامة <strong>GP</strong> على لوحة بيكو، والقطب السالب للعنصر مع شريط القصدير.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpeg" data-fileid="118821" href="https://academy.hsoub.com/uploads/monthly_2023_02/step-three.jpeg.cf321f930e054b033810428ad5347b23.jpeg" rel=""><img alt="كيفية استخدام رجل أرضية مشتركة" class="ipsImage ipsImage_thumbnailed" data-fileid="118821" data-ratio="75.09" data-unique="onq3z0apk" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_02/step-three.thumb.jpeg.c00cd6fd26d268aad21600433fa2985d.jpeg"> </a>
</p>

<p>
	رابعًا، لتوصيل المزيد من العناصر، صِل القطب الموجب للعنصر مع إحدى أرجل الأغراض العامة <strong>GP</strong>، والقطب السالب مع شريط القصدير.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpeg" data-fileid="118819" href="https://academy.hsoub.com/uploads/monthly_2023_02/step-four.jpeg.91306ff66df5c6453d84f3d5efae946a.jpeg" rel=""><img alt="الخطوة 4 لاستخدام رجل أرضية مشتركة" class="ipsImage ipsImage_thumbnailed" data-fileid="118819" data-ratio="75.09" data-unique="i05hfca7f" style="width: 550px; height: auto;" width="744" src="https://academy.hsoub.com/uploads/monthly_2023_02/step-four.thumb.jpeg.81d36ca842315545440289fecc85fd6b.jpeg"> </a>
</p>

<h3>
	كتابة الشيفرة اللازمة لربط اللوحة مع الجرس
</h3>

<p>
	استورد تابع المكبر الصوتي <code>Speaker</code> من مكتبة <code>picozero</code>، ثم أسند أرقام أرجل لوحة بيكو مع الجرس الوحيد للتابع <code>Speaker</code>:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_50" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pln">

speaker </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pun">(</span><span class="lit">5</span><span class="pun">)</span></pre>

<p>
	وتكون الشيفرة اللازمة لتوصيل جرسين على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_52" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pln">

speaker_1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pun">(</span><span class="lit">5</span><span class="pun">)</span><span class="pln">
speaker_2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pun">(</span><span class="lit">10</span><span class="pun">)</span></pre>

<p>
	ننصحك بتسمية المتغيرات Variables بأسماء تدل على وظيفتها، مثلًا عند إسناد صوت الطبل للمتغير <code>Speaker_1</code> فسمّه <code>drum_beat</code>.
</p>

<h3>
	كتابة الشيفرة اللازمة لإصدار الصوت
</h3>

<p>
	عرّف دالة الصوت بكتابة <code>def</code> قبل اسم الدالة، ثم اختر اسمًا مناسبًا ومعبرًا عن الصوت الذي ستصدره آلتك، فعلى سبيل المثال، إذا أردت أن تصدر آلتك صوتًا مزعجًا، فسمِّ دالة الصوت <code>annoying_sound</code>.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_54" style=""><span class="kwd">def</span><span class="pln"> sound_1</span><span class="pun">():</span><span class="pln"> </span><span class="com"># استبدل الدالة باسم دالتك</span></pre>

<p>
	<strong>معلومة:</strong> موسيقا Chiptune الرُقاقة أو ما يُعرف بموسيقا الثمانية بتات، هي موسيقا صُنعية تُوَّلد بواسطة برمجة الرقائق المسؤولة عن إصدار الصوت في الحواسيب لتصدر أصواتًا ذات ترددات معينة، استعاضةً عن استخدام الآلات الموسيقية التقليدية. تجد هذا النوع من الموسيقا في ألعاب الفيديو ذات طراز الريترو Retro، وفي صالات الألعاب.
</p>

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

<h3>
	معلومات مفيدة يجب معرفتها
</h3>

<p>
	دعنا نطلع على بعض المعلومات المفيدة عن الأصوات قبل كتابة الشيفرة:
</p>

<h4>
	النغمات المتاحة
</h4>

<p>
	تُوفر لنا مكتبة "picozero" ثمان وثمانين علامةً موسيقية، تتبع التدوين الغربي للموسيقا وتشمل جميع العلامات الموجودة في لوحة مفاتيح موسيقية كاملة الحجم.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118799" href="https://academy.hsoub.com/uploads/monthly_2023_02/keyboard.png.a58a324f0aaebd57af1739aa98ad3a8d.png" rel=""><img alt="النغمات المتاحة" class="ipsImage ipsImage_thumbnailed" data-fileid="118799" data-ratio="11.83" data-unique="9emlp1ade" style="width: 744px; height: 88px;" width="744" src="https://academy.hsoub.com/uploads/monthly_2023_02/keyboard.thumb.png.d6ec273e63031d0b82277a89bc520cde.png"> </a>
</p>

<p>
	إليك بعض العلامات المُتاحة:
</p>

<ul>
	<li>
		b0
	</li>
	<li>
		c1
	</li>
	<li>
		c#1
	</li>
	<li>
		d1
	</li>
	<li>
		d#1
	</li>
	<li>
		e1
	</li>
	<li>
		f1
	</li>
	<li>
		f#1
	</li>
</ul>

<h4>
	طول النغمة
</h4>

<p>
	توجد عدة طرق لتحديد طول النغمة، هي:
</p>

<p>
	أولًا، تحديد طول نغمة واحدة باستخدام القيم، إذ يمكنك تحديد مدة النغمة الواحدة بإدخال قيمة في حقل الوسيط الثاني في دالة العزف:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_57" style=""><span class="pln">speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">c_note</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اعزف النغمة لمدة 0.1 ثانية</span></pre>

<p>
	ستُعزَف النغمة <strong>C</strong> في مثالنا لمدة 0.1 ثانية.
</p>

<p>
	ثانيًا، تحديد طول نغمة واحدة باستخدام الثوابت، إذ يمكنك التصريح عن أحد الثوابت في حقل الوسيط الثاني في دالة العزف بدلًا عن القيمة، وتعريف هذا الثابت، وذلك كما يلي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_59" style=""><span class="pln">BEAT </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span class="com"># BEAT تعريف الثابت</span><span class="pln">

speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">c_note</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اعزف النغمة لمدة ثانية واحدة</span></pre>

<p>
	لاحظ أنه يمكننا استخدام الثابت <code>BEAT</code> لتحديد طول أي نغمة.
</p>

<p>
	ثالثًا، تحديد طول مجموعة من النغمات باستخدام القيم، فعند عزف لحن ما، يُفضل تخزين النغمات وطول كل منها في قائمة list، كما في مثالنا التالي، إذ خزّنا كل نغمة مع طولها في قائمة، وجمعنا النغمات الثلاث في قائمة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_61" style=""><span class="pln">my_tune </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.5</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1.2</span><span class="pun">]]</span><span class="pln"> </span><span class="com"># قائمة بالنغمات وطول كل منها</span></pre>

<p>
	احرص على كتابة النغمة ضمن علامتي اقتباس <code>' '</code>.
</p>

<p>
	رابعًا، تحديد طول مجموعة من النغمات باستخدام الثوابت، بحيث نبدأ باستخدام الثابت <code>BEAT</code>، إذ اخترنا في مثالنا القيمة 0.4، ثم نصرّح عن النغمات التي نود عزفها في قائمة ضمن علامتي <code>' '</code>، ونستخدم الثابت <code>BEAT</code> لتحديد طول النغمات:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_63" style=""><span class="pln">BEAT </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0.4</span><span class="pln"> </span><span class="com"># طول النغمة الواحدة</span><span class="pln">

my_tune </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">*</span><span class="pln"> </span><span class="lit">1.5</span><span class="pun">]]</span><span class="pln"> </span><span class="com"># قائمة بالنغمات وطول كل منها</span></pre>

<p>
	للتحكم بعدد النغمات في الدقيقة <strong>BPM</strong> يمكنك تقسيم الثابت <code>BEAT</code> على عدد ما للحصول على نغمات أقصر، مثلًا <code>2 / BEAT</code>، أو مضاعفته بضربه بعدد ما للحصول على نغمات أطول، مثلا <code>BEAT*1.5</code>.
</p>

<h4>
	استخدام الأرقام عوضا عن النغمات
</h4>

<p>
	يمكنك الاستعاضة عن النغمات باستخدام قيم الترددات الموافقة لها، والتي تتراوح بين القيمة <strong>150</strong> إلى <strong>10000</strong>، إليك المثال التالي لعزف نغمة ذات التردد 523 لثانية واحدة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_65" style=""><span class="pln">speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="lit">523</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اعزف النغمة ذات التردد 523 لثانية واحدة</span></pre>

<h4>
	تحويل المقطوعات الموسيقية إلى نغمات
</h4>

<p>
	تُتيح لنا مكتبة <code>picozero</code> عزف المقطوعات الموسيقية الشهيرة واستخدامها في مشاريعنا، إذ تستخدم الأحرف الإنجليزية للدلالة على العلامات الموسيقية، والأرقام للدلالة على موقع العلامة في السلم الموسيقي الكبير.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118800" href="https://academy.hsoub.com/uploads/monthly_2023_02/middle-c.png.64edcae219e31780ada0e39eb16882a8.png" rel=""><img alt="تحويل المقطوعات الموسيقية إلى نغمات" class="ipsImage ipsImage_thumbnailed" data-fileid="118800" data-ratio="118.80" data-unique="m099vl2k7" style="width: 250px; height: auto;" width="300" src="https://academy.hsoub.com/uploads/monthly_2023_02/middle-c.png.64edcae219e31780ada0e39eb16882a8.png"> </a>
</p>

<p>
	على سبيل المثال، توجد العلامة <strong>C</strong> الوسطى في منتصف السلم الموسيقي ويعبر عنها بالرمز <strong>C4</strong>.
</p>

<p>
	تزداد الأرقام التي تدل على العلامة كلما صعدنا في السلم الكبير، وتنقص عند النزول.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118785" href="https://academy.hsoub.com/uploads/monthly_2023_02/cdef-cdef.png.477d86171a6a835853a7336f693cbf0f.png" rel=""><img alt="كيفية تحويل المقطوعات الموسيقية إلى نغمات" class="ipsImage ipsImage_thumbnailed" data-fileid="118785" data-ratio="62.67" data-unique="2a21hju29" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_02/cdef-cdef.png.477d86171a6a835853a7336f693cbf0f.png"> </a>
</p>

<p>
	تحتوي المقطوعة الموسيقية علامات حادة يُشار إليها بالرمز <strong>#</strong> وتدعى "دييز". في مثالنا أدناه، توجد عدة علامات موسيقية حادة، أولها العلامة <strong>C</strong> الحادة والتي يرمز لها <strong>c#4</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118814" href="https://academy.hsoub.com/uploads/monthly_2023_02/sharp-notes.png.c1b8ff2474513410c273eed425ff3bf1.png" rel=""><img alt="طريقة تحويل المقطوعات الموسيقية إلى نغمات" class="ipsImage ipsImage_thumbnailed" data-fileid="118814" data-ratio="30.18" data-unique="pfohfdfcv" style="width: 550px; height: auto;" width="650" src="https://academy.hsoub.com/uploads/monthly_2023_02/sharp-notes.png.c1b8ff2474513410c273eed425ff3bf1.png"> </a>
</p>

<p>
	وقد تحتوي المقطوعة الموسيقية على علامات بسيطة يُشار إليها بالرمز <strong>♭</strong> وتدعى "بيمول"، لكن سنشير إليها في مشروعنا بالرمز <strong>#</strong> لعدم احتواء مكتبة "picozero" على شيفرة خاصة للدلالة على العلامات البسيطة، وعلينا النزول نصف درجة في السلم الموسيقي للتحويل من علامة بسيطة إلى حادة.
</p>

<p>
	إليك الأمثلة التالية:
</p>

<ul>
	<li>
		تتحوّل العلامة البسيطة <strong>D</strong> إلى <strong>C</strong> حادة أو <strong>c#4</strong>.
	</li>
	<li>
		تتحوّل العلامة البسيطة <strong>E</strong> إلى <strong>D</strong> حادة أو <strong>d#4</strong>.
	</li>
	<li>
		تتحوّل العلامة البسيطة <strong>G</strong> إلى <strong>F</strong> حادة أو <strong>f#4</strong>.
	</li>
	<li>
		تتحوّل العلامة البسيطة <strong>A</strong> إلى <strong>G</strong> حادة أو <strong>g#4</strong>.
	</li>
</ul>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118792" href="https://academy.hsoub.com/uploads/monthly_2023_02/flat-notes.png.7cdd6a613cdfbeb873d8597f19a0b1cd.png" rel=""><img alt="تحويل المقطوعات الموسيقية إلى نغمات" class="ipsImage ipsImage_thumbnailed" data-fileid="118792" data-ratio="34.91" data-unique="dfgxo1wi1" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_02/flat-notes.png.7cdd6a613cdfbeb873d8597f19a0b1cd.png"> </a>
</p>

<h3>
	أمثلة عن بعض الشيفرات الموسيقية
</h3>

<p>
	إليك مثالًا عن الشيفرة اللازمة لعزف علامة موسيقية واحدة ولتكن العلامة <strong>C</strong> الوسطى مثلًا لمدة نصف ثانية:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_74" style=""><span class="kwd">def</span><span class="pln"> c_note</span><span class="pun">():</span><span class="pln">
   speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="str">'c4'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.5</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اعزف العلامة لمدة نصف ثانية</span></pre>

<p>
	أما لعزف لحن موسيقي، لا بُد من تخزين النغمات وطول كل منها في قائمة للحصول على لحن ما، ثم تشغيل اللحن باستخدام دالة <code>play</code>، كما هو مبين في الشيفرة التالية:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_76" style=""><span class="pln">BEAT </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0.4</span><span class="pln">

liten_mus </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">''</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'b5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">*</span><span class="pln"> </span><span class="lit">1.5</span><span class="pun">]</span><span class="pln"> </span><span class="pun">]</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> play_liten_mus</span><span class="pun">():</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">liten_mus</span><span class="pun">)</span></pre>

<h4>
	الشيفرة اللازمة لتوليد تأثيرات صوتية مختلفة باستخدام الترددات
</h4>

<p>
	يمكننا توليد تأثيرات صوتية ممتعة، أو مزعجة، وذلك بعزف نغمات قصيرة ذات ترددات مختلفة، إذ أنه كلما تغير التردد تختلف العلامة الموسيقية التي نسمعها وتختلف نغمتها.
</p>

<p>
	إليك الشيفرة التالية التي ترتفع فيها الترددات تدريجيًا لخلق صوت مبهج:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_78" style=""><span class="kwd">def</span><span class="pln"> win</span><span class="pun">():</span><span class="pln"> </span><span class="com"># ترددات متزايدة</span><span class="pln">
    </span><span class="kwd">for</span><span class="pln"> i </span><span class="kwd">in</span><span class="pln"> range</span><span class="pun">(</span><span class="lit">2000</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5000</span><span class="pun">,</span><span class="pln"> </span><span class="lit">100</span><span class="pun">):</span><span class="pln">
        speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">i</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.05</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اعزف النغمة لمدة قصيرة جدًا</span></pre>

<p>
	أما المثال التالي، فقد خفضنا فيه الترددات تدريجيًا لتوليد صوت زقزقة العصافير:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_81" style=""><span class="kwd">def</span><span class="pln"> chirp</span><span class="pun">():</span><span class="pln"> </span><span class="com"># توليد صوت زقزقة العصافير</span><span class="pln">
    </span><span class="kwd">for</span><span class="pln"> _ </span><span class="kwd">in</span><span class="pln"> range</span><span class="pun">(</span><span class="lit">2</span><span class="pun">):</span><span class="pln"> </span><span class="com"># decreasing frequency</span><span class="pln">
        </span><span class="kwd">for</span><span class="pln"> i </span><span class="kwd">in</span><span class="pln"> range</span><span class="pun">(</span><span class="lit">5000</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2999</span><span class="pun">,</span><span class="pln"> </span><span class="pun">-</span><span class="lit">100</span><span class="pun">):</span><span class="pln">
            speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">i</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.02</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اعزف النغمة لمدة قصيرة جدًا</span><span class="pln">
        sleep</span><span class="pun">(</span><span class="lit">0.2</span><span class="pun">)</span></pre>

<p>
	غَيّر الترددات المستخدمة في <a href="https://academy.hsoub.com/programming/python/%d8%ad%d9%84%d9%82%d8%a7%d8%aa-%d8%a7%d9%84%d8%aa%d9%83%d8%b1%d8%a7%d8%b1-loops-%d9%81%d9%8a-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86-r291/" rel="">حلقة التكرار</a> <code>for</code> واستخدم الترددات ضمن المجال من <strong>150</strong> إلى <strong>10000</strong>.
</p>

<h4>
	الشيفرة اللازمة لتوليد ضجيج أبيض من صوت قرع الطبل
</h4>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_84" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> time </span><span class="kwd">import</span><span class="pln"> sleep
</span><span class="kwd">from</span><span class="pln"> random </span><span class="kwd">import</span><span class="pln"> randint

speaker </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pun">(</span><span class="lit">5</span><span class="pun">)</span><span class="pln">

</span><span class="kwd">for</span><span class="pln"> i </span><span class="kwd">in</span><span class="pln"> range</span><span class="pun">(</span><span class="lit">100</span><span class="pun">):</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">randint</span><span class="pun">(</span><span class="lit">500</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5000</span><span class="pun">),</span><span class="pln"> duration</span><span class="pun">=</span><span class="kwd">None</span><span class="pun">)</span><span class="pln">
    sleep</span><span class="pun">(</span><span class="lit">0.001</span><span class="pun">)</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">stop</span><span class="pun">()</span><span class="pln">
    sleep</span><span class="pun">(</span><span class="lit">0.5</span><span class="pun">)</span></pre>

<h4>
	الشيفرة اللازمة لعزف النغمات بصورة متكررة
</h4>

<p>
	أنشئ قائمةً بالنغمات التي تريد عزفها وطول كل منها للحصول على لحن ما، ثم استخدم حلقة تكرار <code>for</code> لتشغيل اللحن نغمةً نغمة باستخدام الدالة <code>play</code>:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_86" style=""><span class="pln">BEAT </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0.4</span><span class="pln">

liten_mus </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">''</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'b5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">*</span><span class="pln"> </span><span class="lit">1.5</span><span class="pun">]</span><span class="pln"> </span><span class="pun">]</span><span class="pln">

</span><span class="kwd">for</span><span class="pln"> note </span><span class="kwd">in</span><span class="pln"> liten_mus</span><span class="pun">:</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">note</span><span class="pun">)</span></pre>

<h4>
	الشيفرة اللازمة لعزف عدة نغمات متزامنة
</h4>

<p>
	إذا أردت عزف لحن ما مثلًا، وتشغيل لحن أو تأثير صوتي آخر بالتزامن معه، فيمكنك ذلك بوضع <code>wait=False</code> في حقل الوسيط الثاني للدالة <code>play</code>.
</p>

<p>
	أنشأنا في مثالنا التالي قائمةً بالنغمات التي نريد عزفها وطول كل منها، ثم عرّفنا اللحن الآخر، المزعج، الذي سينطلق بالتزامن مع اللحن الأول عند الضغط على الزر، وسيتوقف معه عند إيقاف الشيفرة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_88" style=""><span class="pln">BEAT </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0.4</span><span class="pln">

liten_mus </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">''</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'b5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">*</span><span class="pln"> </span><span class="lit">1.5</span><span class="pun">]</span><span class="pln"> </span><span class="pun">]</span><span class="pln">

sound </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="pun">[</span><span class="lit">523</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="kwd">None</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="lit">523</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.4</span><span class="pun">]</span><span class="pln"> </span><span class="pun">]</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> annoying_sound</span><span class="pun">():</span><span class="pln">
    speaker2</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">sound</span><span class="pun">,</span><span class="pln"> wait</span><span class="pun">=</span><span class="kwd">False</span><span class="pun">)</span><span class="pln"> </span><span class="com"># شغّل بالتزامن مع اللحن الأول</span><span class="pln">

button</span><span class="pun">.</span><span class="pln">when_pressed </span><span class="pun">=</span><span class="pln"> annoying_sound

</span><span class="kwd">try</span><span class="pun">:</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">liten_mus</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">finally</span><span class="pun">:</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln"> </span><span class="com">#أطفئ مكبر الصوت الأول عند إيقاف البرنامج</span><span class="pln">
    speaker2</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln"> </span><span class="com"># أطفئ مكبر الصوت الثاني عند إيقاف البرنامج</span></pre>

<h4>
	الشيفرة اللازمة لاستدعاء دالة ما
</h4>

<p>
	لاستدعاء دالة ما عليك تعريفها أولًا، ثم التصريح عنها بكتابة اسمها. إليك المثال التالي الذي استدعينا فيه الدالة <code>chirp</code>:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_90" style=""><span class="kwd">def</span><span class="pln"> chirp</span><span class="pun">():</span><span class="pln"> </span><span class="com"># توليد صوت زقزقة العصافير</span><span class="pln">
    </span><span class="kwd">for</span><span class="pln"> _ </span><span class="kwd">in</span><span class="pln"> range</span><span class="pun">(</span><span class="lit">2</span><span class="pun">):</span><span class="pln">
        </span><span class="kwd">for</span><span class="pln"> i </span><span class="kwd">in</span><span class="pln"> range</span><span class="pun">(</span><span class="lit">5000</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2999</span><span class="pun">,</span><span class="pln"> </span><span class="pun">-</span><span class="lit">100</span><span class="pun">):</span><span class="pln">
            speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">i</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.02</span><span class="pun">)</span><span class="pln">
        sleep</span><span class="pun">(</span><span class="lit">0.2</span><span class="pun">)</span><span class="pln">

chirp</span><span class="pun">()</span></pre>

<h3>
	مرحلة التنفيذ
</h3>

<p>
	أولًا، اكتب الشيفرة اللازمة لتشغيل آلتك الموسيقية، واحرص على عدم ترك مسافة قبل اسم الدالة عند استدعائها.
</p>

<p>
	ثانيًا، شغّل الشيفرة للتحقق من عمل آلتك وإصدارها للأصوات، إذ قد يستمر صوت الجرس حتى بعد إيقاف الشفرة، لذلك عليك استعمال <code>try</code> و <code>finally</code> كي يتوقف صوت عند إيقاف الشفرة، كما في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_92" style=""><span class="pln">BEAT </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0.4</span><span class="pln">

liten_mus </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">''</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'b5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">*</span><span class="pln"> </span><span class="lit">1.5</span><span class="pun">]</span><span class="pln"> </span><span class="pun">]</span><span class="pln">

</span><span class="kwd">try</span><span class="pun">:</span><span class="pln">
    </span><span class="kwd">for</span><span class="pln"> note </span><span class="kwd">in</span><span class="pln"> liten_mus</span><span class="pun">:</span><span class="pln">
        speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">note</span><span class="pun">)</span><span class="pln">

</span><span class="kwd">finally</span><span class="pun">:</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln"> </span><span class="com"># أطفئ مكبر الصوت عند إيقاف البرنامج</span></pre>

<h3>
	تصحيح الأخطاء
</h3>

<p>
	قبل التعرف على المشاكل التي قد تواجهك في هذه الخطوة وكيفية إصلاحها، عليك أولًا التحقق من سلامة لوحة بيكو، لذلك استخدم مصباح الليد الموجود على لوحة بيكو للتحقق من سلامة اللوحة، وذلك بجعل المصباح يومض عند تشغيل الشيفرة بإضافة الشيفرة التالية في ملف main.py:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_94" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> pico_led
</span><span class="kwd">from</span><span class="pln"> time </span><span class="kwd">import</span><span class="pln"> sleep

pico_led</span><span class="pun">.</span><span class="pln">on</span><span class="pun">()</span><span class="pln">
sleep</span><span class="pun">(</span><span class="lit">2</span><span class="pun">)</span><span class="pln">
pico_led</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span></pre>

<h4>
	تصحيح الأخطاء الموجودة في الشيفرة
</h4>

<ul>
	<li>
		تحقق من وجود أي رسائل خطأ في نافذة صدفة shell ثوني وتحقق من محتواها، إن وجدت.
	</li>
	<li>
		راجع الشيفرة التي كتبتها وتحقق من خلوها من الأخطاء، مثل نسيان علامة <strong>:</strong>، أو وجود مسافة بادئة دون الحاجة لها.
	</li>
	<li>
		تأكد من استيراد توابع العناصر التي ستستخدمها في مشروعك من مكتبة "picozero"، مثل تابع مصباح الليد <code>RGBLED</code> أو الزر <code>Button</code>.
	</li>
	<li>
		استخدم تعليمة الطباعة <code>print</code> لإضافة شرح مختصر عند كل خطوة، مثل <code>(البدء)print</code> أو <code>(ضبط المصباح على اللون الأخضر)print</code>.
	</li>
</ul>

<h4>
	لا تعمل بعض العناصر الإلكترونية كما يجب
</h4>

<ul>
	<li>
		تأكد أن جميع العناصر متصلة ببعضها جيدًا، وتحقق من ثبات نقاط توصيل الأسلاك مع اللوحة ومع العناصر.
	</li>
	<li>
		تأكد أن أرقام الأرجل المستخدمة في الشيفرة مطابقة لأرقام الأرجل الموصولة مع مصباح الليد، وتأكد من إعادة وصل الأرجل، في حال فصلتها عند العمل على تصميم شكل الآلة الموسيقية.
	</li>
	<li>
		تحقق من وصل العناصر وفق القطبية الصحيحة، إذ قد تحتوي بعض العناصر على قطب موجب <strong>+</strong> وآخر سالب <strong>-</strong>.
	</li>
	<li>
		في حال تحققت من جميع النقاط السابقة ولازالت آلتك لاتعمل، فجرب تبديل العناصر الإلكترونية بأخرى جديدة.
	</li>
</ul>

<h4>
	صوت النغمة مختلف عن الصوت المطلوب
</h4>

<p>
	تحقق من خلو الشيفرة التي كتبتها من الأخطاء وأنها مطابقة للشيفرة في مثالنا. عَدّل على النغمات ومدتها للحصول على الصوت المطلوب.
</p>

<h4>
	يتأخر عزف النغمة عند الضغط على زر ما
</h4>

<p>
	عند استخدام أحد الأحداث events مثل حدث الضغط <code>when_pressed</code> لتشغيل دالة ما، فإن هذه الدالة ستُنفَذ حتى انتهائها وستمنع تشغيل أي شيء آخر في الشيفرة. إذا أردت عزف لحن ما مثلًا من حدث ما، وتشغيل لحن أو تأثير صوتي آخر بالتزامن معه، فيمكنك ذلك بوضع <code>wait=False</code> في حقل الوسيط الثاني للدالة <code>play</code>:
</p>

<pre class="ipsCode">sound = [ [523, 0.1], [None, 0.1], [523, 0.4] ]

def annoying_sound():
    speaker.play(sound, wait=False) # لا تؤخر تشغيل الشيفرة

button.when_pressed = annoying_sound
</pre>

<p>
	حاول حل المشاكل الأخرى التي قد تواجهك عند التنفيذ وشاركنا طريقة الحل في <a href="https://io.hsoub.com/" rel="external">منصة حسوب IO</a>.
</p>

<p>
	احرص على اتباع ما يلي عند كتابة الشيفرات اللازمة لإصدار النغمات الموسيقية، وعند اختبارها:
</p>

<ul>
	<li>
		تعريف الدالة.
	</li>
	<li>
		كتابة الشيفرة الصحيحة.
	</li>
	<li>
		استدعاء الدالة.
	</li>
	<li>
		اختبار الدالة.
	</li>
</ul>

<p>
	عند اختبار الشيفرة، ننصحك بإضافة رمز التعليق <code>#</code> قبل الدالة التي لا تريد تشغيلها، أو حذف استدعاء الدالة لتتمكن من سماع النغمة التي تريد اختبارها.
</p>

<h2>
	التحكم بالأصوات
</h2>

<p>
	سنعمل في هذه الخطوة على إنشاء وسيلة للمستخدم للتحكم في الأصوات باستخدام عناصر دخل مختلفة، وكتابة الشيفرة اللازمة لذلك.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118810" href="https://academy.hsoub.com/uploads/monthly_2023_02/pot-speed.jpg.3093bb36e1e565251459845d7d289926.jpg" rel=""><img alt="إنشاء وسيلة للمستخدم للتحكم في الأصوات" class="ipsImage ipsImage_thumbnailed" data-fileid="118810" data-ratio="52.00" data-unique="tjf0ercn8" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_02/pot-speed.jpg.3093bb36e1e565251459845d7d289926.jpg"> </a>
</p>

<p>
	حدد أولًا ما هي عناصر الدخل التي تود استخدامها. إليك الاقتراحات التالية:
</p>

<ul>
	<li>
		استخدام زر خاص بكل نغمة، أو لحن أو تأثير.
	</li>
	<li>
		استخدام زر لتشغيل الصوت التالي.
	</li>
	<li>
		استخدام سلكين نوع دبوس-مقبس وتوصيلهما إما مع مبدّل إلكتروني أو زر.
	</li>
	<li>
		استخدام مقاومة متغيرة للتحكم بسرعة إيقاع النغمات.
	</li>
</ul>

<p>
	ستحتاج استخدام سلكي توصيل نوع مقبس-مقبس لكل زر، وثلاثة أسلاك نوع مقبس-مقبس للمقاومة المتغيرة.
</p>

<h3>
	توصيل عناصر الدخل مع لوحة بيكو
</h3>

<p>
	سنشرح في الآتي كيفية توصل عناصر الدخل مع لوحة بيكو
</p>

<h4>
	توصيل زر إلكتروني واحد مع اللوحة
</h4>

<p>
	لتوصيل زر مع لوحة بيكو ستحتاج إلى ما يلي:
</p>

<ul>
	<li>
		لوحة راسبيري بيكو.
	</li>
	<li>
		زر إلكتروني.
	</li>
	<li>
		سلكي توصيل نوع مقبس-مقبس.
	</li>
</ul>

<p>
	صِل سلكي التوصيل مع أرجل الزر واستخدم الشريط اللاصق لتثبيتهما إن لزم الأمر، ثم صِل أحد السلكين مع الرجل <strong>GP18</strong> والسلك الآخر مع أقرب رجل أرضية. لا يهمنا ترتيب توصيل الأسلاك إذ لا توجد قطبية للزر.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118815" href="https://academy.hsoub.com/uploads/monthly_2023_02/single-button-wiring.png.bcf528528f842ce566f80d22296fda8e.png" rel=""><img alt="توصيل زر إلكتروني واحد مع اللوحة" class="ipsImage ipsImage_thumbnailed" data-fileid="118815" data-ratio="134.53" data-unique="ht6wabwb9" style="width: 446px; height: auto;" width="446" src="https://academy.hsoub.com/uploads/monthly_2023_02/single-button-wiring.thumb.png.b3fcd32aafc062732e14b8bb37dc22f8.png"> </a>
</p>

<h4>
	توصيل عدة أزرار مع اللوحة
</h4>

<p>
	ستحتاج لتوصيل عدة أزرار مع لوحة بيكو إلى ما يلي:
</p>

<ul>
	<li>
		لوحة راسبيري بيكو.
	</li>
	<li>
		أزرار إلكترونية.
	</li>
	<li>
		سلكي توصيل نوع دبوس-مقبس لكل زر.
	</li>
</ul>

<p>
	توضح الصورة التالية طريقة توصيل ثلاثة أزرار مع لوحة بيكو، وإذا أردت توصيل زر رابع فما عليك سوى توصيله مع إحدى أرجل الأغراض العامة <strong>GP</strong> ورجل أرضية.
</p>

<p>
	استخدم سلكي توصيل نوع دبوس- مقبس لتوصيل الزر الأول مع الرجل <strong>GP18</strong> ومع أقرب رجل أرضية <strong>GND</strong>. ثم صِل الزر الثاني مع الرجل <strong>GP22</strong>، والثالث مع الرجل <strong>GP28</strong> بنفس الطريقة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118801" href="https://academy.hsoub.com/uploads/monthly_2023_02/multiple-button-wiring.png.d1b82280ec5392d2e06a68a8d8af5240.png" rel=""><img alt="توصيل عدة أزرار مع اللوحة" class="ipsImage ipsImage_thumbnailed" data-fileid="118801" data-ratio="134.53" data-unique="k1218507f" style="width: 446px; height: auto;" width="446" src="https://academy.hsoub.com/uploads/monthly_2023_02/multiple-button-wiring.thumb.png.afabc38582b8318ecf701f49bf46e856.png"> </a>
</p>

<h4>
	توصيل مقاومة متغيرة مع اللوحة
</h4>

<p>
	ستحتاج إلى ما يلي:
</p>

<ul>
	<li>
		لوحة راسبيري بيكو.
	</li>
	<li>
		مقاومة متغيرة.
	</li>
	<li>
		أسلاك توصيل نوع مقبس-مقبس (عدد 3).
	</li>
</ul>

<p>
	يوجد للمقاومة المتغيرة ثلاثة أرجل: رجل الأرضية <strong>GND</strong>، ورجل تشابهية Analogue، ورجل التغذية <strong>3V3</strong>؛ وعند تدوير قرص المقاومة المتغيرة إلى أقصى اليسار سيشير السهم إلى الرجل الأرضية <strong>GND</strong>؛ وعند تدويره إلى أقصى اليمين سيشير السهم إلى رجل التغذية <strong>3V3</strong>؛ أما الرجل الوسطى للمقاومة فهي الرجل التشابهية التي تستمد منها لوحة بيكو القيم لقراءتها .
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118811" href="https://academy.hsoub.com/uploads/monthly_2023_02/potentiometer-illustration.png.2f0ec01c39b516fbaec32eb252b2288a.png" rel=""><img alt="توصيل مقاومة متغيرة مع اللوحة" class="ipsImage ipsImage_thumbnailed" data-fileid="118811" data-ratio="100.00" data-unique="36qovpjm3" style="width: 350px; height: auto;" width="350" src="https://academy.hsoub.com/uploads/monthly_2023_02/potentiometer-illustration.thumb.png.e7fb432bda3dcecf53aef68cfae2b0c9.png"> </a>
</p>

<ul>
	<li>
		صِل سلك توصيل ذو نهايات مقبس-مقبس مع كلٍ من أرجل المقاومة الثلاث، وثبّت التوصيلات بالشريط اللاصق إن لزم الأمر.
	</li>
	<li>
		صِل النهاية الحرة للسلك الموصول مع رجل المقاومة ذات الرقم <strong>1</strong> مع رجل الأرض <strong>GND</strong> الموجودة بين الرجلين <strong>GP21</strong> و <strong>GP22</strong>.
	</li>
	<li>
		صِل رجل المقاومة الوسطى مع الرجل <strong>GP26_A0</strong> على لوحة بيكو.
	</li>
	<li>
		صِل رجل المقاومة ذات الرقم <strong>3</strong> مع رجل التغذية <strong>3V3</strong>.
	</li>
</ul>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118809" href="https://academy.hsoub.com/uploads/monthly_2023_02/pot-diagram.png.40c46025876f8f92b7a37f2a1419ffed.png" rel=""><img alt="كيفية توصيل مقاومة متغيرة مع اللوحة" class="ipsImage ipsImage_thumbnailed" data-fileid="118809" data-ratio="112.89" data-unique="8xejpajwf" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_02/pot-diagram.thumb.png.11e05d0bce89667cd263a15577183935.png"> </a>
</p>

<h4>
	توصيل مبدل يدوي أو زر مع لوحة بيكو
</h4>

<p>
	ستحتاج إلى سلكي توصيل نوع دبوس-مقبس، وصِل أحدهما مع الرجل <strong>GP18</strong> والسلك الآخر مع أقرب رجل أرضية، كما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118788" href="https://academy.hsoub.com/uploads/monthly_2023_02/crafted-switch-wiring.png.c20fc983ce1c870ad245aeea8a9e07e3.png" rel=""><img alt="توصيل مبدل يدوي أو زر مع لوحة بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="118788" data-ratio="134.50" data-unique="2s23uri69" style="width: 400px; height: auto;" width="400" src="https://academy.hsoub.com/uploads/monthly_2023_02/crafted-switch-wiring.thumb.png.9117aaefec4df17b57ae32b21b89a045.png"> </a>
</p>

<p>
	يمكنك أيضًا صنع قاطعة يدوية، كما تعلمنا في <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%85%D8%AD%D8%A7%D9%83%D8%A7%D8%A9-%D9%84%D9%85%D9%81%D8%B1%D9%82%D8%B9%D8%A7%D8%AA-%D8%A7%D9%84%D8%AD%D9%81%D9%84%D8%A7%D8%AA-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1861/" rel="">مشروع سابق</a>، وتوصيلها مع اللوحة وذلك بتوصيل النهاية الحرة للأسلاك مع الجزء الناقل من المبدّل مثل النحاس أو ورق القصدير.
</p>

<h4>
	توصيل عدة مبدلات يدوية أو أزرار مع لوحة بيكو
</h4>

<p>
	ستحتاج إلى سلكي توصيل نوع دبوس-مقبس لكل مبدّل تود توصيله مع لوحة بيكو.
</p>

<p>
	استخدم سلكي توصيل نوع دبوس- مقبس لتوصيل المبدّل الأول مع الرجل <strong>GP18</strong> ومع أقرب رجل أرضية <strong>GND</strong>، ثم صِل المبدّل الثاني مع الرجل <strong>GP22</strong> ومع أقرب رجل أرضية، والثالث مع الرجل <strong>GP28</strong> ورجل الأرضية بنفس الطريقة، كما هو موضح في المخطط التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118802" href="https://academy.hsoub.com/uploads/monthly_2023_02/multiple-crafted-switch-wiring.png.3f1b0527d4cdb8a3b208ec8554b91403.png" rel=""><img alt="توصيل عدة مبدلات يدوية أو أزرار مع لوحة بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="118802" data-ratio="134.50" data-unique="rnlz8wjb5" style="width: 400px; height: auto;" width="400" src="https://academy.hsoub.com/uploads/monthly_2023_02/multiple-crafted-switch-wiring.thumb.png.f73969a2bb712964541884411e66f723.png"> </a>
</p>

<h3>
	إسناد عناصر الدخل إلى أرجل معينة على اللوحة
</h3>

<p>
	علينا الآن إنشاء متغيرات لإسناد عناصر الدخل للأرجل الموصولة معها:
</p>

<h4>
	حالة زر واحد
</h4>

<p>
	استورد تابع الزر <code>Button</code> من مكتبة <code>picozero</code>، ثم استخدم الشيفرة التالية لإسناد الزر إلى الرجل الموصول معها على لوحة بيكو:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_104" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">

button </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Button</span><span class="pun">(</span><span class="lit">18</span><span class="pun">)</span></pre>

<h4>
	حالة عدة أزرار
</h4>

<p>
	استورد تابع الزر <code>Button</code> من مكتبة <code>picozero</code>، ثم استخدم الشيفرة التالية لإسناد عدة أزرار إلى الأرجل الموصولة معها على لوحة بيكو:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_106" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">

button_1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Button</span><span class="pun">(</span><span class="lit">18</span><span class="pun">)</span><span class="pln">
button_2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Button</span><span class="pun">(</span><span class="lit">22</span><span class="pun">)</span><span class="pln">
button_3 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Button</span><span class="pun">(</span><span class="lit">28</span><span class="pun">)</span></pre>

<p>
	ننصحك بتسمية المتغيرات بأسماء تدل على عملها، كأن تسمّي الزر المسؤول عن تشغيل المصباح الأحمر <code>red_button</code> أو أي اسم آخر تراه مناسبًا.
</p>

<h4>
	حالة مبدل واحد
</h4>

<p>
	استورد تابع المبدّل <code>Switch</code> من مكتبة <code>picozero</code>، ثم استخدم الشيفرة التالية لإسناد المبدّل إلى الرجل الموصولة معه على لوحة بيكو:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_108" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Switch</span><span class="pln">

switch </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Switch</span><span class="pun">(</span><span class="lit">18</span><span class="pun">)</span></pre>

<h4>
	حالة عدة مبدلات
</h4>

<p>
	استورد تابع المبدّل <code>Switch</code> من مكتبة <code>picozero</code>، ثم استخدم الشيفرة التالية لإسناد عدة مبدّلات إلى الأرجل الموصولة معها على لوحة بيكو:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_110" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Switch</span><span class="pln">

switch_1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Switch</span><span class="pun">(</span><span class="lit">18</span><span class="pun">)</span><span class="pln">
switch_2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Switch</span><span class="pun">(</span><span class="lit">22</span><span class="pun">)</span><span class="pln">
switch_3 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Switch</span><span class="pun">(</span><span class="lit">28</span><span class="pun">)</span></pre>

<p>
	ننصحك بتسمية المتغيرات بأسماء تدل على عملها، كأن تسمّي القاطعة المسؤولة عن تشغيل المصباح الأحمر <code>red_switch</code> أو أي اسم آخر تراه مناسبًا.
</p>

<h4>
	حالة مقاومة متغيرة
</h4>

<p>
	استورد تابع المقاومة المتغيرة <code>Pot</code> من مكتبة <code>picozero</code>، ثم استخدم الشيفرة التالية لإسناد المقاومة المتغيرة إلى الرجل الموصولة معها على لوحة بيكو:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_112" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Pot</span><span class="pln">

dial </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Pot</span><span class="pun">(</span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="com"># Connected to pin A0 (GP_26)</span></pre>

<h3>
	الشيفرة اللازمة لتشغيل عناصر الدخل
</h3>

<p>
	الآن، عليك استدعاء الدوال اللازمة لتشغيل عناصر الدخل:
</p>

<h4>
	تشغيل نغمة معينة عند الضغط على كل زر
</h4>

<p>
	يمكنك إضافة عدة أزرار يستدعي كل منها دالة صوتية مختلفة عند الضغط عليها، وذلك باستدعاء الدالة الموافقة عند الضغط على الزر عن طريق ذكر اسمها بدون استخدام الأقواس، كما في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_114" style=""><span class="pln">annoying_button</span><span class="pun">.</span><span class="pln">when_pressed </span><span class="pun">=</span><span class="pln"> annoying_sound
calming_button</span><span class="pun">.</span><span class="pln">when_pressed </span><span class="pun">=</span><span class="pln"> calming_sound
happy_button</span><span class="pun">.</span><span class="pln">when_pressed </span><span class="pun">=</span><span class="pln"> happy_sound</span></pre>

<p>
	تأكد من مطابقة أسماء الدوال في الشيفرة للدوال التي استخدمتها في مشروعك.
</p>

<h4>
	تشغيل النغمة التالية عند الضغط على الزر
</h4>

<p>
	عرّف متغيرًا ما، وليكن <code>option</code>، لتخزين النغمة الحالية فيه واستدعاء الدالة التالية، واحرص على مطابقة أسماء الدوال في الشيفرة للدوال التي استخدمتها في الفقرة السابقة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_116" style=""><span class="pln">option </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="com"># خزّن النغمة الحالية في هذا المتغير</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> choice</span><span class="pun">():</span><span class="pln"> </span><span class="com"># استدعي الدالة الصوتية التالية وعدّل قيمة متغير التخزين</span><span class="pln">
    </span><span class="kwd">global</span><span class="pln"> option
    </span><span class="kwd">if</span><span class="pln"> option </span><span class="pun">==</span><span class="pln"> </span><span class="lit">0</span><span class="pun">:</span><span class="pln">
        annoying_sound</span><span class="pun">()</span><span class="pln"> </span><span class="com"># دالة النغمة الأولى</span><span class="pln">
    </span><span class="kwd">elif</span><span class="pln"> option </span><span class="pun">==</span><span class="pln"> </span><span class="lit">1</span><span class="pun">:</span><span class="pln">
        calming_sound</span><span class="pun">()</span><span class="pln"> </span><span class="com"># دالة النغمة الثانية</span><span class="pln">
    </span><span class="kwd">elif</span><span class="pln"> option </span><span class="pun">==</span><span class="pln"> </span><span class="lit">2</span><span class="pun">:</span><span class="pln">
        happy_sound</span><span class="pun">()</span><span class="pln"> </span><span class="com"># دالة النغمة الثالثة</span><span class="pln">
    </span><span class="kwd">elif</span><span class="pln"> option </span><span class="pun">==</span><span class="pln"> </span><span class="lit">3</span><span class="pun">:</span><span class="pln">
        rgb</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln">

    </span><span class="com"># انتقل إلى الخيار الثاني</span><span class="pln">
    </span><span class="kwd">if</span><span class="pln"> option </span><span class="pun">==</span><span class="pln"> </span><span class="lit">3</span><span class="pun">:</span><span class="pln">
        option </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pln">
    </span><span class="kwd">else</span><span class="pun">:</span><span class="pln">
        option </span><span class="pun">=</span><span class="pln"> option </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pln">

button</span><span class="pun">.</span><span class="pln">when_pressed </span><span class="pun">=</span><span class="pln"> choice </span><span class="com"># نستدعي الدالة التالية عند الضغط على الزر</span></pre>

<h4>
	التحكم في سرعة عزف النغمة باستخدام المقاومة المتغيرة
</h4>

<p>
	استخدم الشيفرة التالية للتحكم في سرعة عزف النغمة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_118" style=""><span class="pln">BEAT </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0.4</span><span class="pln">

liten_mus </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">''</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'b5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'g5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'c6'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln">
              </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'f5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'d6'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a5'</span><span class="pun">,</span><span class="pln"> BEAT</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="str">'a#5'</span><span class="pun">,</span><span class="pln"> BEAT </span><span class="pun">*</span><span class="pln"> </span><span class="lit">1.5</span><span class="pun">]]</span><span class="pln">

</span><span class="kwd">for</span><span class="pln"> note </span><span class="kwd">in</span><span class="pln"> liten_mus</span><span class="pun">:</span><span class="pln">
        speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="pln">note</span><span class="pun">)</span><span class="pln">
        sleep</span><span class="pun">(</span><span class="pln">dial</span><span class="pun">.</span><span class="pln">value</span><span class="pun">)</span><span class="pln"> </span><span class="com"># ترك مدة قصيرة بين النغمات اعتمادًا على قيمة المقاومة المتغيرة</span></pre>

<p>
	أخيرًا، شغّل الشيفرة وتحقق من عملها، وتأكد أنه بإمكانك التبديل بين النغمات عند النقر على الأزرار أو المبدّلات، وتغيير سرعة عزف النغمة باستخدام المقاومة المتغيرة.
</p>

<h3>
	تصحيح الأخطاء
</h3>

<p>
	قبل التعرف على المشاكل التي قد تواجهك في هذه الخطوة وكيفية إصلاحها، عليك أولًا التحقق من سلامة لوحة بيكو، لذلك استخدم مصباح الليد الموجود على لوحة بيكو للتحقق من سلامة اللوحة، وذلك بجعل المصباح يومض عند تشغيل الشيفرة بإضافة الشيفرة التالية في ملف main.py:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4908_120" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> pico_led
</span><span class="kwd">from</span><span class="pln"> time </span><span class="kwd">import</span><span class="pln"> sleep

pico_led</span><span class="pun">.</span><span class="pln">on</span><span class="pun">()</span><span class="pln">
sleep</span><span class="pun">(</span><span class="lit">2</span><span class="pun">)</span><span class="pln">
pico_led</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span></pre>

<h4>
	تصحيح الأخطاء الموجودة في الشيفرة
</h4>

<ul>
	<li>
		تحقق من وجود أي رسائل خطأ في نافذة صدفة ثوني وتحقق من محتواها، إن وجدت.
	</li>
	<li>
		راجع الشيفرة التي كتبتها وتحقق من خلوها من الأخطاء، مثل نسيان علامة <strong>:</strong>، أو وجود مسافة بادئة دون الحاجة لها.
	</li>
	<li>
		تأكد من استيراد توابع العناصر التي ستستخدمها في مشروعك من مكتبة "picozero"، مثل تابع مصباح الليد <code>RGBLED</code> أو الزر <code>Button</code>.
	</li>
	<li>
		استخدم تعليمة الطباعة <code>print</code> لإضافة شرح مختصر عند كل خطوة، مثل <code>(البدء)print</code> أو <code>(ضبط المصباح على اللون الأخضر)print</code>.
	</li>
</ul>

<h4>
	لا تعمل بعض العناصر الإلكترونية كما يجب
</h4>

<ul>
	<li>
		تأكد أن جميع العناصر متصلة ببعضها جيدًا، وتحقق من ثبات نقاط توصيل الأسلاك مع اللوحة ومع العناصر.
	</li>
	<li>
		تأكد أن أرقام الأرجل المستخدمة في الشيفرة مطابقة لأرقام الأرجل الموصولة مع مصباح الليد، وتأكد من إعادة وصل الأرجل، في حال فصلتها عند العمل على تصميم شكل الآلة الموسيقية.
	</li>
	<li>
		تحقق من وصل العناصر وفق القطبية الصحيحة، إذ قد تحتوي بعض العناصر على قطب موجب <strong>+</strong> وآخر سالب <strong>-</strong>.
	</li>
	<li>
		في حال تحققت من جميع النقاط السابقة ولازالت آلتك لاتعمل، فجرب تبديل العناصر الإلكترونية بأخرى جديدة.
	</li>
</ul>

<h2>
	إعداد الهيكل الخارجي للآلة
</h2>

<p>
	سنعمل الآن على إعداد الهيكل الخارجي لآلتنا الموسيقية.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118817" href="https://academy.hsoub.com/uploads/monthly_2023_02/sound-board.png.9b372940d7969ceebec262564b5c25fd.png" rel=""><img alt="إعداد الهيكل الخارجي للآلة الموسيقية" class="ipsImage ipsImage_thumbnailed" data-fileid="118817" data-ratio="60.18" data-unique="8gy0onbjm" style="width: 550px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_02/sound-board.thumb.png.264ffe094fdf34c78237f2465435ee35.png"> </a>
</p>

<p>
	أولًا، إليك بعض الأسئلة لتساعدك في اعتماد التصميم الخارجي لآلتك:
</p>

<ul>
	<li>
		ما هي المواد التي تود استخدامها؟ هل جميعها متوفرة لديك؟
	</li>
	<li>
		هل تود استخدام أزرار أو مبدّلات يدوية؟ ما هو غرض عملها؟
	</li>
	<li>
		كيف ستثبت العناصر بحيث تكون متينة وسهلة الاستخدام؟
	</li>
</ul>

<p>
	<strong>معلومة:</strong> يختص مهندسو الصوت Acoustic engineers بدراسة علم الصوت وتوفير أفضل تجربة للحضور والمستمعين. الآن، مهندسنا الصغير، حان دورك لتصميم آلتك الموسيقية بحيث تصدر أصواتًا عالية الجودة وتوفر تجربة ممتعة.
</p>

<p>
	ثانيًا، جهّز المواد التي ستستخدمها لتنفيذ تصميمك. إليك بعض الاقتراحات:
</p>

<ul>
	<li>
		الورق المقوى.
	</li>
	<li>
		المواد البلاستيكية المعاد تدويرها.
	</li>
	<li>
		ألعاب قديمة أو قطع الليغو Lego.
	</li>
	<li>
		شريط لاصق.
	</li>
	<li>
		كما يمكنك استخدام الطابعة ثلاثية الأبعاد إن توفر لك ذلك.
	</li>
</ul>

<p>
	اطلب مساعدة أحد البالغين عند الحاجة لاستخدام المقص، أو مسدس السيليكون، أو سكين الحرف؛ واحرص على حفظ ملف الشيفرة، وتصغير نافذة ثوني عند البدء بتنفيذ التصميم؛ تجنبًا للنقر على لوحة المفاتيح والتعديل على الشيفرة دون قصد.
</p>

<p>
	ثالثًا، ابدأ بصنع المبدّلات اليدوية والأزرار التي تود استخدامها، إذ ستحتاج إلى استخدام مادة ناقلة مثل ورق القصدير لتكون بمثابة نقطة الأرض <strong>GND</strong> وتوصيل الأرجل ذات الأغراض العامة <strong>GP</strong> معها، إذ يمكن للوحة بيكو التحسس لحالة الأرجل فيما إذا كان متصلة أم لا.
</p>

<h3>
	إنشاء مبدل فوري يعمل عند الإسقاط
</h3>

<p>
	ستحتاج لإنشاء مبدّل فوري Drop switch إلى ما يلي:
</p>

<ul>
	<li>
		لوحة راسبيري بيكو.
	</li>
	<li>
		سلكي توصيل نوع دبوس-مقبس.
	</li>
	<li>
		ورق قصدير.
	</li>
	<li>
		شريط لاصق.
	</li>
</ul>

<p>
	أولًا، أنشئ شريطين من ورق القصدير، أو من أي مادة ناقلة.
</p>

<p>
	ثانيًا، ثبّت سلكي التوصيل مع شريطي القصدير باستخدام الشريط اللاصق، كما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpeg" data-fileid="118787" href="https://academy.hsoub.com/uploads/monthly_2023_02/connect-pins.jpeg.f42cf2d8375d5b91813bc0b5d45ca341.jpeg" rel=""><img alt="إنشاء مبدل فوري يعمل عند الإسقاط" class="ipsImage ipsImage_thumbnailed" data-fileid="118787" data-ratio="75.09" data-unique="dkypvcfo6" style="width: 550px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_02/connect-pins.thumb.jpeg.af1a0467d0632ec26793b546b707cf97.jpeg"> </a>
</p>

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

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpeg" data-fileid="118794" href="https://academy.hsoub.com/uploads/monthly_2023_02/foil-to-base.jpeg.80558870cb9585702e44809695a1a199.jpeg" rel=""><img alt="كيفية إنشاء مبدل فوري يعمل عند الإسقاط" class="ipsImage ipsImage_thumbnailed" data-fileid="118794" data-ratio="75.09" data-unique="pa58el0a8" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_02/foil-to-base.thumb.jpeg.e110d3dae407118527616f0245ce8c69.jpeg"> </a>
</p>

<p>
	رابعًا، صِل النهايات الحرة للسلكين مع لوحة بيكو وأسقط المجسم لإغلاق المبدّل.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="118790" href="https://academy.hsoub.com/uploads/monthly_2023_02/drop-switch.gif.e888a18d05ea31245dee7f8af53c7991.gif" rel=""><img alt="طريقة إنشاء مبدل فوري يعمل عند الإسقاط" class="ipsImage ipsImage_thumbnailed" data-fileid="118790" data-ratio="56.36" data-unique="apa24p5bf" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_02/drop-switch.gif.e888a18d05ea31245dee7f8af53c7991.gif"> </a>
</p>

<h3>
	إنشاء مبدل يدوي يعمل عند السحب
</h3>

<p>
	إليك ما سنحتاج إليه:
</p>

<ul>
	<li>
		مقص.
	</li>
	<li>
		ورق مقوى.
	</li>
	<li>
		رقائق القصدير.
	</li>
	<li>
		غراء وشريط لاصق.
	</li>
	<li>
		شرائط ملونة وورق ملون.
	</li>
	<li>
		قلم رصاص ومسطرة (اختياري).
	</li>
</ul>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpeg" data-fileid="118824" href="https://academy.hsoub.com/uploads/monthly_2023_02/switch-gather-materials.jpeg.b9e5720a15f11994f77b2bbc01a66604.jpeg" rel=""><img alt="إنشاء مبدل يدوي يعمل عند السحب" class="ipsImage ipsImage_thumbnailed" data-fileid="118824" data-ratio="75.09" data-unique="611i5aexo" style="width: 550px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2023_02/switch-gather-materials.thumb.jpeg.37aa50175948f92fcbf3f4188e07d5b6.jpeg"></a>
</p>

<p>
	أولًا، قُصَّ الورق المقوى إلى ثلاثة مستطيلات متساوية الحجم.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118832" href="https://academy.hsoub.com/uploads/monthly_2023_02/three-rectangles.jpg.b2cbcce8a997f773c681bf42bfe4cf5d.jpg" rel=""><img alt="الخطوة 1 لإنشاء مبدل يدوي يعمل عند السحب" class="ipsImage ipsImage_thumbnailed" data-fileid="118832" data-ratio="68.91" data-unique="2pbbsb0je" style="width: 550px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2023_02/three-rectangles.thumb.jpg.1c52fe027298c268e3c06627b0ea8db4.jpg"></a>
</p>

<p>
	ثانيًا، قُصَّ مستطيلًا صغيرًا في منتصف المستطيل الأول، واحتفظ به لاستخدامه لاحقًا.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118786" href="https://academy.hsoub.com/uploads/monthly_2023_02/centre-cut.jpg.ad90f65c1af2724852f2aae8668391b1.jpg" rel=""><img alt="الخطوة 2 لإنشاء مبدل يدوي يعمل عند السحب" class="ipsImage ipsImage_thumbnailed" data-fileid="118786" data-ratio="91.64" data-unique="uakngo3i3" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_02/centre-cut.thumb.jpg.5addcd275fd120f4d3db6740fc3f1341.jpg"> </a>
</p>

<p>
	ثالثًا، قُصَّ قطعًا من ورق القصدير بحجم المستطيلات الكبيرة، ثم الصقها عليها باستخدام الغراء، واحرص على عدم وضع الغراء على الوجه الخارجي لورق القصدير حتى لا تتأثر التوصيلات لاحقًا.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118783" href="https://academy.hsoub.com/uploads/monthly_2023_02/add-foil.jpg.61d274ebf462c545d18072adfefbabe2.jpg" rel=""><img alt="الخطوة 3 لإنشاء مبدل يدوي يعمل عند السحب" class="ipsImage ipsImage_thumbnailed" data-fileid="118783" data-ratio="101.09" data-unique="lklcaiph4" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_02/add-foil.thumb.jpg.1fd6324bbc55643b7642d998751d1949.jpg"> </a>
</p>

<p>
	رابعًا، قُصَّ أطراف المستطيل الصغير للحصول على شكل مدبب أو بشكل حرف V، ثم قلّم الأطراف بمقدار بضع ملميترات كي يتسع المستطيل الصغير في الفتحة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118834" href="https://academy.hsoub.com/uploads/monthly_2023_02/trim-piece.jpg.2105b5f8ae137a54006fd7e8e545baa2.jpg" rel=""><img alt="الخطوة 4 لإنشاء مبدل يدوي يعمل عند السحب" class="ipsImage ipsImage_thumbnailed" data-fileid="118834" data-ratio="79.64" data-unique="ptd4cz3uu" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_02/trim-piece.thumb.jpg.949c8f27d976b011354777f0889503ec.jpg"> </a>
</p>

<p>
	خامسًا، غلّف كامل المستطيل الصغير بورق القصدير، واحرص على استخدام ورقة قصدير واحدة، إذ ستسمح هذه القطعة بمرور التيار عند إغلاق المبدّل.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="118793" href="https://academy.hsoub.com/uploads/monthly_2023_02/foil-cover.gif.7335f9ac105affb71604d1e45b06d840.gif" rel=""><img alt="الخطوة 5 لإنشاء مبدل يدوي يعمل عند السحب" class="ipsImage ipsImage_thumbnailed" data-fileid="118793" data-ratio="56.36" data-unique="8wpd3cdjc" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_02/foil-cover.gif.7335f9ac105affb71604d1e45b06d840.gif"> </a>
</p>

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

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118806" href="https://academy.hsoub.com/uploads/monthly_2023_02/pin-sticky-tape-1.jpg.9c42bcc52a76c34a6917bb4684d27f00.jpg" rel=""><img alt="الخطوة 6 لإنشاء مبدل يدوي يعمل عند السحب" class="ipsImage ipsImage_thumbnailed" data-fileid="118806" data-ratio="129.67" data-unique="b9yl9wnpg" style="width: 273px; height: auto;" width="250" src="https://academy.hsoub.com/uploads/monthly_2023_02/pin-sticky-tape-1.jpg.9c42bcc52a76c34a6917bb4684d27f00.jpg"> </a>
</p>

<p>
	سابعًا، أضف مزيدًا من الشريط اللاصق لتثبيت السلك ومنع انفكاكه عن طريق الخطأ.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118807" href="https://academy.hsoub.com/uploads/monthly_2023_02/pin-sticky-tape-2.jpg.12e2bcd3e26a6b33bf609d787e9ce409.jpg" rel=""><img alt="الخطوة 7 لإنشاء مبدل يدوي يعمل عند السحب" class="ipsImage ipsImage_thumbnailed" data-fileid="118807" data-ratio="100.73" data-unique="midrupt3l" style="width: 274px; height: auto;" width="274" src="https://academy.hsoub.com/uploads/monthly_2023_02/pin-sticky-tape-2.jpg.12e2bcd3e26a6b33bf609d787e9ce409.jpg"> </a>
</p>

<p>
	ثامنًا، ادهن بعض الغراء على المستطيل الذي فرّغنا منتصفه (الموجود في يسار الصورة) والصقه مع المستطيل المغطى بالقصدير (يمين الصورة). واحرص على ألا تتلامس طبقتي القصدير الموجودتين على حواف المستطيلات، وقُصّها إن لزم الأمر.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118795" href="https://academy.hsoub.com/uploads/monthly_2023_02/glue-left.jpg.6c05782bb554ba8c47d9e9097fdeb286.jpg" rel=""><img alt="الخطوة 8 لإنشاء مبدل يدوي يعمل عند السحب" class="ipsImage ipsImage_thumbnailed" data-fileid="118795" data-ratio="90.36" data-unique="0s84neuda" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_02/glue-left.thumb.jpg.7c717d16fc9b5787bfa9fe7b7cfd9dc0.jpg"> </a>
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118796" href="https://academy.hsoub.com/uploads/monthly_2023_02/glue-right.jpg.491fd075a32bbf23b1b333cbf96f3867.jpg" rel=""><img alt="الخطوة 9 لإنشاء مبدل يدوي يعمل عند السحب" class="ipsImage ipsImage_thumbnailed" data-fileid="118796" data-ratio="91.27" data-unique="7u05khjsh" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_02/glue-right.thumb.jpg.5541be244fde366e940779571f3d4128.jpg"> </a>
</p>

<p>
	أصبح المبدّل جاهزًا للاستخدام في مشروعك.
</p>

<h3>
	استخدام سكين الحرف
</h3>

<p>
	تُعد سكاكين الحرف Crafts مفيدةً عند صنع الحرف اليدوية، لكن يجب أن تكون حذرًا جدًا عند استخدامها لأنها حادةً جدًا ويمكن أن تسبب جروحًا وإصابات. احرص على وجود شخص بالغ عند استخدامك للسكاكين، أو اطلب منه استخدامها عوضًا عنك، كما ننصحك باستخدام لوح القص لحماية الأسطح، أو باستخدام لوح التقطيع الخشبي المتوفر في كل المطابخ.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118784" href="https://academy.hsoub.com/uploads/monthly_2023_02/Box-cutter.jpg.7f23ceab6531f0f4c5ec83e70545ae69.jpg" rel=""><img alt="استخدام سكين الحرف" class="ipsImage ipsImage_thumbnailed" data-fileid="118784" data-ratio="57.33" data-unique="sg97p3ap4" style="width: 450px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_02/Box-cutter.thumb.jpg.b71ef54a703433ea767f747fb4d9accc.jpg"> </a>
</p>

<p>
	ننصحك بتدوين أرقام الأرجل التي استخدمتها والعناصر الموصولة معها، إذ سيساعدك ذلك في إعادة توصيل العناصر بعد فصلها.
</p>

<p>
	ستجد الأرجل المستخدمة في بداية الشيفرة.
</p>

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

<h3>
	توصيل الأسلاك ببعضها
</h3>

<p>
	قد تحتاج إلى أسلاك توصيل طويلة جدًا لتوصيل مصابيح الليد مع أرجل لوحة بيكو، أو يمكنك وصل الأسلاك ببعضها للحصول على سلك طويل، وذلك عبر توصيل سلك ذو نهايات دبوس-مقبس مع سلك ذو نهايات مقبس-مقبس للحصول على سلك مقبس-مقبس طويل جدًا، وتدعى هذه الطريقة بسلسلة الأقحوان daisy chaining.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118789" href="https://academy.hsoub.com/uploads/monthly_2023_02/daisy-chain.jpg.94078dbcabfde16c29b963a099b8112d.jpg" rel=""><img alt="توصيل الأسلاك ببعضها" class="ipsImage ipsImage_thumbnailed" data-fileid="118789" data-ratio="63.27" data-unique="duuz49za7" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_02/daisy-chain.thumb.jpg.2f75a1ccd422950f963565ed5126acd3.jpg"> </a>
</p>

<p>
	ننصحك باستخدام سلكين لهما اللون نفسه ليسهل تتبع السلك ومعرفة العنصر الموصول معه.
</p>

<p>
	تكمن مشكلة هذه الطريقة في أن الأسلاك قد تنفصل عن بعضها، ولذلك ينصح بلصقها بقطعة صغيرة من الشريط اللاصق.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118825" href="https://academy.hsoub.com/uploads/monthly_2023_02/tape-daisy-chain.jpg.e494e8096e225b52132ee1871eef56dc.jpg" rel=""><img alt="طريقة توصيل الأسلاك ببعضها" class="ipsImage ipsImage_thumbnailed" data-fileid="118825" data-ratio="41.45" data-unique="fhq9921yq" style="width: 550px; height: 228px;" width="650" src="https://academy.hsoub.com/uploads/monthly_2023_02/tape-daisy-chain.thumb.jpg.b731bb14756b95531f7ec6768c3d0d1b.jpg"> </a>
</p>

<h3>
	تثبيت العناصر داخل الورق المقوى أو البلاستيك
</h3>

<p>
	يمكنك تثبيت مصابيح الليد أو الأجراس أو المقاومات المتغيرة داخل قطع من الورق المقوى أو البلاستيك، وذلك بصنع ثقوب وإدخال العناصر وأسلاك التوصيل فيها، كما هو موضح:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118812" href="https://academy.hsoub.com/uploads/monthly_2023_02/pre-soldered-mount.jpg.1a82ca59f70618a24314b89408ab3313.jpg" rel=""><img alt="تثبيت العناصر داخل الورق المقوى أو البلاستيك" class="ipsImage ipsImage_thumbnailed" data-fileid="118812" data-ratio="127.00" data-unique="6880lwcen" style="width: 400px; height: auto;" width="472" src="https://academy.hsoub.com/uploads/monthly_2023_02/pre-soldered-mount.thumb.jpg.09bbc874d6fd8e3060dd62e294338b2c.jpg"></a>
</p>

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

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118803" href="https://academy.hsoub.com/uploads/monthly_2023_02/non-soldered-mount.jpg.22a2beed3ddf0445ef0b3833ea103215.jpg" rel=""><img alt="ميفية تثبيت العناصر داخل الورق المقوى أو البلاستيك" class="ipsImage ipsImage_thumbnailed" data-fileid="118803" data-ratio="94.00" data-unique="33h9d4zcr" style="width: 450px; height: auto;" width="638" src="https://academy.hsoub.com/uploads/monthly_2023_02/non-soldered-mount.thumb.jpg.eb90ff980d171d174051a05ddc47a412.jpg"></a>
</p>

<p>
	استخدم الشريط اللاصق لتثبيت العناصر في مكانها.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118827" href="https://academy.hsoub.com/uploads/monthly_2023_02/taped-mount.jpg.f5c5653128ec491d01e29c05e745365f.jpg" rel=""><img alt="تثبيت العناصر مع أسلاك التوصيل" class="ipsImage ipsImage_thumbnailed" data-fileid="118827" data-ratio="97.11" data-unique="a7oukowbm" style="width: 450px; height: auto;" width="618" src="https://academy.hsoub.com/uploads/monthly_2023_02/taped-mount.thumb.jpg.0d8ba7d5e1e35a874d7b805e8fd4b5a4.jpg"></a>
</p>

<p>
	كما يمكنك تثبيت العناصر مع أسلاك التوصيل، أو تثبيتها في مكانها باستخدام الشريط اللاصق، وإزالة الشريط اللاصق بكل سهولة لإعادة استخدام العناصر فيما بعد.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118828" href="https://academy.hsoub.com/uploads/monthly_2023_02/taped-wires.jpg.cf94ab68acd7e3e39d3abbfcf0a6fd99.jpg" rel=""><img alt="تثبيت العناصر مع أسلاك التوصيل" class="ipsImage ipsImage_thumbnailed" data-fileid="118828" data-ratio="49.64" data-unique="c2kulm488" style="width: 550px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2023_02/taped-wires.thumb.jpg.bfb8a83b1df45a96af0df7e72403e8f6.jpg"></a>
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118826" href="https://academy.hsoub.com/uploads/monthly_2023_02/taped-component.jpg.a9b0da9ee6e7580c9e9c243c25f0951b.jpg" rel=""><img alt="كيفية تثبيت العناصر مع أسلاك التوصيل" class="ipsImage ipsImage_thumbnailed" data-fileid="118826" data-ratio="68.55" data-unique="ar2y93971" style="width: 550px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2023_02/taped-component.thumb.jpg.7face2bbd1abfca262ae043c0f0d2b98.jpg"></a>
</p>

<p>
	خامسًا، الآن بعد أن انتهيت من تنفيذ الهيكل الخارجي، عليك تشغيل الآلة والتحقق أنها تعمل كما ينبغي.
</p>

<h3>
	تصحيح الأخطاء
</h3>

<p>
	إليك بعض المشاكل التي قد تواجهك في هذه الخطوة وكيفية إصلاحها:
</p>

<h4>
	طول الأسلاك غير مناسب
</h4>

<p>
	إذا وجدت أن الأسلاك التي استخدمتها لا تفي بالغرض المطلوب بسبب قصر طولها، فما عليك إلا زيادة طولها، وفقًا لما تعلمناه في فقرة توصيل الأسلاك ببعضها.
</p>

<h4>
	لا تثبُت الأسلاك والعناصر في مكانها
</h4>

<p>
	قد تكون بعض التوصيلات أمتن من غيرها، لذا ننصحك باستخدام الشريط اللاصق لإحكام تثبيت الأسلاك.
</p>

<h2>
	ترقية المشروع
</h2>

<p>
	يمكنك ترقية مشروعك حين يتسنى لك ذلك. فكّر في المناسبات التي يمكنك استخدام آلتك الموسيقية فيها؟ مثل إنشاء مقاطع موسيقية لفيديو ما، أو عزف لحن هادئ عندما تحتاج إلى الاسترخاء، أو إزعاج أصدقائك بنغمة حادة ذات إيقاع سريع.
</p>

<p>
	إليك بعض الاقتراحات:
</p>

<ul>
	<li>
		اختبر أداء الآلة أمام جمهورك، ثم حدّد النقاط التي عليك تحسينها.
	</li>
	<li>
		أضف مزيدًا من الأزرار وعناصر التحكم مثل المقاومات المتغيرة والمبدّلات.
	</li>
	<li>
		أضف مزيدًا من البريق على آلتك باستخدام مصابيح الليد.
	</li>
	<li>
		أضف مزيدًا من التحسينات على الهيكل الخارجي لآلتك.
	</li>
</ul>

<p>
	إليك المشروع التالي
</p>

<div class="ipsEmbeddedVideo" contenteditable="false">
	   
	<div>
		       <iframe allowfullscreen="" frameborder="0" height="506" src="https://player.vimeo.com/video/795266155?autoplay=0&amp;color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="900"></iframe>    
	</div>
</div>

<p>
	إذ تتغير النغمة ولون مصباح الليد وفقًا للأزرار، كما يمكنك الاطلاع على المشاريع التي زودناك بها في مقدمة المقال لتستلهم منها بعض الأفكار، أو الاطلاع على <a href="https://wakelet.com/wake/4yPPfjM9lNSfVgGjEvCoH" rel="external nofollow">معرض مشاريع الآلات الموسيقية</a>.
</p>

<h2>
	الخاتمة
</h2>

<p>
	تهانينا، فقد أتممت مشروع تصميم وتنفيذ آلة موسيقية باستخدام لوحة راسبيري باي بيكو.
</p>

<p>
	ننصحك بتنفيذ مشروع تصميم وتنفيذ لعبة حسية تفاعلية باستخدام لوحة راسبيري باي بيكو ومقاومة متغيرة في خطوتك التالية.
</p>

<p>
	إذا واجهت مشاكلًا عند تنفيذ هذا المشروع، فيمكنك الحصول على الدعم والمساعدة عبر إضافة سؤالك في قسم الأسئلة والأجوبة في <a href="https://academy.hsoub.com/questions/" rel="">أكاديمية حسوب</a>.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://projects.raspberrypi.org/en/projects/sound-machine/" rel="external nofollow">Sound machine</a> من الموقع الرسمي لراسبيري باي.
</p>

<p>
	الملف المرفق للمشروع: <a data-fileext="zip" data-fileid="118836" href="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=118836&amp;key=7109b5e65c562a86c657eb901b18c01f" rel="">codes.zip.</a>
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%B5%D9%86%D8%B9-%D8%AC%D9%87%D8%A7%D8%B2-%D9%84%D8%B9%D8%B1%D8%B6-%D8%A7%D9%84%D8%AD%D8%A7%D9%84%D8%A9-%D8%A7%D9%84%D9%85%D8%B2%D8%A7%D8%AC%D9%8A%D8%A9-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1893/" rel="">صنع جهاز لعرض الحالة المزاجية باستخدام لوحة راسبيري باي بيكو</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%B5%D9%86%D8%B9-%D9%82%D9%84%D8%A8-%D9%86%D8%A7%D8%A8%D8%B6-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1862/" rel="">صنع قلب نابض باستخدام لوحة راسبيري باي بيكو</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%85%D8%AD%D8%A7%D9%83%D8%A7%D8%A9-%D9%84%D9%85%D9%81%D8%B1%D9%82%D8%B9%D8%A7%D8%AA-%D8%A7%D9%84%D8%AD%D9%81%D9%84%D8%A7%D8%AA-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1861/" rel="">تصميم محاكاة لمفرقعات الحفلات باستخدام لوحة راسبيري باي بيكو</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1910</guid><pubDate>Fri, 17 Feb 2023 18:04:00 +0000</pubDate></item><item><title>&#x635;&#x646;&#x639; &#x62C;&#x647;&#x627;&#x632; &#x644;&#x639;&#x631;&#x636; &#x627;&#x644;&#x62D;&#x627;&#x644;&#x629; &#x627;&#x644;&#x645;&#x632;&#x627;&#x62C;&#x64A;&#x629; &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x644;&#x648;&#x62D;&#x629; &#x631;&#x627;&#x633;&#x628;&#x64A;&#x631;&#x64A; &#x628;&#x627;&#x64A; &#x628;&#x64A;&#x643;&#x648;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D8%B5%D9%86%D8%B9-%D8%AC%D9%87%D8%A7%D8%B2-%D9%84%D8%B9%D8%B1%D8%B6-%D8%A7%D9%84%D8%AD%D8%A7%D9%84%D8%A9-%D8%A7%D9%84%D9%85%D8%B2%D8%A7%D8%AC%D9%8A%D8%A9-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1893/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2023_02/1271778621_----------.jpg.e98f7d1cfebc54bbb1d08592898e32e2.jpg" /></p>
<p>
	ستتعلم في هذا المقال كيفية تصميم وإنشاء جهاز للتعبير عن مشاعرك باستخدام مصابيح الليد، بحيث تحصل على نتيجة مشابهة لما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="118394" href="https://academy.hsoub.com/uploads/monthly_2023_02/mood-lamp.gif.ecfd792be8adc8622232cb6682428e2a.gif" rel=""><img alt="جهاز لعرض الحالة المزاجية باستخدام لوحة راسبيري باي بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="118394" data-ratio="65.38" data-unique="g5thfr588" style="width: 517px; height: auto;" width="517" src="https://academy.hsoub.com/uploads/monthly_2023_02/mood-lamp.gif.ecfd792be8adc8622232cb6682428e2a.gif"> </a>
</p>

<p>
	تمعن في الصورة المتحركة أعلاه وحاول معرفة كيف يعمل هذا المصباح التفاعلي، لاحظ كيف تُستَخدم الإضاءة المختلفة للتعبير عن المشاعر، وكيف يغير المستخدم لون الإضاءة. كما يمكنك الاطلاع على الشيفرة اللازمة لتنفيذ هذا المشروع من <a data-fileext="zip" data-fileid="118414" href="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=118414&amp;key=52cbf0aa58a37e1365c66ddd1006bf37" rel="">code.zip</a>.
</p>

<p>
	<strong>معلومة:</strong> يُعد الاهتمام بالمزاج والأحاسيس إحدى وسائل العناية بالصحة؛ إذ من الطبيعي الشعور بالحزن أو السعادة، أو الحماس. أعطِ كل شعور حقه، ودوّن مشاعرك وأخبر الآخرين حولك إذا احتجت ذلك، وهذا ما يُعرف بعملية التحقق من الحالة المزاجية Mood check-in.
</p>

<p>
	ستتعلم في هذا المشروع ما يلي:
</p>

<ul>
	<li>
		كيفية التعبير عن المشاعر باستخدام الأضواء.
	</li>
	<li>
		استخدام عناصر دخل إلكترونية لتمكين المستخدمين من التعبير عن مشاعرهم.
	</li>
	<li>
		كتابة الشيفرة اللازمة للتحكم بإضاءة مصابيح الليد وخلق تأثيرات مختلفة.
	</li>
</ul>

<h2>
	متطلبات المشروع
</h2>

<h3>
	عتاد
</h3>

<ol>
	<li>
		لوحة حاسوب راسبيري باي بيكو Raspberry Pi Pico مع أرجل مثبتة عليها.
	</li>
	<li>
		كبل USB لنقل البيانات ذو نهايات من النوع USB A و micro USB.
	</li>
	<li>
		مقاومات متغيرة potentiometer وأزرار buttons.
	</li>
	<li>
		مصباح ليد متعدد الألوان RGB LED ذو مهبط مشترك Common cathode أو مصباح ليد وحيد اللون.
	</li>
	<li>
		أسلاك توصيل ومقاومات عادية resistors.
	</li>
	<li>
		بعض مستلزمات الأشغال اليدوية، مثل الورق المقوى، ورقائق القصدير، وشريط لاصق.
	</li>
</ol>

<h3>
	برمجيات
</h3>

<ul>
	<li>
		برنامج ثوني Thonny: وهو البيئة البرمجية التي سنستخدمها لكتابة الشيفرة <a href="https://academy.hsoub.com/programming/python/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D9%84%D8%BA%D8%A9-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A9-r211/" rel="">بلغة بايثون</a>.
	</li>
</ul>

<h4>
	تثبيت برنامج ثوني على نظام تشغيل راسبيري باي
</h4>

<p>
	يأتي برنامج ثوني مثبتًا مع نظام تشغيل <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%AC%D9%87%D8%A7%D8%B2-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-raspberry-pi-r1356/" rel="">راسبيري باي</a>، المعروف سابقًا براسبيان Raspbian، لكن قد تحتاج إلى تحديثه. انقر على الأيقونة في الزاوية العلوية اليسرى من الشاشة لفتح نافذة الطرفية Terminal، أو اضغط المفاتيح التالية معًا <strong>Ctrl+Alt+T</strong>. ثم اكتب الأمر التالي لتحديث <a href="https://academy.hsoub.com/files/24-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%84%D9%85%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D9%86/" rel="">نظام التشغيل</a> وبرنامج ثوني:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_13" style=""><span class="pln">sudo apt update </span><span class="pun">&amp;&amp;</span><span class="pln"> sudo apt upgrade </span><span class="pun">-</span><span class="pln">y</span></pre>

<h4>
	تثبيت برنامج ثوني على أنظمة التشغيل الأخرى
</h4>

<p>
	يمكنك تثبيت ثوني على الحواسيب العاملة <a href="https://academy.hsoub.com/devops/linux/%D9%85%D8%A7-%D9%87%D9%88-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%8A%D9%86%D9%83%D8%B3%D8%9F-r451/" rel="">بنظام تشغيل لينكس</a>، أو ويندوز، أو ماك، وذلك من الموقع الرسمي <a href="https://thonny.org/" rel="external nofollow">thonny.org</a>. انقر على رابط التنزيل الموافق لنظام تشغيل حاسوبك من الزاوية العلوية اليمنى في الموقع، ثم انقر على الملفات بعد تنزيلها، وقد تظهر لك الرسالة التالية على نظام ويندوز:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118412" href="https://academy.hsoub.com/uploads/monthly_2023_02/thonny-site.png.37b1b44dc32ea753ae46937d13518940.png" rel=""><img alt="تثبيت برنامج ثوني على أنظمة التشغيل الأخرى" class="ipsImage ipsImage_thumbnailed" data-fileid="118412" data-ratio="67.34" data-unique="by05a4nxz" style="width: 297px; height: auto;" width="297" src="https://academy.hsoub.com/uploads/monthly_2023_02/thonny-site.png.37b1b44dc32ea753ae46937d13518940.png"> </a>
</p>

<p>
	انقر على خيار المزيد من المعلومات "More info" ثم على التشغيل على أي حال "Run anyway".
</p>

<h4>
	التعرف على واجهة برنامج ثوني
</h4>

<p>
	ستظهر لك الواجهة التالية عند فتح ثوني:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118411" href="https://academy.hsoub.com/uploads/monthly_2023_02/thonny-editor.png.94daf108d93d0cc3edd72dccd24ca23c.png" rel=""><img alt="التعرف على واجهة برنامج ثوني" class="ipsImage ipsImage_thumbnailed" data-fileid="118411" data-ratio="73.00" data-unique="c7pc6w969" style="width: 700px; height: auto;" width="700" src="https://academy.hsoub.com/uploads/monthly_2023_02/thonny-editor.thumb.png.70ce15d9ca4f741b37700c692015c1b1.png"> </a>
</p>

<p>
	يمكنك الكتابة <a href="https://academy.hsoub.com/programming/python/%D8%A7%D9%84%D9%85%D8%B1%D8%AC%D8%B9-%D8%A7%D9%84%D8%B4%D8%A7%D9%85%D9%84-%D8%A5%D9%84%D9%89-%D8%AA%D8%B9%D9%84%D9%85-%D9%84%D8%BA%D8%A9-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-r735/" rel="">بلغة بايثون</a> في النافذة الرئيسية الكبيرة، ثم النقر على زر التشغيل الأخضر <strong>Run</strong> للتنفيذ، ستظهر لك رسالة لحفظ الملف قبل تشغيله.
</p>

<p>
	اكتب الأمر التالي وشغّله:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_19" style=""><span class="kwd">print</span><span class="pun">(</span><span class="str">'Hello World!'</span><span class="pun">)</span></pre>

<h4>
	تغيير السمة والخط
</h4>

<p>
	يمكنك التحكم بلون الخط وحجمه وتغيير السمة المُستخدمة في واجهة البرنامج، وذلك بالنقر على قائمة الأدوات <strong>Tools</strong> من الشريط أعلى الشاشة، ثم النقر على خيارات <strong>Options</strong>. انقر بعدها على نافذة الخط والسمة <strong>Theme &amp; Font</strong> واختر نوع الخط والسمة التي تفضلها من النافذة المنسدلة ثم انقر على زر موافق <strong>OK</strong> عند الانتهاء.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118410" href="https://academy.hsoub.com/uploads/monthly_2023_02/theme-tab.png.5c4889867a036106a748efe3f1643041.png" rel=""><img alt="تغيير السمة والخط في برنامج ثوني" class="ipsImage ipsImage_thumbnailed" data-fileid="118410" data-ratio="77.11" data-unique="lurzo8v12" style="width: 450px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_02/theme-tab.png.5c4889867a036106a748efe3f1643041.png"> </a>
</p>

<p>
	ننصحك باختيار الخطوط البسيطة الواضحة والابتعاد عن الخطوط المزخرفة أو المشابهة لخط اليد لأنه قد تجعل القراءة أصعب.
</p>

<ul>
	<li>
		إعداد مكتبة picozero سنعمل في هذه الخطوة على إعداد مكتبة picozero وتوصيل لوحة راسبيري باي بيكو وإعداد برنامج مايكرو بايثون.
	</li>
</ul>

<p>
	أولًا، صِل الطرف الصغير لكبل USB إلى لوحة راسبيري باي والطرف الآخر إلى حاسوبك لتتمكن من برمجة اللوحة عن طريقه.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118399" href="https://academy.hsoub.com/uploads/monthly_2023_02/pico-top-plug.png.3cf13bbc0a109a6c0a6f3ffd68409aab.png" rel=""><img alt="وصل لوحة راسبيري باي بكابل USB" class="ipsImage ipsImage_thumbnailed" data-fileid="118399" data-ratio="93.14" data-unique="3jj00u0tu" style="width: 204px; height: auto;" width="204" src="https://academy.hsoub.com/uploads/monthly_2023_02/pico-top-plug.png.3cf13bbc0a109a6c0a6f3ffd68409aab.png"> </a>
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118400" href="https://academy.hsoub.com/uploads/monthly_2023_02/plug-in-pico.png.700622b687a576a977d33298541e2eed.png" rel=""><img alt="وصل لوحة راسبيري باي بالحاسوب" class="ipsImage ipsImage_thumbnailed" data-fileid="118400" data-ratio="81.00" data-unique="7958dvf4n" style="width: 300px; height: auto;" width="300" src="https://academy.hsoub.com/uploads/monthly_2023_02/plug-in-pico.png.700622b687a576a977d33298541e2eed.png"> </a>
</p>

<p>
	ثانيًا، افتح محرر ثوني، ولاحظ ما هو الإصدار المستخدم من بايثون بقراءة النص الموجود في الزاوية السفلية اليمنى من الشاشة، انقر على النص واختر "MicroPython (Raspberry Pi Pico)‎"، إذا لم يكن هذا الخيار محددًا. سيطالبك ثوني بتثبيت برنامج MicroPython على حاسوب راسبيري باي بيكو إذا لم تستخدمه مسبقًا، فقط انقر على زر التثبيت <strong>Install</strong>.
</p>

<p>
	ثالثًا، أضف حزمة بيكو زيرو picozero من خلال النقر على قائمة الأدوات <strong>Tools</strong> من شريط القوائم في برنامج ثوني، ثم النقر على خيار إدارة الحزم <strong>Manage Packages</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118413" href="https://academy.hsoub.com/uploads/monthly_2023_02/tools-manage-packages.png.e5268a9f19ff20194396e22277025b64.png" rel=""><img alt="خيار إدارة الحزم Manage Packages في برنامج ثوني" class="ipsImage ipsImage_thumbnailed" data-fileid="118413" data-ratio="87.12" data-unique="aj3d66cjs" style="width: 233px; height: auto;" width="233" src="https://academy.hsoub.com/uploads/monthly_2023_02/tools-manage-packages.png.e5268a9f19ff20194396e22277025b64.png"> </a>
</p>

<p>
	ثالثًا، اكتب "picozero"، ثم انقر على زر البحث <strong>Search on PyPi</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118407" href="https://academy.hsoub.com/uploads/monthly_2023_02/search-picozero.png.0ae80b789298f8f1c5d5af0e9a7b9065.png" rel=""><img alt="البحث في PyPi" class="ipsImage ipsImage_thumbnailed" data-fileid="118407" data-ratio="94.44" data-unique="na2ust1m9" style="width: 324px; height: auto;" width="324" src="https://academy.hsoub.com/uploads/monthly_2023_02/search-picozero.png.0ae80b789298f8f1c5d5af0e9a7b9065.png"> </a>
</p>

<p>
	رابعًا، انقر على <strong>picozero</strong> من نتائج البحث ثم انقر على زر التثبيت <strong>Install</strong>.
</p>

<h3>
	استلهم أفكارك
</h3>

<p>
	اطلع على المشاريع التالية واستلهم منها بعض الأفكار:
</p>

<h4>
	مشروع البطاقات التعبيرية
</h4>

<p>
	لاحظ كيف غلفنا بطاقات ذات أحجام مختلفة بورق القصدير وكتبنا الحالة المزاجية عليها، وعند وضع البطاقات داخل الصندوق تُغلَق الدارة ويضيء المصباح باللون الموافق للبطاقة. لدينا ثلاث بطاقات، واحدة للتعبير عن الشعور بالسعادة، والثانية عن الحزن، والثالثة عن الغضب.
</p>

<p style="text-align: center;">
	<img alt="مشروع البطاقات التعبيرية" class="ipsImage ipsImage_thumbnailed" data-fileid="118415" data-ratio="47.00" data-unique="qganrt231" style="width: 600px; height: 282px;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_02/drop-switch.gif.60d9847aa6e068d8cd28dce711a44b89.gif">
</p>

<p>
	يمكنك الاطلاع على الشيفرة اللازمة لتنفيذ هذا المشروع باسم drop_switch.py ضمن الملف المرفق <a data-fileext="zip" data-fileid="118414" href="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=118414&amp;key=52cbf0aa58a37e1365c66ddd1006bf37" rel="">code.zip</a>.
</p>

<h4>
	مشروع أيقونة الحالة المزاجية
</h4>

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

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="118393" href="https://academy.hsoub.com/uploads/monthly_2023_02/mood-dial.gif.c242eb0e954f24768e2788921a70411d.gif" rel=""><img alt="مشروع أيقونة الحالة المزاجية" class="ipsImage ipsImage_thumbnailed" data-fileid="118393" data-ratio="56.33" data-unique="3ijxpshfb" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_02/mood-dial.gif.c242eb0e954f24768e2788921a70411d.gif"> </a>
</p>

<p>
	يمكنك الاطلاع على الشيفرة اللازمة لتنفيذ هذا المشروع باسم mood_dial.py ضمن الملف المرفق <a data-fileext="zip" data-fileid="118414" href="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=118414&amp;key=52cbf0aa58a37e1365c66ddd1006bf37" rel="">code.zip</a>.
</p>

<h4>
	مشروع مؤشر التركيز
</h4>

<p>
	استُخدمت ثلاثة مصابيح ليد عادية للتعبير عن ثلاث رموز يمكن استخدامها في القاعة الدراسية، إذ يعني الرمز الأول "يرجى التزام الهدوء وعدم الإزعاج"، أما الرمز الثاني فيعبر عن الحاجة للمساعدة، والرمز الأخير يعني أن المستخدم لا يحتاج إلى مساعدة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="118392" href="https://academy.hsoub.com/uploads/monthly_2023_02/dnd-indicator.gif.6d19f086c3ccf380831dfabbf32e70b4.gif" rel=""><img alt="مشروع مؤشر التركيز" class="ipsImage ipsImage_thumbnailed" data-fileid="118392" data-ratio="64.67" data-unique="8tse7eyuq" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_02/dnd-indicator.gif.6d19f086c3ccf380831dfabbf32e70b4.gif"> </a>
</p>

<p>
	يمكنك الاطلاع على الشيفرة اللازمة لتنفيذ هذا المشروع باسم focus_indicator.py من هنا ضمن الملف المرفق <a data-fileext="zip" data-fileid="118414" href="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=118414&amp;key=52cbf0aa58a37e1365c66ddd1006bf37" rel="">code.zip</a>.
</p>

<h2>
	تصميم الجهاز
</h2>

<p>
	عليك الآن التفكير في كيفية التعبير عن المشاعر المختلفة باستخدام أداتك أو جهازك؟ والآلية التي سيختار بها المستخدم الشعور المناسب.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="118394" href="https://academy.hsoub.com/uploads/monthly_2023_02/mood-lamp.gif.ecfd792be8adc8622232cb6682428e2a.gif" rel=""><img alt="تصميم جهاز عرض الحالة المزاجية باستخدام لوحة راسبيري باي بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="118394" data-ratio="65.38" data-unique="g5thfr588" style="width: 517px; height: auto;" width="517" src="https://academy.hsoub.com/uploads/monthly_2023_02/mood-lamp.gif.ecfd792be8adc8622232cb6682428e2a.gif"> </a>
</p>

<p>
	أولًا، فكر مليًّا في الغرض من الأداة التي ستصنعها، ولمن تريد توجيهها؟ هل تريد استخدامها للتواصل مع البالغين، أو الأصدقاء؟ هل تريد استخدامها لمساعدة الأشخاص الذين يجدون صعوبةً في التواصل؟ أم تفضل استخدامها لتراقب تغيرات مزاجك وتدونها؟
</p>

<p>
	ثانيًا، قرر ما الذي تود التعبير عنه باستخدام أداتك.
</p>

<ul>
	<li>
		هل تود التعبير عما تشعر به، مثل السعادة، أو الحزن، أو الغضب؟
	</li>
	<li>
		أم تود ضبط الجو العام لمكان ما؛ أي جو هادئ أو نشط؟
	</li>
	<li>
		أم تريد استخدام أداتك في قاعة دراسية لطلب المساعدة، أو عدم الإزعاج؟
	</li>
	<li>
		كما يمكنك استخدام أداتك عند البدء في أمر جديد للتعبير عن شعورك بالقلق، أو الحماس، أو التشتت.
	</li>
</ul>

<p>
	ثالثًا، فكر كيف تود التعبير عن المشاعر المختلفة باستخدام أنماط مختلفة من الأضواء والألوان. ما هي الألوان التي ستستخدمها؟ يُستخدم اللون الأحمر عادةً للتعبير عن الحب أو الغضب، أما اللون الأزرق فيستخدم للتعبير عن الحزن أو الشعور بالراحة.
</p>

<p>
	إليك لمحةً عن دلالات بعض الألوان حول العالم:
</p>

<ul>
	<li>
		يرمز اللون الأحمر في الثقافة الصينية للحظ والبهجة والسعادة.
	</li>
	<li>
		يعبر اللون الأصفر والبرتقالي والأحمر في معظم الثقافات عن السعادة. كما تعبر الألوان الساطعة عن الحماس.
	</li>
	<li>
		يستخدم اللون الأزرق والأخضر للتعبير عن السكينة والاسترخاء، لكن يُعد ارتداء اللون الأخضر على خشبة المسرح أمرًا جالبًا للحظ السيء.
	</li>
</ul>

<p>
	الآن دون ملاحظاتك على ورقة ما، أو ارسم التصميم الذي تود اعتماده في جهازك، كي تتشكل لديك خطةً لاتباعها عند العمل.
</p>

<p>
	رابعًا، قرر ما هو نوع المصابيح التي تود استخدامها. هل تود استخدام مصابيح ليد عادية (ذات لون واحد)؟ أم تفضل استخدام المصابيح متعددة الألوان؟
</p>

<p>
	تحتوي لوحة بيكو على ثمانية أرجل أرضية <strong>GND</strong>، لذلك يمكنك توصيل ثمانية عناصر إلكترونية فقط مع لوحة بيكو، كما تحتوي اللوحة على رجل تغذية واحدة ذات جهد <strong>3 فولت</strong>؛ أي يمكنك استخدام مقاومة متغيرة potentiometer واحدة، ويوجد حدٌّ لقيمة التيار الذي توفره لوحة بيكو، ولذلك ننصحك باستخدام مصباحي ليد متعددي الألوان، أو ستة مصابيح ليد عادية ذات لون واحد.
</p>

<p>
	إليك بعض الاقتراحات لعناصر الدخل والخرج التي يمكنك استخدامها معًا:
</p>

<ul>
	<li>
		ثلاثة أزرار وثلاثة <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D8%B5%D8%A8%D8%A7%D8%AD-%D9%84%D9%8A%D8%AF-%D9%8A%D9%88%D9%85%D8%B6-%D9%88%D9%81%D9%82-%D9%86%D9%85%D8%B7-%D9%85%D8%B9%D9%8A%D9%86-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1848/" rel="">مصابيح ليد</a> وحيدة اللون.
	</li>
	<li>
		مقاومة متغيرة واحدة ومصباح ليد متعدد الألوان ذو مهبط مشترك.
	</li>
	<li>
		زر واحد ومصباح ليد متعدد الألوان ذو مهبط مشترك.
	</li>
	<li>
		أربعة أزرار ومصباح ليد متعدد الألوان ذو مهبط مشترك.
	</li>
</ul>

<p>
	خامسًا، قرر ما هي العناصر الإلكترونية التي تود استخدامها، إذ يمكنك استخدام الأزرار الجاهزة، أو المقاومات المتغيرة، أو الأزرار والمبدًلات يدوية الصنع.
</p>

<p>
	سادسًا، فكر مليًّا في التصميم الخارجي لأداتك، كيف ستوصل العناصر الإلكترونية معها؟ بإمكانك تثبيت العناصر داخل لعبة أو مجسم ما، أو جعل أداتك قابلة للارتداء، مثل سوار مثلًا؛ كما يمكنك أن تستوحي بعض الأفكار من المشاريع الموجودة في مقدمة مقالنا.
</p>

<p>
	لا بأس إن لم يكن لديك الآن تصوُّر واضح لأداتك، إذ يمكنك التعديل على التصميم أثناء العمل.
</p>

<h2>
	إضافة الشيفرة اللازمة للتحكم بالإضاءة
</h2>

<p>
	سنعمل في هذه الخطوة على توصيل مصابيح الليد مع لوحة بيكو وإضافة الشيفرة اللازمة للتحكم في إضاءتها، واختبار عملها.
</p>

<p>
	ننصحك بتنفيذ المشروع خطوةً خطوة، بدءًا من الأساسيات، ثم العودة وترقية المشروع حين يتسنى لك ذلك.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="118393" href="https://academy.hsoub.com/uploads/monthly_2023_02/mood-dial.gif.c242eb0e954f24768e2788921a70411d.gif" rel=""><img alt="إضافة الشيفرة اللازمة للتحكم بالإضاءة" class="ipsImage ipsImage_thumbnailed" data-fileid="118393" data-ratio="56.33" data-unique="3ijxpshfb" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_02/mood-dial.gif.c242eb0e954f24768e2788921a70411d.gif"> </a>
</p>

<p>
	<strong>معلومة:</strong> عند تنفيذ مشروع ما يُنصح بإنشاء نموذج أولي Prototyping، أي صنع نسخة مبسطة عن المشروع النهائي لتختبر عمله، وتتأكد أنه يقدم الحلول التي صُنع من أجلها.
</p>

<p>
	سنعمل الآن على إنشاء نموذج أولي لمشروعنا لاختبار التوصيلات والشيفرة، واكتشاف الأمور التي علينا تحسينها قبل البدء بتنفيذ التصميم النهائي للجهاز وتوصيل العناصر.
</p>

<p>
	أولًا، صِل مصابيح الليد مع لوحة بيكو بإتباع الإرشادات التالية:
</p>

<h3>
	توصيل عدة مصابيح ليد ذات اللون الواحد
</h3>

<p>
	ستحتاج لتوصيل عدة مصابيح ليد ذات اللون الواحد إلى ما يلي:
</p>

<ul>
	<li>
		لوحة راسبيري باي بيكو.
	</li>
	<li>
		عدة مصابيح ليد باللون الذي تفضله.
	</li>
	<li>
		مقاومة لكل مصباح.
	</li>
	<li>
		سلكي توصيل نوع مقبس- مقبس لكل مصباح.
	</li>
</ul>

<p>
	يجب توصيل مقاومة مع الرجل الموجبة الطويلة لكل مصباح ليد، كما هو موضح في المخطط التالي؛ إذ تُوصل الرجل الموجبة للمصباح الأول مع الرجل <strong>GP13</strong> على لوحة بيكو والسالبة مع أقرب رجل أرضية <strong>GND</strong>؛ وتُوصل الرجل الموجبة للمصباح الثاني مع الرجل <strong>GP8</strong>، والسالبة مع أقرب رجل أرضية <strong>GND</strong>، وتُويل الرجل الموجبة للمصباح الثالث مع الرجل <strong>GP5</strong>، والسالبة مع أقرب رجل أرضية <strong>GND</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118397" href="https://academy.hsoub.com/uploads/monthly_2023_02/multiple-leds.png.4980887510c93e4c477167dbbdcd7ede.png" rel=""><img alt="توصيل عدة مصابيح ليد ذات اللون الواحد" class="ipsImage ipsImage_thumbnailed" data-fileid="118397" data-ratio="110.00" data-unique="dlgd59txu" style="width: 500px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_02/multiple-leds.thumb.png.cc6e0437a748a46bdfb0b915663328f3.png"> </a>
</p>

<h3>
	توصيل مصباح ليد متعدد الألوان مع لوحة بيكو
</h3>

<p>
	ستحتاج لتوصيل مصباح ليد متعدد الألوان إلى ما يلي:
</p>

<ul>
	<li>
		لوحة راسبيري باي بيكو.
	</li>
	<li>
		مصباح ليد متعدد الألوان ذو مهبط مشترك.
	</li>
	<li>
		ثلاث مقاومات.
	</li>
	<li>
		أسلاك توصيل نوع مقبس- مقبس (عدد 8).
	</li>
</ul>

<p>
	يجب عليك توصيل مقاومة مع الأرجل الثلاثة الطويلة لمصباح الليد، أما الرجل الطويلة فهي رجل الأرضية ولا تحتاج إلى مقاومة.
</p>

<p>
	<strong>معلومة:</strong> لاحظ أنه لمصباح الليد متعدد الألوان أربعة أرجل، لذلك أمسك المصباح بحيث تكون الرجل الأرضية هي ثاني رجل من اليسار، بحيث يصبح ترتيب الأرجل على النحو التالي: الرجل المسؤولة عن اللون الأحمر<strong>R</strong>ed، ثم الرجل الأرضية <strong>GND</strong>، ثم الرجل المسؤولة عن اللون الأخضر<strong>G</strong>reen، فالأزرق <strong>B</strong>lue، وذلك ليسهُل عليك تذكر وظيفة كل رجل.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118405" href="https://academy.hsoub.com/uploads/monthly_2023_02/rgb-led-legs.png.0940bbe524f6eb71a31529a59a9514c8.png" rel=""><img alt="rgb-led-legs.png" class="ipsImage ipsImage_thumbnailed" data-fileid="118405" data-ratio="233.00" data-unique="g24kt3w5o" style="width: 100px; height: auto;" width="100" src="https://academy.hsoub.com/uploads/monthly_2023_02/rgb-led-legs.png.0940bbe524f6eb71a31529a59a9514c8.png"> </a>
</p>

<p>
	صِل أرجل مصباح الليد وفقًا لما يلي:
</p>

<ul>
	<li>
		الرجل المسؤولة عن اللون الأحمر <strong>R</strong> مع الرجل <strong>GP1</strong> على لوحة بيكو.
	</li>
	<li>
		الرجل الأرضية <strong>GND</strong> مع رجل الأرض <strong>GND</strong> على لوحة بيكو.
	</li>
	<li>
		الرجل المسؤولة عن اللون الأخضر<strong>G</strong> مع الرجل <strong>GP2</strong> على لوحة بيكو.
	</li>
	<li>
		الرجل المسؤولة عن اللون الأزرق <strong>B</strong> مع الرجل <strong>GP3</strong> على لوحة بيكو.
	</li>
</ul>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118404" href="https://academy.hsoub.com/uploads/monthly_2023_02/rgb-led-diagram.png.1df0d97b2d62e036867bff73f5e3a415.png" rel=""><img alt="كيفية توصيل مصباح ليد متعدد الألوان مع لوحة بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="118404" data-ratio="136.75" data-unique="1tcnluxyx" style="width: 400px; height: auto;" width="400" src="https://academy.hsoub.com/uploads/monthly_2023_02/rgb-led-diagram.thumb.png.8b2e13429767d8514e7cbfe09b039ba1.png"> </a>
</p>

<p>
	ثانيًا، استورد تابع مصباح الليد العادي <code>LED</code>، أو متعدد الألوان <code>RGBLED</code> من مكتبة <code>picozero</code>، ثم استخدم الشيفرة اللازمة لإسناد المصباح إلى الأرجل الموصول معها على لوحة بيكو.
</p>

<p>
	استخدم الشيفرة التالية لإسناد مصابيح الليد العادية إلى الأرجل الموصولة معها على لوحة بيكو:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_52" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> LED
led_1 </span><span class="pun">=</span><span class="pln"> LED</span><span class="pun">(</span><span class="lit">13</span><span class="pun">)</span><span class="pln">
led_2 </span><span class="pun">=</span><span class="pln"> LED</span><span class="pun">(</span><span class="lit">8</span><span class="pun">)</span><span class="pln">
led_2 </span><span class="pun">=</span><span class="pln"> LED</span><span class="pun">(</span><span class="lit">5</span><span class="pun">)</span></pre>

<p>
	ننصحك بتسمية المتغيرات بأسماء تدل على عملها، كأن تسمّي المصباح المسؤول عن تشغيل المصباح باللون المسؤول عنه، كما يلي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_54" style=""><span class="pln">red_led </span><span class="pun">=</span><span class="pln"> LED</span><span class="pun">(</span><span class="lit">13</span><span class="pun">)</span><span class="pln">
green_led </span><span class="pun">=</span><span class="pln"> LED</span><span class="pun">(</span><span class="lit">8</span><span class="pun">)</span><span class="pln">
pink_led </span><span class="pun">=</span><span class="pln"> LED</span><span class="pun">(</span><span class="lit">5</span><span class="pun">)</span></pre>

<p>
	استخدم الشيفرة التالية لإسناد مصباح الليد متعدد الألوان إلى أرجل لوحة بيكو بعد استيراد تابع المصباح متعدد الألوان <code>RGBLED</code> من مكتبة <code>picozero</code>:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_56" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> RGBLED

rgb </span><span class="pun">=</span><span class="pln"> RGBLED</span><span class="pun">(</span><span class="pln">red </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> green </span><span class="pun">=</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> blue </span><span class="pun">=</span><span class="pln"> </span><span class="lit">3</span><span class="pun">)</span></pre>

<p>
	ثالثًا، أضف التأثير الضوئي الذي تفضله على المصابيح، وذلك باختيار إحدى الدوال التالية وإضافتها على الشيفرة:
</p>

<p>
	تُستخدم الشيفرة التالية لتشغيل وإطفاء عدة مصابيح ليد عادية:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_58" style=""><span class="kwd">def</span><span class="pln"> excited</span><span class="pun">():</span><span class="pln"> </span><span class="com">#  شغّل اللون الموافق لشعورك بالحماس</span><span class="pln">
    purple</span><span class="pun">.</span><span class="pln">on</span><span class="pun">()</span><span class="pln"> </span><span class="com">#  شغّل المصباح البنفسجي</span><span class="pln">
    blue</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln"> </span><span class="com">#  أطفئ المصباح الأزرق</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> worried</span><span class="pun">():</span><span class="pln"> </span><span class="com"># شغّل اللون الموافق لشعورك بالقلق</span><span class="pln">
    purple</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln"> </span><span class="com">#  أطفئ المصباح البنفسجي</span><span class="pln">
    blue</span><span class="pun">.</span><span class="pln">on</span><span class="pun">()</span><span class="pln"> </span><span class="com"># شغّل المصباح الأزرق</span></pre>

<p>
	استخدم الدوال الثلاث التالية: <code>blink</code> و <code>pulse</code> و <code>cycle</code> لإضفاء مزيج من التأثيرات الضوئية على مشروعك، إذ يمكنك التبديل بين التأثيرات عند الضغط على زر وحيد.
</p>

<p>
	يمكنك إضفاء تأثير الوميض أو النبض على مصباح ليد عادي باستخدام دالة الوميض <code>blink</code> أو النبض <code>pulse</code> لتشغيل وإطفاء المصباح بصورةٍ متكررة، كما هو مبين في الشيفرة التالية:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_60" style=""><span class="kwd">def</span><span class="pln"> available</span><span class="pun">():</span><span class="pln"> </span><span class="com"># شغّل الدالة الموافقة للشعور الأول  </span><span class="pln">
    red</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln"> </span><span class="com"># أطفئ المصباح الأحمر</span><span class="pln">
    green</span><span class="pun">.</span><span class="pln">blink</span><span class="pun">()</span><span class="pln">


</span><span class="kwd">def</span><span class="pln"> do_not_disturb</span><span class="pun">():</span><span class="pln"> </span><span class="com"># شغّل الدالة الموافقة للشعور الأول</span><span class="pln">
    green</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln"> </span><span class="com"># أطفئ المصباح الأخضر</span><span class="pln">
    red</span><span class="pun">.</span><span class="pln">pulse</span><span class="pun">()</span></pre>

<p>
	امزج بين عدة ألوان واستخدم الدالتين السابقتين للحصول على التأثير الذي تريده في مشروعك.
</p>

<p>
	يمكنك كذلك استخدام دالة الوميض <code>blink</code> أو النبض <code>pulse</code> أو التكرار <code>cycle</code> لتشغيل وإطفاء مصباح ليد متعدد الألوان بصورةٍ متكررة، كما هو مبين في الشيفرة التالية:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_62" style=""><span class="kwd">def</span><span class="pln"> energise</span><span class="pun">():</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">blink</span><span class="pun">()</span><span class="pln"> </span><span class="com"># شغّل المصباح الأحمر لثانية واحدة، والأخضر لثانية، والأزرق لثانية</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> neutral</span><span class="pun">():</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">pulse</span><span class="pun">(</span><span class="pln">fade_times</span><span class="pun">=</span><span class="lit">3</span><span class="pun">)</span><span class="pln"> </span><span class="com"># تفعيل تأثير النبض البطيء</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> relax</span><span class="pun">():</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">cycle</span><span class="pun">(</span><span class="pln">fade_times</span><span class="pun">=</span><span class="lit">4</span><span class="pun">)</span></pre>

<p>
	يمكنك الاستعانة بالشيفرة التالية لجعل مصباح الليد متعدد الألوان يضيء وفق لون معين:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_64" style=""><span class="kwd">def</span><span class="pln"> happy</span><span class="pun">():</span><span class="pln"> </span><span class="com">#شغّل اللون الموافق لشعورك بالسعادة</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">color </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="com"># شغّل اللون الأخضر </span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> sad</span><span class="pun">():</span><span class="pln"> </span><span class="com"># شغّل اللون الموافق لشعورك بالحزن</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">color </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="com"># شغّل اللون الأحمر </span></pre>

<p>
	ننصحك بإضافة تعليقات ضمن الشيفرة وكتابة اللون الموافق بجانب كل قيمة لونية ليسهُل عليك تذكر الألوان التي استخدمتها عند مراجعة الشيفرة.
</p>

<p>
	رابعًا، عليك التعديل على الشيفرة واستدعاء الدالة التي استخدمتها، وذلك بكتابة اسمها في سطر منفصل، بعد التعريف عنها، ثم اختبر الشيفرة.
</p>

<p>
	إليك المثال التالي، الذي استدعينا فيه الدالة <code>happy</code> في نهاية الشيفرة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_66" style=""><span class="kwd">def</span><span class="pln"> happy</span><span class="pun">():</span><span class="pln"> </span><span class="com">#شغّل اللون الموافق لشعورك بالسعادة</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">color </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="com"># شغّل اللون الأخضر </span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> sad</span><span class="pun">():</span><span class="pln"> </span><span class="com"># شغّل اللون الموافق لشعورك بالحزن</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">color </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="com"># شغّل اللون الأحمر </span><span class="pln">

happy</span><span class="pun">()</span><span class="pln"> </span><span class="com"># غيّر هذا السطر بما يوافق الدالة التي تريد استدعائها</span></pre>

<p>
	احرص على عدم ترك مسافات في بداية السطر الذي استدعيت فيه التابع.
</p>

<h3>
	تمثيل الألوان بصيغة RGB
</h3>

<p>
	يمكننا تمثيل الألوان بصيغة يفهمها الحاسوب وذلك بالتعبير عن نسبة ما يحتويه اللون من اللون الأحمر والأخضر والأزرق، إذ تخزّن هذه القيم في <strong>بايت</strong> (ثمانية بتات) وتكون قيمتها من 0 إلى 255.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="118406" href="https://academy.hsoub.com/uploads/monthly_2023_02/RGB.gif.85829ac2f989b48ebefdc1e2e77baaa0.gif" rel=""><img alt="تمثيل الألوان بصيغة RGB" class="ipsImage ipsImage_thumbnailed" data-fileid="118406" data-ratio="59.75" data-unique="b42u8564x" style="width: 400px; height: auto;" width="400" src="https://academy.hsoub.com/uploads/monthly_2023_02/RGB.gif.85829ac2f989b48ebefdc1e2e77baaa0.gif"> </a>
</p>

<p>
	إليك جدولًا يوضح بعض القيم اللونية:
</p>
<style type="text/css">
table {
    width: 100%;
}

thead {
    vertical-align: middle;
    text-align: center;
} 

td, th {
    border: 1px solid #dddddd;
    text-align: right;
    padding: 8px;
    text-align: inherit;

}
tr:nth-child(even) {
    background-color: #dddddd;
}</style>
<table>
	<thead>
		<tr>
			<th>
				اللون
			</th>
			<th>
				الأحمر
			</th>
			<th>
				الأخضر
			</th>
			<th>
				الأزرق
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				أحمر
			</td>
			<td>
				255
			</td>
			<td>
				0
			</td>
			<td>
				0
			</td>
		</tr>
		<tr>
			<td>
				أخضر
			</td>
			<td>
				0
			</td>
			<td>
				255
			</td>
			<td>
				0
			</td>
		</tr>
		<tr>
			<td>
				أزرق
			</td>
			<td>
				0
			</td>
			<td>
				0
			</td>
			<td>
				255
			</td>
		</tr>
		<tr>
			<td>
				أصفر
			</td>
			<td>
				255
			</td>
			<td>
				255
			</td>
			<td>
				0
			</td>
		</tr>
		<tr>
			<td>
				أرجواني
			</td>
			<td>
				255
			</td>
			<td>
				0
			</td>
			<td>
				255
			</td>
		</tr>
		<tr>
			<td>
				سماوي
			</td>
			<td>
				0
			</td>
			<td>
				255
			</td>
			<td>
				255
			</td>
		</tr>
	</tbody>
</table>

<p>
	كما يمكنك الاستعانة <a href="https://www.w3schools.com/colors/colors_rgb.asp" rel="external nofollow">بمنتقي الألوان</a> من موقع w3schools للحصول على القيم الموافقة للون الذي تريده.
</p>

<h3>
	تصحيح الأخطاء
</h3>

<p>
	إليك بعض المشاكل التي قد تواجهك في هذه الخطوة وكيفية إصلاحها:
</p>

<h4>
	تصحيح الأخطاء الموجودة في الشيفرة
</h4>

<ul>
	<li>
		تحقق من وجود أي رسائل خطأ في نافذة صدفة Shell ثوني وتحقق من محتواها، إن وجدت.
	</li>
	<li>
		راجع الشيفرة التي كتبتها وتحقق من خلوها من الأخطاء، مثل نسيان علامة <strong>:</strong> مثلًا، أو وجود مسافة بادئة دون الحاجة لها.
	</li>
	<li>
		تأكد من استيراد توابع العناصر التي ستستخدمها في مشروعك من مكتبة <code>picozero</code>، مثل تابع مصباح الليد متعدد الالوان <code>RGBLED</code> أو الزر <code>Button</code>.
	</li>
	<li>
		استخدم تعليمة الطباعة <code>print</code> لإضافة شرح مختصر عند كل خطوة، مثل <code>('البدء')print</code>، أو <code>('ضبط المصباح على اللون الأخضر')print</code>.
	</li>
</ul>

<h4>
	لا تعمل بعض العناصر الإلكترونية كما يجب
</h4>

<ul>
	<li>
		تأكد أن جميع العناصر متصلة ببعضها جيدًا، وتحقق من ثبات نقاط توصيل الأسلاك مع اللوحة ومع العناصر.
	</li>
	<li>
		تأكد أن أرقام الأرجل المستخدمة في الشيفرة مطابقة لأرقام الأرجل الموصولة مع مصباح الليد، وتأكد من إعادة وصل الأرجل، في حال فصلتها عند العمل على تصميم الهيكل الخارجي للجهاز.
	</li>
	<li>
		تحقق من وصل العناصر وفق القطبية الصحيحة، إذ قد تحتوي بعض العناصر على قطب موجب <strong>+</strong> وآخر سالب <strong>-</strong>.
	</li>
	<li>
		في حال تحققت من جميع النقاط السابقة ولا زال الجهاز لا يعمل، فجرب تبديل العناصر الإلكترونية بأخرى جديدة.
	</li>
</ul>

<h4>
	لا يضيء مصباح الليد عند استدعاء الدالة المسؤولة عن تشغيله
</h4>

<p>
	تأكد من تطابق الأرجل الموصول معها المصباح على لوحة بيكو للأرجل المسند إليها في الشيفرة.
</p>

<h4>
	لا يضيء مصباح الليد باللون الصحيح
</h4>

<p>
	تحقق من الشيفرة التي كتبتها وأن القيم اللونية مطابقة للون المستخدم، استخدم <a href="https://www.w3schools.com/colors/colors_rgb.asp" rel="external nofollow">منتقي الألوان التالي</a> للتحقق من اللون المستخدم.
</p>

<p>
	حاول حل المشاكل الأخرى التي قد تواجهك عند التنفيذ وشاركنا طريقة الحل في <a href="https://io.hsoub.com/" rel="external">منصة حسوب IO</a> أو في <a href="https://academy.hsoub.com/search/" rel="">أكاديمية حسوب</a>.
</p>

<h2>
	اختيار الحالة المزاجية المناسبة
</h2>

<p>
	سنضيف في هذه الخطوة وسيلةً تتيح للمستخدم اختيار المزاج المناسب باستخدام زر، أو مقاومة متغيرة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="118392" href="https://academy.hsoub.com/uploads/monthly_2023_02/dnd-indicator.gif.6d19f086c3ccf380831dfabbf32e70b4.gif" rel=""><img alt="اختيار الحالة المزاجية المناسبة" class="ipsImage ipsImage_thumbnailed" data-fileid="118392" data-ratio="64.67" data-unique="8tse7eyuq" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_02/dnd-indicator.gif.6d19f086c3ccf380831dfabbf32e70b4.gif"> </a>
</p>

<p>
	أولًا، حدد عناصر الدخل التي تود استخدامها. إليك الاقتراحات التالية:
</p>

<ul>
	<li>
		تخصيص زر لكل مزاج.
	</li>
	<li>
		استخدام زر واحد للتبديل بين المشاعر.
	</li>
	<li>
		استخدام مبدّل يدوي الصنع.
	</li>
	<li>
		استخدام مقاومة متغيرة لاختيار المزاج بناءً على قيمة المقاومة.
	</li>
</ul>

<p>
	ستحتاج إلى سلكي توصيل نوع مقبس-مقبس لكل زر تنوي استخدامه، أو ثلاثة أسلاك لكل مقاومة متغيرة.
</p>

<p>
	ثانيًا، صِل عناصر الدخل التي اخترتها مع لوحة بيكو باتباع الإرشادات التالية:
</p>

<h3>
	توصيل زر إلكتروني واحد
</h3>

<p>
	ستحتاج لتوصيل زر مع لوحة بيكو إلى ما يلي:
</p>

<ul>
	<li>
		لوحة راسبيري باي بيكو.
	</li>
	<li>
		زر إلكتروني.
	</li>
	<li>
		سلكي توصيل نوع مقبس-مقبس.
	</li>
</ul>

<p>
	صِل سلكي التوصيل مع أرجل الزر واستخدم الشريط اللاصق لتثبيتهما إذا لزم الأمر، ثم صِل أحد السلكين مع الرجل **GP18 **والسلك الآخر مع أقرب رجل أرضية. لا يهم ترتيب توصيل الأسلاك إذ لا توجد قطبية للزر.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118408" href="https://academy.hsoub.com/uploads/monthly_2023_02/single-button-wiring.png.270137c61244f9bd4e4851e08055e705.png" rel=""><img alt="توصيل زر إلكتروني واحد في راسبيري باي" class="ipsImage ipsImage_thumbnailed" data-fileid="118408" data-ratio="134.61" data-unique="zpte23bi8" style="width: 445px; height: auto;" width="400" src="https://academy.hsoub.com/uploads/monthly_2023_02/single-button-wiring.thumb.png.1ee46f147f7506d0760aab9bcd7b5e52.png"> </a>
</p>

<h3>
	توصيل عدة أزرار إلكترونية
</h3>

<p>
	ستحتاج لتوصيل عدة أزرار مع لوحة بيكو إلى ما يلي:
</p>

<ul>
	<li>
		لوحة راسبيري باي بيكو.
	</li>
	<li>
		أزرار إلكترونية.
	</li>
	<li>
		سلكي توصيل نوع دبوس-مقبس لكل زر.
	</li>
</ul>

<p>
	توضح الصورة التالية طريقة توصيل ثلاثة أزرار مع لوحة بيكو، وإذا أردت توصيل زر رابع فما عليك سوى توصيله مع إحدى أرجل الأغراض العامة <strong>GP</strong> ورجل أرضية.
</p>

<p>
	استخدم سلكي توصيل نوع دبوس- مقبس لتوصيل الزر الأول مع الرجل <strong>GP18</strong> ومع أقرب رجل أرضية <strong>GND</strong>، ثم صِل الزر الثاني مع الرجل <strong>GP22</strong>، والثالث مع الرجل <strong>GP28</strong> بنفس الطريقة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118395" href="https://academy.hsoub.com/uploads/monthly_2023_02/multiple-button-wiring.png.c16f709771d819f4db926cf9a771ef81.png" rel=""><img alt="توصيل عدة أزرار إلكترونية" class="ipsImage ipsImage_thumbnailed" data-fileid="118395" data-ratio="134.53" data-unique="zy8ix0d4c" style="width: 446px; height: auto;" width="446" src="https://academy.hsoub.com/uploads/monthly_2023_02/multiple-button-wiring.thumb.png.0c5fcdbf6ce443239090b91099bda895.png"> </a>
</p>

<h3>
	توصيل مقاومة متغيرة مع اللوحة
</h3>

<p>
	ستحتاج إلى ما يلي:
</p>

<ul>
	<li>
		لوحة راسبيري باي بيكو.
	</li>
	<li>
		مقاومة متغيرة.
	</li>
	<li>
		أسلاك توصيل نوع مقبس-مقبس (عدد 3).
	</li>
</ul>

<p>
	يوجد للمقاومة المتغيرة ثلاثة أرجل: رجل الأرضية <strong>GND</strong>، ورجل تشابهية Analogue، ورجل التغذية <strong>3V3</strong>، وعند تدوير قرص المقاومة المتغيرة إلى أقصى اليسار يشير السهم إلى الرجل الأرضية <strong>GND</strong>، وعند تدويره إلى أقصى اليمين، يشير السهم إلى رجل التغذية <strong>3V3</strong>، أما الرجل الوسطى للمقاومة فهي الرجل التشابهية التي تستمد منها لوحة بيكو القيم لقراءتها.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118402" href="https://academy.hsoub.com/uploads/monthly_2023_02/potentiometer-illustration.png.d307f367415dd8b77854f8db3c518f6c.png" rel=""><img alt="توصيل مقاومة متغيرة مع اللوحة" class="ipsImage ipsImage_thumbnailed" data-fileid="118402" data-ratio="100.00" data-unique="9k0aj1hqi" style="width: 380px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_02/potentiometer-illustration.thumb.png.1fec2b09248f2308839873132804df74.png"> </a>
</p>

<p>
	صِل سلك توصيل ذو نهايات مقبس-مقبس مع كل أرجل المقاومة الثلاث، وثبت التوصيلات بالشريط اللاصق إن لزم الأمر كما يلي:
</p>

<ul>
	<li>
		صِل النهاية الحرة للسلك الموصول مع رجل المقاومة ذات الرقم <strong>1</strong> مع رجل الأرض <strong>GND</strong> الموجودة بين الرجلين <strong>GP21</strong> و <strong>GP22</strong>.
	</li>
	<li>
		صِل رجل المقاومة الوسطى مع الرجل <strong>GP26_A0</strong> على لوحة بيكو.
	</li>
	<li>
		صِل رجل المقاومة ذات الرقم <strong>3</strong> مع رجل التغذية <strong>3V3</strong>.
	</li>
</ul>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118401" href="https://academy.hsoub.com/uploads/monthly_2023_02/pot-diagram.png.65b254716ed082ff55d64309a9f5f3eb.png" rel=""><img alt="طريقة توصيل مقاومة متغيرة مع اللوحة" class="ipsImage ipsImage_thumbnailed" data-fileid="118401" data-ratio="112.99" data-unique="5kc5h4xwt" style="width: 531px; height: auto;" width="531" src="https://academy.hsoub.com/uploads/monthly_2023_02/pot-diagram.thumb.png.1fbc225725e4cca3fa72657f19d91e08.png"> </a>
</p>

<h3>
	توصيل مبدل يدوية الصنع أو زر مع لوحة بيكو
</h3>

<p>
	ستحتاج إلى سلكي توصيل نوع دبوس-مقبس، بحيث تصِل أحدهما مع الرجل <strong>GP18</strong> والسلك الآخر مع أقرب رجل أرضية، كما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118390" href="https://academy.hsoub.com/uploads/monthly_2023_02/crafted-switch-wiring.png.b0be7493b60f25b7d6784bd0d026d98f.png" rel=""><img alt="توصيل مبدل يدوية الصنع أو زر مع لوحة بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="118390" data-ratio="134.53" data-unique="3d36yymxs" style="width: 446px; height: auto;" width="446" src="https://academy.hsoub.com/uploads/monthly_2023_02/crafted-switch-wiring.thumb.png.b27ec2f78f9e555c585f5fd78d00e4ba.png"> </a>
</p>

<p>
	ثم يمكنك صنع مبدّل يدوي، كما تعلمنا في <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%85%D8%AD%D8%A7%D9%83%D8%A7%D8%A9-%D9%84%D9%85%D9%81%D8%B1%D9%82%D8%B9%D8%A7%D8%AA-%D8%A7%D9%84%D8%AD%D9%81%D9%84%D8%A7%D8%AA-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1861/" rel="">مشروع سابق</a>، وتوصيلها مع اللوحة وذلك بتوصيل النهاية الحرة للأسلاك مع الجزء الناقل من المبدّل، مثل النحاس أو ورق القصدير.
</p>

<h3>
	توصيل عدة مبدلات يدوية أو أزرار مع لوحة بيكو
</h3>

<p>
	ستحتاج إلى سلكي توصيل نوع دبوس-مقبس لكل مبدّل تود توصيله مع لوحة بيكو.
</p>

<p>
	استخدم سلكي توصيل نوع دبوس- مقبس لتوصيل المبدّل الأول مع الرجل <strong>GP18</strong> ومع أقرب رجل أرضية <strong>GND</strong>، ثم صِل المبدّل الثاني مع الرجل <strong>GP22</strong> ومع أقرب رجل أرضية، والثالث مع الرجل <strong>GP28</strong> ورجل الأرضية بنفس الطريقة، كما هو موضح في المخطط التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="118396" href="https://academy.hsoub.com/uploads/monthly_2023_02/multiple-crafted-switch-wiring.png.dffe8f6a6645a22df337c695d80add53.png" rel=""><img alt="توصيل عدة مبدلات يدوية أو أزرار مع لوحة بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="118396" data-ratio="134.53" data-unique="o3r0hp0tz" style="width: 446px; height: auto;" width="446" src="https://academy.hsoub.com/uploads/monthly_2023_02/multiple-crafted-switch-wiring.thumb.png.4373cc54fc60fc21864528a7594704cb.png"> </a>
</p>

<p>
	ثالثًا، عليك استيراد التابع الموافق لعنصر الدخل الذي استخدمته من مكتبة <code>picozero</code>، ثم إنشاء متغيرات لإسناد عناصر الدخل للأرجل الموصولة معها.
</p>

<p>
	لا تنس أنه بإمكانك استيراد عدة توابع معًا، كما يلي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_79" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> LED</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Button</span></pre>

<p>
	لتوصيل زر إلكتروني واحد، علينا إسناده إلى الرجل الموصول معها على لوحة بيكو، كما يلي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_81" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">

button </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Button</span><span class="pun">(</span><span class="lit">18</span><span class="pun">)</span></pre>

<p>
	ولتوصيل عدة أزرار إلكترونية، استورد تابع الزر <code>Button</code> من مكتبة <code>picozero</code>، ثم استخدم الشيفرة التالية لإسناد عدة أزرار إلى الأرجل الموصولة معها على لوحة بيكو:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_83" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">

button_1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Button</span><span class="pun">(</span><span class="lit">18</span><span class="pun">)</span><span class="pln">
button_2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Button</span><span class="pun">(</span><span class="lit">22</span><span class="pun">)</span><span class="pln">
button_3 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Button</span><span class="pun">(</span><span class="lit">28</span><span class="pun">)</span></pre>

<p>
	ننصحك بتسمية المتغيرات بأسماء تدل على عملها، كأن تسمّي الزر المسؤول عن تشغيل المصباح الأحمر <code>red_button</code> أو أي اسم آخر تراه مناسبًا.
</p>

<p>
	من أجل توصيل مبدّل واحد، استورد تابع المبدّل <code>Switch</code> من مكتبة <code>picozero</code>، ثم استخدم الشيفرة التالية لإسناد المبدّل إلى الرجل الموصولة معه على لوحة بيكو:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_85" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Switch</span><span class="pln">

switch </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Switch</span><span class="pun">(</span><span class="lit">18</span><span class="pun">)</span></pre>

<p>
	أما لتوصيل عدة مبدّلات، استورد تابع المبدّل <code>Switch</code> من مكتبة <code>picozero</code> ثم استخدم الشيفرة التالية لإسناد عدة مبدّلات إلى الأرجل الموصولة معها على لوحة بيكو:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_87" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Switch</span><span class="pln">

switch_1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Switch</span><span class="pun">(</span><span class="lit">18</span><span class="pun">)</span><span class="pln">
switch_2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Switch</span><span class="pun">(</span><span class="lit">22</span><span class="pun">)</span><span class="pln">
switch_3 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Switch</span><span class="pun">(</span><span class="lit">28</span><span class="pun">)</span></pre>

<p>
	ننصحك بتسمية المتغيرات بأسماء معبرة عن عملها، كأن تسمّي المبدّل المسؤول عن تشغيل المصباح الأحمر <code>red_switch</code> أو أي اسم آخر تراه مناسبًا.
</p>

<p>
	ويمكنك الاستعانة بالشيفرة التالية لتوصيل مقاومة متغيرة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_89" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Pot</span><span class="pln">

dial </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Pot</span><span class="pun">(</span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="com">#  A0 موصولة مع الرجل رقم </span></pre>

<p>
	رابعًا، أضف الشيفرة اللازمة لاستدعاء الدوال بناءً على عناصر الدخل التي استخدمتها.
</p>

<h3>
	الشيفرة اللازمة لتشغيل الشعور التالي عند الضغط على الزر
</h3>

<p>
	عرّف متغيرًا ما، وليكن <code>option</code>، لتخزين المزاج الحالي فيه واستدعاء الدالة التالية، واحرص على مطابقة أسماء الدوال في الشيفرة للدوال التي استخدمتها في الفقرة السابقة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_91" style=""><span class="pln">option </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="com"># خزّن الخيار الحالي في هذا المتغير</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> choice</span><span class="pun">():</span><span class="pln"> </span><span class="com"># استدعي الدالة التالية وعدّل قيمة متغير التخزين</span><span class="pln">
    </span><span class="kwd">global</span><span class="pln"> option
    </span><span class="kwd">if</span><span class="pln"> option </span><span class="pun">==</span><span class="pln"> </span><span class="lit">0</span><span class="pun">:</span><span class="pln">
        energised</span><span class="pun">()</span><span class="pln"> </span><span class="com"># دالة المزاج الأول</span><span class="pln">
    </span><span class="kwd">elif</span><span class="pln"> option </span><span class="pun">==</span><span class="pln"> </span><span class="lit">1</span><span class="pun">:</span><span class="pln">
            calm</span><span class="pun">()</span><span class="pln"> </span><span class="com"># دالة المزاج الثاني</span><span class="pln">
    </span><span class="kwd">elif</span><span class="pln"> option </span><span class="pun">==</span><span class="pln"> </span><span class="lit">2</span><span class="pun">:</span><span class="pln">
        focused</span><span class="pun">()</span><span class="pln"> </span><span class="com"># دالة المزاج الثالث</span><span class="pln">
    </span><span class="kwd">elif</span><span class="pln"> option </span><span class="pun">==</span><span class="pln"> </span><span class="lit">3</span><span class="pun">:</span><span class="pln">
        rgb</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln">

    </span><span class="com"># انتقل إلى الخيار الثاني</span><span class="pln">
    </span><span class="kwd">if</span><span class="pln"> option </span><span class="pun">==</span><span class="pln"> </span><span class="lit">3</span><span class="pun">:</span><span class="pln">
        option </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pln">
    </span><span class="kwd">else</span><span class="pun">:</span><span class="pln">
        option </span><span class="pun">=</span><span class="pln"> option </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pln">

button</span><span class="pun">.</span><span class="pln">when_pressed </span><span class="pun">=</span><span class="pln"> choice </span><span class="com"># استدعي الدالة التالية عند الضغط على الزر</span></pre>

<h3>
	الشيفرة اللازمة لتشغيل مزاج معين عند الضغط على زر معين
</h3>

<p>
	يمكنك إضافة عدة أزرار يستدعي كل منها دالة موافقة لمزاج مختلف عند الضغط عليها وذلك عن طريق ذكر اسمها دون استخدام الأقواس، كما في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_93" style=""><span class="pln">happy_button</span><span class="pun">.</span><span class="pln">when_pressed </span><span class="pun">=</span><span class="pln"> happy
sad_button</span><span class="pun">.</span><span class="pln">when_pressed </span><span class="pun">=</span><span class="pln"> sad
angry_button</span><span class="pun">.</span><span class="pln">when_pressed </span><span class="pun">=</span><span class="pln"> angry</span></pre>

<h3>
	الشيفرة اللازمة لاستدعاء دالة ما بناء على قيمة المقاومة المتغيرة
</h3>

<p>
	عند استخدام مقاومة متغيرة للتحكم في الخرج، سنحتاج إلى تقسيم قيم المقاومة إلى أجزاء متساوية، كأن نستخدم التابع <code>dial.value</code> للحصول على قيم تتراوح بين <strong>0</strong> و <strong>1</strong>، كما يمكننا ضرب القيمة بالرقم <strong>100</strong> للحصول على نسبة مئوية؛ فإذا كان لديك خمس قيم، يمكنك التحقق ما إذا كانت القيمة أقل من 20 أو 40 أو 60 أو 80 أو 100؛ أما إذا كان لديك ثلاث قيم يمكنك تقسيم القراءات إلى 33 و 66 و 100.
</p>

<p>
	إليك المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_95" style=""><span class="kwd">while</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">:</span><span class="pln">
    mood </span><span class="pun">=</span><span class="pln"> dial</span><span class="pun">.</span><span class="pln">value </span><span class="pun">*</span><span class="pln"> </span><span class="lit">100</span><span class="pln"> </span><span class="com"># تحويل إلى نسبة مئوية</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">mood</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">if</span><span class="pln"> mood </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">20</span><span class="pun">:</span><span class="pln">
        happy</span><span class="pun">()</span><span class="pln">
    </span><span class="kwd">elif</span><span class="pln"> mood </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">40</span><span class="pun">:</span><span class="pln">
        good</span><span class="pun">()</span><span class="pln">
    </span><span class="kwd">elif</span><span class="pln"> mood </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">60</span><span class="pun">:</span><span class="pln">
        okay</span><span class="pun">()</span><span class="pln">
    </span><span class="kwd">elif</span><span class="pln"> mood </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">80</span><span class="pun">:</span><span class="pln">
        unsure</span><span class="pun">()</span><span class="pln">
    </span><span class="kwd">else</span><span class="pun">:</span><span class="pln">
        unhappy</span><span class="pun">()</span><span class="pln">
    sleep</span><span class="pun">(</span><span class="lit">0.1</span><span class="pun">)</span></pre>

<p>
	أخيرًا، شغّل الشيفرة لاختبار المشروع، وتحقق أنه يمكنك التبديل بين الحالات المزاجية المتاحة واختيار أحدها، وإذا واجهت مشاكل عند التنفيذ في هذه الخطوة فراجع فقرة تصحيح الأخطاء السابقة.
</p>

<h3>
	تصحيح الأخطاء
</h3>

<p>
	إليك بعض المشاكل التي قد تواجهك في هذه الخطوة وكيفية إصلاحها:
</p>

<h4>
	تصحيح الأخطاء الموجودة في الشيفرة
</h4>

<ul>
	<li>
		تحقق من وجود أي رسائل خطأ في نافذة صدفة ثوني وتحقق من محتواها، إن وجدت.
	</li>
	<li>
		راجع الشيفرة التي كتبتها وتحقق من خلوها من الأخطاء، مثل نسيان علامة <strong>:</strong> مثلًا، أو وجود مسافة بادئة دون الحاجة لها.
	</li>
	<li>
		تأكد من استيراد توابع العناصر التي ستستخدمها في مشروعك من مكتبة <code>picozero</code>، مثل تابع مصباح الليد متعدد الالوان <code>RGBLED</code> أو الزر <code>Button</code>.
	</li>
	<li>
		استخدم تعليمة الطباعة <code>print</code> لإضافة شرح مختصر عند كل خطوة، مثل <code>('البدء')print</code>، أو <code>('ضبط المصباح على اللون الأخضر')print</code>.
	</li>
</ul>

<h4>
	لا تعمل بعض العناصر الإلكترونية بالدخل أو الخرج كما يجب
</h4>

<ul>
	<li>
		تأكد أن جميع عناصر الدخل أو الخرج متصلة ببعضها جيدًا، وتحقق من ثبات نقاط توصيل الأسلاك مع اللوحة ومع العناصر.
	</li>
	<li>
		تأكد أن أرقام الأرجل المستخدمة في الشيفرة مطابقة لأرقام الأرجل الموصولة مع مصباح الليد، وتأكد من إعادة وصل الأرجل، في حال فصلتها عند العمل على تصميم الهيكل الخارجي للجهاز.
	</li>
	<li>
		تحقق من وصل العناصر وفق القطبية الصحيحة، إذ قد تحتوي بعض العناصر على قطب موجب <strong>+</strong> وآخر سالب <strong>-</strong>.
	</li>
	<li>
		في حال تحققت من جميع النقاط السابقة ولا زال الجهاز لا يعمل، فجرب تبديل العناصر الإلكترونية بأخرى جديدة.
	</li>
</ul>

<p>
	حاول حل المشاكل الأخرى التي قد تواجهك عند التنفيذ وشاركنا طريقة الحل في <a href="https://io.hsoub.com/" rel="external">منصة حسوب IO</a> أو في <a href="https://academy.hsoub.com/search/" rel="">أكاديمية حسوب</a>.
</p>

<h2>
	تنفيذ الهيكل الخارجي
</h2>

<p>
	حان الآن وقت تنفيذ الهيكل الخارجي لجهاز اختبار الحالة المزاجية.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="118394" href="https://academy.hsoub.com/uploads/monthly_2023_02/mood-lamp.gif.ecfd792be8adc8622232cb6682428e2a.gif" rel=""><img alt="تنفيذ الهيكل الخارجي للجهاز" class="ipsImage ipsImage_thumbnailed" data-fileid="118394" data-ratio="65.38" data-unique="g5thfr588" style="width: 517px; height: auto;" width="517" src="https://academy.hsoub.com/uploads/monthly_2023_02/mood-lamp.gif.ecfd792be8adc8622232cb6682428e2a.gif"> </a>
</p>

<p>
	أولًا، أجب على الأسئلة التالية لتساعدك في اختيار التصميم الخارجي:
</p>

<ul>
	<li>
		ما هي المواد التي تود استخدامها؟ هل تتوفر جميعها لديك؟
	</li>
	<li>
		ما نوع المبدّلات التي تود صنعها؟ وما هي آلية عملها؟
	</li>
	<li>
		كيف ستُثبّت العناصر الإلكترونية، مثل المقاومة المتغيرة ومصباح الليد، بحيث تبقى متينةً وسهلة الاستخدام؟ وهل تود استخدام ناشرًا لضوء الليد؟
	</li>
</ul>

<p>
	<strong>معلومة</strong>: في علم البصريات Optics الذي يُعنى بدراسة الضوء والإبصار، يُعَّرف الناشر Diffuser بأنه أي مادة قادرة على تشتيت الضوء؛ فقد يكون ضوء بعض مصابيح الليد موجهًا في اتجاه معين، وبالتالي لا يمكن رؤيته جيدًا من مسافة بعيدة؛ أو قد يكون ساطعًا ومؤلمًا للعين عند النظر إليه من زاوية معينة. يساعد استخدام الناشر في حل هذه المشكلات ونشر الضوء بطريقة مريحة للعين ومُرضية، كما أنه بسيط الصنع، إذ ما عليك سوى استخدام ورقة رقيقة لتغطية المصباح والحصول على ناشر.
</p>

<p>
	إليك المثال التالي الذي استخدمنا فيه بالونًا لنشر الضوء، كما استخدمنا عدة بطاقات مختلفة الحجم وغلّفناها بورق القصدير والنحاس لغلق الدارة وتفعيل الحالة المزاجية الموافقة للبطاقة.
</p>

<div class="ipsEmbeddedVideo" contenteditable="false">
	   
	<div>
		       <iframe allowfullscreen="" frameborder="0" height="506" src="https://player.vimeo.com/video/795265858?autoplay=0&amp;color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="900"></iframe>    
	</div>
</div>

<p>
	ثانيًا، جهز المواد التي ستستخدمها لتنفيذ الهيكل الخارجي لجهازك. إليك بعض الاقتراحات:
</p>

<ul>
	<li>
		الورق المقوى.
	</li>
	<li>
		المواد البلاستيكية المعاد تدويرها.
	</li>
	<li>
		ألعاب قديمة أو قطع الليغو Lego.
	</li>
	<li>
		شريط لاصق.
	</li>
	<li>
		كما يمكنك استخدام الطابعة ثلاثية الأبعاد إن توفر لك ذلك.
	</li>
</ul>

<p>
	لا تنسَ طلب مساعدة أحد البالغين عند الحاجة لاستخدام المقص، أو أي أداة حادة أو ساخنة.
</p>

<p>
	ثالثًا، اصنع الغلاف الخارجي والواجهة لجهازك بالاستعانة بالإرشادات التالية، واطلب مساعدة أحد البالغين عند الحاجة.
</p>

<h3>
	تثبيت العناصر داخل الورق المقوى أو البلاستيك
</h3>

<p>
	بإمكانك تثبيت مصابيح الليد أو الأجراس أو المقاومات المتغيرة داخل قطع من الورق المقوى أو البلاستيك، وذلك بصنع ثقوب وإدخال العناصر وأسلاك التوصيل فيها، كما هو موضح في الصورة التالية:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118403" href="https://academy.hsoub.com/uploads/monthly_2023_02/pre-soldered-mount.jpg.16db64c8eba805e451b4299117423be1.jpg" rel=""><img alt="تثبيت العناصر داخل الورق المقوى أو البلاستيك" class="ipsImage ipsImage_thumbnailed" data-fileid="118403" data-ratio="127.12" data-unique="bew7b95r3" style="width: 472px; height: auto;" width="472" src="https://academy.hsoub.com/uploads/monthly_2023_02/pre-soldered-mount.thumb.jpg.11f704c9ba99db2a2bedfb520ac6a854.jpg"></a>
</p>

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

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118398" href="https://academy.hsoub.com/uploads/monthly_2023_02/non-soldered-mount.jpg.672655fe8b3e3034a4050ef6c9aca68d.jpg" rel=""><img alt="كيفية تثبيت العناصر داخل الورق المقوى أو البلاستيك" class="ipsImage ipsImage_thumbnailed" data-fileid="118398" data-ratio="94.00" data-unique="ca2uago7x" style="width: 500px; height: auto;" width="638" src="https://academy.hsoub.com/uploads/monthly_2023_02/non-soldered-mount.thumb.jpg.3ff3ea0a630f432751c9c87d2c786bf6.jpg"></a>
</p>

<p>
	استخدم الشريط اللاصق لتثبيت العناصر في مكانها.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118409" href="https://academy.hsoub.com/uploads/monthly_2023_02/taped-mount.jpg.f3e695e25661ede77fbd4e91f04cbc7d.jpg" rel=""><img alt="طريقة تثبيت العناصر داخل الورق المقوى أو البلاستيك" class="ipsImage ipsImage_thumbnailed" data-fileid="118409" data-ratio="97.00" data-unique="w09dg72sa" style="width: 500px; height: auto;" width="618" src="https://academy.hsoub.com/uploads/monthly_2023_02/taped-mount.thumb.jpg.beea5ec4fc670e2d7d4e59c522798907.jpg"></a>
</p>

<h3>
	تبديد الضوء المنبعث من مصباح الليد
</h3>

<p>
	نحصل عند تبديد أو نشر ضوء مصباح الليد على تأثير لطيف، وخاصة عند استخدام مصابيح الليد الشفافة، ذات اللون الواحد أو متعددة الألوان، وذلك بوضع المصباح خلف ورقة رقيقة أو شفافة، أو خلف شريط لاصق شفاف، مما سيجعل الضوء ينتشر على مساحة أوسع وبسطوع أقل، فيصبح أكثر راحةً للعين.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="118394" href="https://academy.hsoub.com/uploads/monthly_2023_02/mood-lamp.gif.ecfd792be8adc8622232cb6682428e2a.gif" rel=""><img alt="تبديد الضوء المنبعث من مصباح الليد" class="ipsImage ipsImage_thumbnailed" data-fileid="118394" data-ratio="65.38" data-unique="g5thfr588" style="width: 517px; height: auto;" width="517" src="https://academy.hsoub.com/uploads/monthly_2023_02/mood-lamp.gif.ecfd792be8adc8622232cb6682428e2a.gif"> </a>
</p>

<p>
	كما يمكنك توجيه الضوء في اتجاه معين باستخدام ورقة بيضاء، وذلك لتحصل على أكبر قدر ممكن من الضوء.
</p>

<h3>
	تثبيت أسلاك التوصيل باستخدام الشريط اللاصق
</h3>

<p>
	يمكنك تثبيت أسلاك التوصيل باستخدام الشريط اللاصق وإزالة الشريط اللاصق فيما بعد بكل سهولة لإعادة استخدام العناصر عند الحاجة.
</p>

<h3>
	استخدام سكين الحرف متعدد الاستخدامات
</h3>

<p>
	تُعد سكاكين الحرف Crafts مفيدة عند صنع الحرف اليدوية، لكن يجب أن تكون حذرًا جدًا عند استخدامها لأنها حادة جدًا ويمكن أن تسبب جروحًا وإصابات. احرص على وجود شخص بالغ عند استخدامك للسكاكين، أو اطلب منه استخدامها عوضًا عنك، كما ننصحك باستخدام لوح القص لحماية الأسطح، أو باستخدام لوح التقطيع الخشبي المتوفر في كل المطابخ.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="118389" href="https://academy.hsoub.com/uploads/monthly_2023_02/Box-cutter.jpg.f5e5a7fcbc84a912bb2f2c75eaf62015.jpg" rel=""><img alt="استخدام سكين الحرف متعدد الاستخدامات" class="ipsImage ipsImage_thumbnailed" data-fileid="118389" data-ratio="57.33" data-unique="xsxk2guzv" style="width: 450px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_02/Box-cutter.thumb.jpg.18abdb8827833025dbd4d60af56e2e55.jpg"> </a>
</p>

<p>
	رابعًا، ثبت العناصر الإلكترونية في الهيكل الخارجي لجهازك وصِلها مع واجهة الجهاز.
</p>

<h3>
	توصيل الأسلاك ببعضها
</h3>

<p>
	قد تحتاج إلى أسلاك توصيل طويلة جدًا لتوصيل مصابيح الليد مع أرجل لوحة بيكو، أو يمكنك وصل الأسلاك ببعضها للحصول على سلك طويل، وذلك عبر توصيل سلك ذو نهايات دبوس-مقبس مع سلك ذو نهايات مقبس-مقبس للحصول على سلك مقبس-مقبس طويل جدًا، وتدعى هذه الطريقة باسم سلسلة الأقحوان daisy chaining.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="JPG" data-fileid="119439" href="https://academy.hsoub.com/uploads/monthly_2023_02/daisy-chain-ends.JPG.3f67974c79f716fa3a04a3663d9e5737.JPG" rel=""><img alt="توصيل الأسلاك ببعضها" class="ipsImage ipsImage_thumbnailed" data-fileid="119439" data-ratio="72.77" data-unique="1whe8nmb8" style="width: 470px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2023_02/daisy-chain-ends.thumb.JPG.d151d9e86267dc9da7325ffb76503cb4.JPG"></a>
</p>

<p>
	ننصحك باستخدام سلكين لهما اللون نفسه ليسهل تتبع السلك ومعرفة العنصر الموصول معه.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="JPG" data-fileid="119441" href="https://academy.hsoub.com/uploads/monthly_2023_02/daisy-chain.JPG.e24bcec3fab836bea05380c50735eb88.JPG" rel=""><img alt="كيفية توصيل الأسلاك ببعضها" class="ipsImage ipsImage_thumbnailed" data-fileid="119441" data-ratio="64.68" data-unique="h9vunrubx" style="width: 470px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2023_02/daisy-chain.thumb.JPG.b31c4cf05695290ccc6cba0d505b0b72.JPG"></a>
</p>

<p>
	تكمن مشكلة هذه الطريقة في أن الأسلاك قد تنفصل عن بعضها، ولذلك ينصح بلصقها بقطعة صغيرة من الشريط اللاصق.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="JPG" data-fileid="119440" href="https://academy.hsoub.com/uploads/monthly_2023_02/tape-daisy-chain.JPG.beaea54015078afc8e9f85130a4f41f2.JPG" rel=""><img alt="توصيل الأسلاك ببعضها ولصقها بشريط لاصق" class="ipsImage ipsImage_thumbnailed" data-fileid="119440" data-ratio="60.21" data-unique="jl36sceat" style="width: 470px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2023_02/tape-daisy-chain.thumb.JPG.9c1ac059b2d51ac4842946404516c540.JPG"></a>
</p>

<p>
	خامسًا، شغّل الشيفرة واختبر عمل كل عنصر بدقة، وتأكد أن جميع العناصر تعمل كما ينبغي بعد أن ثبّتها في جهازك. واستعن بفقرة تصحيح الأخطاء إذا واجهت مشكلةً ما.
</p>

<h2>
	ترقية المشروع
</h2>

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

<p>
	جرّب جهازك مع الآخرين للحصول على ملاحظاتهم وترقية المشروع بناءً عليها، وننصحك بالإطلاع على الشيفرة الخاصة بالمشاريع التي ذكرناها في المقدمة لتتعرف على آلية عملها وتستوحي بعض الأفكار منها.
</p>

<p>
	إليك بعض الاقتراحات التي يمكنك تنفيذها:
</p>

<ul>
	<li>
		اختبار الجهاز مع الأصدقاء والعائلة لتحسين تجربة الاستخدام وفقًا لآرائهم.
	</li>
	<li>
		إضافة المزيد من الحالات المزاجية، والألوان، والتأثيرات الضوئية.
	</li>
	<li>
		تحسين التصميم الخارجي للجهاز.
	</li>
	<li>
		إضافة الأصوات على الجهاز باستخدام الأجراس الإلكترونية Buzzers.
	</li>
</ul>

<p>
	كما يمكنك التعديل على شيفرة المشروع وتطوير نمط الوميض، والنبض والتكرار، أو إضافة توقيت، وألوان، أو تحديد عدد معين لمرات تكرار الأنماط، وذلك كما يلي:
</p>

<h3>
	إضفاء تأثير الوميض أو النبض على مصباح ليد
</h3>

<p>
	يمكنك إضفاء تأثير الوميض أو النبض على مصباح ليد عادي عن طريق استخدام دالة الوميض <code>blink</code> لتشغيل وإطفاء المصباح بصورةٍ متكررة.
</p>

<p>
	الشيفرة اللازمة لتطبيق تأثير الوميض على مصباح ليد عادي باستخدام دالة <code>blink</code> هي على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_109" style=""><span class="pln">led</span><span class="pun">.</span><span class="pln">blink</span><span class="pun">()</span><span class="pln"> </span><span class="com"># تشغيل المصباح لثانية واحدة ثم إطفاءه لثانية</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Blinking"</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اطبع ما بين القوسين مباشرةً </span><span class="pln">

sleep</span><span class="pun">(</span><span class="lit">6</span><span class="pun">)</span><span class="pln">
led</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span></pre>

<p>
	والشيفرة اللازمة لتطبيق تأثير الوميض عددًا معينًا من المرات، هي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_111" style=""><span class="pln">led</span><span class="pun">.</span><span class="pln">blink</span><span class="pun">(</span><span class="pln">on_time</span><span class="pun">=</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> off_time</span><span class="pun">=</span><span class="lit">0.5</span><span class="pun">,</span><span class="pln"> n</span><span class="pun">=</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> wait</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Finished blinking"</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اطبع ما بين القوسين بعد تشغيل المصباح وإطفاءه ثلاث مرات</span></pre>

<p>
	لاحظ أنه عند عدم ضبط مدة الإطفاء <code>off_time</code>، ستكون مدتها مطابقةً لمدة التشغيل <code>on_time</code>.
</p>

<p>
	أما الشيفرة اللازمة لزيادة سطوع المصباح تدريجيًا باستخدام تابع النبض <code>pulse</code>، تكون على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_113" style=""><span class="pln">led</span><span class="pun">.</span><span class="pln">pulse</span><span class="pun">()</span><span class="pln"> </span><span class="com"># زيادة السطوع لمدة ثانية واحدة ثم تخفيفه ثانية</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Pulsing"</span><span class="pun">)</span><span class="pln"> </span><span class="com">#  اطبع ما بين القوسين مباشرةً                                                                                     </span></pre>

<p>
	توضح الشيفرة التالية الشيفرة اللازمة للتحكم في سرعة النبض وعدد مرات التكرار
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_115" style=""><span class="pln">led</span><span class="pun">.</span><span class="pln">pulse</span><span class="pun">(</span><span class="pln">fade_in_time</span><span class="pun">=</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> fade_out_time</span><span class="pun">=</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> n</span><span class="pun">=</span><span class="lit">4</span><span class="pun">,</span><span class="pln"> wait</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln"> </span><span class="com">#زيادة السطوع لمدة ثانيتين ثم تخفيفه لمدة ثانية</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Finished pulsing"</span><span class="pun">)</span><span class="pln"> </span><span class="com"># طبع ما بين القوسين بعد 4 نبضات</span></pre>

<p>
	كما يمكنك دمج التأثيرين السابقين للحصول على تأثيرات ساحرة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_117" style=""><span class="pln">led</span><span class="pun">.</span><span class="pln">blink</span><span class="pun">(</span><span class="pln">on_time</span><span class="pun">=</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> off_time</span><span class="pun">=</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> fade_in_time</span><span class="pun">=</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> fade_out_time</span><span class="pun">=</span><span class="lit">1</span><span class="pun">)</span><span class="pln"> </span><span class="com"># تشغيل المصباح لثانية واحدة ثم إطفاءه لثانية وتخفيف السطوع أثناء ذلك</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Fancy"</span><span class="pun">)</span><span class="pln"> </span><span class="com">#  اطبع ما بين القوسين مباشرةً </span></pre>

<p>
	<strong>ملاحظة:</strong> يستمر تنفيذ دالتي الوميض <code>blink</code> والنبض <code>pulse</code> إلى أن يُستدعى تابع الإطفاء <code>off</code> أو إلى أن نستدعي الدالتين بإعدادات جديدة.
</p>

<p>
	استخدم التعليمة <code>wait=True</code> وحدد <code>n</code> والتي هي عدد مرات تنفيذ التأثير.
</p>

<h3>
	إضفاء تأثير الوميض أو النبض أو التكرار على مصباح متعدد الألوان
</h3>

<p>
	استخدم دالة الوميض <code>blink</code> لتبديل الألوان في مصباح الليد متعدد الألوان، كما هو مبين في الشيفرة التالية:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_119" style=""><span class="pln">rgb</span><span class="pun">.</span><span class="pln">blink</span><span class="pun">()</span><span class="pln"> </span><span class="com"># تشغيل اللون الأحمر لمدة ثانية، ثم الأخضر لثانية، ثم الأزرق لثانية</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Blinking"</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اطبع ما بين القوسين مباشرةً </span><span class="pln">

sleep</span><span class="pun">(</span><span class="lit">6</span><span class="pun">)</span><span class="pln">
rgb</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span></pre>

<p>
	أما الشيفرة اللازمة لتطبيق تأثير الوميض على لون واحد في مصباح متعدد الألوان فهي على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_121" style=""><span class="com"># اجعل اللون البنفسجي يومض لمدة ثانيتين، ثم أطفئه لنصف ثانية</span><span class="pln">
rgb</span><span class="pun">.</span><span class="pln">blink</span><span class="pun">(</span><span class="pln">on_times</span><span class="pun">=(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.5</span><span class="pun">),</span><span class="pln"> colors</span><span class="pun">=((</span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">255</span><span class="pun">),</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)),</span><span class="pln"> wait</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">,</span><span class="pln"> n</span><span class="pun">=</span><span class="lit">3</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Finished blinking"</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اطبع ما بين القوسين بعد ثلاثة تكرارات</span></pre>

<p>
	اعتمد على الشيفرة التالية لتطبيق تأثير الوميض عددًا معينًا من المرات بتوقيت وألوان مختلفة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_123" style=""><span class="com"># اجعل اللون البنفسجي يومض لمدة ثانية، والأخضر لنصف ثانية، والأزرق لربع ثانية</span><span class="pln">
rgb</span><span class="pun">.</span><span class="pln">blink</span><span class="pun">((</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.5</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.25</span><span class="pun">),</span><span class="pln"> colors</span><span class="pun">=((</span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">),</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">),</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">255</span><span class="pun">)),</span><span class="pln"> wait</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">,</span><span class="pln"> n</span><span class="pun">=</span><span class="lit">2</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Finished blinking"</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اطبع ما بين القوسين بعد تكرارين</span></pre>

<p>
	لاحظ أنه عند عدم تحديد مدة الإطفاء <code>off_time</code>، ستكون مدتها مطابقة لمدة التشغيل <code>on_time</code>.
</p>

<p>
	استعن بالشيفرة التالية لتغيير سطوع المصباح متعدد الألوان ولونه تدريجيًا باستخدام تابع النبض <code>pulse</code>:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_125" style=""><span class="pln">rgb</span><span class="pun">.</span><span class="pln">pulse</span><span class="pun">()</span><span class="pln"> </span><span class="com"># شغّل اللون الأحمر لمدة ثانية، ثم الأخضر لثانية، ثم الأزرق</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Pulsing"</span><span class="pun">)</span><span class="pln">  </span><span class="com"># اطبع ما بين القوسين مباشرةً                                 </span></pre>

<p>
	للتحكم في سرعة النبض للمصباح متعدد الألوان وعدد مرات التكرار:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_127" style=""><span class="com">#  خفف سطوع اللون البنفسجي لمدة ثانيتين، ثم أطفئ المصباح لمدة نصف ثانية وكرر العملية 3 مرات</span><span class="pln">
rgb</span><span class="pun">.</span><span class="pln">pulse</span><span class="pun">(</span><span class="pln">fade_times</span><span class="pun">=(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.5</span><span class="pun">),</span><span class="pln"> colors</span><span class="pun">=((</span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">255</span><span class="pun">),</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)),</span><span class="pln"> wait</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">,</span><span class="pln"> n</span><span class="pun">=</span><span class="lit">3</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Finished pulsing"</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اطبع ما بين القوسين بعد ثلاثة تكرارات</span></pre>

<p>
	أما للتبديل بين الألوان تدريجيًا باستخدام تابع التكرار <code>cycle</code>، تكون الشيفرة على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_129" style=""><span class="pln">rgb</span><span class="pun">.</span><span class="pln">cycle</span><span class="pun">()</span><span class="pln"> </span><span class="com"># التدوير بين الألوان تدريجيًا من الأحمر للأخضر، ثم الأخضر للأزرق، ثم الأزرق للأحمر</span><span class="pln">

</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Cycle"</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اطبع ما بين القوسين مباشرةً </span></pre>

<p>
	تساعد الشيفرة التالية في التحكم في اللون والمدة وعدد مرات التكرار
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_7410_131" style=""><span class="com"># بدّل بين الألوان بترتيب معاكس وبسرعة أبطأ</span><span class="pln">
rgb</span><span class="pun">.</span><span class="pln">cycle</span><span class="pun">(</span><span class="pln">fade_times</span><span class="pun">=</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> colors</span><span class="pun">=((</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">255</span><span class="pun">),</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">),</span><span class="pln"> </span><span class="pun">(</span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)),</span><span class="pln"> wait</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">,</span><span class="pln"> n</span><span class="pun">=</span><span class="lit">2</span><span class="pun">)</span><span class="pln">
rgb</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span></pre>

<p>
	<strong>ملاحظة:</strong> يستمر تنفيذ دالتي الوميض <code>blink</code> والنبض <code>pulse</code> إلى أن يُستدعى تابع الإطفاء <code>off</code> أو إلى أن نستدعي الدالتين بإعدادات جديدة.
</p>

<p>
	استخدم التعليمة <code>wait=True</code> واضبط <code>n</code> والتي هي عدد مرات تنفيذ التأثير.
</p>

<p>
	إليك الفيديو التالي ليوضح لك تأثير الوميض <code>blink</code> وخفوت الإضاءة عند تطبيق تأثير النبض <code>pulse</code>، كما يمكنك التعديل على جهازك لاحقًا وإضافة حالات مزاجية جديدة بناءً على المواقف التي تمر بها. والإطلاع على <a href="https://wakelet.com/wake/3IamveQ7RR5VNpnRGT_qC" rel="external nofollow">معرض مشاريع أداة اختبار الحالة المزاجية</a> لتستوحي منها بعض الأفكار، ولا تنسى مشاركة مشروعك مع الأصدقاء أو مشاركته معنا على <a href="https://io.hsoub.com/" rel="external">منصة حسوب IO</a>.
</p>

<div class="ipsEmbeddedVideo" contenteditable="false">
	   
	<div>
		       <iframe allowfullscreen="" frameborder="0" height="506" src="https://player.vimeo.com/video/795265958?autoplay=0&amp;color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="600"></iframe>    
	</div>
</div>

<h2>
	الخاتمة
</h2>

<p>
	تهانينا، فقد أتممت مشروع تصميم وتنفيذ جهاز لعرض الحالة المزاجية باستخدام لوحة راسبيري باي بيكو
</p>

<p>
	ننصحك بتنفيذ مشروع تصميم وتنفيذ آلة موسيقية باستخدام لوحة راسبيري باي بيكو في خطوتك التالية، وإذا واجهت مشاكلًا عند تنفيذ هذا المشروع، يمكنك الحصول على الدعم والمساعدة عبر إضافة سؤالك في قسم الأسئلة والأجوبة في <a href="https://academy.hsoub.com/questions/" rel="">أكاديمية حسوب</a>.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://projects.raspberrypi.org/en/projects/mood-indicator/" rel="external nofollow">Mood indicator</a> من <a href="https://raspberrypi.org/" rel="external nofollow">الموقع الرسمي لراسبيري باي</a>.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%B5%D9%86%D8%B9-%D9%82%D9%84%D8%A8-%D9%86%D8%A7%D8%A8%D8%B6-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1862/" rel="">صنع قلب نابض باستخدام لوحة راسبيري باي بيكو</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%85%D8%AD%D8%A7%D9%83%D8%A7%D8%A9-%D9%84%D9%85%D9%81%D8%B1%D9%82%D8%B9%D8%A7%D8%AA-%D8%A7%D9%84%D8%AD%D9%81%D9%84%D8%A7%D8%AA-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1861/" rel="">تصميم محاكاة لمفرقعات الحفلات باستخدام لوحة راسبيري باي بيكو</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D8%B5%D8%A8%D8%A7%D8%AD-%D9%84%D9%8A%D8%AF-%D9%8A%D9%88%D9%85%D8%B6-%D9%88%D9%81%D9%82-%D9%86%D9%85%D8%B7-%D9%85%D8%B9%D9%8A%D9%86-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1848/" rel="">إنشاء مصباح ليد يومض وفق نمط معين باستخدام حاسوب راسبيري باي بيكو</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1893</guid><pubDate>Fri, 03 Feb 2023 16:00:00 +0000</pubDate></item><item><title>&#x635;&#x646;&#x639; &#x642;&#x644;&#x628; &#x646;&#x627;&#x628;&#x636; &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x644;&#x648;&#x62D;&#x629; &#x631;&#x627;&#x633;&#x628;&#x64A;&#x631;&#x64A; &#x628;&#x627;&#x64A; &#x628;&#x64A;&#x643;&#x648;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D8%B5%D9%86%D8%B9-%D9%82%D9%84%D8%A8-%D9%86%D8%A7%D8%A8%D8%B6-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1862/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2023_01/763615467_---------.jpg.24717cc08dad815d558bc3e798151554.jpg" /></p>
<p>
	سنتعلم في هذه المقال كيفية صنع قلب نابض من الورق ومصباح ليد LED ومقاومة متغيرة potentiometer للتحكم بمعدل ضربات القلب.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="116313" href="https://academy.hsoub.com/uploads/monthly_2023_01/heartbeat.gif.09bcb3480bd1af0e91139cab1825b7a7.gif" rel=""><img alt="صنع قلب نابض من الورق ومصباح ليد ومقاومة متغيرة" class="ipsImage ipsImage_thumbnailed" data-fileid="116313" data-ratio="99.75" data-unique="tvzfc5i5k" style="width: 400px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/heartbeat.gif.09bcb3480bd1af0e91139cab1825b7a7.gif"> </a>
</p>

<p>
	شغّل الفيديو وراقب ما الذي سيحدث عند تدوير قرص المقاومة المتغيرة.
</p>

<div class="ipsEmbeddedVideo" contenteditable="false">
	<iframe allowfullscreen="" frameborder="0" height="506" src="https://player.vimeo.com/video/787809744?autoplay=0&amp;color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="900"></iframe>
</div>

<p>
	<strong>تحذير</strong>: سنستخدم في هذا المشروع أضواءً وامضةً والتي قد تسبب اختلاجات أو نوبات شقيقة عند نسبة صغيرة جدًا من الناس، كما أن هذه الأعراض قد تظهر عند الأشخاص السليمين الذين لم يعانوا مسبقًا من الشقيقة أو من نوبات الصرع المُحرَضة من قِبَل الإضاءة العالية، لذلك ننصحك بإيقاف العمل على هذا المشروع ومراجعة طبيب مباشرةً إذا واجهت أية أعراض.
</p>

<p>
	ستتعلم في هذا المشروع ما يلي:
</p>

<ul>
	<li>
		كيفية استخدام المقاومة المتغيرة ذات القرص dial لتغيير معدل ضربات القلب.
	</li>
	<li>
		كيفية الحصول على إضاءة نابضة باستخدام مصباح الليد.
	</li>
	<li>
		تشغيل لوحة راسبيري باي بيكو Raspberry Pi Pico من مصدر طاقة غير الحاسوب.
	</li>
</ul>

<p>
	<strong>معلومة:</strong> يعطينا الدخل التشابهي Analogue مجالًا من القيم المختلفة، على عكس النظام الرقمي Digital الذي يعطي إما القيمة <strong>1</strong> أو <strong>0</strong> (تشغيل أو إطفاء). تُعّد المقاومة المتغيرة من أجهزة الدخل التشابهي، إذ أن لها قرص دوّار يمكن من خلاله زيادة القيم أو إنقاصها. تحتوي لوحة بيكو على أرجل دخل تشابهية يمكننا استخدامها في مشروعنا لقراءة القيم التشابهية.
</p>

<h2>
	متطلبات المشروع
</h2>

<h3>
	عتاد:
</h3>

<ol>
	<li>
		لوحة حاسوب راسبيري باي بيكو مع أرجل مثبتة عليها.
	</li>
	<li>
		كبل USB لنقل البيانات ذو نهايات من النوع USB A و micro USB.
	</li>
	<li>
		مصباح ليد أحمر اللون، أو اللون الذي تفضله مع مقاومة موصولة مع أسلاك من نوع مقبس.
	</li>
	<li>
		مقاومة متغيرة واحدة.
	</li>
	<li>
		أسلاك توصيل ذات نهايات مقبس-مقبس socket-socket (عدد 3).
	</li>
	<li>
		أسلاك توصيل ذات نهايات دبوس-مقبس pin-socket (عدد 3).
	</li>
	<li>
		بعض مستلزمات الأشغال اليدوية: ورق ملون أحمر اللون إن وجد، ورقائق قصدير، وشريط لاصق.
	</li>
	<li>
		مصباح ليد أزرق اللون ومقاومة وأسلاك توصيل إضافية (اختياري).
	</li>
</ol>

<h3>
	أسلاك التوصيل
</h3>

<p>
	تُستخدم أسلاك التوصيل لنقل التيار الإلكتروني بين العناصر الإلكترونية، عند إنشاء النماذج الأولية من المشاريع لسهولة توصيلها مع العناصر وفصلها، دون الحاجة لتلحيمها (إنشاء توصيلات دائمة عن طريق صهر المعدن)، وتوجد ثلاثة أنواع من أسلاك التوصيل حسب نهاياتها:
</p>

<ul>
	<li>
		أسلاك توصيل ذات نهايات مقبس-مقبس socket-socket.
	</li>
	<li>
		أسلاك توصيل ذات نهايات دبوس-مقبس pin-socket.
	</li>
	<li>
		أسلاك توصيل ذات نهايات دبوس-دبوس pin-pin.
	</li>
</ul>

<h4>
	نهاية الدبوس
</h4>

<p>
	هي قطعة معدنية قصيرة تخرج من الطرف البلاستيكي الأسود للسلك،و يمكن إدخالها في طرف المقبس، أو لوحة التجارب، وهي على الشكل التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116317" href="https://academy.hsoub.com/uploads/monthly_2023_01/pin.png.744f32d51b7d2b6db49e4e357acbe402.png" rel=""><img alt="أداة نهاية الدبوس" class="ipsImage ipsImage_thumbnailed" data-fileid="116317" data-ratio="151.81" data-unique="ij1tlfkbd" style="width: 249px; height: auto;" width="249" src="https://academy.hsoub.com/uploads/monthly_2023_01/pin.png.744f32d51b7d2b6db49e4e357acbe402.png"> </a>
</p>

<h4>
	نهاية المقبس
</h4>

<p>
	هي ثقب في الطرف البلاستيكي الأسود للسلك يمكن إدخال نهاية الدبوس، أو أرجل العناصر الإلكترونية فيه.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116328" href="https://academy.hsoub.com/uploads/monthly_2023_01/socket.png.4066113d3c442baaa429009821bfc2a1.png" rel=""><img alt="أداة نهاية المقبس" class="ipsImage ipsImage_thumbnailed" data-fileid="116328" data-ratio="114.64" data-unique="1t385f3hl" style="width: 280px; height: auto;" width="356" src="https://academy.hsoub.com/uploads/monthly_2023_01/socket.png.4066113d3c442baaa429009821bfc2a1.png"> </a>
</p>

<h4>
	شراء أسلاك التوصيل
</h4>

<p>
	قد تلاحظ عند شرائك أسلاك التوصيل أنها تسمى ذكر - ذكر أو أنثى - أنثى، أو ذكر - أنثى، وهي تسميات قديمة إذ يدل الذكر على نهاية الدبوس، والأنثى على نهاية المقبس، ويجب استخدام مصطلحي <strong>الدبوس</strong> و<strong>المقبس</strong> لوصف أسلاك التوصيل لأنها أكثر شمولًا.
</p>

<h3>
	برمجيات
</h3>

<ol>
	<li>
		برنامج ثوني Thonny: وهو البيئة البرمجية التي سنستخدمها لكتابة الشيفرة <a href="https://academy.hsoub.com/programming/python/%D8%A7%D9%84%D9%85%D8%B1%D8%AC%D8%B9-%D8%A7%D9%84%D8%B4%D8%A7%D9%85%D9%84-%D8%A5%D9%84%D9%89-%D8%AA%D8%B9%D9%84%D9%85-%D9%84%D8%BA%D8%A9-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-r735/" rel="">بلغة بايثون</a>.
	</li>
</ol>

<h4>
	تثبيت برنامج ثوني على نظام تشغيل راسبيري باي
</h4>

<p>
	يأتي برنامج ثوني مثبتًا مع <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AC%D9%88%D9%84%D8%A9-%D9%81%D9%8A-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%A7%D9%86-%D9%86%D8%B8%D8%A7%D9%85-%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-r1371/" rel="">نظام تشغيل راسبيري باي</a>، المعروف سابقًا براسبيان Raspbian، لكن قد تحتاج إلى تحديثه. انقر على الأيقونة في الزاوية العلوية اليسرى من الشاشة لفتح نافذة الطرفية Terminal، أو اضغط المفاتيح التالية معًا <strong>Ctrl+Alt+T</strong>. ثم اكتب الأمر التالي لتحديث <a href="https://academy.hsoub.com/files/24-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%84%D9%85%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D9%86/" rel="">نظام التشغيل</a> وبرنامج ثوني:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_613_16" style=""><span class="pln">sudo apt update </span><span class="pun">&amp;&amp;</span><span class="pln"> sudo apt upgrade </span><span class="pun">-</span><span class="pln">y</span></pre>

<h4>
	تثبيت برنامج ثوني على أنظمة التشغيل الأخرى
</h4>

<p>
	يمكنك تثبيت ثوني على الحواسيب العاملة <a href="https://academy.hsoub.com/devops/linux/%D9%85%D8%A7-%D9%87%D9%88-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%8A%D9%86%D9%83%D8%B3%D8%9F-r451/" rel="">بنظام تشغيل لينكس</a>، أو ويندوز، أو ماك، وذلك من الموقع الرسمي <a href="https://thonny.org/" rel="external nofollow">thonny.org</a>. انقر على رابط التنزيل الموافق لنظام تشغيل حاسوبك من الزاوية العلوية اليمنى في الموقع، ثم انقر على الملفات بعد تنزيلها، وقد تظهر لك الرسالة التالية على نظام ويندوز:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116334" href="https://academy.hsoub.com/uploads/monthly_2023_01/thonny-site.png.0b1b2ef83e6521c9e9057ea609925e42.png" rel=""><img alt="النافذة الظاهرة على نظام ويندوز" class="ipsImage ipsImage_thumbnailed" data-fileid="116334" data-ratio="67.34" data-unique="qrqkna1qm" style="width: 297px; height: auto;" width="297" src="https://academy.hsoub.com/uploads/monthly_2023_01/thonny-site.png.0b1b2ef83e6521c9e9057ea609925e42.png"> </a>
</p>

<p>
	انقر على خيار المزيد من المعلومات "More info" ثم على التشغيل على أي حال "Run anyway".
</p>

<h4>
	التعرف على واجهة برنامج ثوني
</h4>

<p>
	عند فتح ثوني ستظهر لك الواجهة التالية:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116332" href="https://academy.hsoub.com/uploads/monthly_2023_01/thonny-editor.png.bbf507d26d4271a0a455e0bb29aa1745.png" rel=""><img alt="واجهة برنامج ثوني" class="ipsImage ipsImage_thumbnailed" data-fileid="116332" data-ratio="73.00" data-unique="ak8jm56d7" style="width: 700px; height: auto;" width="700" src="https://academy.hsoub.com/uploads/monthly_2023_01/thonny-editor.thumb.png.b865bfb53e49fa1bc32f4d373f1fe0cc.png"> </a>
</p>

<p>
	يمكنك الكتابة <a href="https://wiki.hsoub.com/Python" rel="external">بلغة بايثون</a> في النافذة الرئيسية الكبيرة، ثم النقر على زر التشغيل الأخضر <strong>Run</strong> للتنفيذ، ستظهر لك رسالة لحفظ الملف قبل تشغيله.
</p>

<p>
	اكتب الأمر التالي وشغّله:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_613_23" style=""><span class="kwd">print</span><span class="pun">(</span><span class="str">'Hello World!'</span><span class="pun">)</span></pre>

<h4>
	تغيير السمة والخط
</h4>

<p>
	يمكنك التحكم بلون الخط وحجمه وتغيير السمة المستخدمة في واجهة البرنامج، وذلك بالنقر على قائمة الأدوات <strong>Tools</strong> من الشريط أعلى الشاشة، ثم النقر على خيارات <strong>Options</strong>، ثم انقر بعدها على نافذة الخط والسمة <strong>Theme &amp; Font</strong> واختر نوع الخط والسمة التي تفضلها من النافذة المنسدلة ثم انقر على زر موافق <strong>OK</strong> عند الانتهاء.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116331" href="https://academy.hsoub.com/uploads/monthly_2023_01/theme-tab.png.c41e19264787abfcd791555adca0a7b9.png" rel=""><img alt="تغيير السمة والخط في برنامج ثوني" class="ipsImage ipsImage_thumbnailed" data-fileid="116331" data-ratio="77.20" data-unique="yxcj93x1u" style="width: 500px; height: auto;" width="480" src="https://academy.hsoub.com/uploads/monthly_2023_01/theme-tab.png.c41e19264787abfcd791555adca0a7b9.png"> </a>
</p>

<p>
	ننصحك باختيار الخطوط البسيطة الواضحة والابتعاد عن الخطوط المزخرفة أو المشابهة لخط اليد لأنها قد تجعل القراءة أصعب.
</p>

<h2>
	قراءة قيم المقاومة المتغيرة
</h2>

<p>
	توفِّر لنا المقاومة المتغيرة مجالًا من القيم المختلفة، ويمكننا مشاهدة هذه القيم والتأثير الحاصل عند تغييرها باستخدام الراسم plotter في ثوني.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="116333" href="https://academy.hsoub.com/uploads/monthly_2023_01/thonny-plotter.gif.f8ee1d46a5ed5409cb6ec2a9191fc698.gif" rel=""><img alt="قيم المقاومة المتغيرة" class="ipsImage ipsImage_thumbnailed" data-fileid="116333" data-ratio="30.67" data-unique="3eglgem3e" style="width: 450px; height: auto;" width="508" src="https://academy.hsoub.com/uploads/monthly_2023_01/thonny-plotter.gif.f8ee1d46a5ed5409cb6ec2a9191fc698.gif"> </a>
</p>

<h3>
	مبدأ عمل المقاومة المتغيرة
</h3>

<p>
	المقاومة المتغيرة هي إحدى أجهزة الدخل التشابهي، إذ تتغير قيمة المقاومة فيها بتدوير القرص الموجود أعلاها، ولها ثلاثة أرجل؛ رجل للتغذية <strong>3V3</strong>، رجل تشابهية لقراءة القيم، ورجل للتأريض <strong>GND</strong>. إذ تزوِّد الرجل <strong>3V3</strong> المقاومة بالتغذية وتتغير القراءة المُزودة من قِبَل الرجل التشابهية تبعًا لقيمة المقاومة المُعَيّرة. <strong>معلومة:</strong> تحتوي لوحة بيكو على أرجل دخل تشابهية يمكننا استخدامها لتوصيل عناصر الدخل التشابهي، مثل المقاومة المتغيرة، وهذه الأرجل هي <strong>A0</strong>، و<strong>A1</strong>، و<strong>A2</strong>، كما يمكن للوحة بيكو التحسس لقيم الجهد ضمن المجال <strong>0 فولت</strong> إلى <strong>3.3 فولت</strong> باستخدام هذه الأرجل.
</p>

<h3>
	خطوات توصيل المقاومة المتغيرة للدارة
</h3>

<p>
	أولًا، أمسك المقاومة المتغيرة كما في الصورة أدناه ولاحظ وجود القرص الدوّار أعلاها، والذي يمكن تدويره مع اتجاه دوران عقارب الساعة أو عكسه، ولاحظ وجود ثلاث أرجل للمقاومة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116324" href="https://academy.hsoub.com/uploads/monthly_2023_01/potentiometer-illustration.png.1ed34292515b1094c5f2c9b3a17598c1.png" rel=""><img alt="خطوات توصيل المقاومة المتغيرة للدارة" class="ipsImage ipsImage_thumbnailed" data-fileid="116324" data-ratio="100.00" data-unique="hjl5e12wc" style="width: 250px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/potentiometer-illustration.png.1ed34292515b1094c5f2c9b3a17598c1.png"> </a>
</p>

<p>
	عند تدوير القرص إلى أقصى اليسار يشير السهم إلى الرجل الأرضية <strong>GND</strong>، وعند تدويره إلى أقصى اليمين يشير السهم إلى رجل التغذية <strong>3V3</strong> أما الرجل الوسطى للمقاومة فهي الرجل التشابهية التي تستمد منها لوحة بيكو القيم لقراءتها.
</p>

<p>
	ثانيًا، افصل لوحة بيكو عن حاسوبك،ثم وَصّل سلك توصيل ذو نهايات مقبس-مقبس مع كل أرجل المقاومة الثلاث، ثبت التوصيلات بالشريط اللاصق إن لزم الأمر.
</p>

<ul>
	<li>
		صِل النهاية الحرة للسلك الموصول مع رجل المقاومة ذات الرقم <strong>1</strong> مع رجل الأرض <strong>GND</strong> الموجودة بين الرجلين <strong>GP21</strong> و <strong>GP22</strong>.
	</li>
	<li>
		صِل رجل المقاومة الوسطى مع الرجل <strong>GP26_A0</strong> على لوحة بيكو.
	</li>
	<li>
		صِل رجل المقاومة ذات الرقم <strong>3</strong> مع رجل التغذية <strong>3V3</strong>.
	</li>
</ul>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116322" href="https://academy.hsoub.com/uploads/monthly_2023_01/pot-diagram.png.cfd553cc4c9331d3bae6e4e4908dd5f3.png" rel=""><img alt="توصيل المقاومة المتغيرة للدارة" class="ipsImage ipsImage_thumbnailed" data-fileid="116322" data-ratio="113.00" data-unique="lpqule898" style="width: 400px; height: 565px;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/pot-diagram.thumb.png.7c371e5988a19a91adb05814f90bb8c9.png"> </a>
</p>

<p>
	ثالثًا، صِل لوحة بيكو بحاسوبك، ثم افتح برنامج ثوني وأنشئ ملفًا جديدًا واكتب فيه الشيفرة التالية لطباعة <code>print</code> قيم المقاومة المتغيرة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_613_36" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Pot</span><span class="pln"> </span><span class="com">#  هو اختصار لاسم المقاومة المتغيرة باللغة الانجليزية Pot</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> time </span><span class="kwd">import</span><span class="pln"> sleep

dial </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Pot</span><span class="pun">(</span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="com"># A0(GP26) موصولة مع الرجل رقم</span><span class="pln">

</span><span class="kwd">while</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">:</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">dial</span><span class="pun">.</span><span class="pln">value</span><span class="pun">)</span><span class="pln">
    sleep</span><span class="pun">(</span><span class="lit">0.1</span><span class="pun">)</span><span class="pln"> </span><span class="com">#إبطاء خرج المقاومة</span></pre>

<p>
	أضفنا السطر الأخير <code>(sleep(0.1</code> لإبطاء قراءة القيم وطباعتها من المقاومة المتغيرة حتى نتمكن من مشاهدتها في ثوني.
</p>

<p>
	رابعًا، شغّل الشيفرة، ثم دوّر قرص المقاومة وراقب تغيرات القيم في نافذة صدفة Shell ثوني.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116325" href="https://academy.hsoub.com/uploads/monthly_2023_01/potentiometer-shell.png.cf7bbc1d291415d65698369f931d4973.png" rel=""><img alt="تغيرات القيم في نافذة صدفة Shell ثوني" class="ipsImage ipsImage_thumbnailed" data-fileid="116325" data-ratio="39.33" data-unique="0jc5asjs5" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/potentiometer-shell.png.cf7bbc1d291415d65698369f931d4973.png"> </a>
</p>

<p>
	لاحظ أن القيم تتغير بسرعة كبيرة يَصعُب معها إدراك ما يحدث، لذلك سنستخدم الراسم plotter في ثوني لمشاهدة التغير وتمثيله بيانيًا.
</p>

<p>
	خامسًا، انقر على قائمة العرض <strong>View</strong> ثم على الراسم <strong>Plotter</strong>،ستظهر نافذة الراسم بجانب نافذة الصدفة. شغّل الشيفرة ثم دوّر قرص المقاومة وراقب تغيرات القيم على الراسم.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="116333" href="https://academy.hsoub.com/uploads/monthly_2023_01/thonny-plotter.gif.f8ee1d46a5ed5409cb6ec2a9191fc698.gif" rel=""><img alt="تغيرات قيم قرص المقاومة" class="ipsImage ipsImage_thumbnailed" data-fileid="116333" data-ratio="30.67" data-unique="3eglgem3e" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/thonny-plotter.gif.f8ee1d46a5ed5409cb6ec2a9191fc698.gif"> </a>
</p>

<p>
	يجب أن تكون القيم <strong>0</strong> (أو قريبةً من الصفر) عندما يكون قرص المقاومة مُدارًا إلى أقصى اليسار، وأن تكون <strong>1</strong> (أو قريبةً من الواحد) عندما يكون القرص في أقصى اليمين. <strong>ملاحظة:</strong> قد تظهر لك القيم معكوسةً؛ أي قد يعطي الراسم قيمة <strong>1</strong> عندما يكون قرص المقاومة في أقصى اليسار، في هذه الحال عليك التبديل بين السلكين الموصلين مع رجل التغذية <strong>3V3</strong> ورجل التأريض <strong>GND</strong>.
</p>

<h3>
	حساب عدد الضربات في الدقيقة BPM
</h3>

<p>
	تعطينا المقاومة المتغيرة قيمًا تتراوح بين <strong>0</strong> و <strong>1</strong>، ولكن علينا تحويل هذه القيم إلى قيم متوافقة من 40 (ضربات قلب رياضي رشيق) إلى 180 ضربة في الدقيقة. <strong>معلومة:</strong> <strong>BPM</strong> هي اختصار لعدد الضربات في الدقيقة Beats per minute، ويُستخدم للتعبير عن معدل نبضات القلب والإيقاع الموسيقي، وكلّما كان عدد النبضات أو الضربات أكبر كان المعدل أعلى، ويُستخدم في مجال اللياقة لقياس شدة التمارين على الجسم، إذ يُنصح ألا يتجاوز معدل ضربات قلبك 85% من المعدل الأعظمي عند ممارستك الرياضة. يمكنك حساب المعدل الأعظمي بإنقاص عمرك من العدد 220، فالمعدل الأعظمي لطفل ذو 12 عامًا هو 208 ضربة في الدقيقة، ويجب ألا يتجاوز 176 ضربة عند ممارسة التمارين، وهو نفس المعدل لإيقاع موسيقى Drum ‘n’ Bass.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="116319" href="https://academy.hsoub.com/uploads/monthly_2023_01/plotter-bpm.gif.bbf6091c4ff028705ddb5aa1bd3fdb58.gif" rel=""><img alt="حساب عدد الضربات في الدقيقة BPM" class="ipsImage ipsImage_thumbnailed" data-fileid="116319" data-ratio="31.56" data-unique="mjvg4j9s3" style="width: 450px; height: 142px;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/plotter-bpm.gif.bbf6091c4ff028705ddb5aa1bd3fdb58.gif"> </a>
</p>

<p>
	سنستخدم المقاومة المتغيرة للتحكم بمعدل ضربات القلب في مشروعنا. عدّل على الشيفرة لطباعة القيم ورسمها ضمن مجال يتراوح من 40 إلى 180 ضربة، كما يلي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_613_39" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Pot</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> time </span><span class="kwd">import</span><span class="pln"> sleep

dial </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Pot</span><span class="pun">(</span><span class="lit">0</span><span class="pun">)</span><span class="pln">

heart_min </span><span class="pun">=</span><span class="pln"> </span><span class="lit">40</span><span class="pln">
heart_max </span><span class="pun">=</span><span class="pln"> </span><span class="lit">180</span><span class="pln">
heart_range </span><span class="pun">=</span><span class="pln"> heart_max </span><span class="pun">-</span><span class="pln"> heart_min </span><span class="com"># حساب الفرق بين المعدل الأعظمي والأصغري</span><span class="pln">

</span><span class="kwd">while</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">:</span><span class="pln">
    bpm </span><span class="pun">=</span><span class="pln"> heart_min </span><span class="pun">+</span><span class="pln"> dial</span><span class="pun">.</span><span class="pln">value </span><span class="pun">*</span><span class="pln"> heart_range </span><span class="com"># تحويل قيمة المقاومة إلى معدل ضربات القلب</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">bpm</span><span class="pun">)</span><span class="pln">
    sleep</span><span class="pun">(</span><span class="lit">0.1</span><span class="pun">)</span></pre>

<p>
	لاحظ أن المجال الذي يتراوح ضمنه معدل الضربات <code>heart_range</code> يُحسب مثل متغير variable في بداية الشفرة، بينما يُحسب معدل ضربات القلب <code>bpm</code> الذي يعتمد على قيمة المقاومة المتغيرة ضمن حلقة <code>while</code>.
</p>

<p>
	شغّل الشيفرة ثم دوّر قرص المقاومة وراقب تغيرات القيم في الراسم وفي نافذة الصدفة، إذ يجب أن تتراوح القيم بين الأعداد من 40 إلى 180.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116320" href="https://academy.hsoub.com/uploads/monthly_2023_01/plotter-bpm.png.617be26d36c6caf6101f74e25bc83ea5.png" rel=""><img alt="تغيرات القيم في الراسم وفي نافذة الصدفة" class="ipsImage ipsImage_thumbnailed" data-fileid="116320" data-ratio="29.78" data-unique="sb4mgtlov" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/plotter-bpm.png.617be26d36c6caf6101f74e25bc83ea5.png"> </a>
</p>

<h3>
	تصحيح الأخطاء
</h3>

<p>
	إليك بعض الأخطاء التي قد تواجهك في هذه الخطوة وكيفية إصلاحها:
</p>

<h4>
	يظهر البرنامج رسالة خطأ في الشيفرة
</h4>

<p>
	قد تظهر لك رسالة " You have a syntax error"، تحقق عندها من الشيفرة التي كتبتها وتأكد أنها مطابقة للشيفرة في مثالنا.
</p>

<h4>
	توقفت المقاومة المتغيرة عن العمل
</h4>

<p>
	تحقق من متانة توصيل الأسلاك مع المقاومة.
</p>

<h2>
	صنع قلب ورقي
</h2>

<p>
	سنعمل في هذه الخطوة على صنع قلب من الورق لتغليف مصباح الليد وتبديد ضوءه.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpeg" data-fileid="116300" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart.jpeg.7eaf37e8e85620b9daa4df7e5ad63b08.jpeg" rel=""><img alt="الخطوة 1 من عملية صنع قلب ورقي" class="ipsImage ipsImage_thumbnailed" data-fileid="116300" data-ratio="89.11" data-unique="0xe6se59s" style="width: 450px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart.thumb.jpeg.94c6fd46793d5f1eeff80e4a7182583a.jpeg"> </a>
</p>

<p>
	<strong>معلومة:</strong> الحرف الورقية Papercraft هو فن صنع مجسمات ثنائية أو ثلاثية الأبعاد من الورق، وتتعدد الخيارات التي يمكن تنفيذها من منحوتات إلى ملابس ورقية، حتى إنشاء نماذج باستخدام الورق المُعّجن papier-mâché، أو مجسمات باستخدام فن طَيّ الورق أو ما يُعرف بفن الأوريغامي origami، وذلك إما باستخدام قصاصات من الورق أو لفّه.
</p>

<p>
	اختر إحدى الطريقتين التاليتين لصنع القلب الورقي:
</p>

<h3>
	قص شكل القلب
</h3>

<p>
	سنستخدم المقص للحصول على شكل قلب بسيط من الورق:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116296" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart-cutout.png.ad21af71308beaf49ffdd146478cbd50.png" rel=""><img alt="الخطوة 2 من عملية صنع قلب ورقي" class="ipsImage ipsImage_thumbnailed" data-fileid="116296" data-ratio="83.11" data-unique="ilcviq6nm" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart-cutout.png.ad21af71308beaf49ffdd146478cbd50.png"> </a>
</p>

<p>
	قُصَّ شكلين من الورق ثم الصقهما ببعضهما باستخدام الشريط اللاصق:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116297" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart-cutout2.png.da04846d239de396ce625c3d5d2d15b5.png" rel=""><img alt="الخطوة 3 من عملية صنع قلب ورقي" class="ipsImage ipsImage_thumbnailed" data-fileid="116297" data-ratio="73.11" data-unique="a7evg1z89" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart-cutout2.png.da04846d239de396ce625c3d5d2d15b5.png"> </a>
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116298" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart-cutout3.png.f4c09ad4e10133627260439900556c70.png" rel=""><img alt="الخطوة 4 من عملية صنع قلب ورقي" class="ipsImage ipsImage_thumbnailed" data-fileid="116298" data-ratio="64.00" data-unique="93y1bic9v" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart-cutout3.png.f4c09ad4e10133627260439900556c70.png"> </a>
</p>

<h3>
	صنع شكل القلب باستخدام فن طي الورق
</h3>

<p>
	سنتعلم في هذه الخطوة كيفية صنع شكل القلب باستخدام فن طيّ الورق (الأوريغامي).
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116301" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart.png.21f7b4c4d0732c8a29ff8afb56ab2157.png" rel=""><img alt="صنع شكل القلب باستخدام فن طي الورق" class="ipsImage ipsImage_thumbnailed" data-fileid="116301" data-ratio="88.89" data-unique="yyhinswfr" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart.png.21f7b4c4d0732c8a29ff8afb56ab2157.png"> </a>
</p>

<p>
	أولًا، احضر قطعةً مربعةً من الورق (أي نوع من الورق سيفي بالغرض، لكن استخدام الورق الرقيق سيجعل الليد أكثر سطوعًا).
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116302" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart1.png.7d9a4ad52d98b17af7cea7d21145dfbb.png" rel=""><img alt="الخطوة 1 لصنع شكل القلب باستخدام فن طي الورق" class="ipsImage ipsImage_thumbnailed" data-fileid="116302" data-ratio="98.44" data-unique="2he9elcb2" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart1.png.7d9a4ad52d98b17af7cea7d21145dfbb.png"> </a>
</p>

<p>
	ثانيًا، اطوِ الورقة إلى النصف لتحصل على شكل المثلث وذلك بطّي أحد الرؤوس حتى يلامس الرأس المقابل، ثم افرد الورقة:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116305" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart2.png.fc3dbc1d87e177618f25d4705151df4b.png" rel=""><img alt="الخطوة 2 لصنع شكل القلب باستخدام فن طي الورق" class="ipsImage ipsImage_thumbnailed" data-fileid="116305" data-ratio="54.22" data-unique="ckbk1l9ej" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart2.png.fc3dbc1d87e177618f25d4705151df4b.png"> </a>
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116306" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart3.png.8a6cf0c21772cb5c926d6ed222ec4ded.png" rel=""><img alt="الخطوة 3 لصنع شكل القلب باستخدام فن طي الورق" class="ipsImage ipsImage_thumbnailed" data-fileid="116306" data-ratio="93.78" data-unique="zzhisxkmm" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart3.png.8a6cf0c21772cb5c926d6ed222ec4ded.png"> </a>
</p>

<p>
	ثالثًا، اطوِ الورقة إلى النصف مجددًا لتحصل على شكل المثلث، ثم افردها:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116307" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart4.png.e7f5f9152b6cc9979444ce091e2d72c5.png" rel=""><img alt="الخطوة 4 لصنع شكل القلب باستخدام فن طي الورق" class="ipsImage ipsImage_thumbnailed" data-fileid="116307" data-ratio="140.19" data-unique="a95m5alfu" style="width: 428px; height: auto;" width="428" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart4.thumb.png.8ba7c8ca7a62044cfde8ab740857bcdc.png"> </a>
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116308" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart5.png.a3134661392e2b91a02c659bb32fcf7a.png" rel=""><img alt="الخطوة 5 لصنع شكل القلب باستخدام فن طي الورق" class="ipsImage ipsImage_thumbnailed" data-fileid="116308" data-ratio="95.12" data-unique="0st8qbcln" style="width: 430px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart5.png.a3134661392e2b91a02c659bb32fcf7a.png"> </a>
</p>

<p>
	رابعًا، اطوِِ الرأس العلوي إلى منتصف المربع، لتحصل على شكل الدرع.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116309" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart6.png.55f457682c9c847b344dda57edf86185.png" rel=""><img alt="الخطوة 6 لصنع شكل القلب باستخدام فن طي الورق" class="ipsImage ipsImage_thumbnailed" data-fileid="116309" data-ratio="80.00" data-unique="73orx52nk" style="width: 430px; height: auto;" width="430" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart6.png.55f457682c9c847b344dda57edf86185.png"> </a>
</p>

<p>
	خامسًا، اطوِ الرأس السفلي حتى يلامس الحافة العلوية وتحصل على الشكل التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116310" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart7.png.78d9d4c67da0a901474ffab5faea7b37.png" rel=""><img alt="الخطوة 7 لصنع شكل القلب باستخدام فن طي الورق" class="ipsImage ipsImage_thumbnailed" data-fileid="116310" data-ratio="51.78" data-unique="8hhwahq8z" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart7.png.78d9d4c67da0a901474ffab5faea7b37.png"> </a>
</p>

<p>
	سادسًا، اطوِ الحافتين اليمنى واليسرى للأعلى بزاوية 90 درجة، حتى تتلاقى حافتاهما السفليّتان في منتصف المربع:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116311" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart8.png.9721bcb046286ddbc8f56c812cacca7c.png" rel=""><img alt="الخطوة 8 لصنع شكل القلب باستخدام فن طي الورق" class="ipsImage ipsImage_thumbnailed" data-fileid="116311" data-ratio="60.00" data-unique="wj57cgbpm" style="width: 430px; height: auto;" width="430" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart8.png.9721bcb046286ddbc8f56c812cacca7c.png"> </a>
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116312" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart9.png.7e877ed65d985db097f352a34d787684.png" rel=""><img alt="الخطوة 9 لصنع شكل القلب باستخدام فن طي الورق" class="ipsImage ipsImage_thumbnailed" data-fileid="116312" data-ratio="82.56" data-unique="zjsoet3l7" style="width: 430px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart9.png.7e877ed65d985db097f352a34d787684.png"> </a>
</p>

<p>
	سابعًا، اطوِ الحواف العليا والجانبية للخلف:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116303" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart10.png.bbfd26792257ffff34fae779c7631cd8.png" rel=""><img alt="الخطوة 10 لصنع شكل القلب باستخدام فن طي الورق" class="ipsImage ipsImage_thumbnailed" data-fileid="116303" data-ratio="88.60" data-unique="kg8acwjoy" style="width: 430px; height: auto;" width="430" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart10.png.bbfd26792257ffff34fae779c7631cd8.png"> </a>
</p>

<p>
	ثامنًا، استخدم الشريط اللاصق لتثبيت الحواف على طول شكل القلب.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116304" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart11.png.d73a11716bf03af8770d4981bbc8d79d.png" rel=""><img alt="الخطوة 11 لصنع شكل القلب باستخدام فن طي الورق" class="ipsImage ipsImage_thumbnailed" data-fileid="116304" data-ratio="87.21" data-unique="wpxj3qf80" style="width: 430px; height: auto;" width="430" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart11.png.d73a11716bf03af8770d4981bbc8d79d.png"> </a>
</p>

<p>
	أصبح الشكل جاهزًا للاستخدام، اقلبه على الوجه الأخر واستمتع بإنجازك.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116301" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart.png.21f7b4c4d0732c8a29ff8afb56ab2157.png" rel=""><img alt="الخطوة 12 لصنع شكل القلب باستخدام فن طي الورق" class="ipsImage ipsImage_thumbnailed" data-fileid="116301" data-ratio="89.07" data-unique="yyhinswfr" style="width: 430px; height: auto;" width="430" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart.png.21f7b4c4d0732c8a29ff8afb56ab2157.png"> </a>
</p>

<h2>
	إضافة مصباح الليد
</h2>

<p>
	سنبث الحياة في مشروعنا بإضافة الليد وجعل القلب يبدو كأنه ينبض.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116299" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart-static.png.8f9aa0f65943d7c5b134f9b778f0a303.png" rel=""><img alt="إضافة مصباح الليد على شكل القلب" class="ipsImage ipsImage_thumbnailed" data-fileid="116299" data-ratio="99.56" data-unique="j5tgmrr5b" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart-static.png.8f9aa0f65943d7c5b134f9b778f0a303.png"> </a>
</p>

<p>
	<strong>تحذير</strong>: سنستخدم في هذا المشروع أضواءً وامضةً، ما قد يُسبب اختلاجات أو نوبات شقيقة عند نسبة صغيرة جدًا من الناس، كما أن هذه الأعراض قد تظهر عند الأشخاص السليمين الذين لم يعانوا مسبقًا من الشقيقة أو من نوبات الصرع المُحرَضة من قِبَل الإضاءة العالية، لذلك ننصحك بإيقاف العمل على هذا المشروع ومراجعة طبيب مباشرةً إذا واجهت أية أعراض.
</p>

<p>
	سنوصل في البداية مصباح ليد أحمر اللون مع مقاومة باتباع إحدى الطريقتين التاليتين:
</p>

<h3>
	توصيل الليد مع مقاومة وأسلاك توصيل باستخدام شريط عازل
</h3>

<p>
	ستحتاج لتوصيل الليد مع مقاومة وأسلاك توصيل باستخدام شريط عازل إلى ما يلي:
</p>

<ul>
	<li>
		أسلاك توصيل نوع مقبس-مقبس (عدد 2).
	</li>
	<li>
		مقاومة.
	</li>
	<li>
		مصباح ليد.
	</li>
	<li>
		شريط عازل.
	</li>
	<li>
		مقص.
	</li>
</ul>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="116341" href="https://academy.hsoub.com/uploads/monthly_2023_01/you-will-need.jpg.d5ddab9161037d8b8a9b068be6a89e40.jpg" rel=""><img alt="مستلزمات توصيل الليد مع مقاومة وأسلاك توصيل" class="ipsImage ipsImage_thumbnailed" data-fileid="116341" data-ratio="75.11" data-unique="ajzjgf4eo" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/you-will-need.jpg.d5ddab9161037d8b8a9b068be6a89e40.jpg"> </a>
</p>

<p>
	كما تعلمنا سابقًا، فإن لمصباح الليد رجل قصيرة سالبة، وأخرى طويلة هي الموجبة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116321" href="https://academy.hsoub.com/uploads/monthly_2023_01/pos-neg.png.22026096a375d671b560f8f976f25dbf.png" rel=""><img alt="مصباح الليد" class="ipsImage ipsImage_thumbnailed" data-fileid="116321" data-ratio="244.17" data-unique="po5sm471h" style="width: 120px; height: auto;" width="180" src="https://academy.hsoub.com/uploads/monthly_2023_01/pos-neg.png.22026096a375d671b560f8f976f25dbf.png"> </a>
</p>

<p>
	كما يمكنك التمييز بين القطبين عن طريق تلمّس حافة الجزء البلاستيكي للمصباح بإصبعك؛ إذ أن الطرف السالب هو الطرف الأقرب إلى الحافة المسطحة للمصباح.
</p>

<p>
	أولًا، اثنِ أحد طرفي المقاومة حول الرجل الموجبة لمصباح الليد.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="116290" href="https://academy.hsoub.com/uploads/monthly_2023_01/bend-leg.jpg.d4e9f18b181072ca7ad9d9be963dfda6.jpg" rel=""><img alt="ثني أحد طرفي المقاومة حول الرجل الموجبة لمصباح الليد" class="ipsImage ipsImage_thumbnailed" data-fileid="116290" data-ratio="75.00" data-unique="th1rf0an2" style="width: 500px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/bend-leg.jpg.d4e9f18b181072ca7ad9d9be963dfda6.jpg"> </a>
</p>

<p>
	ثم لُف طرف المقاومة حول رجل مصباح الليد ثلاث مرات، كما في الصورة التالية:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="116339" href="https://academy.hsoub.com/uploads/monthly_2023_01/twist-leg.jpg.2ce8a640c272aa38cb2a69dffd52aaad.jpg" rel=""><img alt="لف طرف المقاومة حول رجل مصباح الليد ثلاث مرات" class="ipsImage ipsImage_thumbnailed" data-fileid="116339" data-ratio="75.00" data-unique="uvv78bfgd" style="width: 500px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/twist-leg.jpg.2ce8a640c272aa38cb2a69dffd52aaad.jpg"> </a>
</p>

<p>
	ثانيًا، قُص قطعة من الشريط العازل والصقه على الجزء الملفوف من المقاومة ليساعد في تثبيتها.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="116294" href="https://academy.hsoub.com/uploads/monthly_2023_01/elec-tape.jpg.2839851bd653e7538ad2ecfa15b773fa.jpg" rel=""><img alt="قص قطعة من الشريط العازل ولصقه على الجزء الملفوف من المقاومة" class="ipsImage ipsImage_thumbnailed" data-fileid="116294" data-ratio="75.00" data-unique="zl11xonsw" style="width: 500px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/elec-tape.jpg.2839851bd653e7538ad2ecfa15b773fa.jpg"> </a>
</p>

<p>
	ثالثًا، أدخل سلك توصيل في النهاية الحرة للمقاومة، ثم صل سلكًا آخر مع الرجل السالبة لمصباح الليد.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="116315" href="https://academy.hsoub.com/uploads/monthly_2023_01/jumper-wires.jpg.4b5dc0bf09c6541188cb9cb8f9748c8a.jpg" rel=""><img alt="إدخال سلك توصيل في النهاية الحرة للمقاومة ووصل سلك آخر مع الرجل السالبة لمصباح الليد" class="ipsImage ipsImage_thumbnailed" data-fileid="116315" data-ratio="75.00" data-unique="a3lg3akmd" style="width: 500px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/jumper-wires.jpg.4b5dc0bf09c6541188cb9cb8f9748c8a.jpg"> </a>
</p>

<p>
	كما يمكنك استخدام الشريط العازل لتثبيت التوصيلات.
</p>

<h3>
	توصيل الليد مع مقاومة وأسلاك توصيل باستخدام اللحام وأنابيب الانكماش الحراري
</h3>

<p>
	<strong>تنبيه:</strong> ستحتاج إلى مساعدة أحد البالغين لتنفيذ هذه الخطوة وخاصةً عند استخدام مسدس اللحام.
</p>

<p>
	أولًا، ستحتاج إلى مصباح ليد، ومقاومة (ذات قيمة 70 أوم أو أكبر)، سلكي توصيل نوع مقبس-مقبس، ومسدس لحام، وأسلاك قصدير، وأنابيب انكماش حراري.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="116342" href="https://academy.hsoub.com/uploads/monthly_2023_01/you_will_need.jpg.04417f3dec1c7416c4681d75574a3da4.jpg" rel=""><img alt="توصيل الليد مع مقاومة وأسلاك توصيل باستخدام اللحام وأنابيب الانكماش الحراري" class="ipsImage ipsImage_thumbnailed" data-fileid="116342" data-ratio="51.27" data-unique="ts22s3l4s" style="width: 550px; height: 282px;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/you_will_need.thumb.jpg.3080bfd8063191c613c7937822df913c.jpg"> </a>
</p>

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

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="116336" href="https://academy.hsoub.com/uploads/monthly_2023_01/tin_led.gif.8d3450a79cd7f6cc39dbcd1fd6972130.gif" rel=""><img alt="الخطوة 2 لتوصيل الليد مع مقاومة وأسلاك توصيل" class="ipsImage ipsImage_thumbnailed" data-fileid="116336" data-ratio="56.36" data-unique="u2qii640z" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/tin_led.gif.8d3450a79cd7f6cc39dbcd1fd6972130.gif"> </a>
</p>

<p>
	ثالثًا، الآن سخّن إحدى رجلي المقاومة لبضع ثوان باستخدام مسدس اللحام ثم اصهر اصبع القصدير فوقها، وكرر العملية على الرجل الأخرى. اطلب مساعدة أحد البالغين لتنفيذ هذه الخطوة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="116337" href="https://academy.hsoub.com/uploads/monthly_2023_01/tin_resistor.gif.e2c0d1503c16d832738c207af0e9ce9f.gif" rel=""><img alt="الخطوة 3 لتوصيل الليد مع مقاومة وأسلاك توصيل" class="ipsImage ipsImage_thumbnailed" data-fileid="116337" data-ratio="56.36" data-unique="du8050xie" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/tin_resistor.gif.e2c0d1503c16d832738c207af0e9ce9f.gif"> </a>
</p>

<p>
	رابعًا، ضع رجل الليد الموجبة فوق رجل المقاومة ثم مرر مسدس اللحام عليهما كي تلتحما معًا.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="116292" href="https://academy.hsoub.com/uploads/monthly_2023_01/bond_resistor.gif.1a91636eb265b7a677ddefa820696e01.gif" rel=""><img alt="الخطوة 4 لتوصيل الليد مع مقاومة وأسلاك توصيل" class="ipsImage ipsImage_thumbnailed" data-fileid="116292" data-ratio="56.36" data-unique="6mza43j8t" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/bond_resistor.gif.1a91636eb265b7a677ddefa820696e01.gif"> </a>
</p>

<p>
	خامسًا، قص النهاية البلاستيكية السوداء لسلكي التوصيل، ثم انزع الغلاف البلاستيكي للسلكين حتى تحصل على الجزء النحاسي بدون عزل، كما هو موضح:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="116329" href="https://academy.hsoub.com/uploads/monthly_2023_01/strip_jumpers.gif.22d3d59d8a0f4f5ad0a1685980bfb0a9.gif" rel=""><img alt="الخطوة 5 لتوصيل الليد مع مقاومة وأسلاك توصيل" class="ipsImage ipsImage_thumbnailed" data-fileid="116329" data-ratio="56.36" data-unique="gzt14pnm9" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/strip_jumpers.gif.22d3d59d8a0f4f5ad0a1685980bfb0a9.gif"> </a>
</p>

<p>
	سادسًا، اصهر بعض القصدير على نهايتي السلكين.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="116335" href="https://academy.hsoub.com/uploads/monthly_2023_01/tin_jumpers.gif.502c41fd03fa19fecbb126e825cbdd24.gif" rel=""><img alt="الخطوة 6 لتوصيل الليد مع مقاومة وأسلاك توصيل" class="ipsImage ipsImage_thumbnailed" data-fileid="116335" data-ratio="56.36" data-unique="wc1p7jbuw" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/tin_jumpers.gif.502c41fd03fa19fecbb126e825cbdd24.gif"> </a>
</p>

<p>
	سابعًا، ادخل أنبوب انكماش حراري في كلٍ من السلكين.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="116288" href="https://academy.hsoub.com/uploads/monthly_2023_01/add_heatshrink.gif.88558d5222e87c4f6fe03dad9b817549.gif" rel=""><img alt="الخطوة 7 لتوصيل الليد مع مقاومة وأسلاك توصيل" class="ipsImage ipsImage_thumbnailed" data-fileid="116288" data-ratio="56.36" data-unique="ast5y0jv6" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/add_heatshrink.gif.88558d5222e87c4f6fe03dad9b817549.gif"> </a>
</p>

<p>
	ثامنًا، ضع النهاية المكشوفة لسلك التوصيل الأول فوق الليد، ثم سخنهما كي يلتحما، وكرّر العملية مع السلك الثاني والمقاومة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="116291" href="https://academy.hsoub.com/uploads/monthly_2023_01/bond_jumpers.gif.00f0504a70600d919f50a2fbdb30f5db.gif" rel=""><img alt="الخطوة 8 لتوصيل الليد مع مقاومة وأسلاك توصيل" class="ipsImage ipsImage_thumbnailed" data-fileid="116291" data-ratio="56.36" data-unique="rnklw2d39" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/bond_jumpers.gif.00f0504a70600d919f50a2fbdb30f5db.gif"> </a>
</p>

<p>
	تاسعًا، اسحب أنبوب الانكماش الحراري إلى نهاية السلك ليغطي موضع اللحام.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="116318" href="https://academy.hsoub.com/uploads/monthly_2023_01/place_heatshrink.gif.110c9ba22cdc9051ee27c81e8fd000de.gif" rel=""><img alt="الخطوة 9 لتوصيل الليد مع مقاومة وأسلاك توصيل" class="ipsImage ipsImage_thumbnailed" data-fileid="116318" data-ratio="56.36" data-unique="w0rbgj5u8" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/place_heatshrink.gif.110c9ba22cdc9051ee27c81e8fd000de.gif"> </a>
</p>

<p>
	عاشرًا، سخن أنبوب الانكماش الحراري باستخدام الحافة العريضة من مسدس اللحام حتى ينكمش حول سلك التوصيل.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="116314" href="https://academy.hsoub.com/uploads/monthly_2023_01/heat_heatshrink.gif.46f65e96dd51ff9c66190f08cd49f2ba.gif" rel=""><img alt="الخطوة 10 لتوصيل الليد مع مقاومة وأسلاك توصيل" class="ipsImage ipsImage_thumbnailed" data-fileid="116314" data-ratio="56.36" data-unique="6t4q1rrzy" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/heat_heatshrink.gif.46f65e96dd51ff9c66190f08cd49f2ba.gif"> </a>
</p>

<p>
	أخيرًا، اختبر الليد بتوصيل إحدى السلكين إلى أحد أرجل الأرضية GND على لوحة بيكو، والسلك الآخر إلى إحدى أرجل 3V3.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="116330" href="https://academy.hsoub.com/uploads/monthly_2023_01/test_led.gif.c9d4341741f7c9c885c302a5afee0677.gif" rel=""><img alt="الخطوة الأخيرة لتوصيل الليد مع مقاومة وأسلاك توصيل" class="ipsImage ipsImage_thumbnailed" data-fileid="116330" data-ratio="56.36" data-unique="dmychjavj" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/test_led.gif.c9d4341741f7c9c885c302a5afee0677.gif"> </a>
</p>

<p>
	الآن، وبعد الانتهاء من توصيل الليد والمقاومة، صّل الرجل السالبة لمصباح الليد مع رجل الأرض <strong>GND</strong>، والموجبة مع الرجل <strong>GP13</strong> على لوحة بيكو، كما تعلمنا في <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D8%B5%D8%A8%D8%A7%D8%AD-%D9%84%D9%8A%D8%AF-%D9%8A%D9%88%D9%85%D8%B6-%D9%88%D9%81%D9%82-%D9%86%D9%85%D8%B7-%D9%85%D8%B9%D9%8A%D9%86-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1848/" rel="">مشروع اليراعات الوامضة</a>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116323" href="https://academy.hsoub.com/uploads/monthly_2023_01/pot-led-circuit.png.802e4b14a3745a72abc4ae5727a33d79.png" rel=""><img alt="وصل الرجل السالبة لمصباح الليد مع رجل الأرض GND والموجبة مع الرجل GP13 على لوحة بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="116323" data-ratio="87.09" data-unique="m2qh2adxh" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/pot-led-circuit.png.802e4b14a3745a72abc4ae5727a33d79.png"> </a>
</p>

<p>
	<strong>معلومة:</strong> عملت عالمة الفضاء ماجي أدرين بوكوك Maggie Aderin-Pocock على العديد من الأدوات الإلكترونية مثل ملحقات للتلسكوب، وكاشف ألغام محمول، وأجهزة أُرسلت إلى الفضاء لجمع بيانات تساعد في فهم سبب تغير المناخ، والمدهش أن ماجي لم تكن قادرةً على شراء تلسكوب عندما كانت مراهقة، لذا صنعت تلسكوبها الخاص مستخدمةً الزجاج لصنع العدسات ومعرفتها في الإلكترونيات والبرمجة.
</p>

<p>
	ما رأيك عالمِنا الصغير، هل هناك أداة ترغب في صنعها؟
</p>

<p>
	أضف الشيفرة التالية لبرمجة الليد:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_613_100" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Pot</span><span class="pun">,</span><span class="pln"> LED </span><span class="com"># أضفنا تابع الليد من المكتبة</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> time </span><span class="kwd">import</span><span class="pln"> sleep

dial </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Pot</span><span class="pun">(</span><span class="lit">0</span><span class="pun">)</span><span class="pln">
led </span><span class="pun">=</span><span class="pln"> LED</span><span class="pun">(</span><span class="lit">13</span><span class="pun">)</span><span class="pln"> </span><span class="com"># احرص على كتابة الرقم الصحيح للرجل</span></pre>

<p>
	ثم أضف الشيفرة التالية للتحكم بسطوع الليد:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_613_102" style=""><span class="kwd">while</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">:</span><span class="pln">
    bpm </span><span class="pun">=</span><span class="pln"> heart_min </span><span class="pun">+</span><span class="pln"> dial</span><span class="pun">.</span><span class="pln">value </span><span class="pun">*</span><span class="pln"> heart_range
    </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">bpm</span><span class="pun">)</span><span class="pln">
    beat </span><span class="pun">=</span><span class="pln"> </span><span class="lit">60</span><span class="pun">/</span><span class="pln">bpm
    </span><span class="com"># زِد سطوع الليد في النصف الأول من النبضة</span><span class="pln">
    brighter_time </span><span class="pun">=</span><span class="pln"> beat </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pln"> 
    </span><span class="com"># خفِّف سطوع الليد في النصف الثاني من النبضة</span><span class="pln">
    dimmer_time </span><span class="pun">=</span><span class="pln"> beat </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pln"> 

    </span><span class="com"># انتظر حتى تنتهي النبضة الأولى</span><span class="pln">
    led</span><span class="pun">.</span><span class="pln">pulse</span><span class="pun">(</span><span class="pln">brighter_time</span><span class="pun">,</span><span class="pln"> dimmer_time</span><span class="pun">,</span><span class="pln"> n</span><span class="pun">=</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> wait</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">  </span></pre>

<p>
	لاحظ أن الدالة <code>()pulse</code> تخلق تأثير النبض للمصباح عن طريق زيادة سطوعه وانقاصه. احرص على إضافة شرط الإنتظار <code>wait=True</code> على السطر الأخير من الشيفرة، وإلا سيُعاد تنفيذ حلقة <code>while</code> مباشرةً وسيُعاد النبض.
</p>

<p>
	الآن، شغّل الشيفرة وراقب كيف يخبو ويسطع ضوء المصباح، ثم دوّر قرص المقاومة المتغيرة وراقب كيف تتسرع ومضات المصباح كما لو أنها نبضات قلب.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="116326" href="https://academy.hsoub.com/uploads/monthly_2023_01/pulse-test.gif.7748fdd2d116fc8e0d8a1fbe6a0f8305.gif" rel=""><img alt="تشغيل الشيفرة وتدوير المقاومة للتأكد من ومضات المصباح" class="ipsImage ipsImage_thumbnailed" data-fileid="116326" data-ratio="93.60" data-unique="mki3glwp5" style="width: 500px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/pulse-test.gif.7748fdd2d116fc8e0d8a1fbe6a0f8305.gif"> </a>
</p>

<p>
	ضع الليد داخل القلب الورقي أو خلفه للحصول على تأثير النبض.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="116313" href="https://academy.hsoub.com/uploads/monthly_2023_01/heartbeat.gif.09bcb3480bd1af0e91139cab1825b7a7.gif" rel=""><img alt="وضع الليد داخل القلب الورقي أو خلفه للحصول على تأثير النبض" class="ipsImage ipsImage_thumbnailed" data-fileid="116313" data-ratio="99.60" data-unique="tvzfc5i5k" style="width: 500px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/heartbeat.gif.09bcb3480bd1af0e91139cab1825b7a7.gif"> </a>
</p>

<h3>
	تصحيح الأخطاء
</h3>

<p>
	إليك بعض الأخطاء التي قد تواجهك في هذه الخطوة وكيفية إصلاحها:
</p>

<h4>
	يظهر البرنامج رسالة خطأ في الشيفرة
</h4>

<p>
	قد تظهر لك رسالة " You have a syntax error"، تحقق عندها من الشيفرة التي كتبتها وتأكد أنها مطابقة للشيفرة في مثالنا.
</p>

<h4>
	توقفت المقاومة المتغيرة عن العمل
</h4>

<p>
	تحقق من متانة توصيل الأسلاك مع المقاومة.
</p>

<h4>
	لا يضيء مصباح الليد الموصول
</h4>

<p>
	تحقق من توصيل الليد مع الأرجل الصحيحة وفقًا للمخطط في مقالنا، وتحقق من متانة التوصيلات، وإذا استمرت المشكلة فاستبدل مصباح الليد بآخر.
</p>

<h2>
	استخدام مصدر تغذية محمول
</h2>

<p>
	يمكنك تغذية لوحة بيكو من أي مصدر تغذية آخر غير الحاسوب باستخدام كبل USB.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116299" href="https://academy.hsoub.com/uploads/monthly_2023_01/heart-static.png.8f9aa0f65943d7c5b134f9b778f0a303.png" rel=""><img alt="تغذية لوحة بيكو من أي مصدر تغذية آخر غير الحاسوب باستخدام كبل USB" class="ipsImage ipsImage_thumbnailed" data-fileid="116299" data-ratio="99.60" data-unique="j5tgmrr5b" style="width: 500px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/heart-static.png.8f9aa0f65943d7c5b134f9b778f0a303.png"> </a>
</p>

<h3>
	تشغيل المشروع تلقائيا باستخدام ملف main.py
</h3>

<p>
	عند توصيل لوحة بيكو بمصدر طاقة وتشغيلها، تشغّل اللوحة تلقائيًا ملف "main.py" والذي يمكننا من خلاله تشغيل مشروعنا.
</p>

<p>
	أولًا، انقر على قائمة ملف <strong>File</strong> ثم اختر حفظ باسم <strong>Save as</strong>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116295" href="https://academy.hsoub.com/uploads/monthly_2023_01/file_menu.png.41a6204203b5341d44e045578785d8e4.png" rel=""><img alt="التشغيل التلقائي للمشروع باستخدام ملف main.py" class="ipsImage ipsImage_thumbnailed" data-fileid="116295" data-ratio="113.10" data-unique="jblf4nn8d" style="width: 229px; height: auto;" width="229" src="https://academy.hsoub.com/uploads/monthly_2023_01/file_menu.png.41a6204203b5341d44e045578785d8e4.png"> </a>
</p>

<p>
	ثانيًا، انقر على خيار الحفظ في راسبيري باي بيكو.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116327" href="https://academy.hsoub.com/uploads/monthly_2023_01/save_to_pico.png.6723ad9bb78586a6c778804f60c142a7.png" rel=""><img alt="حفظ المشروع في راسبيري باي بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="116327" data-ratio="54.67" data-unique="ouxyvvhmf" style="width: 300px; height: auto;" width="316" src="https://academy.hsoub.com/uploads/monthly_2023_01/save_to_pico.png.6723ad9bb78586a6c778804f60c142a7.png"> </a>
</p>

<p>
	ثم اختر مكانًا مناسبًا لحفظ الملف وسمّه "main.py".
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116316" href="https://academy.hsoub.com/uploads/monthly_2023_01/main.png.eabfef9d409a8f3f1be5ff88a3cfe5ea.png" rel=""><img alt='حفظ ملف المشروع تحت اسم "main.py"' class="ipsImage ipsImage_thumbnailed" data-fileid="116316" data-ratio="53.40" data-unique="um33hvzpm" style="width: 500px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/main.png.eabfef9d409a8f3f1be5ff88a3cfe5ea.png"> </a>
</p>

<p>
	عند حفظ أي ملف باسم "main.py" على لوحة بيكو، سيعمل البرنامج تلقائيًا عند تغذية اللوحة بمصدر تغذية خارجي مثل البطارية.
</p>

<h3>
	تغذية لوحة بيكو بمصدر تغذية خارجي باستخدام كبل USB
</h3>

<p>
	تتطلب لوحة راسبيري باي بيكو تغذيتها بمصدر طاقة يؤمن تغذية تتراوح بين 1.8 فولت و 5.5 فولت بالحد الأعظمي، والذي يمكن توفيره باستخدام معظم محولات USB. فعلى سبيل المثال،يوفر محول micro USB الرسمي من راسبيري تيارًا يصل إلى 2.5 أمبير عند جهد قيمته 5.1 فولت.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116338" href="https://academy.hsoub.com/uploads/monthly_2023_01/transformer.png.687ec352a4d22592b5cdd1d77b8baca0.png" rel=""><img alt="تغذية لوحة بيكو بمصدر تغذية خارجي باستخدام كبل USB" class="ipsImage ipsImage_thumbnailed" data-fileid="116338" data-ratio="109.33" data-unique="utif86fp3" style="width: 450px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/transformer.thumb.png.1ed3455258325d475d6dac717cda30a7.png"> </a>
</p>

<p>
	كما يمكن أيضًا تشغيل لوحة راسبيري باي بيكو باستخدام بطارية مع كبل USB ذو نهايات USB و micro USB، إذ توفر هذه البطارية تيارًا يصل إلى 2.1 أمبير عند جهد قيمته 5 فولت.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116289" href="https://academy.hsoub.com/uploads/monthly_2023_01/battery_pack.png.86f32fb7ad7245d6b0fb9fb2182c31f0.png" rel=""><img alt="تشغيل لوحة راسبيري باي بيكو باستخدام بطارية مع كبل US" class="ipsImage ipsImage_thumbnailed" data-fileid="116289" data-ratio="28.60" data-unique="4zjknt0in" style="width: 500px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/battery_pack.png.86f32fb7ad7245d6b0fb9fb2182c31f0.png"> </a>
</p>

<p>
	ثالثًا، افصل لوحة بيكو عن حاسوبك، ثم صِلها مع البطارية أو منبع التغذية الخارجي.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="116293" href="https://academy.hsoub.com/uploads/monthly_2023_01/connect-micro-usb.gif.79522af0bc37e81963c7b2b851d8361a.gif" rel=""><img alt="فصل لوحة بيكو عن حاسوبك ووصلها مع البطارية أو منبع التغذية الخارجي" class="ipsImage ipsImage_thumbnailed" data-fileid="116293" data-ratio="62.00" data-unique="48nbew5ly" style="width: 500px; height: 310px;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/connect-micro-usb.gif.79522af0bc37e81963c7b2b851d8361a.gif"> </a>
</p>

<p>
	شَغّل منبع الطاقة، ثم دوّر قرص المقاومة للتحكم بسرعة النبض.
</p>

<h3>
	تصحيح الأخطاء
</h3>

<p>
	إليك بعض الأخطاء التي قد تواجهك في هذه الخطوة وكيفية إصلاحها:
</p>

<h4>
	لا يضيء مصباح الليد الموصول
</h4>

<ul>
	<li>
		تحقق من تشغيل البطارية التي وصلتها، ومن شحنها، وغَيّر كبل USB المستخدم، وإذا لم يفلح الأمر فعليك تغيير البطارية.
	</li>
	<li>
		صِل لوحة بيكو بالحاسوب وتحقق من حفظ الملف "main.py" عليها، وتحقق أن لاحقة الملف هي "py.".
	</li>
</ul>

<h2>
	ترقية المشروع
</h2>

<p>
	يمكنك ترقية مشروعك حين يتسنى لك ذلك، واستخدامه لتزيين غرفتك ومساعدتك على الاسترخاء وذلك بتخفيف سرعة النبضات، أو زيادتها لتتناسب مع ما تستمع إليه من الموسيقى.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="116340" href="https://academy.hsoub.com/uploads/monthly_2023_01/two-beats.gif.deeb18303afa3c5311d673b22500999d.gif" rel=""><img alt="ترقية المشروع" class="ipsImage ipsImage_thumbnailed" data-fileid="116340" data-ratio="92.60" data-unique="42dy1ir0l" style="width: 500px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/two-beats.gif.deeb18303afa3c5311d673b22500999d.gif"> </a>
</p>

<p>
	إليك بعض الاقتراحات لترقية مشروعك:
</p>

<ul>
	<li>
		صنع قلب ورقي آخر أكثر تعقيدًا.
	</li>
	<li>
		إضافة مصباح ليد ذو لون أزرق ليمثل حركة الدم الخالي من الأوكسجين الداخل والخارج من القلب.
	</li>
	<li>
		إضافة صوت لنضات القلب باستخدام جرس إلكتروني غير فعّال passive buzzer.
	</li>
	<li>
		إضافة مزيدٍ من القلوب الورقية ومصابيح الليد (اختر الألوان التي تفضلها) وجعلها تنبض في نفس الوقت.
	</li>
</ul>

<p>
	كما يمكنك الاطلاع على الشيفرة النهائية للمشروع من ملفه <a data-fileext="zip" data-fileid="116344" href="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=116344&amp;key=84184b2e4f9f44913ab9fc5df6d2c4bc" rel="">beating-heart-en-solutions</a>.
</p>

<h2>
	الخاتمة
</h2>

<p>
	تهانينا، فقد أتممت مشروع استخدام لوحة راسبيري باي بيكو للحصول قلب صناعي نابض.
</p>

<p>
	ننصحك بتنفيذ مشروع جهاز عرض الحالة المزاجية باستخدام لوحة راسبيري باي بيكو في خطوتك التالية، وإذا واجهتك مشاكلًا عند تنفيذ هذا المشروع فيمكنك الحصول على الدعم والمساعدة عبر إضافة سؤالك في قسم الأسئلة والأجوبة في <a href="https://academy.hsoub.com/questions/" rel="">أكاديمية حسوب</a>.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://projects.raspberrypi.org/en/projects/beating-heart/" rel="external nofollow">Beating heart</a> من <a href="https://raspberrypi.org/" rel="external nofollow">الموقع الرسمي لراسبيري باي</a>.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%85%D8%AD%D8%A7%D9%83%D8%A7%D8%A9-%D9%84%D9%85%D9%81%D8%B1%D9%82%D8%B9%D8%A7%D8%AA-%D8%A7%D9%84%D8%AD%D9%81%D9%84%D8%A7%D8%AA-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1861/" rel="">تصميم محاكاة لمفرقعات الحفلات باستخدام لوحة راسبيري باي بيكو</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D8%B5%D8%A8%D8%A7%D8%AD-%D9%84%D9%8A%D8%AF-%D9%8A%D9%88%D9%85%D8%B6-%D9%88%D9%81%D9%82-%D9%86%D9%85%D8%B7-%D9%85%D8%B9%D9%8A%D9%86-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1848/" rel="">إنشاء مصباح ليد يومض وفق نمط معين باستخدام حاسوب راسبيري باي بيكو</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D9%85%D8%B5%D8%A8%D8%A7%D8%AD-%D9%84%D9%8A%D8%AF-%D8%AB%D9%84%D8%A7%D8%AB%D9%8A-%D8%A7%D9%84%D8%A3%D8%A8%D8%B9%D8%A7%D8%AF-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%B3%D9%83%D8%B1%D8%A7%D8%AA%D8%B4-%D9%88%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-r1504/" rel="">تنفيذ مصباح ليد ثلاثي الأبعاد باستخدام سكراتش ولوحة راسبيري باي</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%AC%D9%85%D9%8A%D8%B9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D9%88%D8%A7%D9%84%D8%AA%D8%AD%D8%B6%D9%8A%D8%B1-%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%85%D8%A7%D9%84%D9%87-r1370/" rel="">تجميع راسبيري باي والتحضير لاستعماله</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%B1%D8%A8%D8%B7-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D8%B9%D9%86%D8%A7%D8%B5%D8%B1-%D8%A5%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A%D8%A9-%D9%88%D8%A8%D8%B1%D9%85%D8%AC%D8%AA%D9%87%D8%A7-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%B3%D9%83%D8%B1%D8%A7%D8%AA%D8%B4-%D9%88%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-r1496/" rel="">ربط راسبيري باي بعناصر إلكترونية وبرمجتها باستخدام سكراتش وبايثون</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1862</guid><pubDate>Thu, 19 Jan 2023 16:00:00 +0000</pubDate></item><item><title>&#x62A;&#x635;&#x645;&#x64A;&#x645; &#x645;&#x62D;&#x627;&#x643;&#x627;&#x629; &#x644;&#x645;&#x641;&#x631;&#x642;&#x639;&#x627;&#x62A; &#x627;&#x644;&#x62D;&#x641;&#x644;&#x627;&#x62A; &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x644;&#x648;&#x62D;&#x629; &#x631;&#x627;&#x633;&#x628;&#x64A;&#x631;&#x64A; &#x628;&#x627;&#x64A; &#x628;&#x64A;&#x643;&#x648;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%85%D8%AD%D8%A7%D9%83%D8%A7%D8%A9-%D9%84%D9%85%D9%81%D8%B1%D9%82%D8%B9%D8%A7%D8%AA-%D8%A7%D9%84%D8%AD%D9%81%D9%84%D8%A7%D8%AA-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1861/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2023_01/1666846524_--------.jpg.1d2c9aba1028247b6187f7af18ed2cce.jpg" /></p>
<p>
	سنتعلم في هذا المقال كيفية تصميم محاكاة لمفرقعات الحفلات باستخدام لوحة راسبيري باي بيكو Raspberry Pi Pico ومصابيح ليد LED وجرس إلكتروني Buzzer.
</p>

<p>
	استخدمنا في <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D8%B5%D8%A8%D8%A7%D8%AD-%D9%84%D9%8A%D8%AF-%D9%8A%D9%88%D9%85%D8%B6-%D9%88%D9%81%D9%82-%D9%86%D9%85%D8%B7-%D9%85%D8%B9%D9%8A%D9%86-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1848/" rel="">مشروع سابق</a> مصباح ليد ذو لون واحد، أما في مشروعنا هذا فسنستخدم نوعًا مختلفًا من المصابيح وهو مصباح LED متعدد الألوان والذي يعرف باسم RGB LED، لنحصل على نتيجة مشابهة لما يلي، إذ يضيء المصباح بلونٍ بنفسجي Purple وينطلق الجرس الإلكتروني:
</p>

<p style="text-align: center;">
	<img alt="full-popper-test.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="116216" data-unique="hz6p7iu5v" src="https://academy.hsoub.com/uploads/monthly_2023_01/full-popper-test.gif.7ee846277d055dedc83fc825c2c55c3e.gif">
</p>

<p>
	<strong>معلومة:</strong> تُستخدم مفرقعات الحفلات Party poppers في الاحتفالات في جميع أنحاء العالم، فما عليك سوى أن تسحب الخيط المتدلي منها، لتفرقع وتصدر قُصاصاتٍ ملونةً في الهواء. لربما لم تراها مسبقًا، لكن من المؤكد أنك تعرف الرمز التعبيري الخاص بها.
</p>

<p style="text-align: center;">
	<img alt="party-popper.png" class="ipsImage ipsImage_thumbnailed" data-fileid="116227" data-unique="xjx20jbnk" style="width: 150px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/party-popper.png.cce02291c6247d119c72e245e488e6db.png">
</p>

<p>
	ستتعلم في هذا المشروع ما يلي:
</p>

<ul>
	<li>
		كيفية كتابة شيفرة للتحكم بألوان مصباح الليد متعدد الألوان RGB LED ودرجة سطوعها.
	</li>
	<li>
		كيفية التحكم برنين الجرس الإلكتروني buzzer.
	</li>
	<li>
		كيفية صنع مبدّل من الورق المقوى ورقائق القصدير.
	</li>
</ul>

<h2>
	متطلبات المشروع
</h2>

<p>
	سنوضح فيما يلي متطلبات إنجاز هذا المشروع
</p>

<h3>
	عتاد
</h3>

<ol>
	<li>
		لوحة حاسوب راسبيري باي بيكو مع أرجل مثبتة عليها.
	</li>
	<li>
		كبل USB لنقل البيانات ذو نهايات من النوع USB A و micro USB.
	</li>
	<li>
		جرس إلكتروني غير فعّال passive buzzer.
	</li>
	<li>
		مقاومة resistor بقيمة 100 أوم ( يمكن استعمال أي مقاومة ذات قيمة 75Ω -220Ω). (عدد 3)
	</li>
	<li>
		أسلاك توصيل ذات نهايات مقبس-مقبس socket-socket (عدد 6).
	</li>
	<li>
		أسلاك توصيل ذات نهايات دبوس-مقبس pin-socket (عدد 2).
	</li>
	<li>
		مصباح ليد متعدد الألوان RGB LED ذو مهبط مشترك common cathode (عدد 1).
	</li>
	<li>
		بعض مستلزمات الأشغال اليدوية، مثل الورق المقوى السميك، ورقائق القصدير، وخيوط، وشرائط أو ورق ملون، وشريط لاصق.
	</li>
</ol>

<h3>
	برمجيات
</h3>

<ol>
	<li>
		برنامج ثوني Thonny (وهو البيئة البرمجية التي سنستخدمها لكتابة الشيفرة <a href="https://academy.hsoub.com/programming/python/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D9%84%D8%BA%D8%A9-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A9-r211/" rel="">بلغة بايثون</a>).
	</li>
</ol>

<h4>
	تثبيت برنامج ثوني على <span ipsnoautolink="true">نظام تشغيل راسبيري باي</span>
</h4>

<p>
	يأتي برنامج ثوني مثبتًا مع <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AC%D9%88%D9%84%D8%A9-%D9%81%D9%8A-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%A7%D9%86-%D9%86%D8%B8%D8%A7%D9%85-%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-r1371/" rel="">نظام تشغيل راسبيري باي</a>، المعروف سابقًا براسبيان Raspbian، ولكن قد تحتاج إلى تحديثه. انقر على الأيقونة في الزاوية العلوية اليسرى من الشاشة لفتح نافذة الطرفية Terminal، أو اضغط المفاتيح التالية معًا <strong>Ctrl+Alt+T</strong>، ثم اكتب الأمر التالي لتحديث نظام التشغيل وبرنامج ثوني:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_750_56" style=""><span class="pln">sudo apt update </span><span class="pun">&amp;&amp;</span><span class="pln"> sudo apt upgrade </span><span class="pun">-</span><span class="pln">y</span></pre>

<h4>
	تثبيت برنامج ثوني على <a href="https://academy.hsoub.com/files/24-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%84%D9%85%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D9%86/" rel="">أنظمة التشغيل</a> الأخرى
</h4>

<p>
	يمكنك تثبيت ثوني على الحواسيب العاملة <a href="https://academy.hsoub.com/devops/linux/%D9%85%D8%A7-%D9%87%D9%88-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%8A%D9%86%D9%83%D8%B3%D8%9F-r451/" rel="">بنظام تشغيل لينكس</a>، أو ويندوز، أو ماك، وذلك من الموقع الرسمي <a href="https://thonny.org/" rel="external nofollow">thonny.org</a>. انقر على رابط التنزيل الموافق لنظام تشغيل حاسوبك من الزاوية العلوية اليمنى في الموقع، ثم انقر على الملفات بعد تنزيلها، فتظهر لك الرسالة التالية على نظام ويندوز:
</p>

<p style="text-align: center;">
	<img alt="thonny-site.png" class="ipsImage ipsImage_thumbnailed" data-fileid="116248" data-unique="v6bkj3g5r" src="https://academy.hsoub.com/uploads/monthly_2023_01/thonny-site.png.c59fcdcc2c6581aa520a5b7c77bf59d2.png">
</p>

<p>
	انقر على خيار المزيد من المعلومات "More info"، ثم على التشغيل على أي حال "Run anyway".
</p>

<h4>
	التعرف على واجهة برنامج ثوني
</h4>

<p>
	ستظهر لك الواجهة التالية عند فتح ثوني:
</p>

<p style="text-align: center;">
	<img alt="thonny-editor.png" class="ipsImage ipsImage_thumbnailed" data-fileid="116247" data-unique="1h8kzerhx" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/thonny-editor.thumb.png.9bdaa336f7111440596d69db72d290d1.png">
</p>

<p>
	يمكنك الكتابة <a href="https://wiki.hsoub.com/Python" rel="external">بلغة بايثون</a> في النافذة الرئيسية الكبيرة، ثم النقر على زر التشغيل الأخضر <strong>Run</strong> للتنفيذ، فستظهر لك رسالة لحفظ الملف قبل تشغيله.
</p>

<p>
	اكتب الأمر التالي وشغّله:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_750_11" style=""><span class="kwd">print</span><span class="pun">(</span><span class="str">'Hello World!'</span><span class="pun">)</span></pre>

<h4>
	تغيير السمة والخط
</h4>

<p>
	يمكنك التحكم بلون الخط وحجمه وتغيير السمة المستخدمة في واجهة البرنامج، وذلك بالنقر على قائمة الأدوات <strong>Tools</strong> من الشريط أعلى الشاشة، ثم النقر على خيارات <strong>Options</strong>. انقر بعدها على نافذة الخط والسمة <strong>Theme &amp; Font</strong> واختر نوع الخط والسمة التي تفضلها من النافذة المنسدلة، ثم انقر على زر موافق <strong>OK</strong> عند الانتهاء.
</p>

<p style="text-align: center;">
	<img alt="theme-tab.png" class="ipsImage ipsImage_thumbnailed" data-fileid="116246" data-unique="4q20dczgv" style="width: 500px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/theme-tab.png.b79fb4d118c3c37b40fc45cdc5aa1f43.png">
</p>

<p>
	ننصحك باختيار الخطوط البسيطة الواضحة والابتعاد عن الخطوط المزخرفة أو المشابهة لخط اليد لأنه قد تجعل القراءة أصعب.
</p>

<h2>
	تشغيل مصباح الليد متعدد الألوان
</h2>

<p>
	استخدمنا في <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D8%B5%D8%A8%D8%A7%D8%AD-%D9%84%D9%8A%D8%AF-%D9%8A%D9%88%D9%85%D8%B6-%D9%88%D9%81%D9%82-%D9%86%D9%85%D8%B7-%D9%85%D8%B9%D9%8A%D9%86-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1848/" rel="">مشروع سابق مصباح ليد ذو لون واحد</a>، أما في مشروعنا هذا فسنستخدم مصباح LED متعدد الألوان يعرف باسم RGB LED، وسنوصّله مع لوحة راسبيري باي بيكو لنجعله يضيء باللون الذي نريده.
</p>

<p style="text-align: center;">
	<img alt="led-purple.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="116224" data-unique="l3sblhpgv" style="width: 500px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/led-purple.gif.400fd001cc90f5f481fd5a387bdfe288.gif">
</p>

<p>
	<strong>معلومة:</strong> مصباح ليد RGB هو اختصار للألوان الثلاثة التالية: الأحمر<strong>R</strong>ed، والأخضر<strong>G</strong>reen والأزرق <strong>B</strong>lue، إذ تُتيح لك هذه المصابيح التحكم في مقدار إشعاع كل لون باستخدام الشيفرة البرمجية.
</p>

<h3>
	تمثيل الألوان بصيغة RGB
</h3>

<p>
	يمكننا تمثيل الألوان بصيغة يفهمها الحاسوب وذلك بالتعبير عن نسبة ما يحتويه اللون من اللون الأحمر والأخضر والأزرق، إذ تخزن هذه القيم في <strong>بايت</strong> (ثمانية بتات) وتكون قيمتها من 0 إلى 255.
</p>

<p style="text-align: center;">
	<img alt="RGB.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="116285" data-ratio="59.84" data-unique="plhp8povt" width="498" src="https://academy.hsoub.com/uploads/monthly_2023_01/RGB.gif.89aae33e21e376b8f6e9df08d96b5861.gif">
</p>

<p>
	إليك جدولًا يوضح بعض القيم اللونية:
</p>
<style type="text/css">
table {
    width: 100%;
}

thead {
    vertical-align: middle;
    text-align: center;
} 

td, th {
    border: 1px solid #dddddd;
    text-align: right;
    padding: 8px;
    text-align: inherit;

}
tr:nth-child(even) {
    background-color: #dddddd;
}</style>
<table>
	<thead>
		<tr>
			<th>
				اللون
			</th>
			<th>
				الأحمر
			</th>
			<th>
				الأخضر
			</th>
			<th>
				الأزرق
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				أحمر
			</td>
			<td>
				255
			</td>
			<td>
				0
			</td>
			<td>
				0
			</td>
		</tr>
		<tr>
			<td>
				أخضر
			</td>
			<td>
				0
			</td>
			<td>
				255
			</td>
			<td>
				0
			</td>
		</tr>
		<tr>
			<td>
				أزرق
			</td>
			<td>
				0
			</td>
			<td>
				0
			</td>
			<td>
				255
			</td>
		</tr>
		<tr>
			<td>
				أصفر
			</td>
			<td>
				255
			</td>
			<td>
				255
			</td>
			<td>
				0
			</td>
		</tr>
		<tr>
			<td>
				أرجواني
			</td>
			<td>
				255
			</td>
			<td>
				0
			</td>
			<td>
				255
			</td>
		</tr>
		<tr>
			<td>
				سماوي
			</td>
			<td>
				0
			</td>
			<td>
				255
			</td>
			<td>
				255
			</td>
		</tr>
	</tbody>
</table>

<p>
	كما يمكنك الاستعانة <a href="https://www.w3schools.com/colors/colors_rgb.asp" rel="external nofollow">بمنتقي الألوان</a> من موقع w3schools للحصول على القيم الموافقة للون الذي تريده.
</p>

<p>
	احرص على فصل لوحة راسبيري باي بيكو عن حاسوبك قبل توصيل العناصر الإلكترونية معها، وذلك تفاديًا لزيادة تحميل الدارة أو حدوث قصر للدارة والتسبب بإتلافها.
</p>

<h3>
	توصيل المقاومات مع مصباح الليد متعدد الألوان باستخدام أسلاك التوصيل وشريط لاصق
</h3>

<p>
	ستحتاج لتوصيل الليد متعدد الألوان مع المقاومات باستخدام الشريط اللاصق ما يلي:
</p>

<ul>
	<li>
		أربعة أسلاك توصيل نوع مقبس-مقبس، ويفضل أن تكون حمراء وخضراء وزرقاء اللون.
	</li>
	<li>
		مصباح ليد متعدد الألوان ذو مهبط مشترك.
	</li>
	<li>
		ثلاث مقاومات متماثلة القيمة حوالي 220 أوم (يمكن استخدام مقاومات بقيم تتراوح بين 100 أوم و 470 أوم).
	</li>
	<li>
		شريط عازل ملون أحمر وأخضر وأزرق إن وُجِد.
	</li>
	<li>
		مقص.
	</li>
</ul>

<p style="text-align: center;">
	<img alt="you-will-need.png" class="ipsImage ipsImage_thumbnailed" data-fileid="116261" data-unique="ispvm7vi7" style="width: 450px; height: 339px;" src="https://academy.hsoub.com/uploads/monthly_2023_01/you-will-need.png.c9cab3fa80c6d73dbf99647925bc0279.png">
</p>

<h4>
	الطريقة الصحيحة لتوصيل الليد
</h4>

<p>
	يكون لمصباح الليد متعدد الألوان عادةً رجل طويلة هي رجل المهبط cathode والتي يجب توصيلها مع الأرض GND، ويكون ترتيب الأرجل على النحو التالي: الحمراء، ثم رجل المهبط الطويلة، ثم الخضراء، فالزرقاء. لاحظ أن أرجل المصباح غير ملونة فهي مصنوعة من المعدن، وإنما كل رجل مسؤولة عن لون معين.
</p>

<p style="text-align: center;">
	<img alt="rgb-led-legs.png" class="ipsImage ipsImage_thumbnailed" data-fileid="116236" data-unique="9h9jelkzo" style="width: 65px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/rgb-led-legs.png.702427fb514a7b9734384f219312f6b6.png">
</p>

<p>
	باعد بين الرجل الحمراء ورجل المهبط بحذر.
</p>

<h4>
	توصيل المقاومة مع الرجل الحمراء للمصباح
</h4>

<p>
	اثنِ أحد طرفي المقاومة حول الرجل الحمراء لمصباح الليد، ولفّه حولها ثلاث مرات.
</p>

<p style="text-align: center;">
	<img alt="twist-leg.png" class="ipsImage ipsImage_thumbnailed" data-fileid="116259" data-unique="fy7h40dop" style="width: 320px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/twist-leg.png.439a4057fd07672c3a8f3165fed3280b.png">
</p>

<h4>
	تثبيت المقاومة باستخدام الشريط العازل
</h4>

<p>
	قُص قطعة من الشريط العازل والصقه على الجزء الملفوف من المقاومة ليساعد على تثبيتها.
</p>

<p style="text-align: center;">
	<img alt="elec-tape.png" class="ipsImage ipsImage_thumbnailed" data-fileid="116213" data-unique="cegygmg0i" src="https://academy.hsoub.com/uploads/monthly_2023_01/elec-tape.png.c2fd0a8fe467a2aefbcc5bdd0e4322b2.png">
</p>

<h4>
	توصيل مقاومة مع الرجل الخضراء والزرقاء للمصباح
</h4>

<p>
	صِل مقاومة مع كل من الرجلين الخضراء والزرقاء للمصباح كما في الخطوة السابقة، وثبتها بالشريط العازل. يُفضّل استخدام شريط مماثل للون الرجل، إن توفر.
</p>

<p style="text-align: center;">
	<img alt="elec-tape-three.png" class="ipsImage ipsImage_thumbnailed" data-fileid="116212" data-unique="erpgryp57" src="https://academy.hsoub.com/uploads/monthly_2023_01/elec-tape-three.png.7b5ace1b84ce31eb89fa92b59adcf252.png">
</p>

<h4>
	توصيل الأسلاك بالأرجل الأربعة للمصباح
</h4>

<p>
	صِل رجل المهبط الطويلة للمصباح مع سلك توصيل، ثم صِل الأرجل الثلاثة الملونة للمصباح مع أسلاك التوصيل وذلك بإدخال الطرف الحر للمقاومة في القطعة البلاستيكية السوداء للسلك، كما ننصح بقص مقدار 1 سنتيمتر من رجل المقاومة لتسهيل عملية إدخالها في السلك، وبعزل أرجل المقاومات باستخدام الشريط العازل حتى لا تتلامس مع بعضها ولتثبيت الأسلاك، كما يمكنك اختيار ألوان أسلاك موافقة لألوان أرجل المصباح إذا توفر ذلك.
</p>

<p style="text-align: center;">
	<img alt="jumper-wires.png" class="ipsImage ipsImage_thumbnailed" data-fileid="116221" data-unique="wz6mlq7ff" src="https://academy.hsoub.com/uploads/monthly_2023_01/jumper-wires.png.744f21aff97bb29fa26bbeef0e327d25.png">
</p>

<p>
	يمكنك إتباع ما يلي لضمان ثبات التوصيلات:
</p>

<ul>
	<li>
		لَفُّ التوصيلات حول بعضها بإحكام.
	</li>
	<li>
		غلَف كامل الأسلاك بالشريط العازل لتخفيف الضغط على نقطة الاتصال.
	</li>
	<li>
		تجميع الأسلاك، أو المقاومات، ولفّها بالشريط العازل، لكن احرص على فصل أرجل المصباح والمقاومات عن الأسلاك، كما يلي:
	</li>
</ul>

<p style="text-align: center;">
	<img alt="rgb-led-finished.png" class="ipsImage ipsImage_thumbnailed" data-fileid="116235" data-unique="gtfznltts" style="width: 500px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/rgb-led-finished.png.fcb7a4bb1428dad8ae896d5953c460f4.png">
</p>

<p>
	كما يمكنك لصق شريط شفاف على المصباح لبعثرة الضوء وتخفيف شدته.
</p>

<h3>
	توصيل المقاومات مع مصباح الليد متعدد الألوان باستخدام مسدس اللحام وأنابيب الانكماش الحراري
</h3>

<p>
	<strong>تنبيه:</strong> ستحتاج مساعدة أحد البالغين في تنفيذ هذه الخطوة وخاصةً عند استخدام مسدس اللحام heat shrink؛ إذ ستحتاج لتلحيم الليد متعدد الألوان مع المقاومات ما يلي:
</p>

<ul>
	<li>
		أربعة أسلاك توصيل ملونة نوع مقبس-مقبس، ويفضّل أن تكون حمراء وخضراء وزرقاء وسوداء اللون.
	</li>
	<li>
		ثلاث مقاومات متماثلة القيمة ( 70 أوم أو قيمة أعلى).
	</li>
	<li>
		مصباح ليد متعدد الألوان ذو مهبط مشترك.
	</li>
	<li>
		أسلاك قصدير، وأنابيب انكماش حراري ومسدس لحام.
	</li>
	<li>
		قطاعة أسلاك أو أداة تعرية stripper.
	</li>
</ul>

<p style="text-align: center;">
	<img alt="kit.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116222" data-unique="naqfw8j4j" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/kit.thumb.jpg.1be13a71055964094a1cfd4b3a99926f.jpg">
</p>

<h4>
	إيجاد الرجل الحمراء للمصباح
</h4>

<p>
	أوجد الرجل الحمراء للمصباح كما تعلمنا سابقًا، ثم باعد بين الأرجل بحذر، وثبت المصباح بيدك أو باستخدام أدوات مساعدة، أو ملاقط معدنية:
</p>

<p style="text-align: center;">
	<img alt="spread-legs.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116243" data-unique="u5c4ml8bk" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/spread-legs.thumb.jpg.c263f18e8fa692e84acd99c52ccec558.jpg">
</p>

<h4>
	وضع طبقة من القصدير على أرجل المصباح
</h4>

<p>
	مرر إصبع القصدير ومسدس اللحام على كل من الأرجل لبضع ثوان حتى تحصل على طبقة متساوية من القصدير.
</p>

<p style="text-align: center;">
	<img alt="tin_rgb.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="116257" data-unique="sac4rxr3o" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/tin_rgb.gif.8324d38b6f3e26f53d56e4d5cfcf0ba5.gif">
</p>

<h4>
	وضع طبقة من القصدير على أرجل المقاومات
</h4>

<p>
	كرّر الخطوة السابقة بتطبيق القصدير على طرفي المقاومات الثلاث.
</p>

<p style="text-align: center;">
	<img alt="tin_resistor.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="116251" data-unique="5x2p1gwda" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/tin_resistor.gif.eaf90ec7d42adb49f1cb5e3001d989b6.gif">
</p>

<h4>
	تلحيم المقاومات مع أرجل المصباح
</h4>

<p>
	ضع رجل المصباح فوق رجل المقاومة ثم سخن القصدير باستخدام مسدس اللحام كي تلتحما معًا.
</p>

<p style="text-align: center;">
	<img alt="adjacent-legs.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116206" data-unique="tdjvcgk0n" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/adjacent-legs.thumb.jpg.e7beecc68909399a8651eca260c0a615.jpg">
</p>

<p style="text-align: center;">
	<img alt="bond_resistor.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="116208" data-unique="cnty51y53" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/bond_resistor.gif.10d6598439ab0d31eba8f3e8226a6151.gif">
</p>

<p>
	ثم كرر هذه الخطوة على باقي الأرجل، عدا رجل المهبط الطويلة.
</p>

<p style="text-align: center;">
	<img alt="led-three-resistors.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116225" data-unique="k20ah7xyb" src="https://academy.hsoub.com/uploads/monthly_2023_01/led-three-resistors.jpg.75e40f7c768c9cd98474a71ba8fdb6ea.jpg">
</p>

<h4>
	توصيل الأسلاك مع أرجل المصباح
</h4>

<p>
	قُصَّ نهاية سلك التوصيل لتحصل على طول مناسب ثم انزع مقدار 1 سنتيمتر من الغلاف البلاستيكي للسلك باستخدام قطّاعة الأسلاك لتحصل على السلك النحاسي، ثم أدخل أنبوب الانكماش الحراري في السلك، وكرّر العملية للأسلاك الأربعة.
</p>

<p style="text-align: center;">
	<img alt="jumper-lead.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116219" data-unique="58vhle24i" style="width: 464px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/jumper-lead.jpg.28483f0f2b746301335381a4c73d61a6.jpg">
</p>

<p>
	اصهر اصبع القصدير فوق النهاية النحاسية للسلك ثم لحّمها مع رجل المهبط الطويلة لمصباح الليد، واستخدم سلكًا أسود اللون إن أمكن، ثم لحّم الأسلاك الأخرى مع المقاومات الثلاث، كما يلي:
</p>

<p style="text-align: center;">
	<img alt="tin_jumper.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="116250" data-unique="0s9ig5ce6" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/tin_jumper.gif.6e274221f989d93c8a651bbaccf2aeed.gif">
</p>

<p style="text-align: center;">
	<img alt="bond_jumpers.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="116207" data-unique="mc74k4s9c" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/bond_jumpers.gif.0509fd01109e6f84831e2982f641c202.gif">
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="116263" href="https://academy.hsoub.com/uploads/monthly_2023_01/soldered-jumper-leads.png.17357d249961a308fdfb70d80c34668c.png" rel=""><img alt="نتيجة التلحيم" class="ipsImage ipsImage_thumbnailed" data-fileid="116263" data-ratio="136.36" data-unique="upbbisroj" style="width: 440px; height: auto;" width="440" src="https://academy.hsoub.com/uploads/monthly_2023_01/soldered-jumper-leads.thumb.png.ec797350879d788e1f457876fd9cef0a.png"></a>
</p>

<p>
	حرّك أنابيب الانكماش الحراري للأعلى إلى أن تلامس قاعدة المصباح، لتغطي المقاومات ونقاط اللحام، ثم سخّنها باستخدام الحافة العريضة لمسدس اللحام حتى تنكمش وتشكل طبقةً إضافيةً من العزل.
</p>

<p style="text-align: center;">
	<img alt="position_heat_shrink.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="116230" data-unique="wnjllgold" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/position_heat_shrink.gif.0918434e227d5a01ab6a3038211d92a4.gif">
</p>

<p style="text-align: center;">
	<img alt="shrink_heat_shrink.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="116237" data-unique="3n6ws4lu3" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/shrink_heat_shrink.gif.121bf104dd836f15f345983e6359a5b9.gif">
</p>

<p>
	الآن، بعد أن أحكمنا أنابيب الانكماش على الأسلاك، أصبحنا جاهزين لتوصيل مصباح الليد متعدد الألوان مع أرجل الأغراض العامة <strong>GPIO</strong> للوحة راسبيري بيكو.
</p>

<p style="text-align: center;">
	<img alt="rgb-led-finished.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116234" data-unique="cggq3br2o" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/rgb-led-finished.thumb.jpg.211f0889d1e5c7e96a617325d963c7e9.jpg">
</p>

<p>
	توجد أربعة أرجل لمصباح الليد متعدد الألوان، رجل لكل لون، ورجل مهبط مشتركة تُوصل مع الأرض GND.
</p>

<p style="text-align: center;">
	<img alt="rgb-led-legs.png" class="ipsImage ipsImage_thumbnailed" data-fileid="116236" data-unique="9h9jelkzo" style="width: 60px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/rgb-led-legs.png.702427fb514a7b9734384f219312f6b6.png">
</p>

<p>
	امسك مصباح الليد واتبع الصورة أعلاه للتعرف على الأرجل من اليمين لليسار، ولاحظ أن الرجل الأولى مسؤولة عن اللون الأحمر <strong>R</strong>ed، والثانية الطويلة هي رجل المهبط توَصّل مع الأرض <strong>GND</strong>، أما الثالثة فهي للون الأخضر <strong>G</strong>reen، والرابعة للأزرق <strong>B</strong>lue.
</p>

<p>
	اقلب لوحة راسبيري بيكو على الوجه الآخر وابحث عن الأرجل ذات التسميات التالية: <strong>GP1</strong>، و <strong>GP2</strong>، و <strong>GP3</strong>، و <strong>GND</strong>، ثم صِل السلك الموصول مع الرجل الحمراء للمصباح مع الرجل <strong>GP1</strong>، ورجل المهبط (ذات القطبية السالبة) إلى رجل الأرضية <strong>GND</strong>، والرجل الخضراء مع الرجل <strong>GP2</strong> والزرقاء مع <strong>GP3</strong>، كما هو موضح في الصورة التالية:
</p>

<p style="text-align: center;">
	<img alt="rgb-led-diagram.png" class="ipsImage ipsImage_thumbnailed" data-fileid="116233" data-unique="7jw8t5nhd" src="https://academy.hsoub.com/uploads/monthly_2023_01/rgb-led-diagram.thumb.png.47cb9eac0b901d43cfb80bc2e38c1e31.png">
</p>

<p>
	صِل لوحة بيكو مع حاسوبك باستخدام كبل micro USB، ثم أنشئ ملفًا جديدًا في برنامج ثوني بالنقر على قائمة ملف <strong>File</strong> من شريط القوائم الموجود أعلى الشاشة، ثم سمّه "party_popper.py".
</p>

<p style="text-align: center;">
	<img alt="new_thonny.png" class="ipsImage ipsImage_thumbnailed" data-fileid="116226" data-unique="zoe2dytgl" style="width: 250px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/new_thonny.png.cd133db3a540142ef9b16e6a6ef30e09.png">
</p>

<p>
	أضف الشيفرة التالية لاستيراد التابع <code>RGBLED</code> من مكتبة <code>picozero</code>، وإنشاء المتغير <code>rgb</code> الذي سيُمَكّننا من التحكم في إضاءة مصباح الليد متعدد الألوان الذي وصلناه مع لوحة بيكو.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_750_43" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> RGBLED
</span><span class="kwd">from</span><span class="pln"> time </span><span class="kwd">import</span><span class="pln"> sleep

rgb </span><span class="pun">=</span><span class="pln"> RGBLED</span><span class="pun">(</span><span class="pln">red</span><span class="pun">=</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> green</span><span class="pun">=</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> blue</span><span class="pun">=</span><span class="lit">3</span><span class="pun">)</span><span class="pln"> </span><span class="com"># إسناد أرقام للأرجل</span></pre>

<p>
	كما يمكنك كتابة السطر الأخير من الشيفرة السابقة باستخدام أرقام الأرجل كما يلي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_750_41" style=""><span class="pln"> RGBLED</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">)</span></pre>

<p>
	أنشئ الدالة <code>pop</code> لتشغيل المصباح وجعله يضيء بلون معين، وطباعة رسالة ما في صدفة shell ثوني، لتستدل على أن الدالة قد استُدعيت، ثم استدعِ الدالة بكتابة <code>()pop</code>:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_750_39" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> RGBLED
</span><span class="kwd">from</span><span class="pln"> time </span><span class="kwd">import</span><span class="pln"> sleep

rgb </span><span class="pun">=</span><span class="pln"> RGBLED</span><span class="pun">(</span><span class="pln">red</span><span class="pun">=</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> green</span><span class="pun">=</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> blue</span><span class="pun">=</span><span class="lit">3</span><span class="pun">)</span><span class="pln"> </span><span class="com"># إسناد أرقام للأرجل</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> pop</span><span class="pun">():</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Pop"</span><span class="pun">)</span><span class="pln"> </span><span class="com">#  في صدفة ثوني Pop اطبع  </span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">color </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">255</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اللون البنفسجي </span><span class="pln">
    sleep</span><span class="pun">(</span><span class="lit">2</span><span class="pun">)</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln">

pop</span><span class="pun">()</span><span class="pln"> </span><span class="com"># pop استدعاء الدالة</span></pre>

<p>
	أخيرًا، شغَل الملف لاختبار الشيفرة وتحقق أن المصباح يضيء لمدة ثانيتين باللون البنفسجي (إذ وضعنا القيمة العظمى للون الأحمر والأزرق)، وأن الرسالة "Pop" تظهر في صدفة ثوني عند تشغيل الشيفرة.
</p>

<p style="text-align: center;">
	<img alt="led-purple.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="116224" data-unique="l3sblhpgv" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/led-purple.gif.400fd001cc90f5f481fd5a387bdfe288.gif">
</p>

<h3>
	تصحيح الأخطاء
</h3>

<p>
	إليك بعض المشاكل التي قد تواجهك وكيفية إصلاحها:
</p>

<h4>
	تظهر رسالة مفادها أن تابع RGBLED غير معرف
</h4>

<p>
	قد تظهر لك الرسالة التالية "RGBLED is not defined" التي تعني أن التابع <code>RGBLED</code> غير معّرف، ولحل هذه المشكلة تأكد من استيراد التابع من مكتبة <code>picozero</code>، وذلك بإضافة السطر التالي في بداية الشيفرة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_750_37" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> RGBLED</span></pre>

<h4>
	لا تظهر رسالة Pop في الصدفة
</h4>

<p>
	تحقق من خلو الشيفرة التي كتبتها من الأخطاء ومن مطابقتها للشيفرة في مقالنا.
</p>

<h4>
	لا يضيء مصباح الليد متعدد الألوان
</h4>

<p>
	قد تظهر رسالة "Pop" في الصدفة لكن المصباح لا يضيء، وهنا عليك اتباع ما يلي:
</p>

<ul>
	<li>
		التحقق من أن أسلاك التوصيل موصولة من الأرجل الصحيحة للمصباح ولوحة بيكو.
	</li>
	<li>
		التحقق من متانة التوصيلات.
	</li>
	<li>
		تبديل مصباح الليد للتأكد من أنه لم يحترق.
	</li>
</ul>

<h4>
	لا يضيء مصباح الليد باللون البنفسجي
</h4>

<p>
	تأكد أن أرجل المصباح موصولة مع الأرجل الصحيحة للوحة بيكو، ثم اختبر بالترتيب إضاءة المصباح بالألوان الثلاثة الأساسية عند تعديل القيم في الشيفرة لتصبح <strong>(255,0,0)</strong> للون الأحمر، و <strong>(0,255,0)</strong> للون الأخضر، و <strong>(0,0,255)</strong> للون الأزرق. قد تحتاج لتبديل أسلاك التوصيل. إذا أضاء المصباح بلون واحد، فلربما وصّلت رجل المهبط للمصباح مع الرجل المخصصة لذلك اللون على لوحة بيكو.
</p>

<p>
	ننصحك باستخدام تابع الطباعة <code>print</code> لطباعة الرسائل في الصدفة مما قد يسهل عملك عند تصحيح الأخطاء، كأن تطبع رسالةً مفادها أنك تختبر اللون الأحمر <code>("print ("testing the color red</code> عند اختبارك للألوان.
</p>

<h3>
	اختيار الألوان
</h3>

<p>
	اختر اللون الذي تفضله مما يلي ثم عدل مركباته في الشيفرة:
</p>

<ul>
	<li>
		الأحمر: <strong>(255,0,0)</strong>
	</li>
	<li>
		الأخضر: <strong>(0,255,0)</strong>
	</li>
	<li>
		الأزرق: <strong>(0,0,255)</strong>
	</li>
	<li>
		السّماوي: <strong>(0,255,255)</strong>
	</li>
	<li>
		الأصفر: <strong>(255,255,0)</strong>
	</li>
	<li>
		الوردي: <strong>(255,0,50)</strong>
	</li>
</ul>

<p>
	عدّل على القيم لتحصل على الدرجة المناسبة من اللون المطلوب، وجرّب دمج اللون الأحمر والأخضر والأزرق معًا لتحصل على اللون الأبيض، كما يمكنك تخفيف سطوع اللون بتخفيض القيمة المعبرة عنه، فالقيمة (100,0,0) تعطي لونًا أحمرًا، لكنه أقل سطوعًا من (255,0,0).
</p>

<h2>
	إضافة الصوت
</h2>

<p>
	سنضيف في هذه الخطوة جرسًا إلكترونيًا غير فعّال ليصدر صوتًا كما في مفرقعات الحفلات، وسنكتب الشيفرة اللازمة لذلك. سنبدأ أولًا بالتعريف بالأجراس الإلكترونية الفعّالة active وغير الفعالة passive ثم سنجري الخطوات اللازمة لإضافة الصوت.
</p>

<p style="text-align: center;">
	<img alt="rgb-buzzer.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="116231" data-unique="64aetyofu" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/rgb-buzzer.gif.fd47100591c03f451809d908a319b80f.gif">
</p>

<p>
	<strong>معلومة:</strong> يوجد نوعان من الأجراس الإلكترونية، أحدها فعّال، والآخر غير فعّال، والفرق بينهما هو أن الجرس الفعّال يصدر الصوت نفسه دائمًا، أما غير الفعّال فيمكنه إصدار عدة نغمات، ويتطلب الوصل مع مصدر طاقة وإشارة معينة لعزف النغمة المختارة.
</p>

<h3>
	الأجراس الإلكترونية غير الفعالة
</h3>

<h4>
	الأجراس الإلكترونية ومكبرات الصوت
</h4>

<p>
	ينشأ الصوت عن الاهتزاز والحركة، فكل ما يؤدي لتحريك جزيئات الهواء يمكن أن يصدر صوتًا.
</p>

<ul>
	<li>
		يعتمد مبدأ عمل الأجهزة الميكانيكية Mechnical عادةً على طرق قطعتين معدنيتين ببعضها، فالجرس يهتز عند قرعه مما يسبب تحريك الهواء حوله.
	</li>
	<li>
		تعتمد الأجهزة الكهروميكانيكية Electromechnical على الكهرباء لتحريك ملف من الأسلاك والذي بدوره يُحّرك حاجزًا بسرعة كبيرة مما يؤدي إلى توليد الصوت عن طريق تحريك الهواء حوله.
	</li>
	<li>
		تعتمد الأجهزة الكهروانضغاطية Piezoelectric مبدأ تغيير حجم بعض المواد عند تطبيق جهد عليها، إذ تُغيَر قيمة الجهد بسرعة فيتغير حجم المادة بسرعة كبيرة فيتحرك الهواء حولها.
	</li>
</ul>

<p>
	عندما تتحرك المادة بسرعة كبيرة ينتج عنها أصوات حادة النغمة، وعندما تتحرك مسافة كبيرة تنتج أصواتًا مرتفعة النغمة.
</p>

<h4>
	مكبرات الصوت والسماعات
</h4>

<p>
	تندرج مكبرات الصوت والسمّاعات ضمن الأجهزة الكهروميكانيكية، وتشمل مجموعةً واسعةً من الأجهزة بدءًا بمكبرات الصوت الضخمة المستخدمة في الحفلات الموسيقية، وانتهاءً بسمّاعات الرأس الشخصية.
</p>

<p>
	عليك تغيير الجهد المطبق على مكبر الصوت باستمرار لتشغيله، وكلما غيرت الجهد بسرعة أكبر (أي غيرت تردد الإشارة frequency) كلما حصلت على صوت أكثر حدة، أما للحصول على صوت مرتفع فعليك رفع قيمة الجهد (أي مطال الإشارة amplitude).
</p>

<p>
	نستخدم الكبل ذو مقبس السمّاعات headphone jack التالي لتوصيل مكبرات الصوت والسمّاعات مع باقي الأجهزة.
</p>

<p style="text-align: center;">
	<img alt="Klinkenstecker_5-polig.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116223" data-unique="w838pp660" style="width: 450px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/Klinkenstecker_5-polig.jpg.a603dec8fb2cc1d94699101f648ceea5.jpg">
</p>

<p>
	يجب عليك تحديد التردد الذي سيعمل ويهتز به مكبر الصوت، للحصول على نغمة الصوت التي تريدها.
</p>

<h4>
	الأجراس الإلكترونية
</h4>

<p>
	تندرج الأجراس الإلكترونية Buzzers ضمن الأجهزة الكهروانضغاطية، ويدعى الجرس العادي بالجرس غير الفعّال، ومبدأ عمله مماثل لعمل مكبرات الصوت؛ إذ يلعب تردد تغير الجهد، وقيمة هذا التغير دورًا في تغيير نغمة الصوت ومستوى الصوت.
</p>

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

<p style="text-align: center;">
	<img alt="buzzers.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116210" data-unique="mlu4ywxkv" style="width: 450px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/buzzers.thumb.jpg.1b39619ca9719e3e9a2806b7dcf0d8bb.jpg">
</p>

<p>
	أولًا، لاحظ أن الجرس له رجل طويلة لها قطبية موجبة (+) ورجل قصيرة قطبيتها سالبة (-)، كما في مصباح الليد؛ أما إذا كانت الأرجل متشابهةً في الطول فعليك البحث عن إشارة الموجب (+) الموجودة أعلى الجرس.
</p>

<p style="text-align: center;">
	<img alt="buzzer.png" class="ipsImage ipsImage_thumbnailed" data-fileid="116209" data-unique="wwrdo6frm" style="width: 350px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/buzzer.png.a809ac0296a11f5af415025300ef4ee6.png">
</p>

<p>
	ثانيًا، صِل الجرس مع لوحة بيكو باستخدام سلكي توصيل نوع مقبس-مقبس، وذلك بوصل الرجل الطويلة للجرس مع الرجل <strong>GP5</strong> والقصيرة مع أحد أرجل الأرضية <strong>GND</strong>.
</p>

<p style="text-align: center;">
	<img alt="rgb-led-buzzer-diagram.png" class="ipsImage ipsImage_thumbnailed" data-fileid="116232" data-unique="jjds48umh" style="width: 400px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/rgb-led-buzzer-diagram.thumb.png.846100d63a248cc416d537f8781b47ed.png">
</p>

<p>
	<strong>معلومة:</strong> يمكن للبشر سماع الأصوات التي تتراوح تردداتها بين 20 هرتز (الأصوات المنخفضة جدًا) إلى الترددات من رتبة 20000 هرتز (الأصوات المرتفعة جدًا)، وبإمكان الأطفال واليافعين سماع الأصوات المرتفعة أفضل من كبار السن، كما أن النغمات الموسيقية تتوافق مع ترددات صوتية معينة؛ فعلى سبيل المثال، توافق العلامة <strong>C4</strong> (العلامة سي الوسطى) التردد 262 هرتز، إذ تُقاس الترددات بواحدة الهرتز <strong>Hertz</strong> أو اختصارًا <strong>Hz</strong> وهي عدد الهزات في الثانية. إذًا، سيؤدي إرسال الإشارة الصحيحة للجرس إلى اهتزازه وفق التردد الصحيح وبالتالي سنحصل على النغمة الموسيقية الموافقة.
</p>

<p>
	ثالثًا، عدّل الشيفرة المكتوبة في الملف "party_popper.py" لتبدو كما يلي، ثم شغّلها لاختبار عمل الجرس:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_750_34" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> RGBLED</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> time </span><span class="kwd">import</span><span class="pln"> sleep

rgb </span><span class="pun">=</span><span class="pln"> RGBLED</span><span class="pun">(</span><span class="pln">red</span><span class="pun">=</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> green</span><span class="pun">=</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> blue</span><span class="pun">=</span><span class="lit">3</span><span class="pun">)</span><span class="pln"> </span><span class="com"># إسناد أرقام للأرجل</span><span class="pln">
speaker </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pun">(</span><span class="lit">5</span><span class="pun">)</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> pop</span><span class="pun">():</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Pop"</span><span class="pun">)</span><span class="pln">  </span><span class="com">#  اطبع ما بين القوسين في صدفة ثوني  </span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">color </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">255</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اللون البنفسجي</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="lit">262</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">)</span><span class="pln">  </span><span class="com"># ذات التردد 262 لثانية واحدة C4 اعزف العلامة</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln">

pop</span><span class="pun">()</span></pre>

<p>
	لاحظ أننا استوردنا التابع <code>Speaker</code> من المكتبة في السطر الأول.
</p>

<p>
	رابعًا، تمتع بإنشاء مزيج من الأصوات والأضواء ,التي ستصدرها دارتنا عند تشغيلها، إذ أنشأنا في مثالنا صوتًا احتفاليًا "تا-دا Ta-da" يَصدُر بالتزامن مع وميض الليد باللون البنفسجي.
</p>

<p>
	خامسًا، عدّل على الشيفرة لتبدو كما يلي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_750_32" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> RGBLED</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> time </span><span class="kwd">import</span><span class="pln"> sleep

rgb </span><span class="pun">=</span><span class="pln"> RGBLED</span><span class="pun">(</span><span class="pln">red</span><span class="pun">=</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> green</span><span class="pun">=</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> blue</span><span class="pun">=</span><span class="lit">3</span><span class="pun">)</span><span class="pln"> </span><span class="com"># إسناد أرقام للأرجل</span><span class="pln">
speaker </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pun">(</span><span class="lit">5</span><span class="pun">)</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> pop</span><span class="pun">():</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Pop"</span><span class="pun">)</span><span class="pln"> </span><span class="com">#  اطبع ما بين القوسين في صدفة  ثوني  </span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">color </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">255</span><span class="pun">)</span><span class="pln"> </span><span class="com"># Purple</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="lit">262</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">)</span><span class="pln"> </span><span class="com"># ذات التردد 262 لمدة 0.1 ثانية C4 اعزف العلامة</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">color </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="com"># المصباح مطفىء</span><span class="pln">
    sleep</span><span class="pun">(</span><span class="lit">0.1</span><span class="pun">)</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">color </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">255</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اللون البنفسجي</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="lit">262</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.6</span><span class="pun">)</span><span class="pln"> </span><span class="com"># ذات التردد 262 لمدة 0.6 ثانية C4 اعزف العلامة</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln">

pop</span><span class="pun">()</span></pre>

<p>
	سادسًا، شغّل الشيفرة وتحقق أن المصباح والجرس الإلكتروني يعملان معًا.
</p>

<p style="text-align: center;">
	<img alt="rgb-buzzer.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="116231" data-unique="64aetyofu" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/rgb-buzzer.gif.fd47100591c03f451809d908a319b80f.gif">
</p>

<h3>
	تصحيح الأخطاء
</h3>

<p>
	إليك بعض المشاكل التي قد تواجهك في هذه الخطوة وكيفية إصلاحها:
</p>

<h4>
	تظهر رسالة مفادها أن تابع مكبر الصوت Speaker غير معرف
</h4>

<p>
	أضف <code>Speaker ,</code> على نهاية السطر الأول من الشيفرة.
</p>

<h4>
	لا تظهر رسالة Pop في الصدفة
</h4>

<p>
	تحقق من خلو الشيفرة التي كتبتها من الأخطاء ومن مطابقتها للشيفرة في مقالنا.
</p>

<h4>
	لا يضيء مصباح الليد متعدد الألوان
</h4>

<p>
	عليك اتباع ما يلي:
</p>

<ul>
	<li>
		التحقق من أن أسلاك التوصيل موصولة مع الأرجل الصحيحة للمصباح وللوحة بيكو.
	</li>
	<li>
		التحقق من متانة التوصيلات.
	</li>
	<li>
		تبديل مصباح الليد للتأكد من أنه لم يحترق.
	</li>
</ul>

<h4>
	لا يصدر الجرس الإلكتروني صوتا
</h4>

<p>
	لحل المشكلة عليك اتباع ما يلي:
</p>

<ul>
	<li>
		التحقق من أن أسلاك التوصيل موصولة مع الأرجل الصحيحة للجرس.
	</li>
	<li>
		التحقق من متانة التوصيلات.
	</li>
	<li>
		التحقق من استخدام جرس إلكتروني غير فعّال.
	</li>
	<li>
		التحقق من استخدام ترددات ضمن مجال الترددات المسموعة (من 15 هرتز إلى 15000 هرتز).
	</li>
</ul>

<h2>
	تشغيل الدارة
</h2>

<p>
	سنعمل في هذه الخطوة على إنشاء محاكاة بسيطة للمبدّل الإلكتروني باستخدام سلكي توصيل، وذلك لتشغيل دارتنا وإطلاق مفرقعات الحفلة.
</p>

<p style="text-align: center;">
	<img alt="switch-buzzer-led.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116244" data-unique="93o2hca1j" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/switch-buzzer-led.jpg.58a23c02b5660b7c92f97f74b8b0d211.jpg">
</p>

<p>
	<strong>معلومة:</strong> تُقَام عروض الصوت والضوء Light and sound shows في الاحتفالات في جميع أنحاء العالم، وتكون ممتعةً وتفاعليةً وباستخدام أدوات مستدامة sustainable وقابلة لإعادة الاستخدام reusable، مثل الطائرات دون طيّار Drones، والليزر، وعروض الإسقاط، خلافًا لما يُستَخدم سابقًا من أغراض استهلاكية غير صديقة للبيئة، مثل مفرقعات الحفلات والألعاب النارية.
</p>

<p>
	أولًا، جهّز سلكي توصيل نوع دبوس- مقبس لاستخدامهما مثل مبدّل يدوي، ثم صِل السلك الأول مع الرجل <strong>GP18</strong> والثاني مع رجل الأرض <strong>GND</strong> القريبة.
</p>

<p style="text-align: center;">
	<img alt="jumper-switch.png" class="ipsImage ipsImage_thumbnailed" data-fileid="116220" data-unique="mi9vk3zk3" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/jumper-switch.png.e70c353102ae434b3ad0d4bfb71d5056.png">
</p>

<p>
	<strong>معلومة:</strong> توجد طريقتان لتشغيل الشيفرة المعتمدة على دخل من عنصر خارجي (مثل المبدّلات أو الحساسات)، الأولى هي بإنشاء حلقة تكرار والتحقق من حالة الدخل باستمرار وتدعى هذه العملية باسم <strong>الجسّ Polling</strong>، واستخدمناها سابقًا في مشروع اليراعات الوامضة باستخدام الليد؛ بينما تعتمد الطريقة الثانية على استدعاء دالة عند تغير حالة الدخل، باستخدام <strong>أحداث events</strong> تتحسس للتغيرات ومن ثم تتعامل معها.
</p>

<p>
	ثانيًا، عدّل على الشيفرة كي تستدعي مكتبة <code>picpzero</code> الدالة <code>pop</code> كلما فُتِح المبدّل (أي فصلنا سلكي التوصيل عن بعضهما)، ولا تنسى إدراج تابع المبدّل <code>Switch</code> من المكتبة في السطر الأول:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_750_28" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> RGBLED</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Switch</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> time </span><span class="kwd">import</span><span class="pln"> sleep

rgb </span><span class="pun">=</span><span class="pln"> RGBLED</span><span class="pun">(</span><span class="pln">red</span><span class="pun">=</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> green</span><span class="pun">=</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> blue</span><span class="pun">=</span><span class="lit">3</span><span class="pun">)</span><span class="pln"> </span><span class="com"># إسناد أرقام للأرجل</span><span class="pln">
pull </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Switch</span><span class="pun">(</span><span class="lit">18</span><span class="pun">)</span><span class="pln">
speaker </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Speaker</span><span class="pun">(</span><span class="lit">5</span><span class="pun">)</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> pop</span><span class="pun">():</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Pop"</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اطبع ما بين القوسين في صدفة في ثوني  </span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">color </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">255</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اللون البنفسجي</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="lit">262</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">)</span><span class="pln"> </span><span class="com"># لمدة 0.1 ثانية C4 اعزف العلامة</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">color </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="com"># # المصباح مطفىء</span><span class="pln">
    sleep</span><span class="pun">(</span><span class="lit">0.1</span><span class="pun">)</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">color </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">255</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">255</span><span class="pun">)</span><span class="pln"> </span><span class="com"># اللون البنفسجي</span><span class="pln">
    speaker</span><span class="pun">.</span><span class="pln">play</span><span class="pun">(</span><span class="lit">262</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.6</span><span class="pun">)</span><span class="pln"> </span><span class="com"># لمدة 0.6 ثانية C4 اعزف العلامة</span><span class="pln">
    rgb</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln">

pull</span><span class="pun">.</span><span class="pln">when_opened </span><span class="pun">=</span><span class="pln"> pop </span><span class="com"># استدعاء الدالة عند فتح المبدّل</span></pre>

<p>
	عند استخدام الحدث <code>when_opened</code> تُستدعى الدالة <code>pop</code> والتي لا يمكن مقاطعتها إلى أن تكمل عملها، وهذا الأنسب لمشروعنا؛ إذ نود تشغيل المؤثرات الصوتية والضوئية عند فتح المبدّل وتشغيل دارتنا، أي تشغيل مفرقعات الحفلة.
</p>

<p>
	احرص على عدم إضافة الأقواس <strong>( )</strong> في نهاية السطر <code>pull.when_opened = pop</code> إذ أن مهمة هذا السطر هو استدعاء الدالة <code>pop</code> من مكتبة <code>picozero</code> كلما تحقق الحدث <code>when_opened</code>.
</p>

<p>
	ثالثًا، شغّل البرنامج، ثم افصل سلكي التوصيل عن بعضهما لاختبار عمل المصباح والجرس الإلكتروني عند فتح المبدّل.
</p>

<h3>
	تصحيح الأخطاء
</h3>

<p>
	إليك بعض المشاكل التي قد تواجهك في هذه الخطوة وكيفية إصلاحها:
</p>

<h4>
	تظهر رسالة مفادها أن تابع المبدل Switch غير معرف
</h4>

<p>
	أضف <code>Switch ,</code> على نهاية السطر الأول من الشيفرة.
</p>

<h4>
	تعمل الشيفرة قبل فصل المبدل
</h4>

<ul>
	<li>
		تحقق من أن أسلاك المبدّل موصولة مع الأرجل الصحيحة على لوحة بيكو.
	</li>
	<li>
		تحقق من متانة توصيل أسلاك المبدّل وأن الأسلاك بحالة جيدة.
	</li>
	<li>
		تحقق من استبدال السطر <code>()pop</code> بالسطر <code>pull.when_opened = pop</code>.
	</li>
</ul>

<h4>
	لا تظهر رسالة Pop في الصدفة
</h4>

<p>
	تحقق من خلو الشيفرة التي كتبتها من الأخطاء ومن مطابقتها للشيفرة في مقالنا.
</p>

<h4>
	لا يضيء مصباح الليد متعدد الألوان أو أن الجرس الإلكتروني لا يعمل
</h4>

<ul>
	<li>
		تحقق من أن أسلاك التوصيل موصولة من الأرجل الصحيحة للمصباح ولوحة بيكو.
	</li>
	<li>
		تحقق من متانة التوصيلات.
	</li>
	<li>
		بدِّل مصباح الليد للتأكد من أنه لم يحترق.
	</li>
</ul>

<h2>
	تزيين المبدل
</h2>

<p>
	سنصنع غلافًا خارجيًا مزخرفًا للمبدّل من الورق المقوى ورقائق القصدير والغراء، لنحصل على نتيجة مشابهة لما يلي:
</p>

<p style="text-align: center;">
	<img alt="add-ribbon.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116205" data-unique="czyvm0q37" src="https://academy.hsoub.com/uploads/monthly_2023_01/add-ribbon.jpg.678cd4de6f06b3d2fb98732ec8023c88.jpg">
</p>

<p>
	بعد أن تأكدنا من عمل الدارة، سنضيف مظهرًا مزخرفًا على المبدّل اليدوي، إليك ما سنحتاج إليه:
</p>

<ul>
	<li>
		مقص.
	</li>
	<li>
		ورق مقوى.
	</li>
	<li>
		رقائق القصدير.
	</li>
	<li>
		غراء وشريط لاصق.
	</li>
	<li>
		شرائط ملونة وورق ملون.
	</li>
	<li>
		قلم رصاص ومسّطرة (اختياري).
	</li>
</ul>

<p style="text-align: center;">
	<img alt="مستلزمات عمل دارة براسبيري باي بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="116245" data-ratio="75.09" data-unique="g7pdgbtgb" style="width: 550px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_01/switch-gather-materials.jpeg.99f77c2eb72ddcf30cd3be16ffa3d6c3.jpeg">
</p>

<p>
	أولًا، قُصَّ الورق المقوى إلى ثلاثة مستطيلات متساوية الحجم، استخدمنا الأبعاد التالية 3سم × 5سم؛ وإذا لم يتوفر لديك قلم رصاص ومسّطرة، قُص المستطيل الأول ثم ضعه فوق الورق المقوى وقُصَّ حوله للحصول على مستطيلات متماثلة.
</p>

<p style="text-align: center;">
	<img alt="three rectangles" class="ipsImage ipsImage_thumbnailed" data-fileid="116249" data-ratio="68.91" data-unique="8o8ifc9ga" style="width: 550px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_01/three-rectangles.jpg.8bf2699b14471bcf9dd64adee4089aac.jpg">
</p>

<p>
	ثانيًا، قُص مستطيلًا صغيرًا في منتصف المستطيل الأول، واحتفظ به لاستخدامه لاحقًا.
</p>

<p style="text-align: center;">
	<img alt="centre-cut.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116211" data-unique="limy0ho84" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/centre-cut.jpg.92e746f11f6c2af7dea131f9a8062cab.jpg">
</p>

<p>
	ثالثًا، قُصّ قطعًا من ورق القصدير بحجم المستطيلات الكبيرة، ثم الصقها عليها باستخدام الغراء، واحرص على عدم وضع الغراء على الوجه الخارجي لورق القصدير حتى لا تتأثر التوصيلات لاحقًا.
</p>

<p style="text-align: center;">
	<img alt="add-foil.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116204" data-unique="mk5tq8lv2" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/add-foil.thumb.jpg.30e8ee30eed11280c70d4afb0a40f013.jpg">
</p>

<p>
	رابعًا، قُصَّ أطراف المستطيل الصغير للحصول على شكل مدبب أو بشكل حرف V، ثم قلّم الأطراف بمقدار بضع ميليمترات كي يتسع المستطيل الصغير في الفتحة.
</p>

<p style="text-align: center;">
	<img alt="trim-piece.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116258" data-unique="ifuu50no6" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/trim-piece.jpg.b62304593a8536ea00074fd6c7a1900a.jpg">
</p>

<p>
	خامسًا، غلّف المستطيل الصغير بكامله بورق القصدير، واحرص على استخدام ورقة قصدير واحدة، إذ ستسمح هذه القطعة بمرور التيار عند إغلاق المبدّل.
</p>

<p style="text-align: center;">
	<img alt="foil-cover.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="116214" data-unique="uqe8jtbh0" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/foil-cover.gif.3722d652d27dc86b8945c2979349b2a0.gif">
</p>

<p>
	سادسًا، افصل لوحة بيكو عن حاسوبك، وافصل سلكي المبدّل الموصولين مع الرجل <strong>GP18</strong> ورجل الأرضية <strong>GND</strong>، ثم استخدم الشريط اللاصق لتثبيتها على الوجه العلوي للمستطيلات.
</p>

<p>
	احرص على أن يكون الدبوس المعدني للسلك ملامسًا لورق القصدير، وأن يكون الجزء البلاستيكي الأسود ملامسًا حافة المستطيل.
</p>

<p style="text-align: center;">
	<img alt="pin-sticky-tape-1.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116228" data-unique="n6armp2mb" src="https://academy.hsoub.com/uploads/monthly_2023_01/pin-sticky-tape-1.jpg.4f7c231aa7dddd56f72f2218004846d1.jpg">
</p>

<p>
	أضف مزيدًا من الشريط اللاصق لتثبيت السلك ومنع انفكاكه عن طريق الخطأ.
</p>

<p style="text-align: center;">
	<img alt="pin-sticky-tape-2.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116229" data-unique="115zw6vdb" src="https://academy.hsoub.com/uploads/monthly_2023_01/pin-sticky-tape-2.jpg.f25e6175e0265b41987f2ed94a7dcd97.jpg">
</p>

<p>
	سابعًا، أعد توصيل الأسلاك مع الرجل <strong>GP18</strong> ورجل الأرض <strong>GND</strong>، ثم صِل لوحة بيكو بحاسوبك وشغّل الشيفرة.
</p>

<p>
	افتح المبدّل وأغلقه عن طريق ملامسة المستطيلات المغطاة بالقصدير مع بعضها. يجب أن يعمل مصباح الليد والجرس عند فتح المبدّل.
</p>

<p style="text-align: center;">
	<img alt="foil-pad-test.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="116215" data-unique="uequ8r1xz" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/foil-pad-test.gif.12860653897652befae311a67073eb6c.gif">
</p>

<h3>
	تصحيح الأخطاء
</h3>

<p>
	إليك بعض المشاكل التي قد تواجهك وكيفية إصلاحها:
</p>

<h4>
	يستمر الجرس والمصباح بالعمل
</h4>

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

<h4>
	لا تعمل المفرقعات عند فتح المبدل
</h4>

<ul>
	<li>
		تأكد أن أسلاك التوصيل موصولة مع الأرجل الصحيحة.
	</li>
	<li>
		تحقق من متانة توصيل الأسلاك بالأرجل على لوحة بيكو، ومتانة توصيلها بالقصدير، إذ يجب أن تكون جميع العناصر متصلة ببعضها جيدًا.
	</li>
	<li>
		شغّل الشيفرة ثم أغلق المبدّل وافتحه وتأكد أن الحدث <code>when_opened</code> يتولد، وتأكد أن الشيفرة التي كتبتها مطابقة للشيفرة في مثالنا.
	</li>
</ul>

<p>
	ثامنًا، افصل لوحة بيكو عن حاسوبك، وافصل سلكي المبدّل الموصولين مع الرجل <strong>GP18</strong> ورجل الأرضية <strong>GND</strong>، ثم ادهن بعض الغراء على المستطيل الذي فرّغنا منتصفه (الموجود في يسار الصورة) والصقه مع المستطيل المغطى بالقصدير (يمين الصورة)، وبهذا نكون أنشأنا حاجزًا بين طبقتي القصدير، ووفرنا مساحةً لإدخال المستطيل الصغير ضمنها لإغلاق المبدّل بسلاسة وإطلاق المفرقعات عند فتحه.
</p>

<p style="text-align: center;">
	<img alt="glue-left.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116217" data-unique="rg0l4n8zn" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/glue-left.jpg.2392e7f58942ba633d6b3a60761455d5.jpg">
</p>

<p>
	يجب أن تحصل على الشكل التالي، واحرص على ألا يتلامس القصدير الموجود على حواف المستطيلات، وقُصّه إن لزم الأمر:
</p>

<p style="text-align: center;">
	<img alt="glue-right.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116218" data-unique="abq9uwq9c" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/glue-right.jpg.904c67c50b6a0aca68469725086f9e34.jpg">
</p>

<p>
	اختبر الدارة باتباع ما يلي:
</p>

<ul>
	<li>
		أعد توصيل لوحة بيكو مع حاسوبك، ثم أعد توصيل الأسلاك مع الرجل <strong>GP18</strong> ورجل الأرض <strong>GND</strong>.
	</li>
	<li>
		أدخل المستطيل الصغير داخل المبدّل (المستطيلين) لإغلاقه.
	</li>
	<li>
		شغّل الشفرة ثم اسحب المستطيل الصغير لفتح المبدّل وإطلاق المفرقعات.
	</li>
</ul>

<p style="text-align: center;">
	<img alt="full-popper-test.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="116216" data-unique="hz6p7iu5v" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/full-popper-test.gif.7ee846277d055dedc83fc825c2c55c3e.gif">
</p>

<p>
	إذا لم تعمل الدارة وتنطلق المفرقعات عند فتح المبدّل، فعليك التأكد من عدم وجود القصدير على حواف المستطيلات، قُصّه إن وُجِد، وتأكد أنك ضغط على زر التشغيل Run لتشغيل الشيفرة.
</p>

<p>
	يمكنك إضافة قصاصات ملونة، أو شريطًا ملونًا على المستطيل الصغير لإضفاء بعض الحيوية عليه.
</p>

<p style="text-align: center;">
	<img alt="add-ribbon.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116205" data-unique="czyvm0q37" src="https://academy.hsoub.com/uploads/monthly_2023_01/add-ribbon.jpg.678cd4de6f06b3d2fb98732ec8023c88.jpg">
</p>

<h2>
	ترقية المشروع
</h2>

<p>
	بإمكانك ترقية المشروع حين يتسنى لك ذلك، واستخدامه للاحتفال كلما نفّذت مشروعًا أو تعلمت مهارةً جديدة، أو كلما أصلحت خطأً ما.
</p>

<p>
	إليك بعض الاقتراحات لترقية مشروعك:
</p>

<ul>
	<li>
		تعديل الشيفرة وإضافة مزيدٍ من الأضواء والأصوات، استخدم الترددات ضمن المجال (250 هرتز- 500 هرتز) للحصول على نغمات مناسبة.
	</li>
	<li>
		اصنع غلافًا خارجيًا من الورق للجرس ولمصباح الليد، كأن تضعهما ضمن مخروط ورقي.
	</li>
	<li>
		زيّن المبدّل، واجعله أكثر متانة.
	</li>
	<li>
		أعد تشكيل الدارة بما يتناسب مع مناسبة معينة؛ كأن تغير لون إضاءة المصباح وفقًا للون علم بلدك أو فريقك الرياضي المفضل، وحاول الحصول على نغمة مناسبة للحدث.
	</li>
</ul>

<p>
	يمكنك الاطلاع على الشيفرة النهائية للمشروع من <a href="https://rpf.io/p/en/party-popper-get" rel="external nofollow">rpf.io</a>.
</p>

<p style="text-align: center;">
	<img alt="upgrade-popper.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="116260" data-unique="3fsqsrubm" style="width: 500px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2023_01/upgrade-popper.jpg.7eb482f06a5e36d924eb398778e16ff6.jpg">
</p>

<h2>
	الخاتمة
</h2>

<p>
	تهانينا، فقد أتممت مشروع تصميم محاكاة لمفرقعات الحفلات باستخدام لوحة راسبيري باي بيكو، ويمكنك تنزيل كامل شيفرة المشروع  من مجلد <a data-fileext="zip" data-fileid="116262" href="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=116262&amp;key=0c57c21d21303f2128d46290a1749e0b" rel="">party-popper-en-solutions</a>.
</p>

<p>
	ننصحك بتنفيذ مشروع القلب النابض باستخدام لوحة راسبيري باي بيكو ومقاومة متغيرة في خطوتك التالية.
</p>

<p>
	إذا واجهت مشاكلًا عند تنفيذ هذا المشروع، فيمكنك الحصول على الدعم والمساعدة عبر إضافة سؤالك في قسم الأسئلة والأجوبة في <a href="https://academy.hsoub.com/questions/" rel="">أكاديمية حسوب</a>.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://projects.raspberrypi.org/en/projects/party-popper/" rel="external nofollow">Party popper</a> من <a href="https://raspberrypi.org/" rel="external nofollow">الموقع الرسمي لراسبيري باي</a>.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D8%B5%D8%A8%D8%A7%D8%AD-%D9%84%D9%8A%D8%AF-%D9%8A%D9%88%D9%85%D8%B6-%D9%88%D9%81%D9%82-%D9%86%D9%85%D8%B7-%D9%85%D8%B9%D9%8A%D9%86-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1848/" rel="">إنشاء مصباح ليد يومض وفق نمط معين باستخدام حاسوب راسبيري باي بيكو</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D9%85%D8%B5%D8%A8%D8%A7%D8%AD-%D9%84%D9%8A%D8%AF-%D8%AB%D9%84%D8%A7%D8%AB%D9%8A-%D8%A7%D9%84%D8%A3%D8%A8%D8%B9%D8%A7%D8%AF-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%B3%D9%83%D8%B1%D8%A7%D8%AA%D8%B4-%D9%88%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-r1504/" rel="">تنفيذ مصباح ليد ثلاثي الأبعاد باستخدام سكراتش ولوحة راسبيري باي</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%AC%D9%85%D9%8A%D8%B9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D9%88%D8%A7%D9%84%D8%AA%D8%AD%D8%B6%D9%8A%D8%B1-%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%85%D8%A7%D9%84%D9%87-r1370/" rel="">تجميع راسبيري باي والتحضير لاستعماله</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%B1%D8%A8%D8%B7-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D8%B9%D9%86%D8%A7%D8%B5%D8%B1-%D8%A5%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A%D8%A9-%D9%88%D8%A8%D8%B1%D9%85%D8%AC%D8%AA%D9%87%D8%A7-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%B3%D9%83%D8%B1%D8%A7%D8%AA%D8%B4-%D9%88%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-r1496/" rel="">ربط راسبيري باي بعناصر إلكترونية وبرمجتها باستخدام سكراتش وبايثون</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1861</guid><pubDate>Thu, 12 Jan 2023 16:03:01 +0000</pubDate></item><item><title>&#x628;&#x631;&#x645;&#x62C;&#x629; &#x627;&#x644;&#x631;&#x648;&#x628;&#x648;&#x62A;: &#x627;&#x644;&#x62F;&#x644;&#x64A;&#x644; &#x627;&#x644;&#x634;&#x627;&#x645;&#x644;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-%D8%A7%D9%84%D8%B1%D9%88%D8%A8%D9%88%D8%AA-%D8%A7%D9%84%D8%AF%D9%84%D9%8A%D9%84-%D8%A7%D9%84%D8%B4%D8%A7%D9%85%D9%84-r1855/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2023_01/1894030304_-.png.886b5176ae4e9247a30e40ab0f3fb689.png" /></p>
<p>
	يهدف هذا المقال أساسًا إلى التعريف ببرمجة الروبوتات Robots Programming، ونظرًا لاختلاف النُهج المتبعة في البرمجة وفقًا لطبيعة عمل الروبوت، ستختلف عملية برمجة الروبوت وأساليبها، لهذا سنتحدث باختصار عن الروبوتات وأنواعها ثم الاستخدامات الأكثر شيوعًا لها، ومن ثم نعرّج على أهم لغات البرمجة المستخدمة في برمجة الروبوتات وكيفية البدء بمسار تعلم برمجة الروبوت المناسب لك ونتحدث في مقالنا عن برمجة الروبوتات للأطفال وأشهر اللغات والمنصات التي تساعد على دخول عالم برمجة الروبوتات والتحكم بها.
</p>

<h2>
	من الآلات إلى الروبوتات
</h2>

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

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

<p>
	أما المرحلة الثانية من التطور فكانت ظهور المتحكمات الصغرية أو الدقيقة Microcontroller والمعالجات الدقيقة Microprocessor ومن ثم الدارات الرقمية التي طورت على أساسها، إذ مكنت هذه الدارات المهندسين من إعداد بيئة تحكم متكاملة لخط إنتاج أو معمل بأكمله. إذ تُبرمج معطيات التحكم بكل آلة باستخدام لغات برمجة مخصصة ثم تنقل هذه البرمجيات إلى لوحات التحكم المبنية على تلك المعالجات لتقود هذه الآلات بدقة.
</p>

<p>
	ولم يعد أمر تغيير برنامج العمل مرهقَا ولن يتطلب تغييرات في التجهيزات وإيقاف خطوط الإنتاج طويلًا لضبط المتغيرات الجديدة، بل تُعدّل البرمجيات خارج إطار خط الإنتاج ثم تحمّل إلى لوحات التحكم ليتوقف بعدها الخط لدقائق ثم يباشر العمل وفق البرنامج الجديد، وتُعرف هذه اللوحات بالدارات المنطقية القابلة للبرمجة PLC وتُبرمح لتقوم بعمل معين عندما تتحسس لمتغير ما أو يأتيها أمر ما. عندما تقود هذه الدارات تجهيزة محددة لتقوم بمجموعة خطوات معقدة لإنجاز عمل متكامل دعونا هذه التجهيزة روبوت Robot وتعرف عملية برمجتها ببرمجة الروبوت.
</p>

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

<p>
	فالطائرات المسيرة ومركبات استكشاف أجرام المجموعة الشمسية والروبوتات الطبية والتجهيزات المنزلية الذكية وألعاب الأطفال التفاعلية وغيرها الكثير من الأمثلة هي روبوتات تختلف في مستوى تعقيدها وبرمجتها وذكائها.
</p>

<h2>
	لمحة عن الروبوتات
</h2>

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

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="116139" href="https://academy.hsoub.com/uploads/monthly_2023_01/544113378_-.jpg.4925a9b80afca77b410d976159ea5ee1.jpg" rel=""><img alt="برمجة الروبوتات" class="ipsImage ipsImage_thumbnailed" data-fileid="116139" data-ratio="66.83" data-unique="sv96tcrxy" style="width: 600px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2023_01/1365082250_-.thumb.jpg.c7712968053b2f2d9a0252bbf57a7e5f.jpg"></a>
</p>

<h3>
	الأجزاء الرئيسية للروبوت
</h3>

<p>
	يتكون الروبوت بشكل عام من الأقسام الرئيسية التالية:
</p>

<ol>
	<li>
		هيكل فيزيائي Physical Structure مخصص يساعد الروبوت على أداء الوظيفة الخاصة به، وهنا يأتي دور التصميم الصحيح في إنجاز الروبوت المطلوب.فالروبوتات التي تستخدم في صناعة السيارات مثلًا لا بد أن تتمتع بتصميم فيزيائي يناسب عملها.
	</li>
	<li>
		منظومة تحكم Control System تضم كل المكوّنات التي تتلقى البيانات من المحيط وتعالجها. تُبرمج منظومة التحكم لتقود المكوّنات الأخرى للروبوت كي تؤدي العمل المطلوب منها، فهي تتصرف كالدماغ البشري بشكل أو بآخر.
	</li>
	<li>
		الحساسات أو المستشعرات Sensors التي تستكشف البيئة المحيطة (مثل مستشعرات الحرارة والحركة والبعد وغيرها) وتنقل المحرضات إلى منظومة التحكم على شكل إشارات إلكترونية تفهمها منظومة التحكم وتدفع الروبوت إلى الاستجابة لها وفقًا لبرمجة الروبوت المحددة.
	</li>
	<li>
		المشغّلات Actuators المسؤولة عن تحريك الروبوت وتتكون عادة من محركات تتلقى الإشارات من منظومة التحكم لتنفيذ الحركة المطلوبة. وتختلف طريقة عمل هذه المشغلات وفقا لعمل الروبوت، فقد تعمل بالكهرباء أو الهواء المضغوط (مشغلات بنيوماتية pneumatic actuators) أو هيدروليكية وغيرها.
	</li>
	<li>
		مصدر للطاقة الكهربائية لتغذية منظومة التحكم وأجهزة التحسس والمشغلات الكهربائية.
	</li>
	<li>
		الطرفيات المخصصة، وهي مكوّنات خارجية خاصة بكل روبوت لتساعده على أداء وظيفته. فقد تحتاج روبوتات المعامل إلى طرفيات قابلة للتغيير لأغراض الطلاء أو القص أو الثقب، كما يحتاج الروبوت الجراحي إلى معدات خاصة به وهكذا.
	</li>
</ol>

<h3>
	الأنواع الرئيسية للروبوتات
</h3>

<p>
	نشير عادة بالروبوتات إلى الروبوتات الفيزيائية التي تأتي بمختلف الأشكال والأحجام من 0.2 ميليمتر إلى روبوتات بطول 200 متر. لكن لا بد من الإشارة أيضًا إلى الروبوتات البرمجية التي تنفذ مهام روبوتية كاملة عبر الحاسوب في العالم الافتراضي.
</p>

<p>
	يمكن أن نميز بين خمسة أنواع رئيسية من الروبوتات:
</p>

<ol>
	<li>
		<strong>الروبوتات مسبقة البرمجة Pre-Programmed Robots</strong>: وهي روبوتات مصممة لأداء مهام محددة في بيئة فيزيائية محددة مثل الأذرع الروبوتية التي تعمل على خطوط التجميع والتي تنفذ مهامها بسرعة وكفاءة عالية مقارنة بالعامل البشري. وتُعد برمجة الروبوتات في هذه الحالة سهلة نسبيًا
	</li>
	<li>
		<strong>الروبوتات الشبيهة بالبشر Humanoid Robots</strong>: وهي روبوتات تبدو كالبشر وتحاكي أفعالهم عادة كالمشي والعدو والقفز وحمل الأغراض، وقد تصمم أحيانًا لتبدي تعابير تحاكي تعابير الوجه التي يبديها البشر.
	</li>
	<li>
		<strong>روبوتات ذاتية التصرف Autonomous robots</strong>: روبوتات تعمل بشكل مستقل عن المشغلين البشريين وتصمم عادة لتنفيذ مهام في بيئات مفتوحة لا تتطلب مراقبة بشرية أو لا يمكن وجود البشر فيها. وتتميز هذه الروبوتات بوجود بنية قادرة على اتخاذ القرار وهي بنية حاسوبية عادة تقدّر كل خطوة بناءً على البيانات التي ولّتها مسبقًا. تتميز برمجة الروبوتات ذاتية التصرف بالتعقيد وتعتمد على خوارزميات <a href="https://academy.hsoub.com/files/17-%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D9%88%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9/" rel="">الذكاء الصنعي وتعلم الآلة</a>. وكمثال عليها نجد الطائرات المسيرة ذاتية التصرف والروبوتات الطبية وروبوتات الأعمال المنزلية.
	</li>
	<li>
		<strong>الروبوتات الخاضعة للتحكم عن بعد Teleoperated robots</strong>: يتصل الإنسان بهذه الروبوتات غالبًا عبر شبكة لاسلكية ويتحكم بها عبر واجهة تحكم خاصة. تعمل هذه الروبوتات في بيئات جغرافية ومناخية قاسية جدًا كالغواصات الروبوتية والمسيرات المتعقبة للألغام.
	</li>
	<li>
		<strong>روبوتات الواقع المعزز Augmenting robots</strong>: وتستخدم لتعزيز القدرات البشرية أو تعويض القدرات التي قد يفقدها. من هذه الروبوتات الأطراف الصناعية الروبوتية والهياكل الخارجية الروبوتية التي تساعد البشر على رفع الأوزان الثقيلة.
	</li>
</ol>

<h3>
	الروبوتات البرمجية
</h3>

<p>
	الروبوتات أو البوتات البرمجية Bots هي برامج حاسوبية تنفذ مجموعة من المهام الحاسوبية ذاتيًا ومن أشهرها روبوتات المحادثة الآلية. يتطور هذه النوع من الروبوتات مدعومًا بالتطور البرمجي الحاصل في مجالات الذكاء الصناعي و<a href="https://academy.hsoub.com/programming/general/%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">علم البيانات </a>وخوارزميات تعلم الآلة، ويتوقع أن يصبح قادرًا على برمجة الروبوتات الفيزيائية والتحكم بها، فهذه الروبوتات هي المنتج النهائي لعلم الذكاء الصنعي.
</p>

<div class="banner-container ipsBox ipsPadding">
	<div class="inner-banner-container">
		<p class="banner-heading">
			دورة الذكاء الاصطناعي
		</p>

		<p class="banner-subtitle">
			احترف برمجة الذكاء الاصطناعي AI وتحليل البيانات وتعلم كافة المعلومات التي تحتاجها لبناء نماذج ذكاء اصطناعي متخصصة.
		</p>

		<div>
			<a class="ipsButton ipsButton_large ipsButton_primary ipsButton_important" href="https://academy.hsoub.com/learn/artificial-intelligence" rel="">اشترك الآن</a>
		</div>
	</div>

	<div class="banner-img">
		<a href="https://academy.hsoub.com/learn/artificial-intelligence" rel=""><img alt="دورة الذكاء الاصطناعي AI" src="https://academy.hsoub.com/learn/assets/images/courses/artificial-intelligence.png"></a>
	</div>
</div>


<h2>
	كيفية برمجة الروبوت
</h2>

<p>
	تضم معظم الروبوتات الفيزيائية نوعًا من منظومات التحكم الحاسوبية القابلة للبرمجة. فقد تُبني هذه الأنظمة على أساس المتحكمات الصغرية أو المعالجات الصغرية وتكون مخصصة لنوع محدد من الروبوتات أي تُبنى وفق رؤية المصنع.
</p>

<p>
	تُبرمج الروبوتات المخصصة من قبل مُصنِّعها فقط ولا يمكن تعديل برمجياتها ووظائفها إلا من قبل الشركة المصنعة. كما قد تكون منظومات التحكم معممة يمكن استخدامها لتتحكم بأية روبوتات مثل حواسيب أردوينو المصغرة وحواسب راسبيري باي ووحدات الدارات المنطقية القابلة للبرمجة. يمكن لأي شخص استخدام هذه الحواسب سواءً أكان هاويًا في مجال الروبوتات أو حتى خبيرًا لبناء روبوتات بسيطة وصولًا إلى روبوتات عالية التعقيد. تُبرمج منظومات التحكم المخصصة أو المعممة باستخدام لغات برمجة مختلفة نستعرضها في فقرات قادمة.
</p>

<p>
	لا تُعد برمجة الروبوت أمرًا بديهيًا ومباشرًا، بل موضعًا شديد الخصوصية يتعلق أولًا وأخيرا بطبيعة الروبوت ومكوّناته والوظائف المطلوبة منه. ولا يعني ذلك أن برمجة الروبوت أمر معقد وصعب المنال، فحتى الأطفال قادرون على تعلم أساسيات برمجته والتحكم به.
</p>

<h3>
	برمجة الروبوت فيزيائيًا
</h3>

<p>
	تُخفي هذه الروبوتات الجزء المتعلق بكتابة برامجها عن المستخدم، فلا حاجة فيها لشاشة وواجهة خاصة ولغة برمجة روبوت بل يعتمد كليًا على أجزاء فيزيائية (أزرار، روافع، قطع) تبرمج الروبوت ليقوم بأعمال معينة وفق تتابع ضغط هذه الأزرار أو تتابع تركيب هذه الأجزاء أو القطع مثل ألعاب الروبوت <a href="https://www.pitsco.com/Bee-Bot-Programmable-Robot-Single-Kit" rel="external nofollow">Bee-Bot</a>:
</p>

<p style="text-align: center;">
	<img alt="برمجة الروبوت عبر bee bot" class="ipsImage ipsImage_thumbnailed" data-fileid="116136" data-ratio="100.39" data-unique="7hk2x32f3" style="width: 508px; height: auto;" width="508" src="https://academy.hsoub.com/uploads/monthly_2023_01/133821888_---bee-Bot-.png.737360f716dbd58698798f461194bdb5.png">
</p>

<p>
	مثال آخر عليها <a href="https://www.techagekids.com/2016/09/code-pillar-coding-caterpillar-review.html" rel="external nofollow">Code-a-Pillar</a> التي تُستخدم لتعليم الأطفال من 3-8 سنوات برمجة الروبوت من منطق التتابع ومبدأ الاستجابة للأفعال.
</p>

<p style="text-align: center;">
	<img alt="استعمال روبوتات code a pillar" class="ipsImage ipsImage_thumbnailed" data-fileid="116138" data-ratio="83.86" data-unique="1os8xf1vi" style="width: 508px; height: auto;" width="576" src="https://academy.hsoub.com/uploads/monthly_2023_01/712734368_-----Code-a-Pillar.png.d2331043c88cd073661420d401769637.png">
</p>

<h3>
	برمجة الروبوت بالمهام
</h3>

<p>
	لا تختلف هذه الروبوتات عن سابقاتها سوى بفصل منظومة التحكم عن المكونات الفيزيائية للروبوت. تشبه هذه الروبوتات في طبيعتها الألعاب التي يجري التحكم بها عن بعد لكن المستخدم قادر على إدارتها وبرمجة سلوكها من خلال أجهزة تحكم عن بعد أو عن طريق تطبيقات للهواتف الذكية يمكن من خلالها وضع تسلسل معين لعدة مهام مبرمجة مسبقًا ومخزنة في ذاكرة الروبوت لإنجاز وظيفة محددة.
</p>

<p style="text-align: center;">
	<img alt="برمجة الروبوتات بالمهام" class="ipsImage ipsImage_thumbnailed" data-fileid="116135" data-ratio="74.80" data-unique="exc0g9sr6" style="width: 508px; height: auto;" width="611" src="https://academy.hsoub.com/uploads/monthly_2023_01/1315307468_--.png.31b35bdfb5df40e9abe9204c9f0eba8e.png">
</p>

<p>
	تُستخدم هذه الروبوتات كروبوتات تعليمية للمبتدئين والأطفال في مراحل عمرية مبكرة (6-13 عامًا) وتعزز تعليميًا مفهومين اثنين:
</p>

<ul>
	<li>
		الفصل والتمييز بين العتاد الصلب والبرمجيات.
	</li>
	<li>
		اتقان تقسيم أي وظيفة إلى مهام منفصلة ووضعها ضمن التسلسل المنطقي الصحيح.
	</li>
	<li>
		اكتساب مهارات أساسية في برمجة الروبوت.
	</li>
</ul>

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

<p>
	فإن أراد شخص غير مختص برمجة روبوت طائرة مسيرة تُبرمج بالمهام لرفعها مسافة 100 متر ثم فتح الكاميرا والتقاط صورة وفق اتجاه محدد ثم العودة إلى القاعدة وتكرار الأمر 10 مرات يوميًا، ما عليه مثلًا سوى سحب مهمة "التحليق إلى ارتفاع" من قائمة المهام الجاهزة في التطبيق ويضع بعدها "افتح الكاميرا" ثم تعليمة "وجه الكاميرا" ثم "التقط صورة" ثم "انخفض" ويضع كل تلك التعليمات في تعليمة "كرر الخطوات السابقة" ثم يرسل البرنامج إلى الروبوت ليُبرمج!
</p>

<p>
	لا داعٍ في هذه الحالة لأن يعرف أي شيء عن طريقة برمجة كل مهمة ولا عن آلية عمل المستشعرات أو المحركات أو الكاميرا أو آلية التوجيه لكنه يضع المهمات في سياقها الصحيح والنتيجة هي برمجة الروبوت بنجاح.
</p>

<h3>
	برمجة الروبوت بالتعلم والقيادة
</h3>

<p>
	تأتي هذه الروبوتات مصنّعة بالكامل ومخصصة، فلا يمكن تطويرها أو تعديلها سوى من قبل الشركات المصنعة وعادة ما تقوم بوظيفة أو مجموعة وظائف محددة سلفًا كالأذرع الروبوتية. وتتطلب برمجة الروبوت في هذه الحالة وحدة تحكم وبرمجة Programming pendant منفصلة عن جسم الروبوت تتيح للمشغل اختيار مكوّن محدد من مكوّنات الروبوت ثم إعطائه مهمة معينة كأن يختار محرك الجزء العلوي من الذراع ثم تدويره بزاوية محددة وتخزين الأمر.
</p>

<p>
	ينتقل بعدها إلى مكوّن آخر لتنفيذ حركة أو قياس معين ومن ثم تخزين الأمر لينتقل إلى الأمر التالي، وعند الإنتهاء من إملاء مجموعة الأوامر على الروبوت، يُخزّن المشغل هذه الأوامر في برنامج يعطيه اسمًا محددًا ثم يتأكد من تكرار الروبوت لهذا البرنامج بدقة قبل أن يغلق وضع التعليم Teach وينتقل إلى وضع العمل وفقا للبرنامج الجديد وهكذا تنتهي برمجة الروبوت.
</p>

<p style="text-align: center;">
	<img alt="تعليم الروبوتات وبرمجتها" class="ipsImage ipsImage_thumbnailed" data-fileid="116137" data-ratio="55.47" data-unique="45d73lyaz" style="width: 640px; height: auto;" width="640" src="https://academy.hsoub.com/uploads/monthly_2023_01/2129447263_--.png.50e90535d83b1e7371861935fc7e6b54.png">
</p>

<h3>
	الروبوتات المبرمجة بلغات برمجة
</h3>

<p>
	مع ظهور عصر الحواسيب القوية وغير المكلفة، بدأ الميل إلى برمجة الروبوتات باستخدام لغات برمجة الحواسيب أو نسخ مخصصة منها مزودة بمزايا خاصة لتسهيل برمجة الروبوت والتعامل مع مكوّناته. مع ذلك لا زالت الكثير من الشركات تقدم لغات برمجة خاصة لبرمجة روبوتاتها، معظمها لغات وظيفية أو لغات مرئية.
</p>

<p>
	يُصطلح عادة على برامج الروبوت المكتوبة بلغات برمجة مخصصة ببرمجة الروبوتات المطفأة Offline-programming، إذ تكتب البرمجيات على منصات غير متصلة بالروبوت الذي يتابع عمله وفقًا لبرنامجه القديم إن كان مبرمجًا مسبقًا. عند انتهاء برمجة الروبوت على تلك المنصات تجري محاكاة عمل البرنامج الجديد والتأكد من عمله. يُوقف الروبوت لدقائق ريثما يُحمّل برنامجه الجديد ثم يتابع العمل وفق هذا البرنامج.
</p>

<h3>
	لغات برمجة الروبوت
</h3>

<p>
	تُستخدم مجموعة متنوعة من <a href="https://academy.hsoub.com/programming/general/%D9%84%D8%BA%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9/" rel="">لغات البرمجة</a> وأطر العمل لبرمجة الروبوتات واختبار هذه البرمجيات ومن ثم نقلها إلى الروبوت. سنتحدث تاليًا عن مفهوم أنظمة تشغيل الروبوت ومن ثم سنلقي نظرة على لغات البرمجة المخصصة لكتابة برمجيات الروبوتات.
</p>

<h4>
	مفهوم أنظمة تشغيل الروبوت
</h4>

<p>
	يُشار عادة إلى البرمجيات وبيئات العمل والمنصات وأدوات البرمجة الوسطية التي تتكامل في سبيل برمجة الروبوتات بمنظومة تشغيل الروبوت Robot Operating System. لا ينبغي الخلط بين منظومة تشغيل الروبوت ونظام تشغيل وحدة التحكم OS وبرمجيات وحدة التحكم الثابتة (برمجيات العتاد) firmware. فإن استخدمت مثلًا حاسوب <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%AC%D9%87%D8%A7%D8%B2-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-raspberry-pi-r1356/?do=getLastComment&amp;d=2&amp;id=1356" rel="">راسبيري باي</a> للتحكم بروبوت، يكون نظام تشغيل لوحة التحكم هو <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AC%D9%88%D9%84%D8%A9-%D9%81%D9%8A-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%A7%D9%86-%D9%86%D8%B8%D8%A7%D9%85-%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-r1371/" rel="">راسبيان</a> غالبا (نسخة من نظام لينكس) أما الأدوات التي تساعدك برمجة روبوتك ونقل البرنامج إليه والتي تعمل على راسبيان فهي منظومة تشغيل الروبوت.
</p>

<p>
	يميل أغلب مصنعي الروبوتات ذات الوظائف الثابتة كروبوتات التغليف والتعبئة أو الروبوتات المخصصة للعمل في ظروف استثنائية على كتابة برنامج واحد فعّال وتحميله على الروبوت. تُعرف هذه البرامج بالبرمجيات الثابتة.
</p>

<h4>
	برمجة الروبوتات باستخدام لغات البرمجة عامة الأغراض
</h4>

<p>
	تعتمد برمجة الروبوتات وفق هذه الطريقة على لغات برمجة عامة الأغراض مثل <a href="https://academy.hsoub.com/programming/python/%D8%A7%D9%84%D9%85%D8%B1%D8%AC%D8%B9-%D8%A7%D9%84%D8%B4%D8%A7%D9%85%D9%84-%D8%A5%D9%84%D9%89-%D8%AA%D8%B9%D9%84%D9%85-%D9%84%D8%BA%D8%A9-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-r735/" rel="">لغة بايثون</a> أو <a href="https://academy.hsoub.com/programming/java/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%85%D8%A7-%D9%87%D9%8A%D8%A9-%D8%AC%D8%A7%D9%81%D8%A7-java-r1515/" rel="">لغة جافا</a> ثم تبنى مكتبات خاصة أو مجموعة أدوات باستخدام هذه اللغات لتنفيذ إجرائيات برمجية تتحكم بمكونات الروبوت على صعيد الحركة أو تحسس البيئة المحيطة أو عمليات اتخاذ قرار.
</p>

<p>
	يعتمد الأمر في هذه الحالات على منظومة التحكم بالروبوت. فإما أن تُكتب برامج الروبوت بإحدى لغات البرمجة على حاسوب وتختبر ثم تُنقل إلى منظومة تحكم الروبوت مثل معظم الروبوتات الصناعية والروبوتات المبنية على تجهيزات PLC أو تلك المجمعة حول متحكم صغري مثل لوحات أردوينو. أو أن يُحمّل نظام تشغيل متكامل على لوحة التحكم بالروبوت (راسبيان، ويندوز، لينكس،أندرويد،…إلخ.) وكل ما عليك حينها كتابة برنامج الروبوت باستخدام اللغة التي تريد من خلال تثبيت إحدى بيئات العمل المناسبة على <a href="https://academy.hsoub.com/apps/operating-systems/%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84/" rel="">نظام التشغيل</a> ومن ثم تجريب البرنامج على الروبوت مباشرة. من أمثلة لوحات التحكم هذه لوحات راسبيري باي ولوحات أدرويد <a href="https://en.wikipedia.org/wiki/ODROID" rel="external nofollow">ADROID</a> وحواسب <a href="https://en.wikipedia.org/wiki/Asus_Tinker_Board" rel="external nofollow">ASUS Tinker Board</a>، وتدعم اللوحات السابقة أنظمة تشغيل مشتقة من نظام لينكس كما تدعم اللوحتين الأخيريتين نظام أندرويد.
</p>

<p>
	إليك قائمة بأكثر لغات البرمجة شيوعًا في برمجة الروبوتات سواء لكتابة البرامج الثابتة أو القابلة للبرمجة المباشرة:
</p>

<ol>
	<li>
		<strong>لغتي C و ++C</strong>: يعتمد الكثير من مبرمجي الروبوتات على هاتين اللغتين في كتابة برامجهم لأن الكثير من مكتبات التحكم بالتجهيزات الفيزيائية للروبوت قد طورت باستخدام هاتين اللغتين. تسمح هذه المكتبات بالتفاعل المنخفض المستوى من العتاد الصلب وتؤمن أداءً عاليًا شديد الكفاءة في زمن التنفيذ، كما تدخل في تطوير الكثير من بيئات التشغيل الأكثر شهرة مثل <a href="http://dartsim.github.io" rel="external nofollow">DART</a> و<a href="https://www.roboticslibrary.org" rel="external nofollow">Robotics Library (RL)</a>. وعلى الرغم من صعوبة إنجاز بعض الوظائف بهاتين اللغتين مقارنة بلغة بايثون وماتلاب، لكن أداء هاتين اللغتين في زمن التشغيل جعلهما لغتين معياريتين في برمجة الروبوتات حتى مع زيادة شعبية لغة بايثون.
	</li>
	<li>
		<strong>بايثون</strong>: ازدادت شعبية هذه اللغة لسهولة استخدامها والكم الهائل من المكتبات التي تساعد على برمجة الروبوتات، فلا حاجة لإعادة اختراع العجلة، إذ ستجد تقريبًا كل ما تبحث عنه ضمن تلك المكتبات. كما أن اعتمادها مع ++C كلغة أساسية في نظام تشغيل الروبوتات <a href="https://www.ros.org" rel="external nofollow">ROS</a> وكذلك من الحواسيب المخصصة للتحكم بالروبوتات مثل راسبيري باي سيجعلها مرشحة لتكون اللغة الأكثر شعبية في عالم برمجة الروبوتات.
	</li>
	<li>
		<strong>جافا</strong>: نظرًا لشعبية هذه اللغة بين مطوري الروبوت المختصين بعلوم الحاسوب وجدت هذه اللغة طريقها إلى برمجة الروبوت. جافا أيضًا هي لغة مفسّرة ويعني ذلك أنك لن تّضطر إلى نقلها إلى لغة آلة محددة ومعالج محدد أو لوحة تحكم محددة بل تعمل آلة جافا الافتراضية على تنفيذ التعليمات أثناء التشغيل مما يعني إمكانية كتابة الشيفرة مرة واحدة وتنفيذها على آلات مختلفة. تُعد جافا لغة أساسية في تطوير روبوتات العديد من الشركات مثل IBM.
	</li>
	<li>
		<strong>اللغة #C (بيئة NET.)</strong>: تأتي شعبيتها من عدة أسباب أهمها:
		<ul>
			<li>
				اللغة الرئيسية التي تُستخدم في برمجة الروبوتات ضمن بيئة تطوير الروبوتات <a href="https://en.wikipedia.org/wiki/Microsoft_Robotics_Developer_Studio" rel="external nofollow">Microsoft Robotics Developer Studio</a> من مايكروسوفت، فإن أردت العمل على هذه البيئة لا بد من تعلم هذه اللغة.
			</li>
			<li>
				تُستخدم كأساس في محركات الواقع الافتراضي مثل Unity الذي تزداد شعبيته حاليًا.
			</li>
			<li>
				لغة مفسرة وبالتالي يمكن أن يعمل البرنامج ضمن أية آلة أو روبوت.
			</li>
		</ul>
	</li>
	<li>
		<strong>ماتلاب MATLAB</strong>: تشتهر هذه اللغة ضمن صفوف مهندسي ومصممي الروبوت وضمن النطاق الأكاديمي لتحليل البيانات وتطوير أنظمة التحكم. تشتهر هذه اللغة بوجود صندوق الأدوات <a href="https://petercorke.com/toolboxes/robotics-toolbox/" rel="external nofollow">Robotics Toolbox</a> الذي يمكنه المساعدة في تطوير نظام روبوت كامل باستخدام ماتلاب فقط.
	</li>
	<li>
		<strong>لغتي LISP و PROLOG</strong>: يُتوقع ازدياد شعبية هاتين اللغتين مستقبلًا مع زيادة الاهتمام بتطبيق تقنيات الذكاء الصنعي، فهاتين اللغتين من أكثر اللغات استعمالًا في خوارزميات الذكاء الصنعي وستجدان طريقًا للدخول إلى عالم برمجة الروبوتات. إذ استخدمت بيئة تطوير الروبوتات ROS لغة LISP في كتابة بعض أجزائها، واستخدمت IBM لغة PROLOG كجزء من الأدوات البرمجية في مشروع <a href="https://developer.ibm.com/technologies/artificial-intelligence/articles/cc-languages-artificial-intelligence/" rel="external nofollow">IBM's Watson AI</a>.
	</li>
	<li>
		<strong>لغة سكراتش Scratch</strong>: سكراتش هي لغة برمجة مرئية صُممت لتعليم البرمجة للمبتدئين وتستهدف الفئة العمرية بين 8 و 16 عامًا ويزداد الاعتماد على هذه اللغة في نوادي الروبوت والمدارس التقنية. تتكون اللغة من من مجموعة من الكتل البرمجية التي تُسحب وترتب وفق تسلسل معين لإنجاز البرنامج المطلوب. تدعم سكراتش مجموعة من المكتبات التي يمكنها التحكم بالطرفيات التي تتصل بحاسوب راسبيري باي مما زاد في شعبيتها. بإمكانك الاطلاع ضمن أكاديمية حسوب على كتابة برامج تتحسس للوسط الخارجي <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D9%84%D8%AD%D9%88%D8%B3%D8%A8%D8%A9-%D8%A7%D9%84%D9%81%D9%8A%D8%B2%D9%8A%D8%A7%D8%A6%D9%8A%D8%A9-%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D9%85%D8%B9-%D9%84%D9%88%D8%AD%D8%A9-%D8%B3%D9%86%D8%B3-%D9%87%D8%A7%D8%AA-sense-hat-r1600/" rel="">باستخدام راسبيري باي ولغتي بايثون وسكراتش</a>
	</li>
</ol>

<div class="banner-container ipsBox ipsPadding">
	<div class="inner-banner-container">
		<p class="banner-heading">
			دورة تطوير التطبيقات باستخدام لغة Python
		</p>

		<p class="banner-subtitle">
			احترف تطوير التطبيقات مع أكاديمية حسوب والتحق بسوق العمل فور انتهائك من الدورة
		</p>

		<div>
			<a class="ipsButton ipsButton_large ipsButton_primary ipsButton_important" href="https://academy.hsoub.com/learn/python-application-development" rel="">اشترك الآن</a>
		</div>
	</div>

	<div class="banner-img">
		<img alt="دورة تطوير التطبيقات باستخدام لغة Python" src="https://academy.hsoub.com/learn/assets/images/courses/python-application-development.png">
	</div>
</div>

<h4>
	برمجة الروبوتات بلغات برمجة مخصصة
</h4>

<p>
	تظهر الحاجة إلى لغات برمجة مخصصة للروبوتات Robots Programming Languages واختصارًا RPL كنتيجة للتنوع الكبير في الآلات الروبوتية والروبوتات واختلاف وظائفها. إذ تظهر في عالم الصناعة مفاهيم لا بد من أخذها بعين الاعتبار عند برمجة الروبوت مثل التحكم بالقوى المطبقة force control وأداء المهام على التوازي Parallelism. لهذا السبب طوّرت لغات برمجة تمتلك إمكانيات لغات برمجة الحواسيب إلا أنها مخصصة للروبوتات نذكر منها:
</p>

<ul>
	<li>
		<strong>لغة VAL</strong>: طورتها شركة Unimation لبرمجة بروبوتاتها وتستخدم شركة Stäubli حاليا النسخة <a href="https://www.staubli.com/in/en/robotics/products/robot-software/staeubli-robotics-controls/val-3-language.html" rel="external nofollow">VAL 3</a> منها.
	</li>
	<li>
		<strong>لغات HELP و RAIL و Karel</strong>: وهي لغات مخصصة من الجيل الثاني لبرمجة الروبوتات، وقد أظهرت ميزات متطورة للتحكم بالحركة والتعامل مع واجهات الحساسات والمشغلات والتخاطب البيني ضمن الروبوت وأبدت بعض ملامح الذكاء الصنعي.
	</li>
	<li>
		<strong>لغة <a href="https://library.e.abb.com/public/688894b98123f87bc1257cc50044e809/Technical%20reference%20manual_RAPID_3HAC16581-1_revJ_en.pdf" rel="external nofollow">RAPID</a></strong>: التي تستخدمها شركة ABB
	</li>
	<li>
		<strong>لغة <a href="http://drstienecker.com/tech-332/11-the-kuka-robot-programming-language/" rel="external nofollow">KRL</a></strong>: وهي اختصار لعبارة (Kuka Robot Language)وتستخدمها شركة Kuka
	</li>
	<li>
		<strong>لغة <a href="http://www.wmv-robotics.de/home_htm_files/scriptmanual_en_1.5.pdf" rel="external nofollow">URScript</a>:</strong> وتستخدمها شركة Universal Robots.
	</li>
</ul>

<h2>
	مسارات تعلم برمجة الروبوتات والروبوتكس
</h2>

<p>
	ما الغاية من مشروع الروبوت الذي أريد أن أنجزه؟ ما هي مدى معرفتي بالإلكترونيات؟ ما مدى معرفتي بالبرمجة عمومًا؟ هل أنا مهتم حقا ببناء هذا المشروع من الصفر أم أبحث عن حلول سريعة؟
</p>

<p>
	إن الإجابة على الأسئلة السابقة أمر ضروري قبل العمل على أي مشروع يتعلق ببرمجة الروبوتات واستثمارها. فإن كنت هاويًا فضوليًا للمعرفة عليك أن تسلك مسارًا محددًا وإن كنت هاويًا تسعى إلى الاحتراف والعمل في مجال الروبوتات فهي حكاية أخرى وإن كنت ذو خلفية في <a href="https://academy.hsoub.com/programming/general/%D8%B9%D9%84%D9%88%D9%85-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8/" rel="">علوم الحاسوب</a> أو الهندسة يختلف مسار العمل وإن كنت رجل أعمال أو مستشارًا تقنيًا لمؤسسة صناعية يختلف الأمر كذلك.
</p>

<h3>
	برمجة الروبوت للأطفال
</h3>

<p>
	علينا أولًا أن نعزز مفاهيم هامة للطفل مثل السبب والنتيجة والتسلسل الصحيح لإنجاز المهام وذلك في سن مبكرة من 3-6 سنوات. يمكننا بداية الاستفادة من الدمى الروبوتية التي تبرمج فيزيائيا لحث الطفل على التعلم مثل الدمى التي تتحرك وتدور وتصدر أصواتًا وفق تسلسل محدد مسبقًا يتعلمه الطفل بالضغط المتتالي على مجموعة أزرار على الدمية.
</p>

<p>
	كما يمكن بناء مهاراته في التصميم الفيزيائي من خلال ألعاب فك وتركيب المكعبات الملونة لبناء هياكل متوازنة ومتناظرة التصميم.
</p>

<p>
	في سن أكبر من 6-10 سنوات يمكنه العمل على روبوتات مبرمجة بالمهام لإدراك مفهوم البرنامج بشكل منفصل عن الآلة وتنمية الرغبة في التفكير بطريقة عمل هذه المهام. كما يمكن أيضا تلقين الطفل أساسيات الدوائر الكهربائية واستخدام البطاريات وتوصيلها مع أضواء ومحركات صغيرة وحثه على بناء هياكل معدنية أو بلاستيكية عبر ألعاب الفك والتركيب المكونة من قطع متنوعة وعجلات ومحركات وبراغي ومفكات.
</p>

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

<p>
	سيبدي الطفل أو اليافع بعد ذلك رغبته في الاطلاع والتعلم أكثر وسيدرك بنفسه طريق البحث وتعلم ما يلزمه وسيخط مساره في مجال برمجة الروبوتات والروبوتيكس عمومًا بنفسه. على الرغم من ذلك يمكنك إرشاده إلى تعلم لغات برمجة جديدة مثل بايثون والعمل على أنظمة تشغيل مثل لينكس وأندرويد ليألفها ثم العمل مع لوحات تحكم حاسوبية مثل راسبيري باي ليتحكم بعناصر فيزيائية كالأضواء والمصوّتات وتحريك اللوحة على هيكل ذو عجلات وموازنتها و<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D9%84%D8%AD%D9%88%D8%B3%D8%A8%D8%A9-%D8%A7%D9%84%D9%81%D9%8A%D8%B2%D9%8A%D8%A7%D8%A6%D9%8A%D8%A9-%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D9%85%D8%B9-%D9%84%D9%88%D8%AD%D8%A9-%D8%B3%D9%86%D8%B3-%D9%87%D8%A7%D8%AA-sense-hat-r1600/" rel="">استشعار البيئة المحيطة</a>. بإمكانك الاطلاع ضمن أكاديمية حسوب على كتابة برامج تتحسس للوسط الخارجي <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D9%84%D8%AD%D9%88%D8%B3%D8%A8%D8%A9-%D8%A7%D9%84%D9%81%D9%8A%D8%B2%D9%8A%D8%A7%D8%A6%D9%8A%D8%A9-%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D9%85%D8%B9-%D9%84%D9%88%D8%AD%D8%A9-%D8%B3%D9%86%D8%B3-%D9%87%D8%A7%D8%AA-sense-hat-r1600/" rel="">باستخدام راسبيري باي ولغتي بايثون وسكراتش</a>.
</p>

<p>
	وهكذا ستضع الناشئة على الطريق الصحيح للانطلاق في عالم الروبوتات أكاديميًا وتقنيًا.
</p>

<h3>
	برمجة الروبوت للمبرمجين والمهندسين
</h3>

<p>
	إن كنت مبرمجًا فأنت جاهز للانطلاق. قد ترغب في تعزيز معلوماتك في مجال الإلكترونيات وخاصة الحساسات والمحركات ومصادر تغذيتها واستثمارها إن كنت ترغب في تصميم روبوت بنفسك. أما إن كنت ترغب في تشغيل روبوت موجود قابل للبرمجة فأنت في الواقع لا تحتاج شيئًا سوى اختيار لغة البرمجة والبحث عن مكتبات جاهزة لتنفيذ ما تريده. ستظهر المشكلة إن أردت أن يقوم الروبوت بوظيفة واضطررت إلى برمجة هذه الوظيفة بنفسك للمرة الأولى (احتمال ضعيف) عندها عليك العودة إلى المراجع الأكاديمية وتعزيز قدراتك في الفيزياء علم التحريك والإلكترونيات! أما إن كنت مهندسًا كهربائيًا أو مهندس إلكترونيات، عليك فقط تعزيز قدراتك البرمجية التي يُفترض أن تكون موجودة وراجع معلوماتك عن الإلكترونيات ومصادر التغذية وستكون جاهزًا لبرمجة أي روبوت واستثماره وحتى تصميم وبناء روبوت من الصفر. اختر المنصة التي تريد العمل عليها واطلع على أفكار ومشاريع الآخرين وانطلق!
</p>

<p>
	تبقى التوجيهات نفسها للمهندسين غير الاختصاصيين والتقنيين. تعلم لغة برمجة مستخدمة في برمجة الروبوت وافهم مكوّنات الروبوت الذي تنوي العمل عليه وبرمجته أيًا كانت الأسباب التي دفعتك لذلك. استعن بالإنترنت ومنتديات الروبوتيكس التي تهتم بنفس الروبوت الذي تستهدفه واجتهد قليلًا ولن يذهب عناؤك سدى. لكن غالب الظن أنك في مصنع ما وأوكلت إليك مهمة قيادة روبوت أو برمجته لسبب أو لآخر، اطلع على كتيب التشغيل وافهم تعليمات تشغيل الروبوت على وضع التعلم فغالبًا ما تُبرمج هذه الروبوتات بالتعلم حاول أن تبحث عن مقاطع فيديو تشرح آلية برمجته وخذ بعض الوقت في التجربة (لا تبالغ كثيرًا في التجريب فهذه الروبوتات مكلفة!) وسترى أن الأمر سينجح.
</p>

<h3>
	برمجة الروبوت للهواة والفضوليين
</h3>

<p>
	إن كنت طفًلا أو يافعًا أو مبرمجًا أو مهندسًا فقد أرشدناك في فقرات سابقة إلى الطريق الصحيح. أما إن كنت شغوفًا بالتعلم ورأيت أو قرأت محتوى يتحدث عن علم الروبوت ووقع الأمر في نفسك موقعًا حسنًا ورغبت في تجربة الأمر، فاسمح لي أن أهنئك وأشجعك!
</p>

<p>
	ابدأ مسيرتك بتعلم أساسيات التحكم الكهربائي التقليدي فهي من ناحية مهنة محترمة ومن ناحية أخرى ستكون مدخلك إلى التحكم الرقمي. ستجد الكثير من المعاهد التعليمية التقنية؛ سجل في أحدها فهذا أسرع من متابعة قناة على اليوتيوب وعملي أكثر. في الوقت ذاته إن لم تكن متقنًا للعمل على الحاسوب (أعي تماما أن الحاسوب قد أهمل من قبل الكثيرين لصالح الهواتف الذكية) فحاول أن تألف التعامل معه، تعلم على الأقل نظامي ويندوز ولينكس فهذا أساسي.
</p>

<p>
	عندما تنهي أساسيات التحكم التقليدي انتقل إلى التحكم الرقمي باستخدام وحدات PLC (ستجد أنها الخطوة التالية في مسار التعلم في معهدك إن سجلت في أحدها). يعتمد الكثير من الروبوتات على وحدات PLC كمنظومات تحكم، وستتعرف خلال هذه الفترة على مفهوم البرمجة والبرامج، إذ تُبرمج تلك الوحدات من خلال لغات برمجة مرئية بالمهام. لن يكون الأمر صعبًا، فقط اجتهد قليلًا ولا تستسلم. خلال هذه الفترة تعمق قليلًا في أحد توزيعات نظام التشغيل لينكس وستجني ثمار هذا الجهد بالتأكيد.
</p>

<p>
	حتى هذه اللحظة ستكون قد اكتسبت المهارات التالية:
</p>

<ul>
	<li>
		إدراك مفهوم التحكم الصناعي.
	</li>
	<li>
		إدراك مفهوم البرنامج وكتابة برمجيات بسيطة للتحكم بالتجهيزات الكهربائية.
	</li>
	<li>
		التعامل مع عناصر كهربائية وإلكترونية عديدة خلال مسار الدورتين السابقتين وسترى أنك تحتاجها في عالم الروبوت.
	</li>
	<li>
		العمل على الحاسوب وبأكثر من نظام تشغيل.
	</li>
</ul>

<p>
	قد يلبي طموحك هذا الحد، فقد تتمكن إن اجتهدت من تحريك مركبة وتفادي العقبات واستشعار المحيط لكن قد يكون روبوتك كبير الحجم ومحدود الإمكانات لأن أغلب التجهيزات التي تعلمتها كبيرة الحجم من الحساسات إلى المحركات إلى لوحات التحكم والتغذية، لم لا! فالروبوتات الكبيرة لها جاذبيتها!
</p>

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

<p>
	ابدأ بتعلم لغة برمجة وأنصحك <a href="https://academy.hsoub.com/python/" rel="">بتعلم البرمجة بلغة بايثون</a> على الرغم من أنّ لغة سكراتش تمثل مرحلة انتقالية بين لغات برمجة PLC ولغات برمجة الحواسيب. الخيار لك على أية حال. ستجني خلال هذه الفترة ثمار تعلمك لأنظمة تشغيل الحواسب وعندما تنهيها ستكون ملمًا ببرمجة الحواسيب وبأساسيات الإلكترونيات المتعلقة بالروبوت.
</p>

<p>
	انظر دورة <span ipsnoautolink="true">تطوير التطبيقات بلغة بايثون</span> التي تقدمها أكاديمية حسوب لتعليم البرمجة بلغة بايثون بلغة عربية ودون الحاجة إلى خبرة مسبقة:
</p>

<p style="text-align: center;">
	<iframe allowfullscreen="" frameborder="0" height="450" src="https://player.vimeo.com/video/679458551" width="800"></iframe>
</p>

<p>
	أنت مستعد الآن، ابنِ روبوتك الخاص باستخدام حاسوب مصغر مستفيدًا من تجارب الهواة الآخرين. حاول أن تتواصل معهم من خلال المنتديات وأن تعزز قدراتك بالاطلاع المستمر.
</p>

<p>
	تتوفر أيضا صناديق أدوات مخصصة لبناء روبوتات متنوعة تختلف في تعقيدها، يمكنك اقتناء واحدة فهي تزودك بالكثير من التجهيزات والقطع لبناء هيكل الروبوت وبرمجته.
</p>

<h2>
	هؤلاء الذين يريدون تغيير العالم!
</h2>

<p>
	لا شيء سيقف في طريقك سوى ذاتك. ثق بنفسك وبإمكاناتك ووسع مداركك في كل المجالات فعلم الروبوت لا يقتصر على علم واحد فهو مزيج من كل العلوم. لا تستسلم ولا تردد أبدًا عبارة "لا أعرف كيف أفعل ذلك". كن مبرمجًا محترفًا ومهندسًا محترفًا في عملك وتخيل واحلم كما لو كنت طفلًا.
</p>

<p>
	ستسمع كثيرًا عبارة "لا تعد اختراع العجلة"، قد ترى أن هذا صحيح، لكن إن كان عليك إعادة اختراع العجلة فافعل!
</p>

<p>
	رحلة سعيدة إن قررت الانطلاق في عالم الروبوتات! وإن احتجت إلى أي مساعدة، أضف سؤالك في قسم التعليقات أو في قسم <a href="https://academy.hsoub.com/questions/c3-programming/" rel="">الأسئلة والأجوبة</a>.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D9%85%D8%A7-%D9%87%D9%88-%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-raspberry-pi%D8%9F-r1578/" rel="">ما هو حاسوب راسبيري باي Raspberry Pi؟</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D9%85%D8%A7-%D9%87%D9%8A-%D9%84%D9%88%D8%AD%D8%A9-%D8%A3%D8%B1%D8%AF%D9%88%D9%8A%D9%86%D9%88-arduino%D8%9F-r1800/" rel="">ما هي لوحة أردوينو Arduino؟</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D9%84%D8%B9%D8%A8%D8%A9-%D8%A7%D9%84%D8%B3%D9%84%D9%83-%D9%88%D8%A7%D9%84%D8%AD%D9%84%D9%82%D8%A9-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D8%AC-%D8%B3%D9%83%D8%B1%D8%A7%D8%AA%D8%B4-%D9%88%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-r1495/" rel="">تصميم لعبة السلك والحلقة باستخدام برنامج سكراتش وحاسوب راسبيري باي</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/general/%D8%A3%D8%B3%D9%87%D9%84-%D9%84%D8%BA%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9/" rel="">أسهل لغات البرمجة</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/learn-programming/" rel="">تعلم البرمجة</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/general/%D9%81%D9%88%D8%A7%D8%A6%D8%AF-%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9/" rel="">فوائد البرمجة</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1855</guid><pubDate>Mon, 09 Jan 2023 15:07:00 +0000</pubDate></item><item><title>&#x625;&#x646;&#x634;&#x627;&#x621; &#x645;&#x635;&#x628;&#x627;&#x62D; &#x644;&#x64A;&#x62F; &#x64A;&#x648;&#x645;&#x636; &#x648;&#x641;&#x642; &#x646;&#x645;&#x637; &#x645;&#x639;&#x64A;&#x646; &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x62D;&#x627;&#x633;&#x648;&#x628; &#x631;&#x627;&#x633;&#x628;&#x64A;&#x631;&#x64A; &#x628;&#x627;&#x64A; &#x628;&#x64A;&#x643;&#x648;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D9%85%D8%B5%D8%A8%D8%A7%D8%AD-%D9%84%D9%8A%D8%AF-%D9%8A%D9%88%D9%85%D8%B6-%D9%88%D9%81%D9%82-%D9%86%D9%85%D8%B7-%D9%85%D8%B9%D9%8A%D9%86-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D9%8A%D9%83%D9%88-r1848/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2023_01/519447636_-----------.jpg.f7ca6b4948cbd7838ca907f9315f83c2.jpg" /></p>
<p>
	سنتعلم في هذا المقال كيفية استخدام حاسوب راسبيري باي بيكو Raspberry Pi Pico لبناء مصباح ليد LED يومض مثل حشرة اليراعة، وذلك بتعلُّم كيفية توصيل المصباح إلى مبدّل Switch للتحكم بالإضاءة.
</p>

<p>
	لنحصل على نتيجة مشابهة لما يلي:
</p>

<p style="text-align: center;">
	<img alt="استخدام حاسوب Raspberry Pi Pico لبناء مصباح LED" class="ipsImage ipsImage_thumbnailed" data-fileid="116002" data-ratio="56.36" data-unique="kg9haiqfz" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/firefly-blink.gif.68acd3f458db2b4a695acdb9f6007c70.gif">
</p>

<p>
	راقب نمط الوميض المتكرر لمصباح الليد.
</p>

<blockquote class="ipsQuote" data-gramm="false" data-ipsquote="">
	<div class="ipsQuote_citation">
		اقتباس
	</div>

	<div class="ipsQuote_contents ipsClearfix" data-gramm="false">
		<p>
			<strong>تحذير</strong>: سنستخدم في هذا المشروع أضواءً وامضةً والتي قد تسبب اختلاجات أو نوبات شقيقة (صداع نصفي) عند نسبة صغيرة جدًا من الناس. كما أن هذه الأعراض قد تظهر عند الأشخاص السليمين الذين لم يعانوا مسبقًا من الشقيقة أو من نوبات الصرع المُحرَضة من قِبَل الإضاءة العالية، ننصحك بإيقاف العمل على هذا المشروع ومراجعة طبيب مباشرةً إذا واجهت أية أعراض.
		</p>
	</div>
</blockquote>

<p>
	<strong>معلومة</strong>: المتحكمات المُصغرّة Microcontrollers هي حواسيب صغيرة جدًا تُشَغّل الشيفرات البرمجية والتفاعل مع العناصر الإلكترونية، مثل مصابيح الليد والقواطع الإلكترونية، وتُصَمم عادةً لتنفيذ مهمة واحدة لذلك ليس لها نظام تشغيل.
</p>

<p>
	يُعد المتحكم المًصغر راسبيري باي بيكو Raspberry Pi Pico خيارًا مناسبًا للمبتدئين والخبراء أيضًا لتطوير عناصر ومنتجات إلكترونية نظرًا لتكلفته المنخفضة.
</p>

<p style="text-align: center;">
	<img alt="المتحكم المًصغر راسبيري باي بيكو Raspberry Pi Pico" class="ipsImage ipsImage_thumbnailed" data-fileid="116016" data-ratio="57.08" data-unique="9fd1sup2v" style="width: 480px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/pico-hand.thumb.png.1cb7ead9807bd5de414b22f08a0a4419.png">
</p>

<p>
	ستتعلم في هذا المشروع ما يلي:
</p>

<ul>
	<li>
		كيفية التعامل مع حاسوب راسبيري باي بيكو.
	</li>
	<li>
		توصيل مصباح ليد ومبدّل إلكتروني مع أرجل لوحة <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%AC%D9%87%D8%A7%D8%B2-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-raspberry-pi-r1356/" rel="">راسبيري باي</a> باستخدام أسلاك التوصيل.
	</li>
	<li>
		برمجة حاسوب راسبيري باي بيكو باستخدام برنامجي مايكروبايثون MicroPython وبرنامج ثوني Thonny.
	</li>
</ul>

<h2>
	متطلبات المشروع
</h2>

<p>
	سنعرض في الآتي المتطلبات اللازم توفرها للعمل على هذا المشروع
</p>

<h3>
	عتاد
</h3>

<ol>
	<li>
		لوحة حاسوب راسبيري باي بيكو مع أرجل مثبتة عليها.
	</li>
	<li>
		كبل USB لنقل البيانات ذو نهايات من النوع USB A و micro USB.
	</li>
	<li>
		مصباح ليد باللون الذي تفضله.
	</li>
	<li>
		مقاومة resistor بقيمة 100 أوم، تسمى واحدة المقاومة <strong>أوم</strong> ويرمز لها بالرمز التالي <strong>Ω</strong> ( يمكن استعمال أي مقاومة ذات قيمة تتراوح ضمن المجال 75Ω -220Ω).
	</li>
	<li>
		أسلاك توصيل ذات نهايات مقبس-مقبس socket-socket (عدد 3).
	</li>
	<li>
		أسلاك توصيل ذات نهايات دبوس-مقبس pin-socket (عدد 1).
	</li>
	<li>
		شريط لاصق شفاف (اختياري).
	</li>
</ol>

<h3>
	أسلاك التوصيل
</h3>

<p>
	تُستخدم أسلاك التوصيل لنقل التيار الكهربائي بين العناصر الإلكترونية عند إنشاء النماذج الأولية من المشاريع لسهولة توصيلها مع العناصر وفصلها، دون الحاجة إلى تلحيمها (إنشاء توصيلات دائمة عن طريق صهر المعدن).
</p>

<p>
	توجد ثلاثة أنواع من أسلاك التوصيل تبعًا لنهاياتها، وهي:
</p>

<ul>
	<li>
		أسلاك توصيل ذات نهايات مقبس-مقبس socket-socket.
	</li>
	<li>
		أسلاك توصيل ذات نهايات دبوس-مقبس pin-socket.
	</li>
	<li>
		أسلاك توصيل ذات نهايات دبوس-دبوس pin-pin.
	</li>
</ul>

<h4>
	نهاية الدبوس
</h4>

<p>
	هي قطعة معدنية قصيرة تخرج من الطرف البلاستيكي الأسود للسلك، ويمكن إدخالها في طرف المقبس، أو لوحة التجارب، وهي على الشكل التالي:
</p>

<p style="text-align: center;">
	<img alt="نهاية الدبوس" class="ipsImage ipsImage_thumbnailed" data-fileid="116020" data-ratio="151.81" data-unique="7fj7z1yga" style="width: 249px; height: auto;" width="249" src="https://academy.hsoub.com/uploads/monthly_2023_01/pin.png.c491fbe6636b54aa7409eb35e3031249.png">
</p>

<h4>
	نهاية المقبس
</h4>

<p>
	تبدو نهاية المقبس مثل قطعة بلاستيكية سوداء تحتوي ثقب يمكن إدخال نهاية الدبوس فيه أو إدخال أرجل العناصر الإلكترونية:
</p>

<p style="text-align: center;">
	<img alt="نهاية المقبس" class="ipsImage ipsImage_thumbnailed" data-fileid="116027" data-ratio="114.61" data-unique="ptzeho65l" style="width: 356px; height: auto;" width="356" src="https://academy.hsoub.com/uploads/monthly_2023_01/socket.png.cf1fa2fbc097b2ef19118a4b3add3820.png">
</p>

<h4>
	شراء أسلاك التوصيل
</h4>

<p>
	قد تلاحظ عند شرائك أسلاك التوصيل أنها تُسمى ذكر - ذكر، أو أنثى - أنثى، أو ذكر - أنثى، وهي تسميات قديمة إذ يدل الذكر على نهاية الدبوس، والأنثى على نهاية المقبس، ويجب استخدام مصطلحي <strong>الدبوس</strong> و<strong>المقبس</strong> لوصف أسلاك التوصيل لأنها أكثر شمولًا.
</p>

<h3>
	برمجيات
</h3>

<ol>
	<li>
		برنامج ثوني: وهو البيئة البرمجية التي سنستخدمها لكتابة الشيفرة <a href="https://academy.hsoub.com/programming/python/%D8%A7%D9%84%D9%85%D8%B1%D8%AC%D8%B9-%D8%A7%D9%84%D8%B4%D8%A7%D9%85%D9%84-%D8%A5%D9%84%D9%89-%D8%AA%D8%B9%D9%84%D9%85-%D9%84%D8%BA%D8%A9-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-r735/" rel="">بلغة بايثون</a>.
	</li>
</ol>

<h4>
	تثبيت برنامج ثوني على <span ipsnoautolink="true">نظام تشغيل راسبيري باي</span>
</h4>

<p>
	يأتي برنامج ثوني مثبتًا مع <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AC%D9%88%D9%84%D8%A9-%D9%81%D9%8A-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%A7%D9%86-%D9%86%D8%B8%D8%A7%D9%85-%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-r1371/" rel="">نظام تشغيل راسبيري باي</a>، المعروف سابقًا براسبيان Raspbian، لكن قد تحتاج إلى تحديثه. انقر على الأيقونة في الزاوية العلوية اليسرى من الشاشة لفتح نافذة الطرفية Terminal، أو اضغط المفاتيح التالية معًا <strong>Ctrl+Alt+T</strong>. ثم اكتب الأمر التالي لتحديث <a href="https://academy.hsoub.com/files/24-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%84%D9%85%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D9%86/" rel="">نظام التشغيل</a> وبرنامج ثوني:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_972_16" style=""><span class="pln">sudo apt update </span><span class="pun">&amp;&amp;</span><span class="pln"> sudo apt upgrade </span><span class="pun">-</span><span class="pln">y</span></pre>

<h4>
	تثبيت برنامج ثوني على أنظمة التشغيل الأخرى
</h4>

<p>
	يمكنك تثبيت ثوني على الحواسيب العاملة <a href="https://academy.hsoub.com/devops/linux/%D9%85%D8%A7-%D9%87%D9%88-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%8A%D9%86%D9%83%D8%B3%D8%9F-r451/" rel="">بنظام تشغيل لينكس</a>، أو ويندوز، أو ماك، وذلك من الموقع الرسمي <a href="https://thonny.org/" rel="external nofollow">thonny.org</a>. انقر على رابط التنزيل الموافق لنظام تشغيل حاسوبك من الزاوية العلوية اليمنى في الموقع، وانقر على الملفات بعد تنزيلها، قد تظهر لك الرسالة التالية على نظام ويندوز:
</p>

<p style="text-align: center;">
	<img alt="الرسالة الظاهرة على أنظمة ويندوز عند تثبيت ثوني" class="ipsImage ipsImage_thumbnailed" data-fileid="116037" data-ratio="67.34" data-unique="goqdvbnv1" style="width: 297px; height: auto;" width="297" src="https://academy.hsoub.com/uploads/monthly_2023_01/thonny-site.png.eb711275a19eceb7a1c70a30e9ce29b7.png">
</p>

<p>
	انقر على خيار المزيد من المعلومات "More info" ثم على التشغيل على أي حال "Run anyway".
</p>

<h4>
	التعرف على واجهة برنامج ثوني
</h4>

<p>
	عند فتح ثوني، ستظهر لك الواجهة التالية:
</p>

<p style="text-align: center;">
	<img alt="واجهة برنامج ثوني" class="ipsImage ipsImage_thumbnailed" data-fileid="116032" data-ratio="72.92" data-unique="tbf54q5s7" style="width: 650px; height: auto;" width="700" src="https://academy.hsoub.com/uploads/monthly_2023_01/thonny-editor.thumb.png.b211a72c930b06c6fe39641d47152968.png">
</p>

<p>
	يمكنك الكتابة <a href="https://wiki.hsoub.com/Python" rel="external">بلغة بايثون</a> في النافذة الرئيسية الكبيرة، ثم النقر على زر التشغيل الأخضر <strong>Run</strong> للتنفيذ، ستظهر لك رسالة لحفظ الملف قبل تشغيله.
</p>

<p>
	اكتب الأمر التالي وشغّله:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_972_24" style=""><span class="kwd">print</span><span class="pun">(</span><span class="str">'Hello World!'</span><span class="pun">)</span></pre>

<h4>
	تغيير السمة والخط
</h4>

<p>
	يمكنك التحكم بلون الخط وحجمه وتغيير المظهر المُستخدم في واجهة البرنامج، وذلك بالنقر على قائمة الأدوات <strong>Tools</strong> من الشريط أعلى الشاشة، ثم النقر على خيارات <strong>Options</strong>. انقر بعدها على نافذة الخط والسمة <strong>Theme &amp; Font</strong> واختر نوع الخط والسمة التي تفضلها من النافذة المنسدلة، ثم انقر على زر موافق <strong>OK</strong> عند الانتهاء.
</p>

<p style="text-align: center;">
	<img alt="تغيير السمة والخط في واجهة برنامج ثوني" class="ipsImage ipsImage_thumbnailed" data-fileid="116031" data-ratio="77.20" data-unique="lb4qx8d9n" style="width: 500px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/theme-tab.PNG.7a2960f11b2a3e98ced7e409a74ed6e8.PNG">
</p>

<p>
	ننصحك باختيار الخطوط البسيطة الواضحة والابتعاد عن الخطوط المزخرفة أو المشابهة لخط اليد لأنها تجعل القراءة أصعب.
</p>

<h2>
	تجهيز لوحة راسبيري باي بيكو للعمل
</h2>

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

<p>
	<strong>معلومة:</strong> مايكرو بايثون أو MicroPython باللغة الإنجليزية، هو مُفَسِر للغة البرمجة بايثون مخصص للمعالجات المصغرة المماثلة لراسبيري باي بيكو، ويمكن بواسطته كتابة الشفرة بلغة بايثون للتخاطب مع العناصر الإلكترونية.
</p>

<p>
	أولًا، صِل الطرف الصغير لكبل USB إلى لوحة راسبيري باي.
</p>

<p style="text-align: center;">
	<img alt="تجهيز لوحة راسبيري باي بيكو للعمل" class="ipsImage ipsImage_thumbnailed" data-fileid="116018" data-ratio="31.60" data-unique="3ftt7kja1" style="width: 500px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/pico-top-plug.png.71193a85d79d6fa57348ccec8f9dc6a8.png">
</p>

<p>
	ثانيًا، صِل الطرف الآخر للكبل مع حاسوبك المكتبي أو المحمول.
</p>

<p style="text-align: center;">
	<img alt="وصل طرف الكبل مع حاسوبك المكتبي أو المحمول" class="ipsImage ipsImage_thumbnailed" data-fileid="116022" data-ratio="81.00" data-unique="sx68uxutp" style="width: 500px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/plug-in-pico.png.899940b307b6fa31bdc6df8b3b56d48e.png">
</p>

<p>
	ثالثًا، افتح برنامج ثوني، ولاحظ ما هو الإصدار المستخدم من بايثون بقراءة النص الموجود في الزاوية السفلية اليمنى من الشاشة، انقر على النص واختر "MicroPython (Raspberry Pi Pico)‎"، إذا لم يكن هذا الخيار محددًا.
</p>

<p>
	سيطالبك ثوني بتثبيت برنامج MicroPython على حاسوب راسبيري باي بيكو إذا لم تستخدمه مسبقًا، فقط انقر على زر التثبيت <strong>Install</strong>.
</p>

<p style="text-align: center;">
	<img alt="مطالبة ثوني بتثبيت MicroPython على الحاسوب" class="ipsImage ipsImage_thumbnailed" data-fileid="116033" data-ratio="81.59" data-unique="efroylprp" style="width: 440px; height: auto;" width="440" src="https://academy.hsoub.com/uploads/monthly_2023_01/thonny-install-micropython-pico.png.6dfdda5add6d619fd03c29edb222bb21.png">
</p>

<h3>
	تصحيح الأخطاء
</h3>

<p>
	إليك بعض المشاكل التي قد تواجهك عند تثبيت مايكرو بايثون وكيفية إصلاحها:
</p>

<h4>
	ظهور رسالة خطأ أثناء تثبيت البرنامج
</h4>

<p>
	قد تظهر لك رسالة خطأ أثناء تثبيت البرنامج، عندها عليك اتباع ما يلي:
</p>

<ul>
	<li>
		افصل لوحة راسبيري باي بيكو، ثم أعد توصيلها، وأوقف عملية التثبيت بالنقر على زر التوقف <strong>Stop</strong> ثم أعد تشغيلها.
	</li>
</ul>

<p style="text-align: center;">
	<img alt="إيقاف عملية تثبيت لوحة راسبيري باي بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="116015" data-ratio="107.06" data-unique="ngvqp0bf2" style="width: 439px; height: auto;" width="439" src="https://academy.hsoub.com/uploads/monthly_2023_01/pico-firmware-error.png.5d71c72d86aa26b5b603574b63a7469d.png">
</p>

<h4>
	حدوث مشكلة أثناء تثبيت البرنامج
</h4>

<p>
	قد تحدث مشكلة ما أثناء تثبيت البرنامج وتفقد الاتصال بلوحة راسبيري بيكو. لذلك، تأكد أولًا أن راسبيري باي بيكو موصولٌ مع حاسوبك بواسطة كبل micro USB، ثم انقر على القائمة الموجودة أسفل الزاوية اليمنى في واجهة ثوني، ستظهر لك نافذة توضح المُفَسِرات interpreters المتاحة:
</p>

<p style="text-align: center;">
	<img alt="نافذة توضح المُفَسِرات interpreters المتاحة" class="ipsImage ipsImage_thumbnailed" data-fileid="116014" data-ratio="38.89" data-unique="dt7t72dow" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/no-pico-interpreter.png.bf9001bcb109537f4e6afb87a236d45f.png">
</p>

<p>
	إذا لم تجد راسبيري بيكو وبرنامج مايكرو بايثون ضمن القائمة، يجب عليك إعادة توصيل لوحة راسبيري باي بيكو مع النقر على زر <strong>BOOTSEL</strong> لتثبيتها مثل جهاز تخزين، ثم إعادة تثبيت برنامج مايكرو بايثون، كما في الخطوة السابقة.
</p>

<h4>
	فقدان الإتصال مع لوحة راسبيري باي بيكو
</h4>

<p>
	قد تفقد الإتصال بلوحة راسبيري باي بيكو بعد إكمال تثبيت البرنامج، حينها عليك التأكد من سلامة كبل micro USB الذي تستخدمه، وأنه مخصص لنقل البيانات وليس مخصصًا لنقل الطاقة فقط، جرّب تبديل الكبل كحلٍ أخير؛ وإذا لم تنجح أي من الحلول السابقة ولا زلت لا تستطيع الإتصال بلوحة راسبيري باي بيكو، فقد يكون العطل من اللوحة ذاتها.
</p>

<p>
	ستحتاج لتثبيت مكتبة <strong>بيكو زيرو picozero</strong>، وهي إحدى مكتبات مايكرو بايثون المخصصة لمستخدمي راسبيري باي بيكو المبتدئين.
</p>

<p>
	رابعًا، انقر على قائمة الأدوات <strong>Tools</strong> من شريط القوائم في برنامج ثوني، ثم انقر على خيار إدارة الحزم <strong>Manage Packages</strong> لإضافة حزمة بيكو زيرو.
</p>

<p style="text-align: center;">
	<img alt="إدارة الحزم Manage Packages لإضافة حزمة بيكو زيرو" class="ipsImage ipsImage_thumbnailed" data-fileid="116035" data-ratio="71.67" data-unique="9c2ms4e2n" style="width: 780px; height: auto;" width="780" src="https://academy.hsoub.com/uploads/monthly_2023_01/thonny-manage-packages.thumb.jpg.f5fc4e56741afa94ff12628891cab5ad.jpg">
</p>

<p>
	خامسًا، ستظهر لك نافذة إدارة الحزم التالية، اكتب "picozero"، ثم انقر على زر البحث <strong>Search on PyPi</strong>:
</p>

<p style="text-align: center;">
	<img alt="نافذة إدارة الحزم من راسبيري باي بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="116036" data-ratio="70.33" data-unique="10dq100vq" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_01/thonny-packages-picozero.jpg.23378c427d3d27afcfa815d7cf6f28e2.jpg">
</p>

<p>
	انقر على <strong>picozero</strong> من نتائج البحث ثم انقر على زر التثبيت <strong>Install</strong>.
</p>

<p style="text-align: center;">
	<img alt="تثبيت picozero " class="ipsImage ipsImage_thumbnailed" data-fileid="116034" data-ratio="70.33" data-unique="nzb0u0dj7" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_01/thonny-install-package.jpg.d5b1104d344b4409d480cb5f3e902dce.jpg">
</p>

<p>
	أغلق النافذة عند انتهاء عملية التثبيت، ثم أغلق برنامج ثوني وافتحه مجددًا.
</p>

<p>
	إذا واجهت مشاكل عند تثبيت مكتبة "picozero" في ثوني، يمكنك تنزيل ملف المكتبة ثم حفظه على حاسوب راسبيري باي بيكو.
</p>

<h3>
	تنزيل حزمة <code>picozero</code> باستخدام حاسوب آخر
</h3>

<p>
	إذا لم يتوفر لديك اتصالًا بالإنترنت على الحاسوب الموصول مع لوحة راسبيري باي بيكو، أو أنك لا تمتلك صلاحيةً لتثبيت الحزم باستخدام ثوني، فيمكنك تنزيل حزمة "picozero" من حاسوب آخر ثم نقلها باستخدام وحدة تخزين USB إلى راسبيري باي بيكو، وذلك بإتباع الخطوات التالية:
</p>

<ul>
	<li>
		انتقل إلى مستودع بيكو زيرو على <a href="https://raw.githubusercontent.com/RaspberryPiFoundation/picozero/master/picozero/picozero.py?token=GHSAT0AAAAAABRLTKWZCT53CGKBFHMJGE54YSC762A" rel="external nofollow">غيت هب GitHub</a> من خلال المتصفح المفضّل لديك.
	</li>
	<li>
		انقر بزر الفأرة الأيمن على الصفحة ثم انقر على خيار حفظ الصفحة باسم <strong>Save page as</strong>،واختر أين تريد حفظ الملف وأبقِ على اسمه كما هو "picozero.py"، وإذا ظهر لك اسم الملف بصيغة ملف نصي "picozero.txt"، غَيّر لاحقته يدويًا إلى "picozero.py" واختر النوع جميع الملفات <strong>All files</strong> كما هو موضح في الصورة التالية:
	</li>
</ul>

<p style="text-align: center;">
	<img alt="تنزيل حزمة picozero باستخدام حاسوب آخر" class="ipsImage ipsImage_thumbnailed" data-fileid="116000" data-ratio="23.85" data-unique="upss3n0jl" style="width: 650px; height: auto;" width="650" src="https://academy.hsoub.com/uploads/monthly_2023_01/ChangingPicozeroExtension.png.b6092f2d2744d2db653665087bdfae24.png">
</p>

<p>
	أو يمكنك رفع ملف <a data-fileext="zip" data-fileid="116046" href="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=116046&amp;key=9d537afe43b59929557dbaaaabcb32f0" rel="">Thonny</a> والذي تجده أيضًا في مرفقات المشروع في نهاية المقال.
</p>

<p>
	الآن، أنت أمام خيارين، إما أن تستخدم مدير الملفات في ثوني، أو أن تنسخ الملف وتلصقه في ثوني.
</p>

<h3>
	نقل الملفات باستخدام مدير الملفات في ثوني
</h3>

<p>
	أولًا، صِل لوحة راسبيري باي بيكو مع حاسوبك باستخدام كبل microUSB.
</p>

<p>
	ثانيًا، افتح ثوني من قائمة التطبيقات، ثم انقر على قائمة العرض <strong>View</strong> من شريط الأدوات، واختر عرض الملفات Files.
</p>

<p style="text-align: center;">
	<img alt="نقل الملفات باستخدام مدير الملفات في ثوني" class="ipsImage ipsImage_thumbnailed" data-fileid="116043" data-ratio="67.27" data-unique="8y00b86dx" style="width: 550px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/view_files.jpg.16e2d4ce33bf26f66d0e040be1337f7e.jpg">
</p>

<p>
	ثالثًا، استعن بالمسار للانتقال للمجلد الذي حفظت فيه ملف "picozero.py".
</p>

<p style="text-align: center;">
	<img alt='الانتقال للمجلد الذي حفظت فيه ملف "picozero.py"' class="ipsImage ipsImage_thumbnailed" data-fileid="116013" data-ratio="31.33" data-unique="x6pd1m91x" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/navigate_downloads.jpg.5ab90eba83a4ca42e2f64d453d404554.jpg">
</p>

<p>
	رابعًا، انقر بزر الفأرة الأيمن على ملف "picozero.py"، ثم انقر على خيار رفع إلى المجلد الجذر <strong>/ Upload to</strong> من القائمة.
</p>

<p style="text-align: center;">
	<img alt="رفع إلى المجلد الجذر / Upload to من القائمة" class="ipsImage ipsImage_thumbnailed" data-fileid="116042" data-ratio="117.00" data-unique="sgxxvr0il" style="width: 300px; height: auto;" width="300" src="https://academy.hsoub.com/uploads/monthly_2023_01/upload_files.jpg.47e9930bd198be8f088ecf9e2bf30ce1.jpg">
</p>

<p>
	أصبح لديك الآن نسخة من مكتبة "picozero.py" على حاسوب راسبيري باي بيكو.
</p>

<h3>
	نسخ الملفات باستخدام ثوني
</h3>

<p>
	أولًا، حدّد كامل النص في ملف "picozero.py" عن طريق الضغط على مفتاحي <strong>Ctrl + a</strong> من لوحة المفاتيح، ثم اضغط على مفتاحي <strong>Ctrl +c</strong> لنسخه.
</p>

<p>
	ثانيًا، افتح واجهة ثوني وانقر على النافذة الفارغة "untitled"، ثم اضغط على مفتاحي <strong>Ctrl +v</strong> للصق محتوى مكتبة "picozero.py" إلى الملف.
</p>

<p>
	ثالثًا، احفظ الملف بالنقر على مفتاحي <strong>Ctrl +s</strong> ثم انقر على خيار الحفظ في بيكو <strong>Raspberry Pi Pico</strong>.
</p>

<p style="text-align: center;">
	<img alt="نسخ الملفات باستخدام ثوني" class="ipsImage ipsImage_thumbnailed" data-fileid="116026" data-ratio="98.59" data-unique="mjbx0ocfo" style="width: 213px; height: auto;" width="213" src="https://academy.hsoub.com/uploads/monthly_2023_01/save_to.jpg.74f78b578076b6b6d826d9a012a39ade.jpg">
</p>

<p>
	رابعًا، سمِّ الملف "picozero.py"، ثم انقر على زر موافق <strong>OK</strong>.
</p>

<p style="text-align: center;">
	<img alt='تسمية الملف "picozero.py"' class="ipsImage ipsImage_thumbnailed" data-fileid="116025" data-ratio="42.20" data-unique="19wq4q9cw" style="width: 500px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/save_file.jpg.4ad59dcf006e508f47183220adc39da3.jpg">
</p>

<h2>
	اختبار لوحة راسبيري باي بيكو
</h2>

<p>
	سنختبر في هذه الخطوة جاهزية لوحة راسبيري باي بيكو للعمل، وذلك عن طريق اختبار مصباح الليد الصغير الموجود أعلى اللوحة، فإذا أضاء فهذا يعني أن اللوحة مُعَّدة وجاهزة للعمل.
</p>

<p style="text-align: center;">
	<img alt="اختبار لوحة راسبيري باي بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="116010" data-ratio="85.00" data-unique="jhptp2lrb" style="width: 500px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/led-on-off.gif.193651e05d67ddf717b0f3c03fcfe3aa.gif">
</p>

<p>
	<strong>معلومة:</strong> "مصباح ليد" أو LED هو اختصار لاسم العنصر الإلكتروني Light-emitting Diode أي الثنائي الباعث للضوء، ويعتمد هذا المصباح على مبدأ التألق الكهربائي Electroluminescence، إذ تضيئ بعض المواد عند مرور التيار الكهربائي عبرها. يكون لمصباح الليد طرفان، أحدهما طويل وهو يمثل القطب الموجب (<strong>+</strong>)، والطرف القصير يمثل القطب السالب (<strong>-</strong>)، كما يمكنك التمييز بين القطبين بأن الطرف السالب هو الطرف الأقرب للحافة المسطحة للمصباح. المس الحافة بإصبعك لتلاحظ الفرق. من الضروري الانتباه وتوصيل الليد وفق القطبية الصحيحة لأنه لن يضيء عند عكسها.
</p>

<p>
	أولًا، لاحظ وجود الليد على لوحة بيكو، بجانب منفذ USB، كما هو موضح في الصورة التالية:
</p>

<p style="text-align: center;">
	<img alt="وجود الليد على لوحة بيكو بجانب منفذ USB" class="ipsImage ipsImage_thumbnailed" data-fileid="116017" data-ratio="234.50" data-unique="2m7c908wj" style="width: 200px; height: auto;" width="200" src="https://academy.hsoub.com/uploads/monthly_2023_01/pico-led.thumb.jpg.d0738c5da7f17e80525daf46845aa103.jpg">
</p>

<p>
	ثانيًا، افتح برنامج ثوني وأنشئ ملفًا جديدًا فيه، وذلك بالنقر على قائمة ملف <strong>File</strong>، ثم النقر على خيار إنشاء ملف جديد <strong>New</strong>، ولاحظ أنك ستحصل على مساحة عمل جديدة فارغة.
</p>

<p>
	تُتيح لنا مكتبة "picozero" المثبتة مسبقًا، برمجة العناصر الإلكترونية الموصولة مع لوحة بيكو، لكن يجب علينا التصريح عن العناصر التي سنستخدمها في بداية الشيفرة البرمجية لاستيرادها من مكتبة "picozero".
</p>

<p>
	ثانيًا، اكتب الشيفرة التالية في مساحة العمل الفارغة في ثوني لاستيراد عنصر الليد من مكتبة <code>picozero</code>:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_972_49" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> pico_led
pico_led</span><span class="pun">.</span><span class="pln">on</span><span class="pun">()</span></pre>

<p>
	ثالثًا، انقر على قائمة ملف <strong>File</strong> ثم اختر حفظ باسم <strong>Save as</strong> وانقر على خيار الحفظ في حاسوبك <strong>This computer</strong> وليس الحفظ في راسبيري باي بيكو. اختر مكانًا مناسبًا لحفظ الملف وسمّه "firefly.py".
</p>

<p style="text-align: center;">
	<img alt='حفظ الملف في الحاسوب مع تسميته "firefly.py' class="ipsImage ipsImage_thumbnailed" data-fileid="116024" data-ratio="70.33" data-unique="hr5qfz311" style="width: 300px; height: auto;" width="300" src="https://academy.hsoub.com/uploads/monthly_2023_01/save-on-computer.png.55105d4f7633bea81235490bee0919b4.png">
</p>

<p>
	رابعًا، حان الآن وقت اختبار لوحة راسبيري باي بيكو، لذلك انقر على زر التشغيل الأخضر (زر دائري فيه مثلث أبيض) في ثوني، لتنفيذ الشيفرة، إذ يجب أن يضيء الليد على لوحة بيكو دليلًا على سلامتها.
</p>

<p style="text-align: center;">
	<img alt="اختبار لوحة راسبيري باي بيكو" class="ipsImage ipsImage_thumbnailed" data-fileid="116011" data-ratio="133.25" data-unique="4iyeafkk0" style="width: 400px; height: auto;" width="400" src="https://academy.hsoub.com/uploads/monthly_2023_01/led-on.thumb.jpg.7c64e85cb4c78b5cd9b6870d2b011cc2.jpg">
</p>

<h3>
	تصحيح الأخطاء
</h3>

<p>
	إليك بعض المشاكل التي قد تواجهك وكيفية إصلاحها:
</p>

<h4>
	زر التشغيل غير مفعل
</h4>

<p>
	قد يظهر زر التشغيل باللون الرمادي، أي أنه غير مفعّل، في هذه الحالة عليك اتباع مايلي:
</p>

<ul>
	<li>
		انقر على زر التوقف <strong>STOP</strong> الأحمر.
	</li>
	<li>
		تأكد أن لوحة راسبيري باي بيكو موصولة مع حاسوبك بواسطة كبل USB.
	</li>
	<li>
		انقر على أيقونة مايكرو بايثون (أو راسبيري باي بيكو) الموجودة في الزاوية السفلية اليمنى في واجهة ثوني، لإعادة الاتصال.
	</li>
	<li>
		افصل كبل USB ثم أعد توصيله.
	</li>
</ul>

<h4>
	يظهر البرنامج رسالة خطأ في الشيفرة
</h4>

<p>
	تحقق من الشيفرة التي كتبتها وتأكد أنها مطابقة للشيفرة في مثالنا.
</p>

<h4>
	لا يوجد خطأ في الشيفرة ولكن الليد لا يضيء
</h4>

<p>
	غيّر كبل USB وتأكد أنك تستخدم كبلًا مخصصًا لنقل البيانات USB data؛ وإذا كان لديك لوحة راسبيري باي بيكو أخرى، جرب تبديل اللوحة.
</p>

<p>
	لاحظ أن الليد سوف يظل مضيئًا حتى تكتب شيفرةً أخرى لإطفائه، أو إلى أن تفصل لوحة بيكو.
</p>

<p>
	خامسًا، اكتب الشيفرة التالية لاستيراد التابع <code>sleep</code> لإيقاف الليد عن العمل لمدة ثانية واحدة، ثم إطفائه.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_972_53" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> pico_led
</span><span class="kwd">from</span><span class="pln"> time </span><span class="kwd">import</span><span class="pln"> sleep 

pico_led</span><span class="pun">.</span><span class="pln">on</span><span class="pun">()</span><span class="pln"> 
sleep</span><span class="pun">(</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
pico_led</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span></pre>

<p>
	سادسًا، انقر على زر التشغيل الأخضر <strong>play</strong> لتشغيل الشيفرة. سيحفظ برنامج ثوني الملف على لوحة بيكو ثم سيشغله. تحقق أن الليد يضيء ثم ينطفئ، وأبقِ عينيك مفتوحتين جيدًا لأنه سيضيء لثانية واحدة فقط. لا تقلق، يمكنك تشغيل الشيفرة عدة مرات للتحقق.
</p>

<p style="text-align: center;">
	<img alt="التحقق من أن الليد يضيء ثم ينطفئ" class="ipsImage ipsImage_thumbnailed" data-fileid="116010" data-ratio="85.11" data-unique="jhptp2lrb" style="width: 450px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/led-on-off.gif.193651e05d67ddf717b0f3c03fcfe3aa.gif">
</p>

<h3>
	تصحيح الأخطاء
</h3>

<h4>
	يظهِر البرنامج رسالة تفيد بأن تابع التوقف sleep غير معرف
</h4>

<p>
	أضف السطر التالي على برنامجك لتعريف تابع التوقف <code>sleep</code> وإصلاح المشكلة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_972_57" style=""><span class="kwd">from</span><span class="pln"> time </span><span class="kwd">import</span><span class="pln"> sleep </span></pre>

<h2>
	توصيل مصباح ليد بلوحة بيكو وتشغيله
</h2>

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

<p style="text-align: center;">
	<img alt="توصيل مصباح ليد بلوحة بيكو وتشغيله" class="ipsImage ipsImage_thumbnailed" data-fileid="116004" data-ratio="75.00" data-unique="t6plxl84y" style="width: 400px; height: auto;" width="400" src="https://academy.hsoub.com/uploads/monthly_2023_01/firefly-on.jpg.6935b23f981c60a86c9105a8fd80b006.jpg">
</p>

<p>
	يجب أن نحصل عند إتمام هذه الخطوة على مصباح ليد موصول مع مقاومة ولوحة راسبيري باي بيكو باستخدام سلكيّ توصيل نوع مقبس-مقبس. لا يهم لون سلك التوصيل الذي تستخدمه، كما أنه لديك حرية اختيار لون مصباح الليد، لكن عادةً ما تكون أضواء حشرة اليراعة باللون الأصفر أو البرتقالي أو الأخضر، فننصحك باختيار إحدى هذه الألوان.
</p>

<p style="text-align: center;">
	<img alt="led-resistor.jpeg" class="ipsImage ipsImage_thumbnailed" data-fileid="116012" data-unique="g45c7ac03" src="https://academy.hsoub.com/uploads/monthly_2023_01/led-resistor.jpeg.39271a8be488536f681a4efd569a12ab.jpeg">
</p>

<p>
	تعمل المقاومة على التحكم بالتيار المار في الدارة وبالتالي جعل مصباح الليد يستمر في العمل فترةً أطول وحمايته من الإحتراق.
</p>

<h3>
	توصيل الليد مع مقاومة وأسلاك توصيل باستخدام شريط عازل
</h3>

<p>
	ستحتاج لتوصيل الليد إلى ما يلي:
</p>

<ul>
	<li>
		أسلاك توصيل نوع مقبس-مقبس (عدد 2).
	</li>
	<li>
		مقاومة.
	</li>
	<li>
		مصباح ليد.
	</li>
	<li>
		شريط عازل.
	</li>
	<li>
		مقص.
	</li>
</ul>

<p style="text-align: center;">
	<img alt="توصيل الليد مع مقاومة وأسلاك توصيل باستخدام شريط عازل" class="ipsImage ipsImage_thumbnailed" data-fileid="116044" data-ratio="75.00" data-unique="zav8srsj3" style="width: 500px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/you-will-need.jpg.e88abf5c32d106c26328a7aeae0310fd.jpg">
</p>

<h4>
	الطريقة الصحيحة لتوصيل الليد
</h4>

<p>
	كما تعلمنا سابقًا، فإن لمصباح الليد رجل قصيرة سالبة، وأخرى طويلة هي الموجبة.
</p>

<p style="text-align: center;">
	<img alt="لمصباح الليد رجل قصيرة سالبة وأخرى هي الموجبة" class="ipsImage ipsImage_thumbnailed" data-fileid="116023" data-ratio="244.00" data-unique="1735o1lqs" style="width: 150px; height: auto;" width="200" src="https://academy.hsoub.com/uploads/monthly_2023_01/pos-neg.png.7b3736d7d8e160fa8de7a57fbe52d8eb.png">
</p>

<p>
	يمكنك التمييز بين القطبين عن طريق لمس الحافة المسطحة للجزء البلاستيكي للمصباح بإصبعك؛ إذ أن الطرف السالب هو الطرف الأقرب إلى الحافة المسطحة للمصباح.
</p>

<p>
	أولًا، اثنِ أحد طرفي المقاومة حول الرجل الموجبة لمصباح الليد.
</p>

<p style="text-align: center;">
	<img alt="ثني أحد طرفي المقاومة حول الرجل الموجبة لمصباح الليد" class="ipsImage ipsImage_thumbnailed" data-fileid="115997" data-ratio="75.00" data-unique="s6bxvo790" style="width: 500px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/bend-leg.jpg.c7bfcf48aba62191d8ecbe088038d2fb.jpg">
</p>

<p>
	ثم لُف طرف المقاومة حول رجل مصباح الليد ثلاث مرات، كما في الصورة:
</p>

<p style="text-align: center;">
	<img alt="لُف طرف المقاومة حول رجل مصباح الليد ثلاث مرات" class="ipsImage ipsImage_thumbnailed" data-fileid="116041" data-ratio="75.00" data-unique="djdzuf2s2" style="width: 500px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/twist-leg.jpg.acb61645900586d1f2496134bc1b0117.jpg">
</p>

<p>
	ثانيًا، قُص قطعة من الشريط العازل والصقه على الجزء الملفوف من المقاومة ليساعد في تثبيتها.
</p>

<p style="text-align: center;">
	<img alt="قُص قطعة من الشريط العازل والصقه على الجزء الملفوف من المقاومة" class="ipsImage ipsImage_thumbnailed" data-fileid="116001" data-ratio="75.00" data-unique="1050uy0pj" style="width: 500px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/elec-tape.jpg.dc4a6b353dde964f5775ac0ff0088ff0.jpg">
</p>

<p>
	ثالثًا، أدخل سلك توصيل في النهاية الحرة للمقاومة، ثم صِل سلكًا آخر مع الرجل السالبة لمصباح الليد.
</p>

<p style="text-align: center;">
	<img alt="الخطوة 3 من عملية توصيل الليد" class="ipsImage ipsImage_thumbnailed" data-fileid="116009" data-ratio="75.00" data-unique="s0d8a6xdm" style="width: 500px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/jumper-wires.jpg.c8fbe3880f02aee96f1ed2151883a70e.jpg">
</p>

<p>
	يمكنك أيضًا استخدام الشريط العازل لتثبيت التوصيلات.
</p>

<h3>
	توصيل الليد مع مقاومة وأسلاك توصيل باستخدام اللحام وأنابيب الانكماش الحراري
</h3>

<p>
	<strong>تنبيه:</strong> ستحتاج إلى مساعدة أحد البالغين لتنفيذ هذه الخطوة وخاصةً عند استخدام مسدس اللحام.
</p>

<p>
	أولًا، ستحتاج إلى مصباح ليد، ومقاومة (ذات قيمة 70 أوم أو أكبر)، سلكي توصيل نوع مقبس-مقبس، ومسدس أو كاوي لحام، وأسلاك قصدير، وأنابيب انكماش حراري.
</p>

<p style="text-align: center;">
	<img alt="توصيل الليد مع مقاومة وأسلاك توصيل باستخدام اللحام وأنابيب الانكماش الحراري" class="ipsImage ipsImage_thumbnailed" data-fileid="116045" data-ratio="56.29" data-unique="ixge65egn" style="width: 600px; height: auto;" width="700" src="https://academy.hsoub.com/uploads/monthly_2023_01/you_will_need.thumb.jpg.beb50be4b268a0b0c8532ba972f1011b.jpg">
</p>

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

<p style="text-align: center;">
	<img alt="الخطوة 2 من عملية توصيل الليد مع مقاومة وأسلاك توصيل باستخدام اللحام وأنابيب الانكماش الحراري" class="ipsImage ipsImage_thumbnailed" data-fileid="116039" data-ratio="56.33" data-unique="ivtc5wbrb" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_01/tin_led.gif.c35669d1ad80ff158061dad7be27020f.gif">
</p>

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

<p style="text-align: center;">
	<img alt="الخطوة 3 من عملية توصيل الليد مع مقاومة وأسلاك توصيل باستخدام اللحام وأنابيب الانكماش الحراري" class="ipsImage ipsImage_thumbnailed" data-fileid="116040" data-ratio="56.33" data-unique="m7uhr21za" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_01/tin_resistor.gif.2db5abe6126bf2ad0773272ed746381f.gif">
</p>

<p>
	رابعًا، ضع رجل الليد الموجبة فوق رجل المقاومة ثم مرّر مسدس اللحام عليهما كي تلتحما معًا.
</p>

<p style="text-align: center;">
	<img alt="الخطوة 4 من عملية توصيل الليد مع مقاومة وأسلاك توصيل باستخدام اللحام وأنابيب الانكماش الحراري" class="ipsImage ipsImage_thumbnailed" data-fileid="115999" data-ratio="56.33" data-unique="bqfhdlmc5" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_01/bond_resistor.gif.a3a91d6e64a8b2625c22e58d8884a483.gif">
</p>

<p>
	خامسًا، قص النهاية البلاستيكية السوداء لسلكي التوصيل، ثم انزع الغلاف البلاستيكي للسلكين حتى تحصل على الجزء النحاسي بدون عزل، كما هو موضح:
</p>

<p style="text-align: center;">
	<img alt="الخطوة 5 من عملية توصيل الليد مع مقاومة وأسلاك توصيل باستخدام اللحام وأنابيب الانكماش الحراري" class="ipsImage ipsImage_thumbnailed" data-fileid="116028" data-ratio="56.33" data-unique="7lnky0w7e" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_01/strip_jumpers.gif.7cf1bf6c8aaf8cc51b9f8e9659099156.gif">
</p>

<p>
	سادسًا، اصهر بعض القصدير على نهايتي السلكين.
</p>

<p style="text-align: center;">
	<img alt="الخطوة 6 من عملية توصيل الليد مع مقاومة وأسلاك توصيل باستخدام اللحام وأنابيب الانكماش الحراري" class="ipsImage ipsImage_thumbnailed" data-fileid="116038" data-ratio="56.33" data-unique="6gdutvk1m" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_01/tin_jumpers.gif.02ecb893702a12d64223488d8d2427a2.gif">
</p>

<p>
	سابعًا، ادخل أنبوب انكماش حراري في كلٍ من السلكين.
</p>

<p style="text-align: center;">
	<img alt="الخطوة 7 من عملية توصيل الليد مع مقاومة وأسلاك توصيل باستخدام اللحام وأنابيب الانكماش الحراري" class="ipsImage ipsImage_thumbnailed" data-fileid="115996" data-ratio="56.33" data-unique="078rt083n" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_01/add_heatshrink.gif.1a397cf6b3ec778460771566d9862413.gif">
</p>

<p>
	ثامنًا، ضع النهاية المكشوفة لسلك التوصيل الأول فوق الليد، ثم سخّنهما كي يلتحما، وكرّر العملية مع السلك الثاني والمقاومة.
</p>

<p style="text-align: center;">
	<img alt="الخطوة 8 من عملية توصيل الليد مع مقاومة وأسلاك توصيل باستخدام اللحام وأنابيب الانكماش الحراري" class="ipsImage ipsImage_thumbnailed" data-fileid="115998" data-ratio="56.33" data-unique="4ljzpr8py" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_01/bond_jumpers.gif.fc7d6cf261948e19e4460b748b49ced0.gif">
</p>

<p>
	تاسعًا، اسحب أنبوب الانكماش الحراري إلى نهاية السلك ليغطي موضع اللحام.
</p>

<p style="text-align: center;">
	<img alt="الخطوة 9 من عملية توصيل الليد مع مقاومة وأسلاك توصيل باستخدام اللحام وأنابيب الانكماش الحراري" class="ipsImage ipsImage_thumbnailed" data-fileid="116021" data-ratio="56.33" data-unique="g8shlbtwl" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_01/place_heatshrink.gif.de5dceb0a45aa3345d84712d079a9960.gif">
</p>

<p>
	عاشرًا، سخن أنبوب الانكماش الحراري باستخدام الحافة العريضة من مسدس اللحام حتى ينكمش حول سلك التوصيل.
</p>

<p style="text-align: center;">
	<img alt="الخطوة 10 من عملية توصيل الليد مع مقاومة وأسلاك توصيل باستخدام اللحام وأنابيب الانكماش الحراري" class="ipsImage ipsImage_thumbnailed" data-fileid="116008" data-ratio="56.33" data-unique="6kvcjw30k" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_01/heat_heatshrink.gif.29e61beb8797c9b0ef8733816dfbd835.gif">
</p>

<p>
	أخيرًا، اختبر الليد بتوصيل إحدى السلكين إلى أحد أرجل الأرضية GND على لوحة بيكو، والسلك الآخر إلى إحدى أرجل 3V3.
</p>

<p style="text-align: center;">
	<img alt="الخطوة الأخيرة من عملية توصيل الليد مع مقاومة وأسلاك توصيل باستخدام اللحام وأنابيب الانكماش الحراري" class="ipsImage ipsImage_thumbnailed" data-fileid="116030" data-ratio="56.33" data-unique="5qtf8rq7y" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_01/test_led.gif.79729ce0b77c6de8570e053c40bda545.gif">
</p>

<p>
	لاحظ أنه يوجد على لوحة بيكو 40 رجلًا معدنية تتوضع على حافة اللوحة تُمكّنك من توصيل تجهيزات خارجية مع لوحة بيكو، مثل الليد والمقاومة والمبدّلات.
</p>

<p>
	اقلب لوحة بيكو ولاحظ وجود مسميات توضيحية بجانب كل رجل. ابحث عن رجل الأغراض العامة <strong>GP13</strong> وَوصل الرجل الموجبة لليد (الرجل الموصولة مع المقاومة) معها، واحرص على إدخال القطعة البلاستيكية السوداء للسلك في الرجل المعدنية بإحكام حتى نهايتها.
</p>

<p style="text-align: center;">
	<img alt="إدخال القطعة البلاستيكية السوداء للسلك في الرجل المعدنية بإحكام حتى نهايتها" class="ipsImage ipsImage_thumbnailed" data-fileid="116007" data-ratio="75.00" data-unique="8clnr7847" style="width: 480px; height: auto;" width="480" src="https://academy.hsoub.com/uploads/monthly_2023_01/gp13-pico.png.e03d738b96fe889c11ed7ad633428543.png">
</p>

<p>
	بعد ذلك، صِل السلك الموصول مع الطرف السالب لمصباح الليد مع رجل الأرضية <strong>GND</strong> على اللوحة تحت الرجل <strong>GP13</strong> لإكمال الدارة والتحكم فيها عن طريق الشيفرة التي سنكتبها .
</p>

<p style="text-align: center;">
	<img alt="إعداد الدارة لإكمال الدارة والتحكم فيها عن طريق الشيفرة التي سنكتبها" class="ipsImage ipsImage_thumbnailed" data-fileid="116019" data-ratio="160.11" data-unique="9ceatjd74" style="width: 361px; height: auto;" width="361" src="https://academy.hsoub.com/uploads/monthly_2023_01/pico_led_13_bb.png.1bdd1b1bdf55a0dda3d2ef94802a1fbf.png">
</p>

<p>
	استخدمنا في الخطوة الأخيرة التابع <code>pico_led</code> لإضاءة مصباح الليد الموجود على لوحة بيكو، لكن يجب علينا استيراد <code>LED</code>من مكتبة <code>picozero</code> لإضافة مصابيح ليد خارجية والتحكم بها.
</p>

<p>
	أضف <code>LED ,</code> على السطر الأول من الشيفرة، إذ يمكنك استيراد عدّة عناصر من المكتبة عن طريق الفصل بينها بفاصلة. عدّل على الشيفرة لتبدو كما يلي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_972_85" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> pico_led</span><span class="pun">,</span><span class="pln"> LED
</span><span class="kwd">from</span><span class="pln"> time </span><span class="kwd">import</span><span class="pln"> sleep

pico_led</span><span class="pun">.</span><span class="pln">on</span><span class="pun">()</span><span class="pln"> 
sleep</span><span class="pun">(</span><span class="lit">1</span><span class="pun">)</span><span class="pln"> 
pico_led</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln">

firefly </span><span class="pun">=</span><span class="pln"> LED</span><span class="pun">(</span><span class="lit">13</span><span class="pun">)</span><span class="pln">         </span><span class="com"># استخدم الرجل ذات الرقم 13</span><span class="pln">
firefly</span><span class="pun">.</span><span class="pln">on</span><span class="pun">()</span></pre>

<p>
	لاحظ أننا أسندنا مصباح الليد إلى الرجل <strong>GP13</strong>، في السطر ما قبل الأخير، وسمينا التابع <code>firefly</code> أي يراعة، ثم شغّلنا المصباح في السطر الأخير.
</p>

<p>
	الآن، انقر على زر التشغيل Play لتنفيذ الشيفرة وتشغيل المصباح.
</p>

<p style="text-align: center;">
	<img alt="النقر على زر التشغيل Play لتنفيذ الشيفرة وتشغيل المصباح" class="ipsImage ipsImage_thumbnailed" data-fileid="116004" data-ratio="75.00" data-unique="t6plxl84y" style="width: 400px; height: auto;" width="400" src="https://academy.hsoub.com/uploads/monthly_2023_01/firefly-on.jpg.6935b23f981c60a86c9105a8fd80b006.jpg">
</p>

<p>
	أخيرًا، قُص جناحان من الورق المقوى أو الشريط اللاصق وألصقها حول مصباح الليد للحصول على مظهر اليراعة.
</p>

<p style="text-align: center;">
	<img alt="الحصول على مظهر اليراعة مع الليد" class="ipsImage ipsImage_thumbnailed" data-fileid="116006" data-ratio="75.00" data-unique="0yzunvhiq" style="width: 400px; height: auto;" width="45" src="https://academy.hsoub.com/uploads/monthly_2023_01/firefly-wings.jpg.d321d168e139e6fc3b79d677b9e26e36.jpg">
</p>

<h3>
	تصحيح الأخطاء
</h3>

<p>
	إليك بعض الأخطاء التي قد تواجهها في هذه الخطوة وكيفية إصلاحها:
</p>

<h4>
	لا تعمل الشيفرة التي كتبتها
</h4>

<p>
	تأكد من خلو الشيفرة التي كتبتها من الأخطاء وقارنها مع مثالنا، ثم أعد تشغيل الشيفرة بالنقر على زر Play، سيومض مصباح الليد الموجود على لوحة بيكو عند تنفيذ الشيفرة بنجاح.
</p>

<h4>
	لا يضيء مصباح الليد الذي وصلته
</h4>

<ul>
	<li>
		تحقق من توصيل الرجل السالبة (القصيرة) للمصباح مع الرجل الأرضية للوحة بيكو، وتوصيل الرجل الموجبة الطويلة مع المقاومة ثم مع الرجل <strong>GP13</strong>.
	</li>
	<li>
		تحقق من نقاط اللحام، أو نقاط التوصيل، وتأكد أن جميع العناصر متصلة ببعضها جيدًا.
	</li>
	<li>
		غَيّر مصباح الليد.
	</li>
</ul>

<h2>
	جعل مصباح الليد يومض
</h2>

<p>
	سنضيف الشيفرة اللازمة لجعل المصباح يومض باستمرار مثل يراعة مضيئة في الطبيعة.
</p>

<p style="text-align: center;">
	<img alt="جعل مصباح الليد يومض" class="ipsImage ipsImage_thumbnailed" data-fileid="116002" data-ratio="56.33" data-unique="kg9haiqfz" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_01/firefly-blink.gif.68acd3f458db2b4a695acdb9f6007c70.gif">
</p>

<p>
	<strong>معلومة:</strong> اليراعَة هي إحدى أنواع الخنافس، وتدعى أحيانًا بسراج الليل أو الحُبَاحِب lightning bug، تعتمد على التلألؤ البيولوجي لتومض وتتعرف على الحشرات الأخرى من نفس فصيلتها، إذ أن لكل فصيلة نمط وميض معين.
</p>

<p>
	أولًا، أضف حلقة تكرار مستمرة <code>while True:‎</code> على الشيفرة السابقة مع الأزمنة التالية التي تمثل نمط الوميض ليراعة حقيقية، واحرص على ترك مسافة بادئة في الأسطر أسفل <a href="https://academy.hsoub.com/programming/python/%d8%ad%d9%84%d9%82%d8%a7%d8%aa-%d8%a7%d9%84%d8%aa%d9%83%d8%b1%d8%a7%d8%b1-loops-%d9%81%d9%8a-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86-r291/" rel="">حلقة التكرار</a>:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_972_93" style=""><span class="pln">firefly </span><span class="pun">=</span><span class="pln"> LED</span><span class="pun">(</span><span class="lit">13</span><span class="pun">)</span><span class="pln"> </span><span class="com"># Use GP13</span><span class="pln">

</span><span class="kwd">while</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">:</span><span class="pln">
    firefly</span><span class="pun">.</span><span class="pln">on</span><span class="pun">()</span><span class="pln">
    sleep</span><span class="pun">(</span><span class="lit">0.5</span><span class="pun">)</span><span class="pln">
    firefly</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln">
    sleep</span><span class="pun">(</span><span class="lit">2.5</span><span class="pun">)</span></pre>

<p>
	<strong>نصيحة:</strong> يضيف برنامج ثوني عند الضغط على مفتاح Tab عند بداية السطر أربع مسافات فارغة، وعند الضغط على مفتاح Enter فإنه سيضيف نفس المسافة السابقة على السطر الجديد.
</p>

<p>
	ثانيًا، شغّل الشيفرة لاختبار وميض اليراعة.
</p>

<p style="text-align: center;">
	<img alt="تشغيل الشيفرة لاختبار وميض اليراعة" class="ipsImage ipsImage_thumbnailed" data-fileid="116002" data-ratio="56.33" data-unique="kg9haiqfz" style="width: 600px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2023_01/firefly-blink.gif.68acd3f458db2b4a695acdb9f6007c70.gif">
</p>

<p>
	لتفادي المشكلات تأكد أن الوصلات ثابتة في مكانها وتحقق من وجود المسافات في حلقة <code>while</code>.
</p>

<h2>
	إضافة مبدل switch
</h2>

<p>
	سنضيف في هذه الخطوة مبدّلًا يشبه عمله عمل الزر، للتحكم بتشغيل الليد وإطفائه.
</p>

<p style="text-align: center;">
	<img alt="إضافة مبدل switch" class="ipsImage ipsImage_thumbnailed" data-fileid="116005" data-ratio="73.56" data-unique="rc9q4p37j" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/firefly-switch.gif.4d52811d75295403449754d2f97c967e.gif">
</p>

<p>
	<strong>معلومة:</strong> المبدّل هو عنصر إلكتروني يسمح بإكمال الدارة الكهربائية وتمرير التيار عند إغلاقه، ويمنع مروره عند فتحه، ومن أشكاله الزر الذي يسمح بتوصيل الدارة عند الضغط عليه، أما أبسط أشكاله فهو توصيل سلكين ببعضهما للحصول على مبدّل، وفصلهما عن بعضهما لفتحه.
</p>

<p>
	أولًا، جهّز سلكي توصيل الأول ذو نهايات من نوع دبوس-مقبس، والثاني ذو نهايات من نوع مقبس-مقبس، وذلك لتحضير مبدّل بسيط، واختر للسلك اللون الذي تفضله.
</p>

<p style="text-align: center;">
	<img alt="الخطزة 1 من عملية إضافة مبدل switch" class="ipsImage ipsImage_thumbnailed" data-fileid="116009" data-ratio="75.00" data-unique="s0d8a6xdm" style="width: 500px; height: auto;" width="550" src="https://academy.hsoub.com/uploads/monthly_2023_01/jumper-wires.jpg.c8fbe3880f02aee96f1ed2151883a70e.jpg">
</p>

<p>
	ثانيًا، صل أحد السلكين مع الرجل <strong>GP18</strong> والآخر مع رجل التأريض <strong>GND</strong>، لا يهم أيُّ السلكين وصلت مع أيّ رجل.
</p>

<p style="text-align: center;">
	<img alt="الخطوة 2 من عملية إضافة مبدل switch" class="ipsImage ipsImage_thumbnailed" data-fileid="116029" data-ratio="108.67" data-unique="x5ghdxg1s" style="width: 450px; height: auto;" width="450" src="https://academy.hsoub.com/uploads/monthly_2023_01/switch-wiring-diagram.png.b0a7bfa365f00d0665e07d4cb90d2be1.png">
</p>

<p>
	ثالثًا، أضف عنصر المبدّل <code>Switch</code> من مكتبة <code>picozero</code> بإضافة <code>Switch ,</code> في نهاية السطر الأول من الشيفرة. ثم أسند المبدّل إلى الرجل <strong>GP18</strong>:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_972_106" style=""><span class="kwd">from</span><span class="pln"> picozero </span><span class="kwd">import</span><span class="pln"> pico_led</span><span class="pun">,</span><span class="pln"> LED</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Switch</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> time </span><span class="kwd">import</span><span class="pln"> sleep 

pico_led</span><span class="pun">.</span><span class="pln">on</span><span class="pun">()</span><span class="pln"> 
sleep</span><span class="pun">(</span><span class="lit">1</span><span class="pun">)</span><span class="pln"> 
pico_led</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln"> 

firefly </span><span class="pun">=</span><span class="pln"> LED</span><span class="pun">(</span><span class="lit">13</span><span class="pun">)</span><span class="pln">         </span><span class="com"># استخدم الرجل ذات الرقم 13</span><span class="pln">
</span><span class="typ">Switch</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Switch</span><span class="pln"> </span><span class="pun">(</span><span class="lit">18</span><span class="pun">)</span><span class="pln">   </span><span class="com"># استخدم الرجل ذات الرقم 18</span></pre>

<p>
	تستشعر لوحة بيكو عناصر الدخل عند توصيلها مع رجل الأرضية GND وإحدى أرجل الأغراض العامة GP.
</p>

<p>
	عند توصيل سلكي التوصيل ببعضهما، تكتمل الدارة ويمر التيار الكهربائي، فتستشعر لوحة بيكو أن المُبدّل قد أُغلق.
</p>

<p>
	رابعًا، أضف الأسطر التالية على برنامجك للتحقق من حالة المبدّل باستخدام التابع <code>if</code> وتشغيل الليد فقط إذا كان المبدّل مغلقًا (أي أن السلكين موصولين ببعضهما):
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_972_108" style=""><span class="typ">Switch</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Switch</span><span class="pln"> </span><span class="pun">(</span><span class="lit">18</span><span class="pun">)</span><span class="pln">   </span><span class="com"># استخدم الرجل ذات الرقم 18</span><span class="pln">

</span><span class="kwd">while</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">:</span><span class="pln">
    </span><span class="kwd">if</span><span class="pln"> switch</span><span class="pun">.</span><span class="pln">is_closed</span><span class="pun">:</span><span class="pln">         </span><span class="com"># السلكان متصلان ببعضهما  </span><span class="pln">
        firefly</span><span class="pun">.</span><span class="pln">on</span><span class="pun">()</span><span class="pln">
        sleep</span><span class="pun">(</span><span class="lit">0.5</span><span class="pun">)</span><span class="pln">          </span><span class="com"># شَغّل المصباح مدة نصف ثانية</span><span class="pln">
        firefly</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln">
        sleep</span><span class="pun">(</span><span class="lit">2.5</span><span class="pun">)</span><span class="pln">            </span><span class="com">#أطفئ المصباح مدة ثانيتين ونصف</span><span class="pln">
    </span><span class="kwd">else</span><span class="pun">:</span><span class="pln">       </span><span class="com"># السلكان غير متصلان</span><span class="pln">
        firefly</span><span class="pun">.</span><span class="pln">off</span><span class="pun">()</span><span class="pln">
        sleep</span><span class="pun">(</span><span class="lit">0.1</span><span class="pun">)</span><span class="pln">              </span><span class="com"># تأخير بسيط لمدة 0.1 ثانية</span></pre>

<p>
	خامسًا، شَغّل الشيفرة بدون توصيل السلكين ولاحظ ما الذي سيحدث؟ ستنفذ شيفرة حالة الفصل <code>else</code> أي أن المصباح لن يضيء.
</p>

<p>
	سادسًا، صِل السلكين وراقب ما الذي سيحدث؟ يجب أن يومض المصباح.
</p>

<p style="text-align: center;">
	<img alt="الخطوة 6 من عملية إضافة مبدل switch" class="ipsImage ipsImage_thumbnailed" data-fileid="116005" data-ratio="73.60" data-unique="rc9q4p37j" style="width: 500px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/firefly-switch.gif.4d52811d75295403449754d2f97c967e.gif">
</p>

<p>
	افصل السلكين عن بعضهما ولاحظ أن المصباح سينطفئ، لكن فصل السلكين لن يقطع التغذية الكهربائية عن المصباح، إذ يتوقف المصباح عن العمل فقط عند تشغيل السطر <code>firefly.off()‎</code>.
</p>

<p>
	يمكنك تنفيذ المشروع مع أصدقائك، ومزامنة عمل المصابيح عن طريقة توصيل الأسلاك في نفس الوقت.
</p>

<h2>
	ترقية المشروع
</h2>

<p>
	بإمكانك ترقية المشروع حين يتسنى لك ذلك، واستخدامه لتزيين غرفتك وإضفاء لمسةٍ تذكرك بالطبيعة.
</p>

<p>
	<strong>معلومة:</strong> يُعد قضاء الوقت في أحضان الطبيعة أمرًا مفيدًا للصحة ومحفزًا على توليد المشاعر الإيجابية، لكن حين لا يكون ذلك متاحًا لك، يمكنك وضع نبتةً ما في منزلك، أو محاكاة الطبيعة بمشروع مثل مشروعنا.
</p>

<p>
	إليك بعض المقترحات لترقية مشروعك:
</p>

<ul>
	<li>
		إضافة مصباح ليد آخر وجعله يضيء وفق نفس النمط.
	</li>
	<li>
		تغيير نمط وميض المصباح، بالبحث عن أنماط وميض اليراعات في الطبيعة.
	</li>
	<li>
		وضع المصباح في إناء زجاجي لتزيين غرفتك، كما في الصورة التالية:
	</li>
</ul>

<p style="text-align: center;">
	<img alt="ترقية المشروع " class="ipsImage ipsImage_thumbnailed" data-fileid="116003" data-ratio="104.60" data-unique="9b6js0mea" style="width: 500px; height: auto;" width="500" src="https://academy.hsoub.com/uploads/monthly_2023_01/firefly-jar.thumb.gif.82f0aecf2196c4b22b7bd4659e022778.gif">
</p>

<p>
	كما يمكنك الاطلاع على الشيفرة النهائية للمشروع ومف المشروع من <a data-fileext="zip" data-fileid="116046" href="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=116046&amp;key=9d537afe43b59929557dbaaaabcb32f0" rel="">ملف Thonny</a>.
</p>

<h2>
	خاتمة
</h2>

<p>
	تهانينا، فقد أتممت مشروع استخدام حاسوب راسبيري باي بيكو للحصول على مصباح ليد يومض وفق نمط معين.
</p>

<p>
	ننصحك بتنفيذ مشروع تصميم محاكاة لمفرقعات الحفلات باستخدام لوحة راسبيري باي بيكو في خطوتك التالية، وإذا واجهت مشاكلًا عند تنفيذ هذا المشروع فيمكنك الحصول على الدعم والمساعدة عن طريق إضافة سؤالك في قسم الأسئلة والأجوبة في <a href="https://academy.hsoub.com/questions/" rel="">أكاديمية حسوب</a>.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://projects.raspberrypi.org/en/projects/led-firefly/" rel="external nofollow">LED Firefly</a> من <a href="https://raspberrypi.org/" rel="external nofollow">الموقع الرسمي لراسبيري باي</a>.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D9%85%D8%B5%D8%A8%D8%A7%D8%AD-%D9%84%D9%8A%D8%AF-%D8%AB%D9%84%D8%A7%D8%AB%D9%8A-%D8%A7%D9%84%D8%A3%D8%A8%D8%B9%D8%A7%D8%AF-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%B3%D9%83%D8%B1%D8%A7%D8%AA%D8%B4-%D9%88%D9%84%D9%88%D8%AD%D8%A9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-r1504/" rel="">تنفيذ مصباح ليد ثلاثي الأبعاد باستخدام سكراتش ولوحة راسبيري باي</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%AC%D9%85%D9%8A%D8%B9-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D9%88%D8%A7%D9%84%D8%AA%D8%AD%D8%B6%D9%8A%D8%B1-%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%85%D8%A7%D9%84%D9%87-r1370/" rel="">تجميع راسبيري باي والتحضير لاستعماله</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%B1%D8%A8%D8%B7-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%A8%D8%B9%D9%86%D8%A7%D8%B5%D8%B1-%D8%A5%D9%84%D9%83%D8%AA%D8%B1%D9%88%D9%86%D9%8A%D8%A9-%D9%88%D8%A8%D8%B1%D9%85%D8%AC%D8%AA%D9%87%D8%A7-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%B3%D9%83%D8%B1%D8%A7%D8%AA%D8%B4-%D9%88%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-r1496/" rel="">ربط راسبيري باي بعناصر إلكترونية وبرمجتها باستخدام سكراتش وبايثون</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1848</guid><pubDate>Thu, 05 Jan 2023 16:04:00 +0000</pubDate></item><item><title>&#x62A;&#x62D;&#x631;&#x64A;&#x643; &#x634;&#x62E;&#x635;&#x64A;&#x629; &#x643;&#x631;&#x62A;&#x648;&#x646;&#x64A;&#x629; &#x639;&#x628;&#x631; &#x633;&#x643;&#x631;&#x627;&#x62A;&#x634; &#x641;&#x64A; &#x631;&#x627;&#x633;&#x628;&#x631;&#x64A; &#x628;&#x627;&#x64A;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%AD%D8%B1%D9%8A%D9%83-%D8%B4%D8%AE%D8%B5%D9%8A%D8%A9-%D9%83%D8%B1%D8%AA%D9%88%D9%86%D9%8A%D8%A9-%D8%B9%D8%A8%D8%B1-%D8%B3%D9%83%D8%B1%D8%A7%D8%AA%D8%B4-%D9%81%D9%8A-%D8%B1%D8%A7%D8%B3%D8%A8%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-r2082/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2023_08/----.png.4261caf39f66d7e796af619a6ddf2b3a.png" /></p>
<p>
	بعد أن تعرفنا على أهمية سكراتش يأتي هذا الدرس ليكمل التعرف على لغة برمجة سكراتش Scratch، إذ سنشرح كيفية عمل خوارزمية بسيطة باستخدام هذه اللغة، وسنستفيد من هذه الخوارزمية في تحريك شخصية كرتونية مسافة سنحددها نحن. ستتعلم أيضًا كيفية استخدام الحلقات والأوامر والشروط في لغة سكراتش وذلك باستخدام حاسوب راسبيري باي Raspberry Pi.
</p>

<p>
	<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" frameborder="0" height="603" id="ips_uid_8876_5" src="https://academy.hsoub.com/applications/core/interface/index.html" title="تحريك شخصية كرتونية عبر سكراتش في راسبري باي" width="1072" data-embed-src="https://www.youtube.com/embed/Tz4KAxw4WRA"></iframe>
</p>

<p>
	تعرف أكثر على أنظمة التشغيل و سكراتش في <a href="https://academy.hsoub.com/learn/computer-science/" rel="">دورة علوم الحاسوب المقدمة من أكاديمية حسوب</a>، ولا تنسَ الاستعانة خلال رحلة تعلمك وعملك بتوثيقات <a href="https://wiki.hsoub.com/%D8%A7%D9%84%D8%B5%D9%81%D8%AD%D8%A9_%D8%A7%D9%84%D8%B1%D8%A6%D9%8A%D8%B3%D9%8A%D8%A9" rel="external">موسوعة حسوب</a> المجانية. وإذا أردت متابعة المعلومات البرمجية العلمية مكتوبة فيمكنك الاطلاع على <a href="https://academy.hsoub.com/programming/" rel="">قسم البرمجة</a>، كما يمكنك متابعة جديد الفيديوهات التقنية المتاحة على <a href="https://www.youtube.com/@HsoubAcademy" rel="external nofollow">يوتيوب أكاديمية حسوب</a> مجانًا.
</p>
]]></description><guid isPermaLink="false">2082</guid><pubDate>Fri, 09 Dec 2022 15:00:00 +0000</pubDate></item><item><title>&#x645;&#x627; &#x647;&#x64A; &#x644;&#x648;&#x62D;&#x629; &#x623;&#x631;&#x62F;&#x648;&#x64A;&#x646;&#x648; Arduino&#x61F;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D9%85%D8%A7-%D9%87%D9%8A-%D9%84%D9%88%D8%AD%D8%A9-%D8%A3%D8%B1%D8%AF%D9%88%D9%8A%D9%86%D9%88-arduino%D8%9F-r1800/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2022_11/Arduino.png.1f89a5d341411999fd02c17b05c3bfaf.png" /></p>

<p>
	أردوينو Arduino عبارة عن لوحة إلكترونية مُصغَّرة قابلة للبرمجة مطورة على مبدأ العتاد <a href="https://academy.hsoub.com/programming/general/%D9%85%D8%A7-%D8%A7%D9%84%D9%85%D9%82%D8%B5%D9%88%D8%AF-%D8%A8%D9%85%D8%B5%D8%B7%D9%84%D8%AD-%D9%85%D9%81%D8%AA%D9%88%D8%AD-%D8%A7%D9%84%D9%85%D8%B5%D8%AF%D8%B1-open-source%D8%9F-r885/" rel="">مفتوح المصدر open hardware</a> وهو العتاد الذي يتيح الاطلاع على العناصر المكون منها وفحصها وتعديلها وتطويرها ثم إعادة توزيعها مرة أخرى، أي الأمر مشابه تمامًا للبرمجيات مفتوحة المصدر ولكن مع العتاد.
</p>

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

<h2>
	استخدامات لوحة أردوينو
</h2>

<p>
	تستخدم لوحة أردوينو في بناء المشاريع الإلكترونية بمختلف مستوياتها سواءً المشاريع الإلكترونية البسيطة مثل مقياس حراري أو مقياس رطوبة وعرض النتائج على شاشة بسيطة وحتى المشاريع المعقدة مثل الروبوتات والسيارات المتحركة الذكية وحتى أجهزة <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D9%81%D9%8A-%D8%A5%D9%86%D8%AA%D8%B1%D9%86%D8%AA-%D8%A7%D9%84%D8%A3%D8%B4%D9%8A%D8%A7%D8%A1-iot-r1514/" rel="">إنترنت الأشياء IoT</a> وإدارة المنازل الذكية.
</p>

<p style="text-align: center;">
	<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="450" title="YouTube video player" width="800" src="https://www.youtube.com/embed/lFdaJPl249g"></iframe>
</p>

<p>
	الغرض الأساسي من لوحة أردوينو هو تسهيل وصل العناصر الإلكترونية مع بعضها وبرمجتها لتؤدي الغرض المطلوب دون الحاجة إلى خبرة مسبقة بمجال الكهرباء والإلكترونيات وحتى بمجال البرمجة، ويمكن بذلك لأعمار صغيرة -وهي أهم فئة مستهدفة- استخدام اللوحة وتعلم برمجتها بسهولة تبدأ من عمر 8 سنوات وما فوق.
</p>

<h2>
	مكونات لوحة أردوينو
</h2>

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

<h3>
	مقابس pins
</h3>

<p>
	تُستخدم للاتصال مع المكونات المختلفة التي قد ترتبط مع اللوحة، وتأتي هذه المقابس في نوعين:
</p>

<ul>
<li>
		مقابس رقمية Digital: يمكنها قراءة وكتابة حالة واحدة أي إشارة أو لا إشارة أو المكون يعمل أو لا يعمل on/off، وتحتوي معظم اللوحات على 14 مقبس إدخال/إخراج رقمي.
	</li>
	<li>
		المقابس التشابهية Analog: يمكنها قراءة مجموعة من القيم وهي مفيدة لتحكم دقيق بالأجهزة والعناصر الإلكترونية وتحتوي معظم اللوحات على ستة منها.
	</li>
</ul>
<p>
	تُرتب هذه المقابس بنمط معين ليسل تركيب أي لوحة إضافية عليها وتسمى عادةً تلك اللوحات الإضافية "الدرع shield".
</p>

<h3>
	موصل طاقة power connector
</h3>

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

<h3>
	متحكم صغري microcontroller
</h3>

<p>
	هو الشريحة الأساسية التي تسمح لك ببرمجة لوحة أردوينو Arduino حتى تتمكن من تنفيذ الأوامر واتخاذ القرارات بناءً على المدخلات المختلفة.
</p>

<p>
	يختلف المتحكم الصغري أو المتحكم الدقيق اعتمادًا على نوع لوحة أردوينو وإصدارها المُستخدم، لكنها تكون عمومًا متحكمات من نوع أتميل Atmel وعادةً ما تكون ATmega8 أو ATmega168 أو ATmega328 أو ATmega1280 أو ATmega2560 والتي تختلف عن بعضها بحجم الذاكرة المدمجة.
</p>

<h3>
	موصل تسلسلي serial connector
</h3>

<p>
	يكون هنالك موصل تسلسلي وهو في معظم اللوحات الحديثة منفذ يو إس بي USB معياري، ويتيح هذا الموصل الاتصال باللوحة عبر جهاز حاسوب والتواصل معها بتحميل برامج جديدة عليها وبرمجتها وغيرها من الإجراءات، كما يمكن تشغيل لوحة أردوينو من خلال منفذ USB مما يلغي الحاجة إلى موصل طاقة منفصل.
</p>

<h3>
	عناصر إلكترونية إضافية
</h3>

<p>
	تختلف العناصر الإلكترونية المضافة على اللوحة باختلاف إصدارها منها مولد الذبذبات oscillator ومنظم الجهد وغيرها التي توفر إمكانات مهمة للوحة ولكن لا يتعامل معها المستخدم بشكل مباشر.
</p>

<h2>
	كيفية برمجة لوحة أردوينو
</h2>

<p>
	يبدأ المستخدم الجديد عادة باستخدام بيئة التطوير المتكاملة الرسمية لأردوينو Arduino IDE وهو برنامج مفتوح المصدر مكتوب <a href="https://academy.hsoub.com/programming/java/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-%D8%A8%D9%84%D8%BA%D8%A9-java-%D9%85%D8%A7-%D9%87%D9%8A-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9%D8%9F-r371/" rel="">بلغة Java</a> ويعمل على مجموعة متنوعة من الأنظمة الأساسية مثل ويندوز Windows وماك Mac و<a href="https://academy.hsoub.com/devops/linux/%D9%85%D8%A7-%D9%87%D9%88-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%8A%D9%86%D9%83%D8%B3%D8%9F-r451/" rel="">لينكس Linux</a>.
</p>

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

<p>
	اللغة المستعملة في برمجة أردوينو هي <a href="https://wiki.hsoub.com/Arduino" rel="external">لغة أردوينو</a> وهي مجرد مجموعة من دوال ++C/C أي مشتقة بشكل رئيسي من لغة C و ++C ومن إطار العمل وايرينغ Wiring الذي يعتمد على لغة البرمجة Processing.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="112538" href="https://academy.hsoub.com/uploads/monthly_2022_11/6378aab56d5e9_IDE.PNG.d4d856ebc80cacebf7c74792f2a91d23.PNG" rel=""><img alt="كيفية برمجة لوحة أردوينو" class="ipsImage ipsImage_thumbnailed" data-fileid="112538" data-unique="mohmp1huw" src="https://academy.hsoub.com/uploads/monthly_2022_11/6378aab77f139_IDE.thumb.PNG.4f0ab9710c7eea2dc20ea13b9302b295.PNG" style="width: 650px; height: auto;"></a>
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://opensource.com/resources/what-arduino" rel="external nofollow">What is an Arduino?‎</a>.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
<li>
		<a href="https://wiki.hsoub.com/Arduino/arduinoide" rel="external">تثبيت أردوينو IDE ورفع الشيفرات على لوحة أردوينو</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D9%85%D8%A7-%D9%87%D9%88-%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-%D8%B1%D8%A7%D8%B3%D8%A8%D9%8A%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-raspberry-pi%D8%9F-r1578/" rel="">ما هو حاسوب راسبيري باي Raspberry Pi؟</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1800</guid><pubDate>Tue, 06 Dec 2022 16:08:05 +0000</pubDate></item><item><title>&#x623;&#x647;&#x645; &#x627;&#x644;&#x645;&#x641;&#x627;&#x647;&#x64A;&#x645; &#x627;&#x644;&#x62A;&#x64A; &#x62A;&#x646;&#x638;&#x645; &#x627;&#x644;&#x639;&#x645;&#x644;&#x64A;&#x627;&#x62A; &#x648;&#x62A;&#x639;&#x627;&#x644;&#x62C;&#x647;&#x627; &#x641;&#x64A; &#x645;&#x639;&#x645;&#x627;&#x631;&#x64A;&#x629; &#x627;&#x644;&#x62D;&#x627;&#x633;&#x648;&#x628; &#x627;&#x644;&#x62D;&#x62F;&#x64A;&#x62B;&#x629;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D8%A3%D9%87%D9%85-%D8%A7%D9%84%D9%85%D9%81%D8%A7%D9%87%D9%8A%D9%85-%D8%A7%D9%84%D8%AA%D9%8A-%D8%AA%D9%86%D8%B8%D9%85-%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA-%D9%88%D8%AA%D8%B9%D8%A7%D9%84%D8%AC%D9%87%D8%A7-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-%D8%A7%D9%84%D8%AD%D8%AF%D9%8A%D8%AB%D8%A9-r1760/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2022_11/63611264ee618_------------(1).png.67b040473163e289a6407e70749c2685.png" /></p>
<p>
	سنتعرّف في هذا المقال على ثلاثة من أهم المفاهيم التي تنظم العمليات وتعالجها في معمارية الحواسيب الحديثة وهي الجدولة Scheduling والصدَفة Shell والإشارات Signals.
</p>

<h2>
	الجدولة Scheduling
</h2>

<p>
	يحتوي النظام المُشغَّل على مئات أو حتى أُلوف العمليات، ويُطلَق على جزء النواة Kernel الذي يتعقّب جميع هذه العمليات اسم المجدوِل Scheduler لأنه يجدول أيّ عملية يجب تشغيلها لاحقًا.
</p>

<p>
	تُعَدّ <a href="https://academy.hsoub.com/programming/advanced/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%A7%D9%84%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A7%D8%AA-r1282/" rel="">خوارزميات</a> الجدولة كثيرةً ومتنوعةً، إذ يكون لمعظم المستخدِمين أهداف مختلفة تتعلق بما يريدون تنفيذه من حواسيبهم، وهذا يؤثّر على قرارات الجدولة، فأنت تريد مثلًا التأكد من منح التطبيقات الرسومية في حاسوبك المكتبي متسعًا من الوقت للتشغيل حتى إذا استغرقت عمليات النظام وقتًا أطول قليلًا، مما سيؤدي إلى زيادة الاستجابة التي يشعر بها المستخدِم، وبالتالي سيكون لأفعالهم استجابات فورية، في حين يمكن أن ترغب في إعطاء الأولوية لتطبيق <a href="https://academy.hsoub.com/devops/servers/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%AE%D8%A7%D8%AF%D9%85-%D8%A7%D9%84%D9%88%D9%8A%D8%A8-r574/" rel="">خادم الويب</a> إذا عملتَ على خادم.
</p>

<p>
	ينشئ الناس دائمًا خوارزميات جديدةً، كما يمكنك إنشاء خوارزمياتك الخاصة بسهولة إلى حد ما، ولكن هناك عدد من المكونات المختلفة للجدولة.
</p>

<h3>
	الجدولة ذات الأولوية Preemptive والجدولة التعاونية Co-operative
</h3>

<p>
	يمكن أن تنقسم استراتيجيات الجدولة إلى فئتين:
</p>

<ol>
	<li>
		الجدولة التعاونية Co-operative Scheduling: هي المكان الذي تتخلى فيه العملية المُشغَّلة حاليًا طواعيةً عن التنفيذ للسماح بتشغيل عملية أخرى، والعيب في هذه الاستراتيجية هو أنّ العملية يمكنها اتخاذ قرار بعدم التخلي عن التنفيذ بسبب خطأ تسبَّب في شكل من أشكال الحلقة اللانهائية مثلًا، وبالتالي لا يمكن تشغيل أيّ شيء آخر.
	</li>
	<li>
		الجدولة الاستباقية Preemptive Scheduling: هي المكان الذي تُقاطَع فيه العملية لإيقافها للسماح بتشغيل عملية أخرى، إذ تحصل كل عملية على شريحة زمنية Time-slice لتعمل فيها، كما سيُعاد ضبط عدّاد الوقت عند كل عملية تبديل سياق Context Switching وستُشغَّل العملية ثم تُقاطَع عند انتهاء الشريحة الزمنية، فتبديل السياق Context Switching هو العملية التي تطبّقها النواة للتبديل من عملية إلى أخرى، في حين يتعامل العتاد مع المقاطعة على أنها مستقلة عن العملية المُشغَّلة، وبالتالي سيعود التحكم إلى نظام التشغيل عند حدوث المقاطعة، كما يمكن أن يقرِّر المجدوِل العملية التالية التي ستُشغَّل، وهذا هو نوع الجدولة الذي تستخدمه جميع أنظمة التشغيل الحديثة.
	</li>
</ol>

<h3>
	الوقت الفعلي Realtime
</h3>

<p>
	تحتاج بعض العمليات إلى معرفة المدة التي ستستغرقها شريحتها الزمنية والمدة التي المُستغرَقة قبل أن تحصل على شريحة زمنية أخرى لتعمل، ولنفترض أنه لديك نظامًا يشغّل جهاز القلب والرئتين، إذ لا تريد أن تتأخر النبضة التالية لأنّ شيئًا آخر قرّر العمل في النظام.
</p>

<p>
	تقدّم أنظمة الوقت الفعلي الصارمة Hard Realtime ضمانات حول جدولة القرارات مثل الحد الأقصى لمقدار الوقت الذي ستُقاطَع فيه العملية قبل تشغيلها مرةً أخرى، إذ تُستخدَم غالبًا في التطبيقات الحرجة مثل التطبيقات الطبية والعسكرية وتطبيقات الطائرات، في حين لا تكون الضمانات في أنظمة الوقت الفعلي غير الصارمة Soft Realtime صارمةً ولكن يمكن التنبؤ بسلوك النظام العام.
</p>

<p>
	يمكن استخدام <a href="https://academy.hsoub.com/devops/linux/%D9%85%D8%A7-%D9%87%D9%88-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%8A%D9%86%D9%83%D8%B3%D8%9F-r451/" rel="">نظام لينكس</a> على أساس نظام وقت فعلي غير صارم، إذ يُستخدَم في الأنظمة التي تتعامل مع الصوت والفيديو، وإذا أردتَ تسجيل بث صوتي، فلا بد أنك لا تريد مقاطعتك لفترات طويلة من الوقت لأنك ستفقد البيانات الصوتية التي لا يمكن استرجاعها.
</p>

<h3>
	القيمة اللطيفة
</h3>

<p>
	تسنِد أنظمة يونيكس لكل عملية قيمةً لطيفة Nice Value، إذ ينظر المجدوِل إلى هذه القيمة ويمكن أن يعطي الأولوية لتلك العمليات التي تتمتع بأعلى قيمة لطيفة.
</p>

<h3>
	مجدول لينكس
</h3>

<p>
	خضع مجدول لينكس ولا يزال يخضع للعديد من التغييرات، إذ يحاول المطورون الجدد تحسين سلوكه، ويُعرَف المجدول الحالي باسم المجدول O(1)‎ الذي يشير إلى الخاصية التي تمثل أنّ المجدول سيختار العملية التالية لتشغيلها في فترة زمنية ثابتة بغض النظر عن عدد العمليات التي يجب عليه الاختيار من بينها.
</p>

<p>
	تُعَدّ <a href="https://academy.hsoub.com/programming/advanced/%D8%AA%D8%B1%D9%85%D9%8A%D8%B2-big-o-%D9%81%D9%8A-%D8%A7%D9%84%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A7%D8%AA-r1290/" rel="">صيغة Big-O</a> طريقةً لوصف الوقت الذي تستغرقه الخوارزمية للتشغيل بالنظر إلى الدخل المتزايد، فإذا استغرقت الخوارزمية ضعف الوقت للتشغيل مع ضعف الدخل، فهذا يؤدي إلى التزايد خطيًا، وإذا استغرقت خوارزمية أخرى أربعة أضعاف الوقت للتشغيل مع ضعف الدخل، فهذا يؤدي إلى تزايد أسي؛ أما إذا استغرق الأمر الوقت نفسه مهما كان مقدار الدخل، فستُشغَّل الخوارزمية في وقت ثابت، ويمكنك رؤية أنه كلما كانت الخوارزمية تنمو بصورة أبطأ مع مزيد من الدخل، كان ذلك أفضل.
</p>

<p>
	استخدمت مجدولات لينكس السابقة مفهوم الجودة Goodness لتحديد العملية التالية لتشغيلها، إذ يُحتفَظ بجميع المهام المُحتمَلة في رتل تشغيل Run Queue، وهو قائمة مترابطة من العمليات التي تعرِف النواة أنها في حالة قابلية للتشغيل، أي لا تنتظر نشاطًا من القرص الصلب أو ليست في حالة سكون.
</p>

<p>
	تبرز مشكلة أنه يجب حساب مدى جودة كل عملية قابلة للتشغيل بحيث تفوز العملية التي تتمتع بأعلى جودة لتكون العملية التالية التي يجب تشغيلها، إذ سيستغرق الأمر وقتًا أطول بكثير لمزيد من المهام لتحديد العمليات التالية التي ستشغَّل.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="111021" href="https://academy.hsoub.com/uploads/monthly_2022_11/01_o1queue.png.777e9bbb14ebd8a74c94454210414acb.png" rel=""><img alt="شكل المجدول O(1)‎" class="ipsImage ipsImage_thumbnailed" data-fileid="111021" data-unique="vtbvdhq7z" style="width: 466px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2022_11/01_o1queue.png.777e9bbb14ebd8a74c94454210414acb.png"></a>
</p>

<p style="text-align: center;">
	المجدول O(1)‎
</p>

<p>
	يستخدِم المجدول O(1)‎ بنية رتل التشغيل الموضح في الشكل السابق، كما يحتوي رتل التشغيل على عدد من الحزم Buckets مرتبةً حسب الأولوية وخارطة نقطية Bitmap تشير إلى الحزم التي تحتوي على عمليات متاحة، إذ يُعَدّ البحث عن العملية التالية لتشغيلها بمثابة قراءة الخارطة النقطية للعثور على حزمة العمليات الأولى، ثم اختيار العملية الأولى من رتل الحزم.
</p>

<p>
	يحتفظ المجدول ببنيتَين هما مصفوفة العمليات النشطة Active التي يمكن تشغيلها ومصفوفة العمليات منتهية الصلاحية Expired التي استخدمت شريحتها الزمنية بالكامل، كما يمكن تبديل هاتين البنيتَين ببساطة من خلال تعديل المؤشرات عندما يكون لجميع العمليات بعض الوقت من <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%88%D8%AD%D8%AF%D8%A9-%D8%A7%D9%84%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D9%85%D8%B1%D9%83%D8%B2%D9%8A%D8%A9-%D9%88%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA%D9%87%D8%A7-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1716/" rel="">وحدة المعالجة المركزية</a>.
</p>

<p>
	لكن الجزء المهم هو كيفية تحديد المكان الذي يجب أن تذهب إليه العملية في رتل التشغيل، فمن الأشياء التي يجب أخذها في الحسبان هو المستوى اللطيف Nice Level، وتقارب المعالج Processor Affinity أو الحفاظ على العمليات مرتبطة بالمعالج الذي تُشغَّل عليه لأن نقل العملية إلى وحدة معالجة مركزية أخرى في نظام SMP يمكن أن يكون عمليةً مكلفةً، بالإضافة إلى دعم أفضل لتحديد البرامج التفاعلية مثل تطبيقات واجهة المستخدم الرسومية التي يمكن أن تقضي الكثير من الوقت في حالة سكون في انتظار الدخل من المستخدِم، ولكن يريد المستخدِم استجابةً سريعةً عندما يتفاعل معها.
</p>

<h2>
	الصدفة Shell
</h2>

<p>
	تُعَدّ الصدَفة في نظام يونيكس الواجهة المعيارية لمعالجة العمليات على نظامك، ولكن تحتوي أنظمة لينكس الحديثة على واجهة مستخدِم رسومية وتوفّر صدفةً عبر تطبيق طرفية Terminal أو ما شابه ذلك، كما تتمثل مهمة الصدَفة الأساسية في مساعدة المستخدِم على التعامل مع بدء العمليات المُشغَّلة في النظام وإيقافها والتحكم فيها.
</p>

<p>
	إذا كتبتَ أمرًا في موجّه أوامر الصدفة، فسيؤدي ذلك إلى تطبيق الاستدعاء <code>fork</code> على نسخة منه وتطبيق الاستدعاء <code>exec</code> على الأمر الذي حددته، ثم تنتظِر الصدَفة بعد ذلك افتراضيًا حتى ينتهي تشغيل هذه العملية قبل العودة إلى موجّه الأوامر لبدء العملية بأكملها مرةً أخرى.
</p>

<p>
	كما تسمح لك الصدَفة بتشغيل وظيفة ما في الخلفية Background من خلال وضع <code>&amp;</code> بعد اسم الأمر للإشارة إلى وجوب تفرع الصدَفة وتنفيذ الأمر دون الانتظار حتى يكتمل الأمر قبل أن تُظهِر لك موجّه الأوامر مرةً أخرى، في حين تعمل العملية الجديدة في الخلفية مع جهوزية الصدَفة في انتظار بدء عملية جديدة إذا رغبت في ذلك، لكن يمكنك إخبار الصدَفة بتنفيذ عملية ما في الأمام Foreground، مما يعني أننا نريد انتظار انتهاء العملية فعلًا.
</p>

<h2>
	الإشارات Signals
</h2>

<p>
	تتطلب العمليات المُشغَّلة في النظام طريقةً لإخبارنا بالأحداث التي تؤثر عليها، إذ توجد بنية تحتية في نظام يونيكس بين النواة Kernel والعمليات تسمّى الإشارات Signals التي تسمح للعملية بتلقي إشعار بالأحداث المهمة بالنسبة لها.
</p>

<p>
	تستدعي النواة معالِجًا Handler يجب أن تسجّله العملية مع النواة للتعامل مع الإشارة المُرسَلة إلى عملية ما، والمعالج هو دالة مصمّمة في الشيفرة البرمجية التي كُتِبت لمعالجة المقاطعة، كما تُرسَل الإشارة في أغلب الأحيان من النواة نفسها، ولكن يمكن أن ترسِل إحدى العمليات إشارةً إلى عملية أخرى، وهذا يمثِّل أحد أشكال التواصل بين العمليات Interprocess Communication.
</p>

<p>
	يُستدعَى معالج الإشارة بصورة غير متزامنة، إذ يُقاطَع البرنامج المشغَّل حاليًا عمّا يفعله لمعالجة حدث الإشارة، كما تُعَدّ المقاطعة أحد أنواع الإشارات التي تُحدَّد في ترويسات النظام بالاسم <code>SIGINT</code>، إذ تُسلَّم إلى العملية عند الضغط على الاختصار <code>ctrl-c</code>.
</p>

<p>
	تستخدِم العملية استدعاء نظام <code>read</code> لقراءة الدخل من لوحة المفاتيح، إذ ستراقب النواة مجرى الدخل بحثًا عن محارف خاصة، لكن ستنتقل إلى وضع معالجة الإشارة في حالة ظهور الاختصار <code>ctrl-c</code>، وستبحث النواة لمعرفة ما إذا سجّلت العملية معالجًا لهذه المقاطعة، فإذا كان الأمر كذلك، فسيُمرَّر التنفيذ إلى تلك الدالة التي ستعالج المقاطعة، وإذا لم تسجّل العملية معالجًا لهذه الإشارة، فستتخذ النواة بعض الإجراءات الافتراضية، ويكون الإجراء الافتراضي هو إنهاء العملية باستخدام <code>ctrl-c</code>.
</p>

<p>
	يمكن أن تختار العملية تجاهل بعض الإشارات ولكن لا تسمح بتجاهل الإشارات الأخرى، فالإشارة <code>SIGKILL</code> مثلًا هي الإشارة المرسَلة عندما يجب إنهاء العملية، حيث سترى النواة أن العملية أرسلت هذه الإشارة وتنهي تشغيل العملية دون طرح أيّ أسئلة، كما لا يمكن للعملية الطلب من النواة تجاهل هذه الإشارة، إذ تكون النواة حريصةً للغاية بشأن العملية المسموح لها بإرسال هذه الإشارة إلى عملية أخرى، فلا يجوز لك إرسالها إلا إلى العمليات التي تمتلكها إلا إذا كنت المستخدِم الجذر.
</p>

<p>
	لا بد أنك رأيت الأمر <code>kill -9</code> الذي يأتي من تطبيق الإشارة <code>SIGKILL</code>، إذ تُعرَّف الإشارة <code>SIGKILL</code> على أنها <code>0x9</code>، لذا ستتوقف العملية المحددة مباشرةً عند تحديدها على أساس وسيط لبرنامج <code>kill</code>، ونظرًا لأنه لا يمكن للعملية اختيار تجاهل هذه الإشارة أو معالجتها، فسيُنظَر إلى هذه الإشارة على أنها الملاذ الأخير، إذ لن يكون لدى البرنامج فرصةً للتنظيف أو الإنهاء بصورة نظيفة.
</p>

<p>
	يُفضَّل إرسال الإشارة <code>SIGTERM</code> -للإنهاء Terminate- إلى العملية أولًا، فإذا تعطلت أو لم تنتهي، فيمكنك اللجوء إلى الإشارة <code>SIGKILL</code>، كما تثبّت معظم البرامج معالجًا للإشارة <code>SIGHUP</code>، أي تعليق Hangup الطرفيات وأجهزة المودِم التسلسلية، إذ سيعيد هذا المعالج تحميل البرنامج لالتقاط التغييرات في ملف الإعداد أو ما شابه ذلك.
</p>

<p>
	إذا سبق لك وبرمجتَ على نظام يونيكس، فستكون على دراية بأخطاء التقطيع <code>segmentation faults</code> عندما تحاول القراءة أو الكتابة في ذاكرة غير مخصَّصة لك، فإذا لاحظت النواة أنك تحاول الوصول إلى ذاكرة ليست مخصَّصة لك، فسترسل لك إشارة خطأ تقطيع segmentation fault signal، ولن تمتلك العملية معالجًا مثبَّتًا لهذه الإشارة، وبالتالي فإنّ الإجراء الافتراضي هو إنهاء البرنامج وتعطيل برنامجك، كما يمكن أن يثبّت البرنامج معالجًا لأخطاء التقطيع في بعض الحالات المحدودة.
</p>

<p>
	لكن يمكنك التساؤل عمّا يحدث بعد تلقي الإشارة، إذ سيُعاد التحكم إلى العملية التي تستأنف عملها من حيث توقفت بمجرد انتهاء معالج الإشارة من عمله، ويقدّم البرنامج البسيط التالي تشغيل بعض الإشارات:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6629_13" style=""><span class="pln">$ cat signal</span><span class="pun">.</span><span class="pln">c
</span><span class="com">#include</span><span class="pln"> </span><span class="str">&lt;stdio.h&gt;</span><span class="pln">
</span><span class="com">#include</span><span class="pln"> </span><span class="str">&lt;unistd.h&gt;</span><span class="pln">
</span><span class="com">#include</span><span class="pln"> </span><span class="str">&lt;signal.h&gt;</span><span class="pln">

</span><span class="kwd">void</span><span class="pln"> sigint_handler</span><span class="pun">(</span><span class="typ">int</span><span class="pln"> signum</span><span class="pun">)</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
  printf</span><span class="pun">(</span><span class="str">"got SIGINT\n"</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="typ">int</span><span class="pln"> main</span><span class="pun">(</span><span class="kwd">void</span><span class="pun">)</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
  signal</span><span class="pun">(</span><span class="pln">SIGINT</span><span class="pun">,</span><span class="pln"> sigint_handler</span><span class="pun">);</span><span class="pln">
  printf</span><span class="pun">(</span><span class="str">"pid is %d\n"</span><span class="pun">,</span><span class="pln"> getpid</span><span class="pun">());</span><span class="pln">
  </span><span class="kwd">while</span><span class="pln"> </span><span class="pun">(</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
    sleep</span><span class="pun">(</span><span class="lit">1</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
$ gcc </span><span class="pun">-</span><span class="typ">Wall</span><span class="pln"> </span><span class="pun">-</span><span class="pln">o signal signal</span><span class="pun">.</span><span class="pln">c
$ </span><span class="pun">./</span><span class="pln">signal
pid is </span><span class="lit">2859</span><span class="pln">
got SIGINT </span><span class="com"># press ctrl-c </span><span class="pln">
           </span><span class="com"># press ctrl-z</span><span class="pln">
</span><span class="pun">[</span><span class="lit">1</span><span class="pun">]+</span><span class="pln">  </span><span class="typ">Stopped</span><span class="pln">                 </span><span class="pun">./</span><span class="pln">signal

$ kill </span><span class="pun">-</span><span class="pln">SIGINT </span><span class="lit">2859</span><span class="pln">
$ fg
</span><span class="pun">./</span><span class="pln">signal
got SIGINT
</span><span class="typ">Quit</span><span class="pln"> </span><span class="com"># press ctrl-\</span><span class="pln">

$</span></pre>

<p>
	يعرّف البرنامج البسيط السابق معالجًا للإشارة <code>SIGINT</code> التي تُرسَل عندما يضغط المستخدِم على الاختصار <code>ctrl-c</code>، إذ تُعرَّف جميع إشارات النظام في مكتبة <code>signal.h</code> بما في ذلك الدالة <code>signal</code> التي تسمح لنا بتسجيل دالة المعالجة.
</p>

<p>
	يبقى البرنامج ضمن حلقة لا تفعل شيئًا حتى يتوقف، وحاول الضغط على الاختصار <code>ctrl-c</code> عند بدء البرنامج لإنهائه، إذ يُستدعَى المعالج ونحصل على الخرج المتوقَّع بدلًا من اتخاذ الإجراء الافتراضي، ثم نضغط بعد ذلك على الاختصار <code>ctrl-z</code> الذي يرسل الإشارة <code>SIGSTOP</code> التي تضع العملية افتراضيًا في وضع السكون، أي أنها لم تُوضَع في رتل تشغيل المجدول وبالتالي تُعَدّ خاملةً في النظام.
</p>

<p>
	نستخدم برنامج <code>kill</code> لإرسال الإشارة نفسها من نافذة طرفية أخرى، إذ يمكن تطبيق ذلك فعليًا باستخدام استدعاء النظام <code>kill</code> الذي يأخذ إشارة ومعرّف <abbr title="Process IDentifier | معرّف العملية أو البرنامج"><abbr title="Process IDentifier | معرّف العملية أو البرنامج">PID</abbr></abbr> لإرسالها، ويُعَدّ اسم هذه الدالة خاطئًا بعض الشيء، إذ لا تقتل جميعُ الإشارات العمليةَ فعليًا، ولكن تُستخدَم الدالة <code>signal</code> لتسجيل المعالج Handler، كما توضَع الإشارة في رتل خاص بهذه العملية عند توقفها، وبالتالي تأخذ النواة ملاحظةً بالإشارة وتسلّمها في الوقت المناسب.
</p>

<p>
	ننبّه العملية بعد ذلك باستخدام الأمر <code>fg</code> الذي يرسل الإشارة <code>SIGCONT</code> إلى العملية، مما يؤدي إلى تنشيط العملية افتراضيًا، كما تدرك النواة وضع العملية في رتل التشغيل وتمنحها وقتًا من وحدة المعالجة المركزية مرةً أخرى، إذ نرى في هذه المرحلة تسليم الإشارة الموجودة في رتل التشغيل.
</p>

<p>
	نحاول أخيرًا الضغط على الاختصار <code>ctrl-\‎</code> الذي يرسل الإشارة <code>SIGQUIT</code> -أي إلغاء- إلى العملية، ويأتي خرج الإلغاء <code>Quit</code> من استخدام مزيد من الإشارات بالرغم من إلغاء العملية، وإذا كان لدى الأب عملية ابن ميتة أو منتهية، فسيحصل على الإشارة <code>SIGCHLD</code>، إذ تُعَدّ الصدَفةُ أنها العملية الأب في هذه الحالة، أي أنها ستحصل على الإشارة.
</p>

<p>
	تذكّر أنّ العملية الزومبي Zombie التي يجب حصادها باستخدام الاستدعاء <code>wait</code> للحصول على الشيفرة المُعادة من العملية الابن، ولكن هناك شيء آخر يمنحه الابن للأب وهو رقم الإشارة التي أدّت إلى موت الابن، وهكذا تعرف الصدَفة أنّ العملية الابن قد ماتت أو انتهت بسبب الإشارة <code>SIGABRT</code> وتطبع معلومات أخرى للمستخدِم على أساس خدمة إعلامية، إذ تحدُث العملية نفسها لطباعة خطأ التقطيع Segmentation Fault عندما تموت العملية الابن بسبب الإشارة <code>SIGSEGV</code>.
</p>

<p>
	يمكنك رؤية استخدام حوالي خمس إشارات مختلفة للتواصل بين العمليات والنواة والحفاظ على سير الأمور حتى في برنامج بسيط، وهناك العديد من الإشارات الأخرى، لكننا استخدمنا في هذا المثال الإشارات الأكثر شيوعًا، إذ تحتوي معظمها على دوال نظام تعرّفها النواة، ولكن هناك بعض الإشارات المحجوزة للمستخدِمين لاستخدامها لأغراضهم الخاصة في برامجهم <code>SIGUSR</code>.
</p>

<p>
	ترجمة -وبتصرُّف- للأقسام <a href="https://www.bottomupcs.com/context_switching.xhtml" rel="external nofollow">Context Switching</a> و <a href="https://www.bottomupcs.com/scheduling.xhtml" rel="external nofollow">Scheduling</a> و <a href="https://www.bottomupcs.com/the_shell.xhtml" rel="external nofollow">The Shell</a> و <a href="https://www.bottomupcs.com/signals.xhtml" rel="external nofollow">Signals</a> من الفصل <a href="https://www.bottomupcs.com/chapter04.xhtml" rel="external nofollow">The Process</a> من كتاب <a href="https://www.bottomupcs.com/" rel="external nofollow">Computer Science from the Bottom Up</a> لصاحبه Ian Wienand.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/general/%D8%A7%D9%84%D8%B0%D8%A7%D9%83%D8%B1%D8%A9-%D8%A7%D9%84%D9%88%D9%87%D9%85%D9%8A%D8%A9-%D9%88%D8%A7%D9%84%D8%B0%D8%A7%D9%83%D8%B1%D8%A9-%D8%A7%D9%84%D8%AD%D9%82%D9%8A%D9%82%D9%8A%D8%A9-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1918/" rel="">الذاكرة الوهمية والذاكرة الحقيقية في معمارية الحاسوب</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B3%D9%84%D8%B3%D9%84-%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D9%87%D8%B1%D9%85%D9%8A-%D9%88%D8%A7%D8%B3%D8%AA%D8%AF%D8%B9%D8%A7%D8%A1%D8%A7%D8%AA-%D8%A7%D9%84%D9%86%D8%B8%D8%A7%D9%85-fork-%D9%88-exec-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1759/" rel="">تسلسل العمليات الهرمي واستدعاءات النظام Fork و Exec في نظام تشغيل الحاسوب</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/devops/networking/%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8%D9%8A%D8%A9-%D9%88%D8%B4%D8%A8%D9%83%D8%A9-%D8%A7%D9%84%D8%A5%D9%86%D8%AA%D8%B1%D9%86%D8%AA-network-architecture-r484/" rel="">معمارية الشبكة الحاسوبية وشبكة الإنترنت (Network Architecture)</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AF%D9%88%D8%B1-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%88%D8%AA%D9%86%D8%B8%D9%8A%D9%85%D9%87-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1723/" rel="">دور نظام التشغيل وتنظيمه في معمارية الحاسوب</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%88%D8%AD%D8%AF%D8%A9-%D8%A7%D9%84%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D9%85%D8%B1%D9%83%D8%B2%D9%8A%D8%A9-%D9%88%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA%D9%87%D8%A7-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1716/" rel="">تعرف على وحدة المعالجة المركزية وعملياتها في معمارية الحاسوب</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1760</guid><pubDate>Fri, 25 Nov 2022 16:05:00 +0000</pubDate></item><item><title>&#x62A;&#x633;&#x644;&#x633;&#x644; &#x627;&#x644;&#x639;&#x645;&#x644;&#x64A;&#x627;&#x62A; &#x627;&#x644;&#x647;&#x631;&#x645;&#x64A; &#x648;&#x627;&#x633;&#x62A;&#x62F;&#x639;&#x627;&#x621;&#x627;&#x62A; &#x627;&#x644;&#x646;&#x638;&#x627;&#x645; Fork &#x648; Exec &#x641;&#x64A; &#x646;&#x638;&#x627;&#x645; &#x62A;&#x634;&#x63A;&#x64A;&#x644; &#x627;&#x644;&#x62D;&#x627;&#x633;&#x648;&#x628;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B3%D9%84%D8%B3%D9%84-%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D9%87%D8%B1%D9%85%D9%8A-%D9%88%D8%A7%D8%B3%D8%AA%D8%AF%D8%B9%D8%A7%D8%A1%D8%A7%D8%AA-%D8%A7%D9%84%D9%86%D8%B8%D8%A7%D9%85-fork-%D9%88-exec-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1759/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2022_11/63610fde8df5f_------Fork--Exec.png.342ab5d2462e35267bd4d2a59cbb54cb.png" /></p>
<p>
	يمكن <a href="https://academy.hsoub.com/files/24-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%84%D9%85%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D9%86/" rel="">لنظام التشغيل</a> تشغيلُ العديد من العمليات في الوقت نفسه، إلّا أنه يبدأ بتشغيل عملية واحدة مباشرةً تُدعَى بالعملية الأولية init -اختصارًا للكلمة Initial- التي لا تُعَدّ عمليةً خاصةً باستثناء أنً معرِّف العملية <abbr title="Process IDentifier | معرّف العملية أو البرنامج"><abbr title="Process IDentifier | معرّف العملية أو البرنامج">PID</abbr></abbr> الخاص بها هو 0 دائمًا وستبقى مُشغَّلةً دائمًا.
</p>

<p>
	تُعَدّ جميع العمليات الأخرى أبناءً Children لهذه العملية الأولية، فللعمليات شجرة عائلة مثل أيّ شجرة أخرى، إذ يكون لكل عملية أبًا Parent ويمكن أن يكون لها العديد من الأشقاء Siblings التي تُعَدّ عمليات أنشأها الأب نفسه.
</p>

<p>
	يُستخدَم المصطلح "تولّد Spawn" عند الحديث عن العمليات الآباء التي تنشئ العمليات الأبناء مثل القول بأن "عملية ولّدت ابنًا"، كما يمكن أن تنشئ العمليات الأبناء مزيدًا من الأبناء وهكذا، وإليك مثال عن تنفيذ الأمر <code>pstree</code> الذي يعرض العمليات المُشغَّلة مثل شجرة:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3272_11" style=""><span class="pln">init</span><span class="pun">-+-</span><span class="pln">apmd
     </span><span class="pun">|-</span><span class="pln">atd
     </span><span class="pun">|-</span><span class="pln">cron
     </span><span class="pun">...</span><span class="pln">
     </span><span class="pun">|-</span><span class="pln">dhclient
     </span><span class="pun">|-</span><span class="pln">firefox</span><span class="pun">-</span><span class="pln">bin</span><span class="pun">-+-</span><span class="pln">firefox</span><span class="pun">-</span><span class="pln">bin</span><span class="pun">---</span><span class="lit">2</span><span class="pun">*[</span><span class="pln">firefox</span><span class="pun">-</span><span class="pln">bin</span><span class="pun">]</span><span class="pln">
     </span><span class="pun">|</span><span class="pln">             </span><span class="pun">|-</span><span class="pln">java_vm</span><span class="pun">---</span><span class="pln">java_vm</span><span class="pun">---</span><span class="lit">13</span><span class="pun">*[</span><span class="pln">java_vm</span><span class="pun">]</span><span class="pln">
     </span><span class="pun">|</span><span class="pln">             </span><span class="pun">`-</span><span class="pln">swf_play</span></pre>

<p>
	يمكن إنشاء عمليات جديدة باستخدام واجهتين متعلقتين ببعضهما هما <code>fork</code> و <code>exec</code>.
</p>

<h2>
	استدعاءات Fork
</h2>

<p>
	إذا وصلتَ إلى مفترق طرق، فسيكون لديك خياران لتختار من بينهما وسيؤثر هذا القرار على مستقبلك، كما تصل البرامج الحاسوبية إلى مفترق طرق عندما تضغط على استدعاء النظام <code>fork()‎</code>، إذ سيُنشئ نظام التشغيل عمليةً جديدةً مماثلةً للعملية الأب، إذ ستُنسَخ جميع الحالات التي تحدّثنا عنها سابقًا بما في ذلك الملفات المفتوحة وحالة المسجّل وجميع عمليات تخصيص الذاكرة التي تتضمن شيفرة البرنامج.
</p>

<p>
	تُعَدّ القيمة المُعادة من استدعاء النظام الطريقةَ الوحيدة التي يمكن للعملية من خلالها تحديد ما إذا كانت العملية موجودةً مسبقًا أم عملية جديدة، إذ ستكون القيمة المُعادة إلى العملية الأب هي معرّف عملية الابن Process ID أو <abbr title="Process IDentifier | معرّف العملية أو البرنامج"><abbr title="Process IDentifier | معرّف العملية أو البرنامج">PID</abbr></abbr> اختصارًا، في حين سيحصل الابن على القيمة المُعادة 0، وعندها نقول أن العملية متفرعة forked مع وجود علاقة أب-ابن.
</p>

<h2>
	استدعاءات Exec
</h2>

<p>
	يوفّر التفريع Forking طريقةً للعملية الحالية بأن تبدأ عملية جديدة، فإذا لم تكن العملية الجديدة جزءًا من برنامج العملية الأب كما هو الحال في الصدَفة Shell، إذ يجب أن يشغِّل المستخدِم أمرًا في عملية جديدة ليس لها علاقة بالصدَفة، فيجب تشغيل استدعاء النظام <code>exec</code> الذي سيبدّل بمحتويات العملية المُشغَّلة حاليًا معلومات من برنامج ثنائي.
</p>

<p>
	العملية التي تتبعها الصدَفة عند إطلاق برنامج جديد هي <code>fork</code> أولًا، مما يؤدي إلى إنشاء عملية جديدة، ثم تنفيذ الاستدعاء <code>exec</code>، أي تحميل البرنامج الثنائي الذي يُفترَض تشغيله في الذاكرة وتنفيذه.
</p>

<h2>
	كيفية تعامل لينكس مع fork و exec
</h2>

<p>
	سنشرح كيفية تعامل نظام التشغيل لينكس مع عملية النسخ fork وعملية الاستدعاء exec.
</p>

<h3>
	النسخ
</h3>

<p>
	يُنفَّذ الاستدعاء <code>fork</code> باستخدام استدعاء النظام <code>clone</code> في النواة، إذ توفّر واجهات <code>clone</code> بفعالية مستوًى من التجريد لكيفية إنشاء نواة لينكس للعمليات، كما يتيح الاستدعاء <code>clone</code> تحديد أجزاء العملية الجديدة المنسوخة في العملية الجديدة والأجزاء المشتركة بين العمليتين صراحةً، وقد يبدو هذا غريبًا بعض الشيء في البداية، لكنه يسمح لنا بسهولة بتطبيق الخيوط Threads باستخدام واجهة واحدة بسيطة جدًا.
</p>

<h3>
	الخيوط Threads
</h3>

<p>
	ينسخ الاستدعاء <code>fork</code> جميع السمات التي ذكرناها سابقًا. تخيّل نسخ كل شيء للعملية الجديدة باستثناء الذاكرة، فهذا يعني اشتراك الأب والابن في الذاكرة نفسها التي تتضمن شيفرة البرنامج والبيانات.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="111019" href="https://academy.hsoub.com/uploads/monthly_2022_11/01_threads.png.c9eab677bb5e49c77db7e3a05e299950.png" rel=""><img alt="01_threads.png" class="ipsImage ipsImage_thumbnailed" data-fileid="111019" data-unique="c576gsmqk" src="https://academy.hsoub.com/uploads/monthly_2022_11/01_threads.png.c9eab677bb5e49c77db7e3a05e299950.png"></a>
</p>

<p>
	يُسمَّى الابن الهجين السابق بالخيط، كما تحتوي الخيوط على عدد من المزايا بالموازنة مع المكان الذي يُستخدَم فيه الاستدعاء <code>fork</code> ومنها ما يلي:
</p>

<ol>
	<li>
		لا يمكن للعمليات المنفصلة أن ترى ذاكرة بعضها بعضًا، وإنما يمكنها التواصل مع بعضها بعضًا عبر استدعاءات النظام الأخرى فقط، لكن مع ذلك تشترك الخيوط في الذاكرة نفسها، لذا سيكون لديك ميزة العمليات المتعددة مع الاضطرار إلى استخدام استدعاءات النظام للتواصل فيما بينها، وتكمن مشكلة ذلك في إمكانية تداخل الخيوط بسهولة مع بعضها بعضًا، إذ يمكن أن يزيد أحد الخيوط متغيرًا، في حين يمكن أن ينقصه خيط آخر بدون إعلام الخيط الأول، وتسمى هذه الأنواع من المشاكل بمشاكل التزامن وهي كثيرة ومتنوعة، ولكن يمكن حل هذه المشكلة باستخدام مكتبات مجال المستخدِم التي تساعد المبرمجين على العمل مع الخيوط بصورة صحيحة، وتسمى أكثر الخيوط شيوعًا بخيوط POSIX أو كما يشار إليها <code>pthreads</code> بصورة شائعة.
	</li>
	<li>
		يُعَدّ التبديل بين العمليات مكلفًا جدًا، ومن أكثر الأمور تكلفةً هو تعقّب الذاكرة التي تستخدِمها كل عملية، ويمكن تجنّب ذلك من خلال مشاركة الذاكرة التي تزيد الأداء بصورة ملحوظة.
	</li>
</ol>

<p>
	هناك العديد من الطرق المختلفة لتطبيق الخيوط، إذ يمكن أن يطبِّق مجال المستخدِم الخيوط ضمن عملية دون أن تكون لدى النواة أيّ فكرة عن ذلك، إذ تظهر جميع الخيوط للنواة كأنها تعمل في عملية واحدة، ويُعَدّ ذلك دون المستوى الأمثل لأنّ النواة تحجب معلومات عمّا يجري تشغيله في النظام؛ أما مهمة النواة فهي التأكد من استخدام موارد النظام بأفضل طريقة ممكنة، وإذا كان ما تعتقده النواة هو وجود عملية واحدة تشغّل خيوط عمليات متعددة، فيمكن أن تتخذ قرارات دون المستوى الأمثل.
</p>

<p>
	الطريقة الأخرى هي أن تكون للنواة معرفة كاملة بالخيط، إذ يمكن إنشاء ذلك في <a href="https://academy.hsoub.com/devops/linux/%D9%85%D8%A7-%D9%87%D9%88-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%8A%D9%86%D9%83%D8%B3%D8%9F-r451/" rel="">نظام لينكس</a> من خلال جعل جميع العمليات قادرة على مشاركة الموارد عبر استدعاء النظام <code>clone</code>، ولا يزال كل خيط يحتوي على موارد مرتبطة بالنواة، لذلك يمكن أن تأخذها النواة في حساباتها عند إجراء عمليات تخصيص الموارد.
</p>

<p>
	تحتوي أنظمة التشغيل الأخرى على طريقة هجينة من الطريقتين السابقتين، إذ يمكن تحديد بعض الخيوط للتشغيل في مجال المستخدِم فقط -أي مخفيّة عن النواة- ويمكن أن يكون البعض الآخر من الخيوط عمليةً خفيفة الوزن، ويُعَدّ ذلك مؤشرًا مشابهًا للنواة على أن العمليات هي جزء من مجموعة خيوط.
</p>

<h3>
	النسخ عند الكتابة
</h3>

<p>
	يُعَدّ نسخ ذاكرة عملية كاملة إلى عملية أخرى عند استخدام الاستدعاء <code>fork</code> عمليةً مكلفةً كما ذكرنا سابقًا، ويمكن تحسين ذلك باستخدام ما يُسمَّى بالنسخ عند الكتابة Copy On Write، إذ يمكن مشاركة الذاكرة فعليًا بدلًا من نسخها بين العمليتين عند استدعاء <code>fork</code>، فإذا كانت العمليات ستقرأ الذاكرة فقط، فلن يكون نسخ البيانات ضروريًا، لكن يجب أن تكون النسخة خاصةً وغير مشتركة عندما تكتب عملية ما في ذاكرتها.
</p>

<p>
	يعمل النسخ عند الكتابة -كما يوحي اسمه- على تحسين ذلك من خلال النسخ من الذاكرة فقط عندما تُكتَب النسخة فيها، وللنسخ عند الكتابة فائدة كبيرة للاستدعاء <code>exec</code> الذي سيكتب البرنامج الجديد في الذاكرة، لذا سيضيّع نسخ الذاكرة الكثير من الوقت، وبالتالي ستوفّر عملية النسخ عند الكتابة علينا النسخ فعليًا.
</p>

<h2>
	العملية الأولية Init Process
</h2>

<p>
	ناقشنا سابقًا الهدف العام للعملية الأولية وسنفهم الآن كيفية عملها، إذ تبدأ النواةُ العمليةَ الأولية <code>init</code> عند بدء التشغيل وتفرّع وتنفّذ هذه العملية بعد ذلك سكربتات بدء تشغيل الأنظمة التي تفرّع وتنفّذ مزيدًا من البرامج، وينتهي بها الأمر في النهاية إلى تفريع عملية تسجيل الدخول.
</p>

<p>
	الوظيفة الأخرى للعملية <code>init</code> هي الحصاد Reaping، إذ سترغب العملية الأب في التحقق من الشيفرة المُعادة للتأكد من إنهاء العملية الابن بصورة صحيحة أم لا عندما تستدعي العملية استدعاء الإنهاء <code>exit</code> باستخدام الشيفرة المُعادة، لكن تُعَدّ شيفرة الإنهاء جزءًا من العملية التي استدعت <code>exit</code>، لذا يُقال أنّ هذه العملية ميتة Dead مثل أنها لا تعمل، ولكنها لا تزال بحاجة إلى البقاء حتى جمع الشيفرة المُعادة، وتسمى العملية في هذه الحالة شبه ميتة أو زومبي Zombie.
</p>

<p>
	تبقى العملية في حالة زومبي حتى تجمع العملية الأب الشيفرة المُعادة من الاستدعاء <code>wait</code>، ولكن إذا انتهت العملية الأب قبل جمع الشيفرة المُعادة، فستبقى عملية الزومبي موجودةً وتنتظر بلا هدف لإعطاء حالتها لعمليةٍ ما، ثم ستُنسَب العملية الابن التي تكون في حالة زومبي إلى العملية الأولية التي تمتلك معالجًا خاصًا يحصد القيمة المُعادة، وستكون العملية حرةً في النهاية ويمكن إزالة واصفها من جدول عمليات النواة.
</p>

<h3>
	مثال عملية شبه ميتة
</h3>

<p>
	إليك مثال عن عملية شبه ميتة أو عملية زومبي كما يقال:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3272_16" style=""><span class="pln">$ cat zombie</span><span class="pun">.</span><span class="pln">c
</span><span class="com">#include</span><span class="pln"> </span><span class="str">&lt;stdio.h&gt;</span><span class="pln">
</span><span class="com">#include</span><span class="pln"> </span><span class="str">&lt;stdlib.h&gt;</span><span class="pln">

</span><span class="typ">int</span><span class="pln"> main</span><span class="pun">(</span><span class="kwd">void</span><span class="pun">)</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
  </span><span class="typ">pid_t</span><span class="pln"> pid</span><span class="pun">;</span><span class="pln">

  printf</span><span class="pun">(</span><span class="str">"parent : %d\n"</span><span class="pun">,</span><span class="pln"> getpid</span><span class="pun">());</span><span class="pln">

  pid </span><span class="pun">=</span><span class="pln"> fork</span><span class="pun">();</span><span class="pln">

  </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">pid </span><span class="pun">==</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    printf</span><span class="pun">(</span><span class="str">"child : %d\n"</span><span class="pun">,</span><span class="pln"> getpid</span><span class="pun">());</span><span class="pln">
    sleep</span><span class="pun">(</span><span class="lit">2</span><span class="pun">);</span><span class="pln">
    printf</span><span class="pun">(</span><span class="str">"child exit\n"</span><span class="pun">);</span><span class="pln">
    exit</span><span class="pun">(</span><span class="lit">1</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">

  </span><span class="com">/* في الأب */</span><span class="pln">
  </span><span class="kwd">while</span><span class="pln"> </span><span class="pun">(</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
  </span><span class="pun">{</span><span class="pln">
    sleep</span><span class="pun">(</span><span class="lit">1</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

$ ps ax </span><span class="pun">|</span><span class="pln"> grep </span><span class="pun">[</span><span class="pln">z</span><span class="pun">]</span><span class="pln">ombie
</span><span class="lit">16168</span><span class="pln"> pts</span><span class="pun">/</span><span class="lit">9</span><span class="pln">    S      </span><span class="lit">0</span><span class="pun">:</span><span class="lit">00</span><span class="pln"> </span><span class="pun">./</span><span class="pln">zombie
</span><span class="lit">16169</span><span class="pln"> pts</span><span class="pun">/</span><span class="lit">9</span><span class="pln">    Z      </span><span class="lit">0</span><span class="pun">:</span><span class="lit">00</span><span class="pln"> </span><span class="pun">[</span><span class="pln">zombie</span><span class="pun">]</span><span class="pln"> </span><span class="str">&lt;defunct&gt;</span></pre>

<p>
	أنشأنا في المثال السابق عملية زومبي، إذ ستكون العملية الأب في حالة سكون Sleep إلى الأبد، في حين ستنتهي العملية الابن بعد بضع ثوان، ويمكنك رؤية نتائج تشغيل البرنامج بعد الشيفرة البرمجية.
</p>

<p>
	تكون العملية الأب (16168) في الحالة <code>S</code> للإشارة إلى أنها في حالة سكون وتكون العملية الابن في الحالة <code>Z</code> للإشارة إلى أنها في حالة زومبي، في حين يخبرنا خرج الأمر <code>ps</code> أن العملية أصبحت زومبي أو <code>defunct</code> في وصف العملية.
</p>

<p>
	<strong>ملاحظة:</strong> الأقواس المربعة حول الحرف "z" في الكلمة "zombie" هي خدعة صغيرة لتزيل عمليات الأمر <code>grep</code> نفسها من خرج الأمر <code>ps</code>، إذ يفسّر الأمر <code>grep</code> كل شيء بين الأقواس المربعة على أنه صنف محرفي Character Class، أي يبحث عن تطابق واحد فقط بين المحارف الموجودة بين القوسين والنص، ولكن بما أن اسم العملية سيكون "grep [z]ombie" مع الأقواس، فلن يكون هناك تطابق.
</p>

<p>
	ترجمة -وبتصرُّف- للقسمين <a href="https://www.bottomupcs.com/process_hierarchy.xhtml" rel="external nofollow">Process Hierarchy</a> و <a href="https://www.bottomupcs.com/fork_and_exec.xhtml" rel="external nofollow">Fork and Exec</a> من الفصل <a href="https://www.bottomupcs.com/chapter04.xhtml" rel="external nofollow">The Process</a> من كتاب <a href="https://www.bottomupcs.com/" rel="external nofollow">Computer Science from the Bottom Up</a> لصاحبه Ian Wienand.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A3%D9%87%D9%85-%D8%A7%D9%84%D9%85%D9%81%D8%A7%D9%87%D9%8A%D9%85-%D8%A7%D9%84%D8%AA%D9%8A-%D8%AA%D9%86%D8%B8%D9%85-%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA-%D9%88%D8%AA%D8%B9%D8%A7%D9%84%D8%AC%D9%87%D8%A7-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-%D8%A7%D9%84%D8%AD%D8%AF%D9%8A%D8%AB%D8%A9-r1760/" rel="">أهم المفاهيم التي تنظم العمليات وتعالجها في معمارية الحاسوب الحديثة</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA-%D9%88%D8%B9%D9%86%D8%A7%D8%B5%D8%B1%D9%87%D8%A7-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1758/" rel="">العمليات وعناصرها في نظام تشغيل الحاسوب</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D8%B3%D8%AA%D8%AF%D8%B9%D8%A7%D8%A1%D8%A7%D8%AA-%D8%A7%D9%84%D9%86%D8%B8%D8%A7%D9%85-%D9%88%D8%A7%D9%84%D8%B5%D9%84%D8%A7%D8%AD%D9%8A%D8%A7%D8%AA-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-r1757/" rel="">استدعاءات النظام والصلاحيات في نظام التشغيل</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AF%D9%88%D8%B1-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%88%D8%AA%D9%86%D8%B8%D9%8A%D9%85%D9%87-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1723/" rel="">دور نظام التشغيل وتنظيمه في معمارية الحاسوب</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/c/%D8%A7%D9%84%D9%81%D8%B5%D9%84-%D8%A7%D9%84%D8%AB%D8%A7%D9%86%D9%8A-%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA-processes-%D9%81%D9%8A-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-r977/" rel="">العمليات (Processes) في أنظمة التشغيل</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/files/24-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%84%D9%85%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D9%86/" rel="">أنظمة التشغيل للمبرمجين</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1759</guid><pubDate>Fri, 18 Nov 2022 16:07:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x639;&#x645;&#x644;&#x64A;&#x627;&#x62A; &#x648;&#x639;&#x646;&#x627;&#x635;&#x631;&#x647;&#x627; &#x641;&#x64A; &#x646;&#x638;&#x627;&#x645; &#x62A;&#x634;&#x63A;&#x64A;&#x644; &#x627;&#x644;&#x62D;&#x627;&#x633;&#x648;&#x628;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA-%D9%88%D8%B9%D9%86%D8%A7%D8%B5%D8%B1%D9%87%D8%A7-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1758/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2022_11/63610b7f252b7_-----.png.eb25a4152c92a42833bebb4a32cbcdf1.png" /></p>
<p>
	جميعنا على دراية <a href="https://academy.hsoub.com/files/24-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%84%D9%85%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D9%86/" rel="">بنظام التشغيل</a> الحديث الذي يدير العديد من المهام في وقت واحد أو ما يسمى بتعدد المهام Multitasking، حيث تُعَدّ <a href="https://academy.hsoub.com/programming/c/%D8%A7%D9%84%D9%81%D8%B5%D9%84-%D8%A7%D9%84%D8%AB%D8%A7%D9%86%D9%8A-%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA-processes-%D9%81%D9%8A-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-r977/" rel="">العملية</a> حزمةً من العناصر التي تحتفظ بها النواة لتعقّب جميع المهام التي تكون قيد التشغيل.
</p>

<h2>
	عناصر العملية
</h2>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="111015" href="https://academy.hsoub.com/uploads/monthly_2022_11/01_theprocess.png.5f28211df5171c87b60fd5cb377eb987.png" rel=""><img alt="01_theprocess.png" class="ipsImage ipsImage_thumbnailed" data-fileid="111015" data-unique="pz5m0wwps" src="https://academy.hsoub.com/uploads/monthly_2022_11/01_theprocess.png.5f28211df5171c87b60fd5cb377eb987.png"></a>
</p>

<h3>
	معرف العملية
</h3>

<p>
	يضبط نظام التشغيل معرّف العملية Process ID -أو <abbr title="Process IDentifier | معرّف العملية أو البرنامج"><abbr title="Process IDentifier | معرّف العملية أو البرنامج">PID</abbr></abbr> اختصارًا- ويكون فريدًا لكل عملية مُشغَّلة.
</p>

<h3>
	الذاكرة
</h3>

<p>
	سنتعلم كيف تحصل عملية ما على ذاكرتها لاحقًا، وتُعَدّ الذاكرة أحد الأجزاء الأساسية لكيفية عمل نظام التشغيل، ولكن سنكتفي حاليًا بمعرفة أنّ كل عملية لها قسمها الخاص من الذاكرة.
</p>

<p>
	تُخزَّن شيفرة البرنامج في هذه الذاكرة مع المتغيرات وأيّ عمليات تخزين أخرى مخصَّصة، ويمكن مشاركة أجزاء من الذاكرة بين العمليات، إذ تسمَّى بالذاكرة المشتركة Shared Memory، كما يمكن أن تراها بالاسم System Five Shared Memory -أو SysV SHM اختصارًا- بعد التطبيق الأصلي في نظام تشغيل أقدم.
</p>

<p>
	مفهوم مهم آخر يمكن أن تستخدِمه العملية هو مفهوم ربط ملف موجود في القرص الصلب مع الذاكرة أو ما يُسمى mmaping، إذ يبدو الملف كما لو كان أيّ نوع آخر من الذاكرة RAM بدلًا من الاضطرار إلى فتح الملف واستخدام أوامر مثل <code>read()‎</code> و <code>write()‎</code>، كما تمتلك مناطق <code>mmaped</code> أذونات يجب تعقّبها مثل القراءة والكتابة والتنفيذ، فمهمّة نظام التشغيل هي الحفاظ على الأمن والاستقرار، لذلك يجب التحقق مما إذا كانت العملية تحاول الكتابة في منطقة للقراءة فقط وإعادة خطأ بذلك.
</p>

<h3>
	الشيفرة والبيانات
</h3>

<p>
	يمكن تقسيم العملية بصورة أكبر إلى قسمين هما الشيفرة Code والبيانات Data، إذ يجب الاحتفاظ بشيفرة البرنامج وبياناته بصورة منفصلة لأنها تتطلب أذونات مختلفة من نظام التشغيل، ويسهّل هذا المقال بينهما مشاركة الشيفرة كما سنرى لاحقًا، كما يجب أن يعطي نظام التشغيل إذنًا لشيفرة البرنامج للتمكّن من قراءتها وتنفيذها دون الكتابة فيها، في حين تتطلب البيانات (المتغيرات) أذونات القراءة والكتابة ولا ينبغي أن تكون قابلةً للتنفيذ، ولكن لا تدعم جميع المعماريات ذلك، مما أدى إلى مجموعة واسعة من مشاكل الأمان في العديد منها.
</p>

<h3>
	المكدس Stack
</h3>

<p>
	يُعَدّ المكدس جزءًا مهمًا آخر من العملية وهو منطقة من الذاكرة وجزء من قسم البيانات في العملية، ويشارك في تنفيذ أيّ برنامج، كما يُعَدّ بنية بيانات عامة تعمل مثل مجموعة الأطباق، إذ يمكنك دفع push عنصر أو وضع طبق أعلى كومة من الأطباق بحيث يصبح العنصر العلوي، أو يمكنك سحب pop عنصر أو سحب طبق وظهور الطبق السابق.
</p>

<p>
	المكدسات أساسية لاستدعاءات الدوال، إذ تحصل على إطار مكدس stack frame جديد في كل مرة تُستدعَى فيها الدالة، وهي منطقة من الذاكرة تحتوي على الأقل على العنوان الذي يجب الرجوع إليه عند الانتهاء ووسائط دخل الدالة وفضاء المتغيرات المحلية.
</p>

<p>
	تنمو المكدسات عادةً إلى الأسفل، إذ يبدأ المكدس عند عنوان مرتفع في الذاكرة وينخفض تدريجيًا، في حين تحتوي بعض المعماريات مثل PA-RISC من HP على مكدسات تنمو للأعلى، وتوجد في بعض المعماريات الأخرى مثل IA64 مناطق تخزين أخرى (مخزن داعم للمسجّل) تنمو من الأسفل باتجاه المكدس.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="111016" href="https://academy.hsoub.com/uploads/monthly_2022_11/02_stack.png.cdb0bea180d4749c8e32e6337a5eec1d.png" rel=""><img alt="اتجاه المكدس Stack" class="ipsImage ipsImage_thumbnailed" data-fileid="111016" data-unique="j7lxsz1x5" style="width: 427px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2022_11/02_stack.png.cdb0bea180d4749c8e32e6337a5eec1d.png"></a>
</p>

<p>
	يعطي وجود مكدس العديد من الميزات للدوال ومنها ما يلي:
</p>

<p>
	أولًا، لكل دالة نسختها الخاصة من وسائط الدخل، إذ يُخصَّص إطار مكدس جديد لكل دالة مع وسائطها في منطقة جديدة من الذاكرة، + وبالتالي لا يمكن أن ترى الدوال الأخرى المتغير المُعرَّف في دالة ما، في حين تُخزَّن المتغيرات العامة التي يمكن أن تراها أيّ دالة في منطقة منفصلة من ذاكرة البيانات، مما يسهّل الاستدعاءات العودية Recursive Calls، وهذا يعني أنّ الدالة حرة في استدعاء نفسها مرةً أخرى، إذ سيُنشَأ إطار مكدس جديد لجميع متغيراتها المحلية.
</p>

<p>
	ثانيًا، يحتوي كل إطار على عنوان للعودة إليه، وتسمح لغة C فقط بإعادة قيمة واحدة من الدالة، لذلك تُعاد هذه القيمة إلى دالة الاستدعاء في مسجّل محدد بدلًا من المكدس.
</p>

<p>
	ثالثًا، يحتوي كل إطار على مرجع للإطار الذي يسبقه، لذا يمكن لمنقّح الأخطاء العودة للخلف متتبّعًا المؤشرات ليصل إلى أعلى المكدس، ويمكن أن ينتج متعقّب مكدسات Stack Trace الذي يُظهِر لك جميع الدوال التي جرى استدعاؤها حتى الوصول إلى هذه الدالة، ويُعَدّ ذلك مفيدًا لتنقيح الأخطاء، كما يمكنك رؤية كيف تتناسب الطريقة التي تعمل بها الدوال مع طبيعة المكدس، إذ يمكن لأيّ دالة استدعاءُ أيّ دالة أخرى، وبالتالي تصبح الدالة الأعلى بحيث تُوضَع في أعلى المكدس، وستعيد هذه الدالة في النهاية النتيجة إلى الدالة التي استدعتها، أي تخرج من المكدس.
</p>

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

<p>
	خامسًا، لا بد أنك سمعت بمصطلح طفحان المكدس Stack Overflow الذي يُعَدّ طريقةً شائعةً لاختراق النظام من خلال تمرير قيم وهمية، فإذا كنت مبرمجًا تقبل بالإدخال العشوائي في متغير المكدس مثل القراءة من لوحة المفاتيح أو عبر الشبكة، فيجب عليك تحديد حجم هذه البيانات صراحةً، إذ يؤدي السماح بأيّ كمية من البيانات دون تحديد إلى الكتابة فوق الذاكرة، مما يؤدي إلى حدوث عطل، ولكن أدرك بعض الأشخاص أنهم إذا كتبوا في ذاكرة كافية فقط لوضع قيمة محددة في جزء العنوان المُعاد من إطار المكدس، فيمكنهم إعادتها في البيانات التي أرسلوها للتو عند اكتمال الدالة بدلًا من الإعادة إلى المكان الصحيح الذي استدعاها، فإذا احتوت هذه البيانات على شيفرة ثنائية قابلة للتنفيذ وتخترق النظام مثل تشغيل طرفية للمستخدِم مع صلاحيات الجذر، فهذا يعني تعرّض حاسوبك للاختراق. يحدث ذلك بسبب نمو المكدس للأسفل، ولكن تُقرَأ البيانات للأعلى أي من العنوان الأدنى إلى العناوين الأعلى.
</p>

<p>
	هناك عدة طرق للتغلب على هذه المشكلة، إذ يجب عليك التأكد -بصفتك مبرمجًا- من أنك تتحقق دائمًا من كمية البيانات التي تتلقاها في متغير، ويمكن أن يساعد نظام التشغيل في تجنّب ذلك نيابةً عن المبرمج من خلال التأكد من تمييز المكدس على أنه غير قابل للتنفيذ، وبالتالي لن يشغّل المعالج أيّ شيفرة برمجية، حتى إذا حاول مستخدِم سيئ تمرير شيفرة برمجية إلى برنامجك، وتدعم المعماريات وأنظمة التشغيل الحديثة هذه الوظيفة.
</p>

<p>
	سادسًا، يدير المصرّف Compiler المكدسات، فهو المسؤول عن إنشاء شيفرة البرنامج، ويبدو المكدس بالنسبة لنظام التشغيل مثل أيّ منطقة أخرى من الذاكرة الخاصة بالعملية.
</p>

<p>
	يعرِّف العتاد المسجِّل بوصفه مؤشر المكدس Stack Pointer بهدف تعقّب نمو المكدس الحالي، إذ يستخدِم المصرّف -أو المبرمج عند الكتابة باستخدام لغة التجميع- هذا المسجِّل لتعقّب الجزء العلوي الحالي من المكدس، وإليك مثال عن مؤشر المكدس:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_785_10" style=""><span class="pln">$ cat sp</span><span class="pun">.</span><span class="pln">c
</span><span class="kwd">void</span><span class="pln"> function</span><span class="pun">(</span><span class="kwd">void</span><span class="pun">)</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
  </span><span class="typ">int</span><span class="pln"> i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">100</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">int</span><span class="pln"> j </span><span class="pun">=</span><span class="pln"> </span><span class="lit">200</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">int</span><span class="pln"> k </span><span class="pun">=</span><span class="pln"> </span><span class="lit">300</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

$ gcc </span><span class="pun">-</span><span class="pln">fomit</span><span class="pun">-</span><span class="pln">frame</span><span class="pun">-</span><span class="pln">pointer </span><span class="pun">-</span><span class="pln">S sp</span><span class="pun">.</span><span class="pln">c

$ cat sp</span><span class="pun">.</span><span class="pln">s
  </span><span class="pun">.</span><span class="pln">file   </span><span class="str">"sp.c"</span><span class="pln">
  </span><span class="pun">.</span><span class="pln">text
</span><span class="pun">.</span><span class="pln">globl function
  </span><span class="pun">.</span><span class="pln">type   function</span><span class="pun">,</span><span class="pln"> </span><span class="lit">@function</span><span class="pln">
function</span><span class="pun">:</span><span class="pln">
  subl    $16</span><span class="pun">,</span><span class="pln"> </span><span class="pun">%</span><span class="pln">esp
  movl    $100</span><span class="pun">,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">(%</span><span class="pln">esp</span><span class="pun">)</span><span class="pln">
  movl    $200</span><span class="pun">,</span><span class="pln"> </span><span class="lit">8</span><span class="pun">(%</span><span class="pln">esp</span><span class="pun">)</span><span class="pln">
  movl    $300</span><span class="pun">,</span><span class="pln"> </span><span class="lit">12</span><span class="pun">(%</span><span class="pln">esp</span><span class="pun">)</span><span class="pln">
  addl    $16</span><span class="pun">,</span><span class="pln"> </span><span class="pun">%</span><span class="pln">esp
  ret
  </span><span class="pun">.</span><span class="pln">size   function</span><span class="pun">,</span><span class="pln"> </span><span class="pun">.-</span><span class="pln">function
  </span><span class="pun">.</span><span class="pln">ident  </span><span class="str">"GCC: (GNU) 4.0.2 20050806 (prerelease) (Debian 4.0.1-4)"</span><span class="pln">
  </span><span class="pun">.</span><span class="pln">section        </span><span class="pun">.</span><span class="pln">note</span><span class="pun">.</span><span class="pln">GNU</span><span class="pun">-</span><span class="typ">stack</span><span class="pun">,</span><span class="str">""</span><span class="pun">,</span><span class="lit">@progbits</span></pre>

<p>
	عرضنا في المثال السابق دالةً بسيطةً تخصّص ثلاثة متغيرات على المكدس، إذ توضّح شيفرة فك التجميع السابقة استخدام مؤشر المكدس في معمارية x86.
</p>

<p>
	أولًا، نخصّص مساحةً على المكدس لمتغيراتنا المحلية، كما تنمو المكدسات للأسفل، لذلك يجب أن نطرح من القيمة الموجودة في مؤشر المكدس.
</p>

<p>
	تُعَدّ القيمة 16 قيمةً كبيرةً بما يكفي للاحتفاظ بمتغيراتنا المحلية، ولكن يمكن ألّا تكون بالحجم المطلوب للحفاظ على محاذاة المكدس في الذاكرة ضمن الحدود التي يتطلبها المصرّف، إذ نحتاج مثلًا 12 بايت فقط وليس 16 مع 3 قيم من النوع <code>int</code> المكوَّن من 4 بايتات، وننقل بعد ذلك القيم إلى ذاكرة المكدس التي تستخدِمها الدالة الحقيقية.
</p>

<p>
	أخيرًا، نسحب القيم من المكدس قبل العودة إلى الدالة الأصلية من خلال تحريك مؤشر المكدس إلى حيث كان قبل أن نبدأ.
</p>

<p>
	<strong>ملاحظة</strong>: لاحظ أننا استخدمنا رايةً خاصةً في مصرّف gcc، وهذه الراية هي <code>‎-fomit-frame-pointer</code> التي تحدِّد أنه لا ينبغي استخدام مسجل إضافي للاحتفاظ بمؤشر إلى بداية إطار المكدس، إذ يساعد وجود هذا المؤشر منقّحات الأخطاء للانتقال للأعلى عبر إطارات المكدس، ولكنه يجعل المسجِّل متاحًا بصورة أقل للتطبيقات الأخرى.
</p>

<h3>
	الكومة Heap
</h3>

<p>
	الكومة Heap هي مساحة من الذاكرة تديرها العملية لتخصيص الذاكرة السريع، وتُستخدَم مع المتغيرات التي لا تكون متطلبات ذاكرتها معروفةً في وقت التصريف، ويُعرَف الجزء السفلي من الكومة بالاسم <code>brk</code> وهو استدعاء النظام الذي يعدّل الكومة، كما يمكن للعملية أن تطلب من النواة تخصيص مزيد من الذاكرة لاستخدامها باستخدام الاستدعاء <code>brk</code> لتوسيع المنطقة إلى الأسفل.
</p>

<p>
	يدير استدعاء مكتبة <code>malloc</code> الكومةَ، وهذا يجعل إدارة الكومة أمرًا سهلًا للمبرمج من خلال السماح له بتخصيص وتحرير كومة ذاكرة باستخدام الاستدعاء <code>free</code>، كما يمكن أن يستخدِم الاستدعاء <code>malloc</code> أنظمةً مثل مخصّص الأصدقاء Buddy Allocator لإدارة كومة ذاكرة المستخدِم، ويمكن أن يكون الاستدعاء <code>malloc</code> ذكيًا فيما يتعلق بعملية التخصيص ويمكنه استخدام عمليات ربط مجهولة Anonymous mmaps لذاكرة عملية إضافية، وهو المكان الذي يربط منطقة من ذاكرة RAM الخاصة بالنظام مباشرةً بدلًا من ربط ملف مع ذاكرة العملية، إذ يمكن أن يكون ذلك أكثر كفاءةً، كما أنه ليس مألوفًا أن يكون لأيّ برنامج حديث سبب لاستدعاء <code>brk</code> مباشرة نظرًا لتعقيد إدارة الذاكرة بصورة صحيحة.
</p>

<h3>
	تخطيط الذاكرة
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="111017" href="https://academy.hsoub.com/uploads/monthly_2022_11/03_memory-layout.png.9d2580b696632113a4b0aa5df16c0f6d.png" rel=""><img alt="03_memory-layout.png" class="ipsImage ipsImage_thumbnailed" data-fileid="111017" data-unique="7fuv4zfyt" src="https://academy.hsoub.com/uploads/monthly_2022_11/03_memory-layout.png.9d2580b696632113a4b0aa5df16c0f6d.png"></a>
</p>

<p>
	تمتلك العملية مناطق أصغر من الذاكرة المخصَّصة لها ويكون لكل منها غرض محدد.
</p>

<p>
	ذكرنا في الشكل السابق كيفية وضع العملية في الذاكرة باستخدام النواة، إذ تحتفظ النواة لنفسها ببعض الذاكرة في الجزء العلوي من العملية، ويمكن مشاركة هذه الذاكرة فعليًا بين جميع العمليات باستخدام الذاكرة الوهمية، كما يوجد أسفل ذلك مساحة للملفات والمكتبات المربوطة <code>mmaped</code>، ثم يوجد المكدس وتحته الكومة، في حين توجد في الجزء السفلي صورة البرنامج كما جرى تحميلها من الملف القابل للتنفيذ على القرص الصلب، وسنلقي نظرةً على عملية تحميل هذه البيانات في مقالات لاحقة.
</p>

<h2>
	واصفات الملف File Descriptors
</h2>

<p>
	تعرّفنا سابقًا على الملفات الافتراضية المعطاة لكل عملية وهي <code>stdin</code> و <code>stdout</code> و <code>stderr</code>، إذ يكون لهذه الملفات دائمًا رقم واصف الملف نفسه (0 و 1 و 2 على التوالي)، وبالتالي تحتفظ النواة بواصفات الملفات بصورة فردية لكل عملية.
</p>

<p>
	تمتلك واصفات الملفات أذونات أيضًا، إذ يمكن أن تتمكّن من القراءة من ملف ولكن لا يمكنك الكتابة فيه مثلًا، إذ يحتفظ نظام التشغيل عند فتح الملف بسجل أذونات العمليات لهذا الملف في واصف الملف ولا يسمح للعملية بفعل أيّ شيء لا ينبغي فعله.
</p>

<h2>
	المسجلات Registers
</h2>

<p>
	يطبّق المعالج عمليات بسيطة على القيم الموجودة في المسجِّلات، وتُقرَأ هذه القيم وتُكتَب في الذاكرة، فلكل عملية منطقة مخصَّصة لها في الذاكرة التي تتعقّبها النواة، لذا يجب تعقّب المسجلات، فإذا حان الوقت لتتخلّى العملية المُشغَّلة عن المعالج لتشغيل عملية أخرى، فيجب حفظ حالتها الحالية، كما يجب أن نكون قادرِين على استعادة هذه الحالة عند منح العملية مزيدًا من الوقت للتشغيل على وحدة المعالجة المركزية، لذا يجب على نظام التشغيل تخزين نسخة من مسجِّلات وحدة المعالجة المركزية في الذاكرة.
</p>

<p>
	ينسخ نظام التشغيل قيم المسجّل مرةً أخرى من الذاكرة إلى مسجلات وحدة المعالجة المركزية عندما يحين وقت تشغيل العملية مرةً أخرى وستعود العملية للعمل من حيث توقفت.
</p>

<h2>
	حالة النواة
</h2>

<p>
	يجب أن تتعقّب النواة عددًا من العناصر لكل عملية والتي سنوضّحها فيما يلي.
</p>

<h3>
	حالة العملية
</h3>

<p>
	يجب على نظام التشغيل تعقّب حالة العملية، فإذا كانت العملية قيد التشغيل حاليًا، فيجب أن تكون بحالة تشغيل Running، لكن إذا طلبت العملية قراءة ملف من القرص الصلب، فسنعلَم من تسلسل الذواكر الهرمي أنّ ذلك يمكن أن يستغرق وقتًا طويلًا، إذ يجب على العملية التخلي عن تنفيذها الحالي للسماح بتشغيل عملية أخرى، ولكن لا يجب أن تسمح النواة بتشغيل العملية مرةً أخرى حتى تصبح البيانات من القرص الصلب متاحةً في الذاكرة، وبالتالي يمكن تحديد العملية على أنها في حالة انتظار القرص الصلب Disk Wait حتى تصبح البيانات جاهزةً.
</p>

<h3>
	الأولوية Priority
</h3>

<p>
	تُعَدّ بعض العمليات أكثر أهميةً من غيرها وتحظى بأولوية أعلى.
</p>

<h3>
	الإحصائيات
</h3>

<p>
	يمكن للنواة الاحتفاظ بإحصائيات حول سلوك كل عملية والتي يمكن أن تساعدها في اتخاذ قرارات حول كيفية تصرف العملية مثل معرفة ما إذا كانت العملية تقرأ من القرص الصلب في أغلب الأحيان أم أنها تنفّذ عمليات مكثفةً في وحدة المعالجة المركزية بمعدّل أعلى.
</p>

<p>
	ترجمة -وبتصرُّف- للقسمين <a href="https://www.bottomupcs.com/chapter04.xhtml" rel="external nofollow">What is a process?</a> و <a href="https://www.bottomupcs.com/elements_of_a_process.xhtml" rel="external nofollow">Elements of a process</a> من الفصل <a href="https://www.bottomupcs.com/chapter04.xhtml" rel="external nofollow">The Process</a> من كتاب <a href="https://www.bottomupcs.com/" rel="external nofollow">Computer Science from the Bottom Up</a> لصاحبه Ian Wienand.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B3%D9%84%D8%B3%D9%84-%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D9%87%D8%B1%D9%85%D9%8A-%D9%88%D8%A7%D8%B3%D8%AA%D8%AF%D8%B9%D8%A7%D8%A1%D8%A7%D8%AA-%D8%A7%D9%84%D9%86%D8%B8%D8%A7%D9%85-fork-%D9%88-exec-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1759/" rel="">تسلسل العمليات الهرمي واستدعاءات النظام Fork و Exec في نظام تشغيل الحاسوب</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D8%B3%D8%AA%D8%AF%D8%B9%D8%A7%D8%A1%D8%A7%D8%AA-%D8%A7%D9%84%D9%86%D8%B8%D8%A7%D9%85-%D9%88%D8%A7%D9%84%D8%B5%D9%84%D8%A7%D8%AD%D9%8A%D8%A7%D8%AA-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-r1757/" rel="">استدعاءات النظام والصلاحيات في نظام التشغيل</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AF%D9%88%D8%B1-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%88%D8%AA%D9%86%D8%B8%D9%8A%D9%85%D9%87-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1723/" rel="">دور نظام التشغيل وتنظيمه في معمارية الحاسوب</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/c/%D8%A7%D9%84%D9%81%D8%B5%D9%84-%D8%A7%D9%84%D8%AB%D8%A7%D9%86%D9%8A-%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA-processes-%D9%81%D9%8A-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-r977/" rel="">العمليات (Processes) في أنظمة التشغيل</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/files/24-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%84%D9%85%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D9%86/" rel="">أنظمة التشغيل للمبرمجين</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1758</guid><pubDate>Fri, 11 Nov 2022 16:09:00 +0000</pubDate></item><item><title>&#x627;&#x628;&#x62F;&#x623; &#x645;&#x639; &#x633;&#x643;&#x631;&#x627;&#x62A;&#x634; &#x641;&#x64A; &#x631;&#x627;&#x633;&#x628;&#x631;&#x64A; &#x628;&#x627;&#x64A;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D8%A8%D8%AF%D8%A3-%D9%85%D8%B9-%D8%B3%D9%83%D8%B1%D8%A7%D8%AA%D8%B4-%D9%81%D9%8A-%D8%B1%D8%A7%D8%B3%D8%A8%D8%B1%D9%8A-%D8%A8%D8%A7%D9%8A-r2083/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2023_08/----.png.386d51b83d89d76e13cb616e70797935.png" /></p>
<p>
	ستتعرف في هذا الدرس على أهم لغات البرمجة للمبتدئين حيث أننا سنشرح في هذا الدرس عن أهمية لغة سكراتش Scratch البرمجية والتي تعد مدخل إلى عالم البرمجة والفهم الصحيح للخوارزميات؛ كما ستتعرف على كيفية تنزيل تطبيق سكراتش على حاسوب راسبيري باي Raspberry Pi.
</p>

<p>
	<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" frameborder="0" height="603" id="ips_uid_8081_5" src="https://academy.hsoub.com/applications/core/interface/index.html" title="ابدأ مع سكراتش في راسبري باي" width="1072" data-embed-src="https://www.youtube.com/embed/qpMrZBJ22iM"></iframe>
</p>

<p>
	تعرف أكثر على أنظمة التشغيل و <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">سكراتش</abbr> في <a href="https://academy.hsoub.com/learn/computer-science/" rel="">دورة علوم الحاسوب المقدمة من أكاديمية حسوب</a>، ولا تنسَ الاستعانة خلال رحلة تعلمك وعملك بتوثيقات <a href="https://wiki.hsoub.com/%D8%A7%D9%84%D8%B5%D9%81%D8%AD%D8%A9_%D8%A7%D9%84%D8%B1%D8%A6%D9%8A%D8%B3%D9%8A%D8%A9" rel="external">موسوعة حسوب</a> المجانية. وإذا أردت متابعة المعلومات البرمجية العلمية مكتوبة فيمكنك الاطلاع على <a href="https://academy.hsoub.com/programming/" rel="">قسم البرمجة</a>، كما يمكنك متابعة جديد الفيديوهات التقنية المتاحة على <a href="https://www.youtube.com/@HsoubAcademy" rel="external nofollow">يوتيوب أكاديمية حسوب</a> مجانًا.
</p>
]]></description><guid isPermaLink="false">2083</guid><pubDate>Wed, 09 Nov 2022 15:00:00 +0000</pubDate></item><item><title>&#x627;&#x633;&#x62A;&#x62F;&#x639;&#x627;&#x621;&#x627;&#x62A; &#x627;&#x644;&#x646;&#x638;&#x627;&#x645; &#x648;&#x627;&#x644;&#x635;&#x644;&#x627;&#x62D;&#x64A;&#x627;&#x62A; &#x641;&#x64A; &#x646;&#x638;&#x627;&#x645; &#x627;&#x644;&#x62A;&#x634;&#x63A;&#x64A;&#x644;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D8%B3%D8%AA%D8%AF%D8%B9%D8%A7%D8%A1%D8%A7%D8%AA-%D8%A7%D9%84%D9%86%D8%B8%D8%A7%D9%85-%D9%88%D8%A7%D9%84%D8%B5%D9%84%D8%A7%D8%AD%D9%8A%D8%A7%D8%AA-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-r1757/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2022_11/636104cb6e9b6_------.png.739fc703e1a3df9001b50d5925ab5620.png" /></p>
<p>
	استدعاءات النظام system calls هي كيفية تفاعل برامج مجال المستخدِم Userspace مع نواة النظام Kernel، إذ سنشرح فيما يلي المبدأ العام لكيفية عمل هذه الاستدعاءات، وسنتعرّف على الصلاحيات في نظام التشغيل للوصول إلى الموارد.
</p>

<h2>
	أرقام استدعاءات النظام
</h2>

<p>
	لكل استدعاء نظام رقم يعرفه مجال المستخدِم والنواة، إذ يعرِف كلاهما أنّ رقم استدعاء النظام 10 هو الاستدعاء <code>open()‎</code> ورقم استدعاء النظام 11 هو الاستدعاء <code>read()‎</code> على سبيل المثال.
</p>

<p>
	تُعَدّ واجهة التطبيق الثنائية Application Binary Interface -أو ABI اختصارًا- مشابهةً جدًا <a href="https://academy.hsoub.com/programming/general/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%A7%D9%84%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A9-api-r1314/" rel="">لواجهة برمجة التطبيقات <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr></a>، ولكنها مُخصَّصة للعتاد بدلًا من أن تكون خاصةً بالبرمجيات، إذ ستحدّد واجهة برمجة التطبيقات <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr> المسجّل Register الذي يجب إدخال رقم استدعاء النظام فيه لتتمكّن النواة من العثور عليه عندما يُطلب منها إجراء استدعاء النظام.
</p>

<h2>
	الوسائط Arguments
</h2>

<p>
	لا تكون استدعاءات النظام جيدةً بدون الوسائط، فالاستدعاء <code>open()‎</code> مثلًا يحتاج إلى إعلام النواة بالضبط بالملف الذي يجب فتحه، وستحدّد واجهة ABI أيًا من وسائط المسجّلات التي يجب وضعها لاستدعاء النظام.
</p>

<h2>
	المصيدة Trap
</h2>

<p>
	يجب أن تكون هناك طريقة ما للاتصال بالنواة التي نريد إجراء استدعاء نظام إليها، إذ تعرِّف جميع المعماريات الحاسوبية تعليمةً تسمى عادةً <code>break</code> أو شيئًا آخر مشابه يشير إلى العتاد الذي نريد إجراء استدعاء النظام إليه، وستخبر هذه التعليمة العتاد بتعديل مؤشر التعليمة ليؤشّر إلى معالج استدعاءات النظام الخاص بالنواة، إذ يخبر نظام التشغيل العتاد بمكان وجود معالج استدعاء النظام عندما يضبط نفسه، لذلك يفقد مجال المستخدِم السيطرة على البرنامج وتمريره إلى النواة بمجرد أن يستدعي التعليمة <code>break</code>.
</p>

<p>
	يُعَدّ ما تبقى من هذه العملية بسيطًا إلى حد ما، إذ تبحث النواة في المسجل المُعرَّف مسبقًا عن رقم استدعاء النظام وتبحث عنه في جدول لمعرفة الدالة التي يجب أن تستدعيها، وتُستدعَى هذه الدالة وتنفّذ ما يجب تنفيذه، ثم تضع القيمة المُعادة في مسجل آخر تعرّفه الواجهة ABI بوصفه مسجّل إعادة Return.
</p>

<p>
	تتمثل الخطوة الأخيرة في أن تنفّذ النواة تعليمات قفز إلى برنامج مجال المستخدِم لتتمكّن من المتابعة من حيث توقفت، ويحصل برنامج مجال المستخدِم على البيانات التي يحتاجها من مسجِّل الإعادة ثم يكمل عمله، كما يمكن أن تصبح تفاصيل هذه العملية خطيرة للغاية، إلّا أنّ هذا كله يتعلق باستدعاء النظام.
</p>

<h2>
	مكتبة libc
</h2>

<p>
	يمكنك تنفيذ كل ما سبق يدويًا لكل استدعاء نظام، لكن تنفّذ مكتبات النظام معظم العمل نيابةً عنك عادةً، والمكتبة القياسية التي تتعامل مع استدعاءات النظام على أنظمة يونيكس هي مكتبة <code>libc</code>.
</p>

<h2>
	تحليل استدعاء النظام
</h2>

<p>
	بما أنّ مكتبات النظام تجعل الأنظمة تستدعي نيابة عنك، فيجب تطبيق اختراق منخفض المستوى لتوضيح كيفية عمل استدعاءات النظام، وسنوضح كيفية عمل أبسط استدعاء نظام <code>getpid()‎</code> الذي لا يأخذ أيّ وسيط ويعيد معرّف البرنامج أو العملية التي تكون قيد التشغيل حاليًا.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_852_16" style=""><span class="com">#include</span><span class="pln"> </span><span class="str">&lt;stdio.h&gt;</span><span class="pln">

</span><span class="pun">‫</span><span class="com">/* ‫خاصة باستدعاء النظام syscall()‎ */</span><span class="pln">
</span><span class="com">#include</span><span class="pln"> </span><span class="str">&lt;sys/syscall.h&gt;</span><span class="pln">
</span><span class="com">#include</span><span class="pln"> </span><span class="str">&lt;unistd.h&gt;</span><span class="pln">

</span><span class="com">/* أرقام استدعاءات النظام */</span><span class="pln">
</span><span class="com">#include</span><span class="pln"> </span><span class="str">&lt;asm/unistd.h&gt;</span><span class="pln">

</span><span class="kwd">void</span><span class="pln"> function</span><span class="pun">(</span><span class="kwd">void</span><span class="pun">)</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
  </span><span class="typ">int</span><span class="pln"> pid</span><span class="pun">;</span><span class="pln">

  pid </span><span class="pun">=</span><span class="pln"> __syscall</span><span class="pun">(</span><span class="pln">__NR_getpid</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">    </span></pre>

<p>
	نبدأ بكتابة برنامج صغير بلغة C لتوضيح آلية عمل استدعاءات النظام، وأول شيء يجب ملاحظته هو وجود الوسيط <code>syscall</code> الذي توفّره مكتبات النظام لإجراء استدعاءات النظام مباشرةً، إذ يوفِّر هذا الوسيط طريقةً سهلةً للمبرمجين لإجراء استدعاءات النظام مباشرةً دون الحاجة إلى معرفة إجراءات لغة التجميع الدقيقة لإجراء الاستدعاء على عتادهم.
</p>

<p>
	نستخدِم الدالة <code>getpid()‎</code> لأنّ استخدام اسم دالة رمزي في شيفرتك البرمجية أوضح وتعمل الدالة <code>getpid()‎</code> بطرق مختلفة جدًا على أنظمة مختلفة، إذ يمكن تخزين الاستدعاء <code>getpid()‎</code> في الذاكرة المخبئية في نظام لينكس مثلًا، لذا إذا جرى تشغيله مرتين، فلن تتحمل مكتبة النظام عقوبة الاضطرار إلى إجراء استدعاء نظام بالكامل للعثور على المعلومات نفسها مرةً أخرى.
</p>

<p>
	تُعرَّف أرقام استدعاءات النظام في الملف asm/unistd.h من مصدر النواة في <a href="https://academy.hsoub.com/devops/linux/%D9%85%D8%A7-%D9%87%D9%88-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%8A%D9%86%D9%83%D8%B3%D8%9F-r451/" rel="">نظام لينكس</a>، وبما أنّ هذا الملف موجود في المجلد الفرعي <code>asm</code>، فسيختلف ذلك لكل معمارية يعمل عليها نظام لينكس، كما تُعطَى أرقام استدعاءات النظام اسمًا <code>‎#define</code> يتكون من <code>‎__NR_‎</code>، وبالتالي يمكنك رؤية أنّ شيفرتك البرمجية ستجري استدعاء النظام <code>getpid</code> ويخزّن القيمة في المعرِّف <code>pid</code>.
</p>

<p>
	سنلقي نظرةً على كيفية تطبيق العديد من المعماريات لهذه الشيفرة البرمجية وسنطّلع على الشيفرة البرمجية الحقيقية التي يمكن أن تكون خطيرةً ولكن يجب الالتزام بها، فهذه هي بالضبط الطريقة التي يعمل بها نظامك.
</p>

<h3>
	معمارية PowerPC
</h3>

<p>
	يُعَدّ نظام PowerPC معماريةَ RISC شائعة في حواسيب Apple القديمة، وهو جوهر أجهزة أحدث إصدار من Xbox مثلًا، وفيما يلي مثال عن استدعاء نظام PowerPC:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_852_14" style=""><span class="com">/* ‫يتلِف استدعاءُ النظام المسجّلاتِ نفسها لاستدعاء الدالة في نظام powerpc،
* ‫باستثناء المسجّل LR الذي يحتاجه التسلسل "sc; bnslr"
* ‫والمسجّل CR حيث يُتلَف المسجل CR0.SO فقط الذي يشير إلى
* ‫حالة إعادة خطأ.
*/</span><span class="pln">

</span><span class="com">#define</span><span class="pln"> __syscall_nr</span><span class="pun">(</span><span class="pln">nr</span><span class="pun">,</span><span class="pln"> type</span><span class="pun">,</span><span class="pln"> name</span><span class="pun">,</span><span class="pln"> args</span><span class="pun">...)</span><span class="pln">                \
  </span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">long</span><span class="pln"> __sc_ret</span><span class="pun">,</span><span class="pln"> __sc_err</span><span class="pun">;</span><span class="pln">                \
  </span><span class="pun">{</span><span class="pln">                                \
    </span><span class="kwd">register</span><span class="pln"> </span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">long</span><span class="pln"> __sc_0  __asm__ </span><span class="pun">(</span><span class="str">"r0"</span><span class="pun">);</span><span class="pln">        \
    </span><span class="kwd">register</span><span class="pln"> </span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">long</span><span class="pln"> __sc_3  __asm__ </span><span class="pun">(</span><span class="str">"r3"</span><span class="pun">);</span><span class="pln">        \
    </span><span class="kwd">register</span><span class="pln"> </span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">long</span><span class="pln"> __sc_4  __asm__ </span><span class="pun">(</span><span class="str">"r4"</span><span class="pun">);</span><span class="pln">        \
    </span><span class="kwd">register</span><span class="pln"> </span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">long</span><span class="pln"> __sc_5  __asm__ </span><span class="pun">(</span><span class="str">"r5"</span><span class="pun">);</span><span class="pln">        \
    </span><span class="kwd">register</span><span class="pln"> </span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">long</span><span class="pln"> __sc_6  __asm__ </span><span class="pun">(</span><span class="str">"r6"</span><span class="pun">);</span><span class="pln">        \
    </span><span class="kwd">register</span><span class="pln"> </span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">long</span><span class="pln"> __sc_7  __asm__ </span><span class="pun">(</span><span class="str">"r7"</span><span class="pun">);</span><span class="pln">        \
                                    \
    __sc_loadargs_</span><span class="com">##nr(name, args);                \</span><span class="pln">
    __asm__ __volatile__                    \
      </span><span class="pun">(</span><span class="str">"sc           \n\t"</span><span class="pln">                \
        </span><span class="str">"mfcr %0      "</span><span class="pln">                \
      </span><span class="pun">:</span><span class="pln"> </span><span class="str">"=&amp;r"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__sc_0</span><span class="pun">),</span><span class="pln">                \
        </span><span class="str">"=&amp;r"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__sc_3</span><span class="pun">),</span><span class="pln">  </span><span class="str">"=&amp;r"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__sc_4</span><span class="pun">),</span><span class="pln">        \
        </span><span class="str">"=&amp;r"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__sc_5</span><span class="pun">),</span><span class="pln">  </span><span class="str">"=&amp;r"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__sc_6</span><span class="pun">),</span><span class="pln">        \
        </span><span class="str">"=&amp;r"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__sc_7</span><span class="pun">)</span><span class="pln">                \
      </span><span class="pun">:</span><span class="pln"> __sc_asm_input_</span><span class="com">##nr                \</span><span class="pln">
      </span><span class="pun">:</span><span class="pln"> </span><span class="str">"cr0"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"ctr"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"memory"</span><span class="pun">,</span><span class="pln">            \
        </span><span class="str">"r8"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"r9"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"r10"</span><span class="pun">,</span><span class="str">"r11"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"r12"</span><span class="pun">);</span><span class="pln">        \
    __sc_ret </span><span class="pun">=</span><span class="pln"> __sc_3</span><span class="pun">;</span><span class="pln">                    \
    __sc_err </span><span class="pun">=</span><span class="pln"> __sc_0</span><span class="pun">;</span><span class="pln">                    \
  </span><span class="pun">}</span><span class="pln">                                \
  </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__sc_err </span><span class="pun">&amp;</span><span class="pln"> </span><span class="lit">0x10000000</span><span class="pun">)</span><span class="pln">                    \
  </span><span class="pun">{</span><span class="pln">                                \
    errno </span><span class="pun">=</span><span class="pln"> __sc_ret</span><span class="pun">;</span><span class="pln">                    \
    __sc_ret </span><span class="pun">=</span><span class="pln"> </span><span class="pun">-</span><span class="lit">1</span><span class="pun">;</span><span class="pln">                        \
  </span><span class="pun">}</span><span class="pln">                                \
  </span><span class="kwd">return</span><span class="pln"> </span><span class="pun">(</span><span class="pln">type</span><span class="pun">)</span><span class="pln"> __sc_ret

</span><span class="com">#define</span><span class="pln"> __sc_loadargs_0</span><span class="pun">(</span><span class="pln">name</span><span class="pun">,</span><span class="pln"> dummy</span><span class="pun">...)</span><span class="pln">                    \
  __sc_0 </span><span class="pun">=</span><span class="pln"> __NR_</span><span class="com">##name</span><span class="pln">
</span><span class="com">#define</span><span class="pln"> __sc_loadargs_1</span><span class="pun">(</span><span class="pln">name</span><span class="pun">,</span><span class="pln"> arg1</span><span class="pun">)</span><span class="pln">                    \
  __sc_loadargs_0</span><span class="pun">(</span><span class="pln">name</span><span class="pun">);</span><span class="pln">                        \
  __sc_3 </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">long</span><span class="pun">)</span><span class="pln"> </span><span class="pun">(</span><span class="pln">arg1</span><span class="pun">)</span><span class="pln">
</span><span class="com">#define</span><span class="pln"> __sc_loadargs_2</span><span class="pun">(</span><span class="pln">name</span><span class="pun">,</span><span class="pln"> arg1</span><span class="pun">,</span><span class="pln"> arg2</span><span class="pun">)</span><span class="pln">                \
  __sc_loadargs_1</span><span class="pun">(</span><span class="pln">name</span><span class="pun">,</span><span class="pln"> arg1</span><span class="pun">);</span><span class="pln">                    \
  __sc_4 </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">long</span><span class="pun">)</span><span class="pln"> </span><span class="pun">(</span><span class="pln">arg2</span><span class="pun">)</span><span class="pln">
</span><span class="com">#define</span><span class="pln"> __sc_loadargs_3</span><span class="pun">(</span><span class="pln">name</span><span class="pun">,</span><span class="pln"> arg1</span><span class="pun">,</span><span class="pln"> arg2</span><span class="pun">,</span><span class="pln"> arg3</span><span class="pun">)</span><span class="pln">                \
  __sc_loadargs_2</span><span class="pun">(</span><span class="pln">name</span><span class="pun">,</span><span class="pln"> arg1</span><span class="pun">,</span><span class="pln"> arg2</span><span class="pun">);</span><span class="pln">                \
  __sc_5 </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">long</span><span class="pun">)</span><span class="pln"> </span><span class="pun">(</span><span class="pln">arg3</span><span class="pun">)</span><span class="pln">
</span><span class="com">#define</span><span class="pln"> __sc_loadargs_4</span><span class="pun">(</span><span class="pln">name</span><span class="pun">,</span><span class="pln"> arg1</span><span class="pun">,</span><span class="pln"> arg2</span><span class="pun">,</span><span class="pln"> arg3</span><span class="pun">,</span><span class="pln"> arg4</span><span class="pun">)</span><span class="pln">            \
  __sc_loadargs_3</span><span class="pun">(</span><span class="pln">name</span><span class="pun">,</span><span class="pln"> arg1</span><span class="pun">,</span><span class="pln"> arg2</span><span class="pun">,</span><span class="pln"> arg3</span><span class="pun">);</span><span class="pln">            \
  __sc_6 </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">long</span><span class="pun">)</span><span class="pln"> </span><span class="pun">(</span><span class="pln">arg4</span><span class="pun">)</span><span class="pln">
</span><span class="com">#define</span><span class="pln"> __sc_loadargs_5</span><span class="pun">(</span><span class="pln">name</span><span class="pun">,</span><span class="pln"> arg1</span><span class="pun">,</span><span class="pln"> arg2</span><span class="pun">,</span><span class="pln"> arg3</span><span class="pun">,</span><span class="pln"> arg4</span><span class="pun">,</span><span class="pln"> arg5</span><span class="pun">)</span><span class="pln">        \
  __sc_loadargs_4</span><span class="pun">(</span><span class="pln">name</span><span class="pun">,</span><span class="pln"> arg1</span><span class="pun">,</span><span class="pln"> arg2</span><span class="pun">,</span><span class="pln"> arg3</span><span class="pun">,</span><span class="pln"> arg4</span><span class="pun">);</span><span class="pln">            \
  __sc_7 </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">long</span><span class="pun">)</span><span class="pln"> </span><span class="pun">(</span><span class="pln">arg5</span><span class="pun">)</span><span class="pln">

</span><span class="com">#define</span><span class="pln"> __sc_asm_input_0 </span><span class="str">"0"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__sc_0</span><span class="pun">)</span><span class="pln">
</span><span class="com">#define</span><span class="pln"> __sc_asm_input_1 __sc_asm_input_0</span><span class="pun">,</span><span class="pln"> </span><span class="str">"1"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__sc_3</span><span class="pun">)</span><span class="pln">
</span><span class="com">#define</span><span class="pln"> __sc_asm_input_2 __sc_asm_input_1</span><span class="pun">,</span><span class="pln"> </span><span class="str">"2"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__sc_4</span><span class="pun">)</span><span class="pln">
</span><span class="com">#define</span><span class="pln"> __sc_asm_input_3 __sc_asm_input_2</span><span class="pun">,</span><span class="pln"> </span><span class="str">"3"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__sc_5</span><span class="pun">)</span><span class="pln">
</span><span class="com">#define</span><span class="pln"> __sc_asm_input_4 __sc_asm_input_3</span><span class="pun">,</span><span class="pln"> </span><span class="str">"4"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__sc_6</span><span class="pun">)</span><span class="pln">
</span><span class="com">#define</span><span class="pln"> __sc_asm_input_5 __sc_asm_input_4</span><span class="pun">,</span><span class="pln"> </span><span class="str">"5"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__sc_7</span><span class="pun">)</span><span class="pln">

</span><span class="com">#define</span><span class="pln"> _syscall0</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">name</span><span class="pun">)</span><span class="pln">                        \
type name</span><span class="pun">(</span><span class="kwd">void</span><span class="pun">)</span><span class="pln">                                \
</span><span class="pun">{</span><span class="pln">                                    \
    __syscall_nr</span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> type</span><span class="pun">,</span><span class="pln"> name</span><span class="pun">);</span><span class="pln">                    \
</span><span class="pun">}</span><span class="pln">

</span><span class="com">#define</span><span class="pln"> _syscall1</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">name</span><span class="pun">,</span><span class="pln">type1</span><span class="pun">,</span><span class="pln">arg1</span><span class="pun">)</span><span class="pln">                    \
type name</span><span class="pun">(</span><span class="pln">type1 arg1</span><span class="pun">)</span><span class="pln">                            \
</span><span class="pun">{</span><span class="pln">                                    \
  __syscall_nr</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> type</span><span class="pun">,</span><span class="pln"> name</span><span class="pun">,</span><span class="pln"> arg1</span><span class="pun">);</span><span class="pln">                \
</span><span class="pun">}</span><span class="pln">

</span><span class="com">#define</span><span class="pln"> _syscall2</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">name</span><span class="pun">,</span><span class="pln">type1</span><span class="pun">,</span><span class="pln">arg1</span><span class="pun">,</span><span class="pln">type2</span><span class="pun">,</span><span class="pln">arg2</span><span class="pun">)</span><span class="pln">            \
type name</span><span class="pun">(</span><span class="pln">type1 arg1</span><span class="pun">,</span><span class="pln"> type2 arg2</span><span class="pun">)</span><span class="pln">                    \
</span><span class="pun">{</span><span class="pln">                                    \
  __syscall_nr</span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> type</span><span class="pun">,</span><span class="pln"> name</span><span class="pun">,</span><span class="pln"> arg1</span><span class="pun">,</span><span class="pln"> arg2</span><span class="pun">);</span><span class="pln">            \
</span><span class="pun">}</span><span class="pln">

</span><span class="com">#define</span><span class="pln"> _syscall3</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">name</span><span class="pun">,</span><span class="pln">type1</span><span class="pun">,</span><span class="pln">arg1</span><span class="pun">,</span><span class="pln">type2</span><span class="pun">,</span><span class="pln">arg2</span><span class="pun">,</span><span class="pln">type3</span><span class="pun">,</span><span class="pln">arg3</span><span class="pun">)</span><span class="pln">        \
type name</span><span class="pun">(</span><span class="pln">type1 arg1</span><span class="pun">,</span><span class="pln"> type2 arg2</span><span class="pun">,</span><span class="pln"> type3 arg3</span><span class="pun">)</span><span class="pln">                \
</span><span class="pun">{</span><span class="pln">                                    \
  __syscall_nr</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> type</span><span class="pun">,</span><span class="pln"> name</span><span class="pun">,</span><span class="pln"> arg1</span><span class="pun">,</span><span class="pln"> arg2</span><span class="pun">,</span><span class="pln"> arg3</span><span class="pun">);</span><span class="pln">            \
</span><span class="pun">}</span><span class="pln">

</span><span class="com">#define</span><span class="pln"> _syscall4</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">name</span><span class="pun">,</span><span class="pln">type1</span><span class="pun">,</span><span class="pln">arg1</span><span class="pun">,</span><span class="pln">type2</span><span class="pun">,</span><span class="pln">arg2</span><span class="pun">,</span><span class="pln">type3</span><span class="pun">,</span><span class="pln">arg3</span><span class="pun">,</span><span class="pln">type4</span><span class="pun">,</span><span class="pln">arg4</span><span class="pun">)</span><span class="pln"> \
type name</span><span class="pun">(</span><span class="pln">type1 arg1</span><span class="pun">,</span><span class="pln"> type2 arg2</span><span class="pun">,</span><span class="pln"> type3 arg3</span><span class="pun">,</span><span class="pln"> type4 arg4</span><span class="pun">)</span><span class="pln">        \
</span><span class="pun">{</span><span class="pln">                                    \
  __syscall_nr</span><span class="pun">(</span><span class="lit">4</span><span class="pun">,</span><span class="pln"> type</span><span class="pun">,</span><span class="pln"> name</span><span class="pun">,</span><span class="pln"> arg1</span><span class="pun">,</span><span class="pln"> arg2</span><span class="pun">,</span><span class="pln"> arg3</span><span class="pun">,</span><span class="pln"> arg4</span><span class="pun">);</span><span class="pln">        \
</span><span class="pun">}</span><span class="pln">

</span><span class="com">#define</span><span class="pln"> _syscall5</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">name</span><span class="pun">,</span><span class="pln">type1</span><span class="pun">,</span><span class="pln">arg1</span><span class="pun">,</span><span class="pln">type2</span><span class="pun">,</span><span class="pln">arg2</span><span class="pun">,</span><span class="pln">type3</span><span class="pun">,</span><span class="pln">arg3</span><span class="pun">,</span><span class="pln">type4</span><span class="pun">,</span><span class="pln">arg4</span><span class="pun">,</span><span class="pln">type5</span><span class="pun">,</span><span class="pln">arg5</span><span class="pun">)</span><span class="pln"> \
type name</span><span class="pun">(</span><span class="pln">type1 arg1</span><span class="pun">,</span><span class="pln"> type2 arg2</span><span class="pun">,</span><span class="pln"> type3 arg3</span><span class="pun">,</span><span class="pln"> type4 arg4</span><span class="pun">,</span><span class="pln"> type5 arg5</span><span class="pun">)</span><span class="pln">    \
</span><span class="pun">{</span><span class="pln">                                    \
  __syscall_nr</span><span class="pun">(</span><span class="lit">5</span><span class="pun">,</span><span class="pln"> type</span><span class="pun">,</span><span class="pln"> name</span><span class="pun">,</span><span class="pln"> arg1</span><span class="pun">,</span><span class="pln"> arg2</span><span class="pun">,</span><span class="pln"> arg3</span><span class="pun">,</span><span class="pln"> arg4</span><span class="pun">,</span><span class="pln"> arg5</span><span class="pun">);</span><span class="pln">    \
</span><span class="pun">}</span><span class="pln">    </span></pre>

<p>
	يوضِّح جزء الشيفرة البرمجية السابق من ملف ترويسة النواة asm/unistd.h كيف يمكننا تطبيق استدعاءات النظام على نظام PowerPC، ويمكن أن يبدو الأمر معقدًا للغاية، ولكن لنشرحه خطوةً خطوة.
</p>

<p>
	انتقل أولًا إلى نهاية المثال إلى تعريف وحدات الماكرو <code>‎_syscallN</code>، إذ يمكنك رؤية أنّ هناك العديد من وحدات الماكرو ويأخذ كل منها وسيطًا آخر تدريجيًا، وسنركّز على أبسط إصدار وهو <code>‎_syscall0</code> للبدء به والذي لا يتطلب سوى وسيطَين هما نوع القيمة المُعادة لاستدعاء النظام مثل <code>int</code> أو <code>char</code> واسم استدعاء النظام، إذ يكون مع الاستدعاء <code>getpid</code> بالصورة <code>‎_syscall0(int,getpid)‎</code>.
</p>

<p>
	سنبدأ الآن بتفكيك الماكرو <code>‎__syscall_nr</code> الذي لا يختلف عما كان عليه سابقًا، إذ سنأخذ عدد الوسائط على أنه المعامِل الأول ثم النوع والاسم والوسائط الفعلية، فالخطوة الأولى هي التصريح عن بعض الأسماء للمسجّلات، إذ يشير الاسم <code>‎__sc_0</code> إلى المسجّل <code>r0</code> أي المسجّل 0، ويستخدِم المصرِّف Compiler المسجلات بالطريقة التي يريدها، لذلك يجب أن نعطيه قيودًا حتى لا يقرّر استخدام المسجّل الذي نحتاجه بطريقة مخصصة.
</p>

<p>
	سنستدعي بعد ذلك <code>sc_loadargs</code> إلى جانب المعامِل <code>##</code> الذي يُعَدّ أمر لصق يُستبدَل بالمتغير <code>nr</code>، وسنوسّعه إلى <code>‎__sc_loadargs_0(name, args);‎</code>، ويمكننا رؤية <code>‎__sc_loadargs</code> الذي يضبط <code>‎__sc_0</code> ليكون رقم استدعاء النظام، ولاحظ معامِل اللصق مرةً أخرى مع البادئة <code>‎__NR_‎</code> واسم المتغير الذي يشير إلى مسجّل معيّن، لذا تُستخدَم هذه الشيفرة البرمجية السابقة ذات المظهر الصعب لوضع رقم استدعاء النظام في المسجّل 0، كما يمكنك باتباع الشيفرة البرمجية السابقة رؤية أن وحدات الماكرو الأخرى ستضع وسائط استدعاء النظام في المسجّل <code>r3</code> عبر المسجّل <code>r7</code>، ويمكنك فقط الحصول على 5 وسائط على أساس حد أقصى لاستدعاء النظام.
</p>

<p>
	سنعالج الآن القسم <code>__asm__</code>، إذ لدينا هنا ما يسمّى بالتجميع المُضمَّن Inline Assembly لأنها شيفرة تجميع مختلطة مع الشيفرة المصدرية، وهذه الصيغة معقدة بعض الشيء، لذلك سنشير إلى الأجزاء المهمة منها فقط، كما عليك تجاهل البت <code>__volatile__</code> حاليًا والذي يخبر المصرّف أنّ هذه الشيفرة البرمجية لا يمكن التنبؤ بها، لذا لا تحاول التعامل معها بذكاء، كما أنّ كل الأشياء الموجودة بعد النقطتين هي طريقة للتواصل مع المصرّف حول ما يفعله التجميع المضمَّن لمسجلات وحدة المعالجة المركزية، ويجب أن يعرِف المصرّف ذلك حتى لا يحاول استخدام أيّ من هذه المسجلات بطرق يمكنها التسبب في حدوث عطل.
</p>

<p>
	لكن الجزء المهم هو وجود تعليمتَي التجميع في الوسيط الأول، إذ ينفِّذ الاستدعاء <code>sc</code> كل العمل، وهذا كل ما عليك تطبيقه لإجراء استدعاء نظام، وبالتالي يحدث ما يلي عند إجراء استدعاء النظام، إذ يعرف المعالِج المُقاطَع أنه يجب عليه نقل التحكم إلى جزء معيّن من إعداد الشيفرة البرمجية في وقت بدء تشغيل النظام لمعالجة المقاطعات، كما توجد هناك العديد من المقاطعات، وتُعَدّ استدعاءات النظام إحداها، وتبحث هذه الشيفرة البرمجية بعد ذلك في المسجل 0 للعثور على رقم استدعاء النظام، ثم تبحث في جدول لإيجاد الدالة الصحيحة للانتقال إليها لمعالجة استدعاء النظام، وتتلقى هذه الدالة وسائطها من المسجل 3 إلى المسجل 7.
</p>

<p>
	يعود التحكم إلى التعليمة التالية بعد <code>sc</code> وهي في هذه الحالة تعليمات سور الذاكرة Memory Fence بمجرد تشغيل معالج استدعاء النظام واكتماله، كما تتأكد تعليمات سور الذاكرة من أن كل شيء ملتزم بالذاكرة، حيث تضمن هذه التعليمة أنّ كل ما نعتقد أنه مكتوب في الذاكرة قد حدث فعليًا دون المرور عبر خط أنابيب Pipeline في مكان ما.
</p>

<p>
	انتهينا تقريبًا، ولكن الشيء الوحيد المتبقي هو إعادة القيمة من استدعاء النظام، إذ نرى ضبط القيمة <code>‎__sc_ret</code> من المسجل r3 وضبط القيمة <code>‎__sc_err</code> من المسجل r0، فالقيمة الأولى هي القيمة المُعادة، والأخرى هي قيمة الخطأ، إذ يمكن أن تفشل استدعاءات النظام مثل أيّ دالة أخرى، لكن تكمن المشكلة في أنّ استدعاء النظام يمكن أن يعيد أيّ قيمة ممكنة، إذ لا يمكننا أن نقول أن القيمة السالبة تشير إلى الفشل، لأنها يمكن أن تكون مقبولةً لبعض استدعاءات النظام، لذا تضمن دالة استدعاء النظام أنّ نتيجتها في المسجل r3 وأنّ أيّ رمز خطأ موجود في المسجل r0 قبل إعادة النتيجة.
</p>

<p>
	يجب التحقق من رمز الخطأ للتأكد من ضبط البِتّ العلوي الذي من شأنه الإشارة إلى عدد سالب، فإذا كان الأمر كذلك، فسنضبط قيمة المتغير <code>errno</code> العام على هذه القيمة وهي المتغير القياسي للحصول على معلومات الخطأ عند فشل الاستدعاء، كما سنضبط القيمة المُعادة على <code>‎-1</code>، وسنعيد النتيجة مباشرةً في حالة تلقّي نتيجة صالحة، لذا يجب على دالة الاستدعاء التحقق من أنّ القيمة المعادة ليست <code>‎-1</code>، فإذا كان الأمر كذلك، فيمكنها التحقق من المتغير <code>errno</code> للعثور على سبب فشل الاستدعاء، وهذا هو استدعاء نظام كامل على نظام PowerPC.
</p>

<h3>
	استدعاءات نظام x86
</h3>

<p>
	إليك الواجهة المطبَّقة لمعالج x86:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_852_20" style=""><span class="pun">‫/‫*</span><span class="pln"> </span><span class="pun">‫توجد</span><span class="pln"> </span><span class="pun">أرقام</span><span class="pln"> </span><span class="pun">الأخطاء</span><span class="pln"> </span><span class="pun">المرئية</span><span class="pln"> </span><span class="pun">للمستخدِم</span><span class="pln"> </span><span class="pun">ضمن</span><span class="pln"> </span><span class="pun">المجال</span><span class="pln"> </span><span class="pun">من</span><span class="pln"> </span><span class="pun">‎-</span><span class="lit">1</span><span class="pln"> </span><span class="pun">إلى</span><span class="pln"> </span><span class="pun">‎-</span><span class="lit">124</span><span class="pun">:</span><span class="pln"> </span><span class="pun">راجع</span><span class="pln"> </span><span class="str">&lt;asm-i386/errno.h&gt;</span><span class="pln"> </span><span class="pun">*/</span><span class="pln">

</span><span class="com">#define</span><span class="pln"> __syscall_return</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln"> res</span><span class="pun">)</span><span class="pln">                \
</span><span class="kwd">do</span><span class="pln"> </span><span class="pun">{</span><span class="pln">                                \
  </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">((</span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">long</span><span class="pun">)(</span><span class="pln">res</span><span class="pun">)</span><span class="pln"> </span><span class="pun">&gt;=</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">long</span><span class="pun">)(-</span><span class="lit">125</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span><span class="pln">    \
    errno </span><span class="pun">=</span><span class="pln"> </span><span class="pun">-(</span><span class="pln">res</span><span class="pun">);</span><span class="pln">                    \
    res </span><span class="pun">=</span><span class="pln"> </span><span class="pun">-</span><span class="lit">1</span><span class="pun">;</span><span class="pln">                    \
  </span><span class="pun">}</span><span class="pln">                            \
  </span><span class="kwd">return</span><span class="pln"> </span><span class="pun">(</span><span class="pln">type</span><span class="pun">)</span><span class="pln"> </span><span class="pun">(</span><span class="pln">res</span><span class="pun">);</span><span class="pln">                    \
</span><span class="pun">}</span><span class="pln"> </span><span class="kwd">while</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0</span><span class="pun">)</span><span class="pln">

</span><span class="pun">‫/‫*</span><span class="pln"> </span><span class="pun">‫‎</span><span class="pln">_foo </span><span class="pun">يجب</span><span class="pln"> </span><span class="pun">أن</span><span class="pln"> </span><span class="pun">تكون</span><span class="pln"> </span><span class="pun">‎</span><span class="pln">__foo</span><span class="pun">،</span><span class="pln"> </span><span class="pun">بينما</span><span class="pln"> </span><span class="pun">‎</span><span class="pln">__NR_bar </span><span class="pun">يمكن</span><span class="pln"> </span><span class="pun">أن</span><span class="pln"> </span><span class="pun">تكون</span><span class="pln"> </span><span class="pun">‎</span><span class="pln">_NR_bar </span><span class="pun">*/</span><span class="pln">
</span><span class="com">#define</span><span class="pln"> _syscall0</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">name</span><span class="pun">)</span><span class="pln">            \
type name</span><span class="pun">(</span><span class="kwd">void</span><span class="pun">)</span><span class="pln">                    \
</span><span class="pun">{</span><span class="pln">                        \
</span><span class="kwd">long</span><span class="pln"> __res</span><span class="pun">;</span><span class="pln">                    \
__asm__ </span><span class="kwd">volatile</span><span class="pln"> </span><span class="pun">(</span><span class="str">"int $0x80"</span><span class="pln">            \
  </span><span class="pun">:</span><span class="pln"> </span><span class="str">"=a"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__res</span><span class="pun">)</span><span class="pln">                \
  </span><span class="pun">:</span><span class="pln"> </span><span class="str">"0"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__NR_</span><span class="com">##name));            \</span><span class="pln">
__syscall_return</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">__res</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="com">#define</span><span class="pln"> _syscall1</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">name</span><span class="pun">,</span><span class="pln">type1</span><span class="pun">,</span><span class="pln">arg1</span><span class="pun">)</span><span class="pln">            \
type name</span><span class="pun">(</span><span class="pln">type1 arg1</span><span class="pun">)</span><span class="pln">                    \
</span><span class="pun">{</span><span class="pln">                            \
</span><span class="kwd">long</span><span class="pln"> __res</span><span class="pun">;</span><span class="pln">                        \
__asm__ </span><span class="kwd">volatile</span><span class="pln"> </span><span class="pun">(</span><span class="str">"int $0x80"</span><span class="pln">                \
  </span><span class="pun">:</span><span class="pln"> </span><span class="str">"=a"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__res</span><span class="pun">)</span><span class="pln">                    \
  </span><span class="pun">:</span><span class="pln"> </span><span class="str">"0"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__NR_</span><span class="com">##name),"b" ((long)(arg1)));    \</span><span class="pln">
__syscall_return</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">__res</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="com">#define</span><span class="pln"> _syscall2</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">name</span><span class="pun">,</span><span class="pln">type1</span><span class="pun">,</span><span class="pln">arg1</span><span class="pun">,</span><span class="pln">type2</span><span class="pun">,</span><span class="pln">arg2</span><span class="pun">)</span><span class="pln">            \
type name</span><span class="pun">(</span><span class="pln">type1 arg1</span><span class="pun">,</span><span class="pln">type2 arg2</span><span class="pun">)</span><span class="pln">                    \
</span><span class="pun">{</span><span class="pln">                                    \
</span><span class="kwd">long</span><span class="pln"> __res</span><span class="pun">;</span><span class="pln">                                \
__asm__ </span><span class="kwd">volatile</span><span class="pln"> </span><span class="pun">(</span><span class="str">"int $0x80"</span><span class="pln">                        \
  </span><span class="pun">:</span><span class="pln"> </span><span class="str">"=a"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__res</span><span class="pun">)</span><span class="pln">                            \
  </span><span class="pun">:</span><span class="pln"> </span><span class="str">"0"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__NR_</span><span class="com">##name),"b" ((long)(arg1)),"c" ((long)(arg2)));    \</span><span class="pln">
__syscall_return</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">__res</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="com">#define</span><span class="pln"> _syscall3</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">name</span><span class="pun">,</span><span class="pln">type1</span><span class="pun">,</span><span class="pln">arg1</span><span class="pun">,</span><span class="pln">type2</span><span class="pun">,</span><span class="pln">arg2</span><span class="pun">,</span><span class="pln">type3</span><span class="pun">,</span><span class="pln">arg3</span><span class="pun">)</span><span class="pln">        \
type name</span><span class="pun">(</span><span class="pln">type1 arg1</span><span class="pun">,</span><span class="pln">type2 arg2</span><span class="pun">,</span><span class="pln">type3 arg3</span><span class="pun">)</span><span class="pln">                \
</span><span class="pun">{</span><span class="pln">                                    \
</span><span class="kwd">long</span><span class="pln"> __res</span><span class="pun">;</span><span class="pln">                                \
__asm__ </span><span class="kwd">volatile</span><span class="pln"> </span><span class="pun">(</span><span class="str">"int $0x80"</span><span class="pln">                        \
  </span><span class="pun">:</span><span class="pln"> </span><span class="str">"=a"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__res</span><span class="pun">)</span><span class="pln">                            \
  </span><span class="pun">:</span><span class="pln"> </span><span class="str">"0"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__NR_</span><span class="com">##name),"b" ((long)(arg1)),"c" ((long)(arg2)),    \</span><span class="pln">
                  </span><span class="str">"d"</span><span class="pln"> </span><span class="pun">((</span><span class="kwd">long</span><span class="pun">)(</span><span class="pln">arg3</span><span class="pun">)));</span><span class="pln">                    \
__syscall_return</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">__res</span><span class="pun">);</span><span class="pln">                        \
</span><span class="pun">}</span><span class="pln">

</span><span class="com">#define</span><span class="pln"> _syscall4</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">name</span><span class="pun">,</span><span class="pln">type1</span><span class="pun">,</span><span class="pln">arg1</span><span class="pun">,</span><span class="pln">type2</span><span class="pun">,</span><span class="pln">arg2</span><span class="pun">,</span><span class="pln">type3</span><span class="pun">,</span><span class="pln">arg3</span><span class="pun">,</span><span class="pln">type4</span><span class="pun">,</span><span class="pln">arg4</span><span class="pun">)</span><span class="pln">    \
type name </span><span class="pun">(</span><span class="pln">type1 arg1</span><span class="pun">,</span><span class="pln"> type2 arg2</span><span class="pun">,</span><span class="pln"> type3 arg3</span><span class="pun">,</span><span class="pln"> type4 arg4</span><span class="pun">)</span><span class="pln">            \
</span><span class="pun">{</span><span class="pln">                                        \
</span><span class="kwd">long</span><span class="pln"> __res</span><span class="pun">;</span><span class="pln">                                    \
__asm__ </span><span class="kwd">volatile</span><span class="pln"> </span><span class="pun">(</span><span class="str">"int $0x80"</span><span class="pln">                            \
  </span><span class="pun">:</span><span class="pln"> </span><span class="str">"=a"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__res</span><span class="pun">)</span><span class="pln">                                \
  </span><span class="pun">:</span><span class="pln"> </span><span class="str">"0"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__NR_</span><span class="com">##name),"b" ((long)(arg1)),"c" ((long)(arg2)),        \</span><span class="pln">
          </span><span class="str">"d"</span><span class="pln"> </span><span class="pun">((</span><span class="kwd">long</span><span class="pun">)(</span><span class="pln">arg3</span><span class="pun">)),</span><span class="str">"S"</span><span class="pln"> </span><span class="pun">((</span><span class="kwd">long</span><span class="pun">)(</span><span class="pln">arg4</span><span class="pun">)));</span><span class="pln">                \
__syscall_return</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">__res</span><span class="pun">);</span><span class="pln">                            \
</span><span class="pun">}</span><span class="pln">

</span><span class="com">#define</span><span class="pln"> _syscall5</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">name</span><span class="pun">,</span><span class="pln">type1</span><span class="pun">,</span><span class="pln">arg1</span><span class="pun">,</span><span class="pln">type2</span><span class="pun">,</span><span class="pln">arg2</span><span class="pun">,</span><span class="pln">type3</span><span class="pun">,</span><span class="pln">arg3</span><span class="pun">,</span><span class="pln">type4</span><span class="pun">,</span><span class="pln">arg4</span><span class="pun">,</span><span class="pln">    \
          type5</span><span class="pun">,</span><span class="pln">arg5</span><span class="pun">)</span><span class="pln">                                \
type name </span><span class="pun">(</span><span class="pln">type1 arg1</span><span class="pun">,</span><span class="pln">type2 arg2</span><span class="pun">,</span><span class="pln">type3 arg3</span><span class="pun">,</span><span class="pln">type4 arg4</span><span class="pun">,</span><span class="pln">type5 arg5</span><span class="pun">)</span><span class="pln">        \
</span><span class="pun">{</span><span class="pln">                                        \
</span><span class="kwd">long</span><span class="pln"> __res</span><span class="pun">;</span><span class="pln">                                    \
__asm__ </span><span class="kwd">volatile</span><span class="pln"> </span><span class="pun">(</span><span class="str">"int $0x80"</span><span class="pln">                            \
  </span><span class="pun">:</span><span class="pln"> </span><span class="str">"=a"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__res</span><span class="pun">)</span><span class="pln">                                \
  </span><span class="pun">:</span><span class="pln"> </span><span class="str">"0"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__NR_</span><span class="com">##name),"b" ((long)(arg1)),"c" ((long)(arg2)),        \</span><span class="pln">
          </span><span class="str">"d"</span><span class="pln"> </span><span class="pun">((</span><span class="kwd">long</span><span class="pun">)(</span><span class="pln">arg3</span><span class="pun">)),</span><span class="str">"S"</span><span class="pln"> </span><span class="pun">((</span><span class="kwd">long</span><span class="pun">)(</span><span class="pln">arg4</span><span class="pun">)),</span><span class="str">"D"</span><span class="pln"> </span><span class="pun">((</span><span class="kwd">long</span><span class="pun">)(</span><span class="pln">arg5</span><span class="pun">)));</span><span class="pln">        \
__syscall_return</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">__res</span><span class="pun">);</span><span class="pln">                            \
</span><span class="pun">}</span><span class="pln">

</span><span class="com">#define</span><span class="pln"> _syscall6</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">name</span><span class="pun">,</span><span class="pln">type1</span><span class="pun">,</span><span class="pln">arg1</span><span class="pun">,</span><span class="pln">type2</span><span class="pun">,</span><span class="pln">arg2</span><span class="pun">,</span><span class="pln">type3</span><span class="pun">,</span><span class="pln">arg3</span><span class="pun">,</span><span class="pln">type4</span><span class="pun">,</span><span class="pln">arg4</span><span class="pun">,</span><span class="pln">            \
          type5</span><span class="pun">,</span><span class="pln">arg5</span><span class="pun">,</span><span class="pln">type6</span><span class="pun">,</span><span class="pln">arg6</span><span class="pun">)</span><span class="pln">                                \
type name </span><span class="pun">(</span><span class="pln">type1 arg1</span><span class="pun">,</span><span class="pln">type2 arg2</span><span class="pun">,</span><span class="pln">type3 arg3</span><span class="pun">,</span><span class="pln">type4 arg4</span><span class="pun">,</span><span class="pln">type5 arg5</span><span class="pun">,</span><span class="pln">type6 arg6</span><span class="pun">)</span><span class="pln">            \
</span><span class="pun">{</span><span class="pln">                                                \
</span><span class="kwd">long</span><span class="pln"> __res</span><span class="pun">;</span><span class="pln">                                            \
__asm__ </span><span class="kwd">volatile</span><span class="pln"> </span><span class="pun">(</span><span class="str">"push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; int $0x80 ; pop %%ebp"</span><span class="pln">    \
  </span><span class="pun">:</span><span class="pln"> </span><span class="str">"=a"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__res</span><span class="pun">)</span><span class="pln">                                        \
  </span><span class="pun">:</span><span class="pln"> </span><span class="str">"i"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">__NR_</span><span class="com">##name),"b" ((long)(arg1)),"c" ((long)(arg2)),                \</span><span class="pln">
          </span><span class="str">"d"</span><span class="pln"> </span><span class="pun">((</span><span class="kwd">long</span><span class="pun">)(</span><span class="pln">arg3</span><span class="pun">)),</span><span class="str">"S"</span><span class="pln"> </span><span class="pun">((</span><span class="kwd">long</span><span class="pun">)(</span><span class="pln">arg4</span><span class="pun">)),</span><span class="str">"D"</span><span class="pln"> </span><span class="pun">((</span><span class="kwd">long</span><span class="pun">)(</span><span class="pln">arg5</span><span class="pun">)),</span><span class="pln">                \
          </span><span class="str">"0"</span><span class="pln"> </span><span class="pun">((</span><span class="kwd">long</span><span class="pun">)(</span><span class="pln">arg6</span><span class="pun">)));</span><span class="pln">                                    \
__syscall_return</span><span class="pun">(</span><span class="pln">type</span><span class="pun">,</span><span class="pln">__res</span><span class="pun">);</span><span class="pln">                                    \
</span><span class="pun">}</span><span class="pln">    </span></pre>

<p>
	تختلف معمارية x86 كثيرًا عن PowerPC التي تحدّثنا عنها سابقًا، إذ يُصنَّف x86 على أنه معالِج من النوع CISC على عكس PowerPC الذي يُعَدذ من النوع RISC، ولديه مسجلات أقل بكثير.
</p>

<p>
	اطّلع على أبسط ماكرو <code>‎_syscall0</code> الذي يستدعي تعليمة من النوع <code>int</code> والقيمة <code>0x80</code>، إذ تعمل هذه التعليمة على جعل وحدة المعالجة المركزية ترفع المقاطعة 0x80 التي ستنتقل إلى الشيفرة البرمجية التي تعالج استدعاءات النظام في النواة.
</p>

<p>
	لنفحص الآن كيفية تمرير الوسائط باستخدام وحدات الماكرو الأطول، ولاحظ كيف أنّ نظام PowerPC قد طبّق تتال وانسياب cascade من وحدات الماكرو من خلال إضافة وسيط واحد في كل مرة، كما يحتوي هذا التطبيق على شيفرة برمجية منسوخة ولكن اتباعه أسهل قليلًا.
</p>

<p>
	تستند أسماء المسجّلات في معمارية x86 إلى الأحرف عوضًا عن أسماء المسجّلات الرقمية في PowerPC، إذ يمكننا رؤية من الماكرو عديم الوسائط أنّ المسجّل <code>A</code> يُحمَّل فقط، وبالتالي يمكننا القول أنّ رقم استدعاء النظام متوقَّع وجوده في المسجّل <code>EAX</code>، كما يمكنك رؤية أسماء المسجلات المختصرة في وسائط استدعاء <code>__asm__</code> عندما نبدأ بتحميل المسجلات في وحدات الماكرو الأخرى.
</p>

<p>
	لاحظ الماكرو <code>‎__syscall6</code> الذي يأخذ 6 وسائط، إذ تعمل التعليمتان <code>push</code> و <code>pop</code> مع المكدس في x86، بحيث تدفع إحداهما قيمةً إلى أعلى المكدس في الذاكرة وتسحب الأخرى القيمة من المكدس في الذاكرة، كما يجب تخزين قيمة المسجل <code>ebp</code> في الذاكرة ووضع الوسيط في التعليمة <code>mov</code> وإجراء استدعاء للنظام، ثم إعادة القيمة الأصلية إلى المسجل <code>ebp</code> في حالة وجود ستة مسجلات، كما يمكنك هنا رؤية عيوب عدم وجود مسجلات كافية، إذ يُعَدّ التخزين في الذاكرة باهظ الثمن، لذا كلما تمكنت من تجنّبها، كان ذلك أفضل.
</p>

<p>
	لاحظ عدم وجود تعليمات سور الذاكرة التي رأيناها سابقًا مع PowerPC لأنّ معمارية x86 تضمن أن يكون تأثير جميع التعليمات مرئيًا عند اكتمالها، مما يسهّل البرمجة على المصرّف والمبرمج ولكنه يقلل من المرونة.
</p>

<p>
	يوجد أيضًا اختلاف في القيمة المُعادة، فقد كان لدينا مسجّلَين مع قيم مُعادة من النواة في معمارية PowerPC، إحداهما هي القيمة والأخرى هي رمز الخطأ، في حين لدينا قيمة مُعادة واحدة في معمارية x86 تُمرَّر إلى الماكرو <code>‎__syscall_return</code> الذي يغيّر نوع القيمة المُعادة إلى النوع <code>unsigned long</code> ويوازنها مع مجال من القيم السالبة تعتمد على المعمارية والنواة، حيث تمثّل هذه القيم رموز الخطأ.
</p>

<p>
	لاحظ أنّ قيمة رمز الخطأ <code>errno</code> موجبة، مما يؤدي إلى إلغاء النتيجة السالبة من النواة، لكن يعني هذا أنّ استدعاءات النظام لا يمكنها إعادة قيم سالبة صغيرة، إذ لا يمكن تمييزها عن رموز الخطأ، كما تضيف بعض استدعاءات النظام التي لديها هذا المتطلب مثل الاستدعاء <code>getpriority()‎</code> إزاحةً إلى القيمة المُعادة لإجبارها بأن تكون دائمًا موجبة، فالأمر متروك لمجال المستخدِم لإدراك ذلك وطرح هذه القيمة الثابتة للحصول على القيمة الحقيقية.
</p>

<h2>
	الصلاحيات
</h2>

<p>
	يُعَدّ تطبيق الأمان أحد مهام <a href="https://academy.hsoub.com/files/24-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%84%D9%85%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D9%86/" rel="">نظام التشغيل</a> الرئيسية بهدف عدم السماح لتطبيق أو مستخدِم بالتضارب مع أيّ تطبيق آخر يعمل في النظام، وهذا يعني أن التطبيقات يجب ألّا تكون قادرةً على الكتابة في ذاكرة أو ملفات التطبيقات الأخرى، ويجب أن تصل فقط إلى الموارد وفق سياسة النظام.
</p>

<p>
	لكن يكون لأحد التطبيقات عند تشغليها استخدام حصري للمعالج، إذ سنرى كيف يعمل ذلك عندما نتعرّف على العمليات في المقال التالي، ويمكن التأكد من وصول التطبيق إلى الذاكرة التي يمتلكها فقط باستخدام نظام الذاكرة الوهمية Virtual Memory، إذ يُعَدّ العتاد مسؤولًا عن تطبيق هذه القواعد.
</p>

<p>
	تُعَدّ واجهة استدعاء النظام بوابة التطبيق للوصول إلى موارد النظام، إذ يمكن للنواة فرض قواعد حول نوع الوصول الذي يمكن توفيره من خلال إجبار التطبيق على طلب الموارد من خلال استخدام استدعاء نظام إلى النواة، فإذا أجرى أحد التطبيقات استدعاء النظام <code>open()‎</code> لفتح ملف على القرص الصلب مثلًا، فسيتحقق من أذونات المستخدِم المقابلة لأذونات الملف ثم سيسمح بوصوله أو يرفضه.
</p>

<h3>
	مستويات الصلاحيات
</h3>

<p>
	تُعَدّ حماية العتاد مجموعةً من الحلقات متحدة المركز حول مجموعة أساسية من العمليات.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="111011" href="https://academy.hsoub.com/uploads/monthly_2022_11/01_priv.png.b216abf2314fcccaf58165aff8ca66ae.png" rel=""><img alt="مستويات الصلاحيات في معمارية x86" class="ipsImage ipsImage_thumbnailed" data-fileid="111011" data-unique="6avufe4bz" style="width: 313px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2022_11/01_priv.png.b216abf2314fcccaf58165aff8ca66ae.png"></a>
</p>

<p style="text-align: center;">
	مستويات الصلاحيات في معمارية x86
</p>

<p>
	توجد التعليمات ذات الحماية الأكبر في الحلقة الداخلية، وهي التعليمات التي يجب السماح للنواة فقط باستدعائها مثل التعليمة <code>HLT</code> المُستخدَمة لإيقاف المعالج، إذ يجب ألّا يُسمَح بأن يشغّلها تطبيق مستخدِم، لأن ذلك سيوقف الحاسوب بأكمله عن العمل، لكن يجب أن تكون النواة قادرةً على استدعاء هذه التعليمة عند إيقاف تشغيل الحاسوب بطريقة نظامية، إذ يرفع العتاد استثناءً عندما يستدعي تطبيق ما هذه التعليمة، ويتضمّن هذا الاستثناء القفز إلى معالج محدد في نظام التشغيل مشابه لمعالج استدعاء النظام، كما يُحتمَل أن ينهي نظام التشغيل بعد ذلك البرنامج ويعطي المستخدِم بعض الأخطاء حول كيفية تعطل التطبيق.
</p>

<p>
	يمكن لكل حلقة داخلية الوصول إلى أيّ تعليمات تحميها حلقة خارجية، ولكن لا يمكنها الوصول إلى تعليمة تحميها حلقة داخلية، كما لا تحتوي جميع المعماريات على مستويات متعددة من الحلقات كما في الشكل السابق، ولكن سيوفر معظمها على الأقل مستوى النواة Kernel ومستوى المستخدِم User.
</p>

<h4>
	نموذج الحماية 386
</h4>

<p>
	يحتوي نموذج الحماية 386 على أربع حلقات بالرغم من أن معظم أنظمة التشغيل مثل لينكس وويندوز تستخدِم حلقتَين فقط للحفاظ على التوافق مع المعماريات الأخرى التي تسمح الآن بأكبر عدد من مستويات الحماية المنفصلة، كما يحتفظ النموذج 386 بالصلاحيات من خلال أن يكون لكل جزء من شيفرة التطبيق البرمجية المُشغَّلة في النظام واصف صغير يسمى واصف الشيفرة البرمجية Code Descriptor الذي يصِف مستوى صلاحياتها.
</p>

<p>
	تقفز شيفرة التطبيق عند تشغليها سريعًا إلى الشيفرة البرمجية الموجودة خارج المنطقة التي يصِفها واصفُ شيفرة التطبيق مع التحقق من مستوى صلاحيات الهدف، فإذا كانت الصلاحيات أعلى من صلاحيات الشيفرة المُشغَّلة حاليًا، فلن يسمح العتاد بهذه القفزة وسيتعطل التطبيق.
</p>

<h4>
	رفع مستوى الصلاحيات
</h4>

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

<p>
	رأينا كيف يوقِف العتاد التطبيق الذي يكون قيد التشغيل ويسلّم التحكم إلى النواة عند استدعاء هذه التعليمات، ويجب أن تعمل النواة بوصفها حارسًا للبوابة للتأكد من عدم دخول أيّ شيء غير مرغوب به من البوابة، إذ يجب التحقق من وسائط استدعاء النظام بعناية للتأكد من أنه لن ينخدع بفعل شيء لا ينبغي أن يفعله، وبالتالي حدوث خطأ أمني.
</p>

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

<h4>
	استدعاءات النظام السريعة
</h4>

<p>
	تتمثل إحدى مشاكل المصائد كما هو موضح سابقًا في أنها باهظة الثمن بالنسبة للمعالج لتطبيقها، فهناك الكثير من الحالات التي يجب حفظها قبل تبديل السياق، وقد أدركت المعالجات الحديثة هذا الحِمل وتسعى جاهدة لتقليله.
</p>

<p>
	يتطلب فهم آلية بوابة الاستدعاءات الموضحة سابقًا التدقيق في مخطط التقطيع المبتكر والمعقد الذي يستخدمه المعالج، وقد كان السبب الأصلي لتطبيق التقطيع هو القدرة على استخدام أكثر من 16 بِتًا متوفرًا في المسجل لعنوان ما كما هو موضح في الشكل التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="111012" href="https://academy.hsoub.com/uploads/monthly_2022_11/02_ia32-segmentation.png.341c55d3b2d7f607c64f1a6f651edc47.png" rel=""><img alt="تقطيع العنونة Segmentation Addressing في معمارية x86" class="ipsImage ipsImage_thumbnailed" data-fileid="111012" data-unique="cgycqmfkt" style="width: 447px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2022_11/02_ia32-segmentation.png.341c55d3b2d7f607c64f1a6f651edc47.png"></a>
</p>

<p>
	تقطيع العنونة Segmentation Addressing في معمارية x86: يؤدي التقطيع إلى توسيع مساحة عناوين المعالج من خلال تقسيمه إلى أجزاء. يحتفظ المعالج بمسجلات مقاطع خاصة، ويمكن تحديد العناوين من خلال مسجّل المقطع والإزاحة. تُضاف قيمة مسجل المقطع إلى جزء الإزاحة للعثور على العنوان النهائي.
</p>

<p>
	بقي مخطط التقطيع كما هو ولكن بتنسيق مختلف عندما انتقلت معمارية x86 إلى مسجّلات بحجم 32 بِتًا، إذ يُسمَح للمقاطع بأن تكون بأيّ حجم بدلًا من استخدام أحجام ثابتة، ويجب أن يتعقّب المعالج كل هذه المقاطع المختلفة وأحجامها، وهو ما يفعله باستخدام الواصفات Descriptors.
</p>

<p>
	تكون واصفات المقاطع المتاحة للجميع محفوظةً في جدول الواصفات العام Global Descriptor Table أو GDT اختصارًا، كما تحتوي كل عملية على عدد من المسجلات التي توشّر إلى مدخلات في جدول GDT، وهذه المدخلات هي المقاطع التي يمكن للعملية الوصول إليها، كما توجد جداول واصفات محلية، وتتفاعل جميعها مع مقاطع حالة المهمات، لكنها ليست مهمةً حاليًا.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="111013" href="https://academy.hsoub.com/uploads/monthly_2022_11/03_ia32-segments.png.2c2b673f258410107cc3bc232ef2e8bb.png" rel=""><img alt="مقاطع x86" class="ipsImage ipsImage_thumbnailed" data-fileid="111013" data-unique="88wq288ps" style="width: 630px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2022_11/03_ia32-segments.thumb.png.d9b65603556035799c6fab746a10fb33.png"></a>
</p>

<p>
	مقاطع x86: لاحظ كيف يمر الاستدعاء البعيد عبر بوابة الاستدعاءات التي توجّهه إلى مقطع من الشيفرة يعمل على مستوى الحلقة الأدنى. الطريقة الوحيدة لتعديل محدّد مقطع الشيفرة -المستخدَم ضمنيًا لجميع عناوين الشيفرة- هي استخدام آلية الاستدعاء، حيث تضمن آلية بوابة الاستدعاءات اختيار واصف مقطع جديد، مما يؤدي إلى تغيير مستويات الحماية التي يجب عليك الانتقال إليها عبر نقطة دخول معروفة.
</p>

<p>
	يضبط نظام التشغيل مسجلات المقطع بوصفها جزءًا من حالة العملية، لذا يعرِف عتاد المعالِج مقاطع الذاكرة التي يمكن للعملية المُشغَّلة الوصول إليها، كما يمكنه فرض الحماية لضمان عدم وصول العملية لأيّ شيء لا يُفترَض أن تصل إليه، فإذا خرجت العملية خارج حدودها المفروضة، فستتلقّى خطأ تقطيع Segmentation Fault يعرفه معظم المبرمجين.
</p>

<p>
	إذا احتاج تشغيل الشيفرة البرمجية إلى إجراء استدعاءات إلى شيفرة موجودة في مقطع آخر، فستطبّق معمارية x86 ذلك كما في الحلقات Rings، إذ تكون الحلقة 0 هي الحلقة ذات الإذن الأعلى والحلقة 3 هي الأدنى، ويمكن للحلقات الداخلية الوصول إلى الحلقات الخارجية ولكن ليس العكس.
</p>

<p>
	إذا أرادت شيفرة الحلقة 3 القفز إلى شيفرة الحلقة 0، فستعدّل محدّد مقطع الشيفرة الخاص بها ليؤشّر إلى مقطع مختلف، لذلك يجب أن تستخدِم تعليمة استدعاءات بعيدة خاصة بحيث يتأكد العتاد من مرورها عبر بوابة الاستدعاءات، ولا توجد طريقة أخرى للعملية المُشغَّلة لاختيار واصف مقطع شيفرة جديد، وسيبدأ المعالج بعد ذلك في تنفيذ الشيفرة البرمجية عند الإزاحة المعروفة في مقطع الحلقة 0، وهذا هو سبب الحفاظ على السلامة مثل عدم قراءة الشيفرة البرمجية العشوائية والضارة وتنفيذها، كما سيبحث المهاجمون دائمًا عن طرق لجعل شيفرتك البرمجية تفعل شيئًا لا تريده.
</p>

<p>
	يسمح ذلك بتسلسل هرمي كامل للمقاطع والأذونات، ولاحظ أنّ استدعاء المقطع العرضي يشبه استدعاء النظام، فإذا سبق لك أن شاهدت لغة تجميع لينكس x86، فالطريقة القياسية لإجراء استدعاء النظام هي باستخدام <code>int 0x80</code> التي ترفع المقاطعة <code>0x80</code>، إذ توقِف المقاطعة المعالج وتنتقل إلى بوابة المقاطعات التي تعمل بعد ذلك بطريقة بوابة الاستدعاءات نفسها بحيث تغيّر مستوى الصلاحيات وتعيدك إلى منطقة أخرى من الشيفرة البرمجية.
</p>

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

<p>
	لا يُستخدَم نظام الحلقات ذو المستويات الأربعة في تقطيع نظام x86 الحديث بفضل الذاكرة الوهمية، والشيء الوحيد الذي يحدث فعليًا مع تبديل التقطيع هو استدعاءات النظام التي تتحوّل من الوضع 3 -أي مجال المستخدِم- إلى الوضع 0 وتقفز إلى شيفرة معالج استدعاء النظام في النواة.
</p>

<p>
	يوفّر المعالِج تعليمات استدعاء نظام فائقة السرعة تسمى <code>sysenter</code> (و <code>sysexit</code> للعودة)، إذ تسرّع هذه التعليمات العملية برمتها عبر الاستدعاء <code>int 0x80</code> من خلال إزالة الطبيعة العامة للاستدعاء البعيد، أي إمكانية الانتقال إلى أيّ مقطع في أيّ مستوى حلقة، وتقييد الاستدعاء للانتقال فقط إلى شيفرة الحلقة 0 في مقطع معيّن مع الإزاحة كما هي مخزّنة في المسجلات.
</p>

<p>
	بما أننا استبدلنا هذه الطبيعة العامة بالكثير من المعلومات المعروفة مسبقًا، فيمكن تسريع العملية، وبالتالي سنحصل على استدعاء النظام السريع الذي ذكرناه سابقًا، والشيء الآخر الذي يجب ملاحظته هو أنّ الحالة لا تُحفَظ عندما ينتقل التحكم إلى النواة، إذ يجب أن تكون النواة حريصةً على عدم تدمير الحالة، ولكن يعني هذا أنها حرة في حفظ الحالة الصغيرة كما هو مطلوب لتنفيذ المهمة، لذلك يمكن أن تكون أكثر فاعليةً، إذ تتعلق هذه الفكرة بمعمارية RISC، وتوضّح كيفية تلاشي الخط بين معالجات RISC و CISC.
</p>

<p>
	هناك طرق أخرى للتواصل مع النواة مثل ioctl وأنظمة الملفات مثل proc و sysfs و debugfs وغير ذلك.
</p>

<p>
	ترجمة -وبتصرُّف- للقسمين <a href="https://www.bottomupcs.com/system_calls.xhtml" rel="external nofollow">System Calls</a> و <a href="https://www.bottomupcs.com/privileges.xhtml" rel="external nofollow">Privileges</a> من الفصل <a href="https://www.bottomupcs.com/chapter03.xhtml" rel="external nofollow">The Operating System</a> من كتاب <a href="https://www.bottomupcs.com/" rel="external nofollow">Computer Science from the Bottom Up</a> لصاحبه Ian Wienand.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA-%D9%88%D8%B9%D9%86%D8%A7%D8%B5%D8%B1%D9%87%D8%A7-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1758/" rel="">العمليات وعناصرها في نظام تشغيل الحاسوب</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AF%D9%88%D8%B1-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%88%D8%AA%D9%86%D8%B8%D9%8A%D9%85%D9%87-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1723/" rel="">دور نظام التشغيل وتنظيمه في معمارية الحاسوب</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/c/%D8%A7%D9%84%D9%81%D8%B5%D9%84-%D8%A7%D9%84%D8%AB%D8%A7%D9%86%D9%8A-%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA-processes-%D9%81%D9%8A-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-r977/" rel="">العمليات (Processes) في أنظمة التشغيل</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/files/24-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%84%D9%85%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D9%86/" rel="">أنظمة التشغيل للمبرمجين</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1757</guid><pubDate>Fri, 04 Nov 2022 16:00:00 +0000</pubDate></item><item><title>&#x62F;&#x648;&#x631; &#x646;&#x638;&#x627;&#x645; &#x627;&#x644;&#x62A;&#x634;&#x63A;&#x64A;&#x644; &#x648;&#x62A;&#x646;&#x638;&#x64A;&#x645;&#x647; &#x641;&#x64A; &#x645;&#x639;&#x645;&#x627;&#x631;&#x64A;&#x629; &#x627;&#x644;&#x62D;&#x627;&#x633;&#x648;&#x628;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D8%AF%D9%88%D8%B1-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%88%D8%AA%D9%86%D8%B8%D9%8A%D9%85%D9%87-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1723/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2022_09/63357be700cf2_-------.png.77114b8fee10a8f6a52a0e79b4bf980f.png" /></p>
<p>
	يدعم <a href="https://academy.hsoub.com/tags/%D9%85%D8%AF%D8%AE%D9%84%20%D8%A5%D9%84%D9%89%20%D8%A3%D9%86%D8%B8%D9%85%D8%A9%20%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84/" rel="">نظام التشغيل</a> العملية الكاملة للحواسيب الحديثة، فهو عنصر أساسي في معمارية الحواسيب، لذا سنتعرّف في هذا المقال على دوره وكيفية تنظيمه.
</p>

<h2>
	تجريد العتاد
</h2>

<p>
	تتمثل العملية الأساسية لنظام التشغيل Operating System -أو OS اختصارًا- في تجريد Abstraction العتاد للمبرمج والمستخدِم، إذ يوفّر نظام التشغيل واجهات عامة للخدمات التي يقدمها العتاد الأساسي، كما يجب على المبرمجين معرفة تفاصيل العتاد الأساسي الأكثر خصوصيةً لتشغيل أيّ شيء في عالم خال من <a href="https://academy.hsoub.com/files/24-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%84%D9%85%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D9%86/" rel="">أنظمة التشغيل</a>، إذ لن تعمل برامجهم على عتاد آخر حتى عند وجود اختلافات طفيفة في هذا العتاد.
</p>

<h2>
	تعدد المهام Multitasking
</h2>

<p>
	نتوقع من الحواسيب الحديثة تنفيذ العديد من الأشياء المختلفة في وقت واحد، لذا يجب التحكيم بين جميع البرامج المختلفة التي تعمل على النظام، ويُعَدً ذلك وظيفة أنظمة التشغيل التي تسمح بحدوث ذلك بسلاسة، فنظام التشغيل مسؤول عن إدارة الموارد داخل النظام، إذ تتنافس المهام المتعددة على موارده أثناء تشغيله بما في ذلك وقت المعالج والذاكرة والقرص الصلب ودخل المستخدِم، كما تتمثل وظيفته في التحكيم في وصول المهام المتعددة لهذه الموارد بطريقة منظمة.
</p>

<p>
	لا بد أنك مررت بفشل حاسوبك وتعطله مثل ظهور شاشة الموت الزرقاء Blue Screen of Death الشهيرة بسبب التنافس على هذه الموارد.
</p>

<h2>
	الواجهات الموحدة Standardised Interfaces
</h2>

<p>
	يرغب المبرمجون في كتابة برامج تعمل على أكبر عدد ممكن من المنصات العتادية، ويمكن ذلك من خلال دعم نظام التشغيل للواجهات الموحَّدة المعيارية، فإذا كانت دالة فتح ملف مثلًا على أحد الأنظمة <code>open()‎</code> وكانت <code>open_file()‎</code> و <code>openf()‎</code> على نظام آخر، فسيواجه المبرمجون مشكلةً مزدوجةً تتمثل في الاضطرار إلى تذكّر ما يفعله كل نظام مع عدم عمل البرامج على أنظمة متعددة.
</p>

<p>
	تُعَدّ واجهة نظام التشغيل المتنقلة Portable Operating System Interface -أو POSIX اختصارًا- معيارًا مهمًا للغاية تطبّقه أنظمة تشغيل من نوع يونيكس UNIX، كما يملك نظام مايكروسوفت ويندوز معايير مشابهة، ويأتي حرف X في POSIX من نظام يونيكس Unix الذي نشأ منه المعيار، وهو اليوم الإصدار رقم 3 من مواصفات يونيكس الواحدة Single UNIX Specification Version 3 أو ISO/IEC 9945:2002 نفسه، كما أنه معيار مجاني ومتاح على <a href="https://academy.hsoub.com/devops/networking/%D8%A2%D9%84%D9%8A%D8%A9-%D8%B9%D9%85%D9%84-%D8%B4%D8%A8%D9%83%D8%A9-%D8%A7%D9%84%D8%A5%D9%86%D8%AA%D8%B1%D9%86%D8%AA-r571/" rel="">الإنترنت</a>.
</p>

<p>
	كانت مواصفات يونيكس الواحدة ومعايير POSIX كيانات منفصلةً سابقًا، وقد أصدر اتحاد يسمّى المجموعة المفتوحة Open Group مواصفات يونيكس الواحدة، وكان متاحًا مجانًا وفقًا لمتطلبات هذا الاتحاد، وأحدث إصدار هو الإصدار الثالث من مواصفات يونيكس الواحدة، كما أُصدِرت معايير IEEE POSIX بوصفها معايير بالشكل [رقم المراجعة، رقم الإصدار].IEEE Std 1003، ولم تكن متاحةً مجانًا، وأحدث إصدار منها هو IEEE 1003.1-2001 وهو مكافئ للإصدار الثالث من مواصفات يونيكس الواحدة.
</p>

<p>
	دُمِج هذان المعياران المنفصلان فيما يُعرف باسم الإصدار الثالث من مواصفات يونيكس الواحدة، ووحّدته منظمة ISO بالاسم ISO/IEC 9945:2002 في بداية عام 2002، لذا عندما يتحدث الناس عن معيار POSIX أو SUS3 أو ISO/IEC 9945:2002، فإنهم يعنون الشيء نفسه.
</p>

<h2>
	الأمن
</h2>

<p>
	يُعَدّ الأمن مهمًا جدًا في الأنظمة متعددة المستخدِمين، إذ يكون نظام التشغيل -بصفته المتحكّم في الوصول إلى النظام- مسؤولًا عن ضمان أنّ الأشخاص الذين لديهم الأذونات الصحيحة فقط يمكنهم الوصول إلى الموارد، فإذا امتلك مستخدِم أحد الملفات مثلًا، فلا ينبغي السماح لمستخدِم آخر بفتحه وقراءته، ولكن هناك حاجة لوجود آليات لمشاركة هذا الملف بأمان بين المستخدِمين إذا أرادوا ذلك.
</p>

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

<h2>
	الأداء
</h2>

<p>
	يوفِّر نظام التشغيل العديد من الخدمات للحاسوب، لذلك يُعَدّ أداؤه أمرًا بالغ الأهمية، إذ تعمل أجزاء كثيرة من نظام التشغيل بصورة متكررة، كما يمكن أن تؤدي زيادة عدد دورات المعالج إلى انخفاض كبير في أداء النظام، ويحتاج نظام التشغيل لاستغلال ميزات العتاد الأساسي للتأكد من الحصول على أفضل أداء ممكن لإجراء العمليات، وبالتالي يجب على مبرمجي الأنظمة فهم التفاصيل الدقيقة للمعمارية التي يبنون نظام التشغيل من أجلها.
</p>

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

<h2>
	تنظيم نظام التشغيل
</h2>

<p>
	يُعَدّ نظام التشغيل منظمًا تقريبًا كما في الصورة التالية:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="108801" href="https://academy.hsoub.com/uploads/monthly_2022_09/01_kernel.png.51cf56309cf0a6d85fa311f98f6042d5.png" rel=""><img alt="01_kernel.png" class="ipsImage ipsImage_thumbnailed" data-fileid="108801" data-unique="on08y85jk" style="width: 400px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2022_09/01_kernel.png.51cf56309cf0a6d85fa311f98f6042d5.png"></a>
</p>

<p>
	تنظيم النواة Kernel: تُشغَّل عمليات النواة مباشرةً في مجال المستخدِم Userspace، وتتواصل النواة مباشرةً مع العتاد Hardware وعبر المشغّلات Drivers.
</p>

<h3>
	النواة Kernel
</h3>

<p>
	تُعَدّ النواة نظام تشغيل، وتجرّد المشغّلات Drivers العتاد للنواة كما تجرّد النواة العتاد لبرامج المستخدِم، حيث يوجد العديد من أنواع بطاقات الرسوم المختلفة على سبيل المثال، ولكل منها ميزات مختلفة قليلًا عن بعضها البعض، ولكن طالما أن النواة تصدّر <a href="https://academy.hsoub.com/programming/general/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%A7%D9%84%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A9-api-r1314/" rel="">واجهة برمجة تطبيقات <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr></a>، فيمكن للأشخاص الذين لديهم إذن الوصول إلى مواصفات العتاد كتابةُ برامج للمشغّلات لتطبيق هذه الواجهة، ويمكن للنواة باستخدام هذه الطريقة الوصول إلى أنواع مختلفة من العتاد.
</p>

<p>
	تُوصَف النواة بأن لها صلاحيات Privileged، فللعتاد أدوار مهمة يؤديها لتشغيل مهام متعددة والحفاظ على أمان النظام، ولكن لا تُطبَّق هذه القواعد على النواة، كما يجب أن تتعامل النواة مع البرامج التي تتعطل، فوظيفة أنظمة التشغيل هي فقط تنظيم العمل والتحكيم بين العديد من البرامج التي تعمل على النظام نفسه، وليس هناك ما يضمن أنها ستتصرف لحل المشاكل، ولكن سيصبح النظام بأكمله عديم الفائدة في حالة تعطل أي جزء داخلي من نظام التشغيل، كما يمكن أن تستغل عمليات المستخدِم مشاكل الأمان لترفع مستواها إلى مستوى صلاحيات النواة، وبالتالي يمكنها الوصول إلى أيّ جزء من النظام.
</p>

<h3>
	النواة الأحادية Monolithic والنواة الدقيقة Microkernel
</h3>

<p>
	أحد الأمور الجدلية التي تُطرَح غالبًا حول أنظمة التشغيل هو ما إذا كانت النواة أحادية Monolithic أو نواة دقيقة Microkernel.
</p>

<p>
	تُعَدّ النواة الأحادية الأكثر شيوعًا كما هو الحال في معظم أنظمة يونيكس الشائعة مثل <a href="https://academy.hsoub.com/devops/linux/%D9%85%D8%A7-%D9%87%D9%88-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%8A%D9%86%D9%83%D8%B3%D8%9F-r451/" rel="">لينكس</a>، إذ تكون النواة في هذا النموذج ذات صلاحيات كبيرة، وتحتوي على مشغّلات العتاد ومتحكمات الوصول إلى نظام الملفات وفحص الأذونات والخدمات مثل نظام ملفات الشبكة Network File System -أو NFS اختصارًا.
</p>

<p>
	تتمتع النواة دائمًا بصلاحيات، لذلك إذا تعطل أيّ جزء منها، فيُحتمَل أن يتوقف النظام بأكمله، وإذا كان لدى مشغّل خطأ برمجي ما bug، فيمكنه الكتابة في أيّ ذاكرة في النظام دون أيّ مشاكل، مما يؤدي في النهاية إلى تعطل النظام.
</p>

<p>
	تحاول معمارية النواة الدقيقة تقليل هذا الاحتمال من خلال جعل الجزء الذي يمتلك الصلاحيات من النواة صغيرًا قدر الإمكان. هذا يعني أن معظم النظام يعمل كبرامج دون صلاحيات، مما يحد من الضرر الذي يمكن أن يسبّبه أيّ مكونٍ معطَّل، فمثلًا يمكن تشغيل مشغّلات العتاد في عمليات منفصلة، وبالتالي إذا تعطّل أحد هذه المشغّلات، فلن يتمكّن من الكتابة في أيّ ذاكرة غير تلك المخصصة له.
</p>

<p>
	تبدو معمارية النواة الدقيقة جيدةً، ولكنها ستؤدي إلى المشكلتين التاليتين:
</p>

<ol>
	<li>
		انخفاض الأداء، إذ يمكن أن يؤدي التواصل بين العديد من المكونات المختلفة إلى تقليل الأداء.
	</li>
	<li>
		يُعَدّ تطبيقها أصعب قليلًا على المبرمجين.
	</li>
</ol>

<p>
	تأتي هذه المشاكل بسبب تطبيق معظم الأنوية الدقيقة باستخدام نظام قائم على تمرير الرسائل Message Passing بهدف الحفاظ على الفصل بين المكونات، ويشار إلى هذا النظام عادةً باسم التواصل بين العمليات Inter-process Communication أو IPC اختصارًا.
</p>

<p>
	يحدث التواصل بين المكونات باستخدام رسائل منفصلة يجب تجميعها ضمن حزم وإرسالها إلى المكوِّن الآخر وتفكيكها وتشغيلها وإعادة تجميعها وإعادة إرسالها ثم تفكيكها مرةً أخرى للحصول على النتيجة، وهذه خطوات كثيرة لطلبٍ بسيط إلى حد ما من مكون خارجي، ويمكن أن تجعل أحد الطلبات المكون الآخر يُجري طلبات أكثر لمكونات أكثر، وستتفاقم المشكلة.
</p>

<p>
	كانت تطبيقات تمرير الرسائل البطيئة مسؤولة إلى حد كبير عن الأداء الضعيف لأنظمة النواة الدقيقة القديمة، وكانت مفاهيم تمرير الرسائل أصعب قليلًا على المبرمجين، ولم تكن الحماية المُحسَّنة من تشغيل المكونات بصورة منفصلة كافيةً للتغلب على هذه العقبات في أنظمة النواة الدقيقة القديمة، لذا أصبحت قديمة الطراز، في حين تكون الاستدعاءات بين المكونات استدعاءات وظيفيةً بسيطةً في النواة الأحادية كما هو معتاد لدى جميع المبرمجين.
</p>

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

<h4>
	الوحدات Modules
</h4>

<p>
	تطبّق نواة لينكس نظام الوحدات، حيث يمكن تحميل المشغّلات في النواة المشغَّلة مباشرةً كما هو مطلوب، وهذا أمر جيد لأنّ المشغّلات التي تشكّل جزءًا كبيرًا من شيفرة نظام التشغيل لا تُحمَّل للأجهزة غير الموجودة في النظام، كما يمكن لأيّ شخص يريد أن يصنع أكثر نواة عامة ممكنة -أي تعمل على العديد من الأجهزة المختلفة مثل RedHat أو Debian- تضمينَ معظم المشغّلات بوصفها وحدات تُحمَّل فقط إذا احتوى النظام الذي يعمل عليه على العتاد المتاح، لكن تُحمَّل الوحدات مباشرةً في النواة ذات الصلاحيات وتعمل على مستوى الصلاحيات نفسه لبقية أجزاء النواة، لذلك لا يزال يُعَدّ النظام نواةً أحاديةَ.
</p>

<h3>
	الافتراضية Virtualisation
</h3>

<p>
	يرتبط مفهوم العتاد الوهمي أو الافتراضي ارتباطًا وثيقًا بالنواة، إذ تُعَدّ الحواسيب الحديثة قوية جدًا، ولا يُفضَّل استخدامها على أساس نظام واحد كامل، وإنما تقسيم الحاسوب الحقيقي الواحد إلى آلات افتراضية منفصلة virtual machines، إذ تبحث كلٌّ من هذه الآلات الافتراضية عن جميع الأهداف والأغراض بوصفها آلة منفصلة تمامًا بالرغم من أنها فيزيائيًا موجودة في المكان نفسه.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="108802" href="https://academy.hsoub.com/uploads/monthly_2022_09/02_virtual.png.fcebb55ef8dd6ac28b2b6d53ccfcc802.png" rel=""><img alt="02_virtual.png" class="ipsImage ipsImage_thumbnailed" data-fileid="108802" data-unique="owrk2v34k" style="width: 780px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2022_09/02_virtual.thumb.png.0cf2e0eccb625232b75475807b6ff958.png"></a>
</p>

<p style="text-align: center;">
	بعض طرق تطبيق الافتراضية المختلفة
</p>

<p>
	يمكن تنظيم الافتراضية بعدة طرق مختلفة، إذ يمكن تشغيل مراقب آلة افتراضية Virtual Machine Monitor صغير مباشرةً على العتاد وتوفير واجهة لأنظمة تشغيل المضيف التي تعمل في الأعلى، ويُطلَق على مراقب الآلة الافتراضية VMM اسم المشرف Hypervisor من الكلمة Supervisor.
</p>

<p>
	يشترك المشرف في كثير الأمور مع النواة الدقيقة، كما يسعيان ليكوّنا طبقات صغيرةً لتقديم العتاد بطريقة آمنة عن الطبقات التي تعلوها، ويمكن ألّا يكون لدى نظام التشغيل الموجود في الطبقة العليا أيّ فكرة عن وجود المشرف Hypervisor على الإطلاق، إذ يقدم هذا المشرف ما يبدو أنه نظام كامل، ويعترض العمليات بين نظام التشغيل المضيف والعتاد ويقدّم مجموعةً فرعيةً من موارد النظام لكل منها.
</p>

<p>
	يُستخدَم المشرف غالبًا على الأجهزة الكبيرة التي تحتوي على العديد من وحدات المعالجة المركزية والكثير من ذواكر RAM لتطبيق عملية التجزيء Partitioning، وهذا يعني أنه يمكن تقسيم الجهاز إلى أجهزة افتراضية أصغر، كما يمكنك تخصيص المزيد من الموارد لتشغيل الأنظمة حسب المتطلبات، ويُعَدّ المشرفون الموجودون على العديد من أجهزة IBM الكبيرة معقدةً للغاية مع ملايين الأسطر من الشيفرة البرمجية مع توفير العديد من خدمات إدارة النظام.
</p>

<p>
	الخيار الآخر هو جعل نظام التشغيل على دراية بالمشرف الأساسي وطلب موارد النظام عبره، إذ يشار إلى ذلك في بعض الأحيان باسم شبه الوهمية Paravirtualisation نظرًا لطبيعته غير المكتملة، وهو مشابه للطريقة التي تعمل بها الإصدارات الأولى من نظام Xen الذي يُعَدّ حلًا وسطًا، إذ توفّر هذه الطريقة أداءً أفضل لأن نظام التشغيل يطلب صراحةً موارد النظام من المشرف عند الحاجة بدلًا من أن يطبّق المشرف الأمور آليًا.
</p>

<p>
	أخيرًا، يمكن أن تصادف موقفًا حيث يقدّم التطبيق الذي يعمل على نظام التشغيل الحالي نظامًا وهميًا يتضمن وحدة معالجة مركزية وذاكرةً ونظام BIOS وقرص صلب وغير ذلك، ويمكن تشغيل نظام تشغيل عادي عليه، إذ يحوّل التطبيق الطلبات إلى العتاد ثم إلى العتاد الأساسي عبر نظام التشغيل الحالي، وهذا مشابه لكيفية عمل برنامج VMWare.
</p>

<p>
	تتطلب هذه الطريقة تكلفةً أكبر، إذ يتعين على عملية التطبيق محاكاة نظام بأكمله وتحويل كل شيء إلى طلبات من نظام التشغيل الأساسي، ولكنها تتيح محاكاةً معماريةً مختلفةً تمامًا، إذ يمكنك ترجمة التعليمات آليًا من نوع معالج إلى آخر كما يفعل نظام روزيتا Rosetta مع برمجيات Apple التي انتقلت من معالج PowerPC إلى المعالجات القائمة على إنتل Intel.
</p>

<p>
	يُعَدّ الأداء مصدر قلق كبير عند استخدام أيّ من تقنيات الوهمية، إذ يجب أن تمر العمليات -التي كانت تُعَدّ سابقًا عمليات سريعةً ومباشرةً على العتاد- عبر طبقات التجريد.
</p>

<p>
	ناقشت شركة إنتل Intel دعم العتاد للوهمية لتكون موجودةً في أحدث معالجاتها، إذ تعمل هذه التوسعات من خلال رفع استثناء خاص للعمليات التي يمكن أن تتطلب تدخّل مراقب الآلة الافتراضية، وبالتالي فإن المعالج يشبه المعالج غير الافتراضي الخاص بالتطبيق الذي يعمل عليه، ولكن يمكن استدعاء مراقب الآلة الافتراضية عندما يقدّم هذا التطبيق طلبات للحصول على موارد يمكن مشاركتها بين أنظمة تشغيل المضيف الأخرى.
</p>

<p>
	يوفّر ذلك أداءً فائقًا لأنّ مراقب الآلة الافتراضية لا يحتاج إلى مراقبة كل عملية لمعرفة ما إذا كانت آمنةً، ولكن يمكنه الانتظار حتى يُعلِم المعالج بحدوث شيء غير آمن.
</p>

<h4>
	القنوات السرية Covert Channels
</h4>

<p>
	إذا لم يكن تقسيم النظام ساكنًا وإنما آليًا، فهناك مشكلة أمنية محتملة متضمنة في النظام ويُعَدّ هذا عيبًا أمنيًا يتعلق بالآلات الافتراضية. تُخصَّص الموارد لأنظمة التشغيل التي تعمل في الطبقة العليا حسب الحاجة في النظام الآلي، وبالتالي إذا كان أحد هذه الأنظمة ينفّذ عمليات مكثفةً لوحدة المعالجة المركزية بينما ينتظر النظام الآخر وصول البيانات من الأقراص الصلبة، فستُمنَح المهمة الأولى مزيدًا من طاقة <a href="https://academy.hsoub.com/certificates/comptia/%D9%88%D8%AD%D8%AF%D8%A9-%D8%A7%D9%84%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D9%85%D8%B1%D9%83%D8%B2%D9%8A%D8%A9-r58/" rel="">وحدة المعالجة المركزية</a>، في حين سيحصل كل منهما على 50% من طاقة وحدة المعالجة المركزية في النظام الساكن، وسيُهدَر الجزء غير المستخدَم.
</p>

<p>
	يفتح التخصيص الآلي قناة اتصال بين نظامَي التشغيل التي تكون كافيةً للتواصل في نظام ثنائي في أيّ مكان يمكن الإشارة فيه إلى تلك الحالتين، لكن تخيل أنّ كلا النظامين آمنان جدًا، ولا ينبغي أن تكون أيّ معلومات قادرةً على المرور بينهما على الإطلاق، كما يمكن أن يتآمر شخصان لديها إذن وصول لتمرير المعلومات فيما بينهما من خلال كتابة برنامجين يحاولان أخذ كميات كبيرة من الموارد في الوقت نفسه.
</p>

<p>
	إذا أخذ أحدهما مساحةً كبيرةً من الذاكرة، فسيكون هناك قدر أقل من المساحة المتاحة للآخر؛ أما إذا تعقّبا الحد الأقصى من التخصيصات، فيمكن نقل القليل من المعلومات فقط، ولنفترض أنهما اتفقا على التحقق في كل ثانية مما إذا كان بإمكانهما تخصيص هذا القدر الكبير من الذاكرة، فإذا كان الطرف الهدف قادرًا على ذلك، فستُعَدّ هذه الحالة 0 ثنائيًا، وإذا لم يستطع ذلك -أيّ أن الجهاز الآخر يحتوي على كل الذاكرة-، فستُعَدّ هذه الحالة 1 ثنائيًا، كما أنه ليس معدل البيانات المُقدَّر ببت واحد في الثانية مذهلًا، ولكن هذا يدل على وجود تدفق للمعلومات.
</p>

<p>
	يسمى ذلك بالقناة السرية Covert Channel، وهذا يظهِر أنّ الأمور ليست بهذا البساطة على مبرمج الأنظمة بالرغم من وجود أمثلة عن انتهاكات أمنية في مثل هذه الآليات.
</p>

<h3>
	مجال المستخدم
</h3>

<p>
	نسمي المكان الذي يشغِّل فيه المستخدِم البرامج باسم مجال المستخدِم Userspace، إذ يعمل كل برنامج في مجال مستخدِم، ويتواصل مع النواة عبر استدعاءات النظام التي سنوضحّها في المقال القادم، كما لا يتمتع مجال المستخدِم بصلاحيات Unprivileged، إذ يمكن لبرامج المستخدِم تطبيق مجموعة محدودة فقط من الأشياء، ويجب ألّا تكون قادرةً على تعطيل البرامج الأخرى حتى إذا تعطلت هي نفسها.
</p>

<p>
	ترجمة -وبتصرُّف- للقسمين <a href="https://www.bottomupcs.com/organisation_of_os.xhtml" rel="external nofollow">Operating System Organisation</a> و <a href="https://www.bottomupcs.com/chapter03.xhtml" rel="external nofollow">The role of the operating system</a> من الفصل <a href="https://www.bottomupcs.com/chapter03.xhtml" rel="external nofollow">The Operating System</a> من كتاب <a href="https://www.bottomupcs.com/" rel="external nofollow">Computer Science from the Bottom Up</a> لصاحبه Ian Wienand.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال التالي:  <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D8%B3%D8%AA%D8%AF%D8%B9%D8%A7%D8%A1%D8%A7%D8%AA-%D8%A7%D9%84%D9%86%D8%B8%D8%A7%D9%85-%D9%88%D8%A7%D9%84%D8%B5%D9%84%D8%A7%D8%AD%D9%8A%D8%A7%D8%AA-%D9%81%D9%8A-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-r1757/" rel="">استدعاءات النظام والصلاحيات في نظام التشغيل</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A7%D8%AA-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1722/" rel="">أنظمة المعالجات في معمارية الحاسوب</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/general/%D8%B9%D9%84%D9%88%D9%85-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8/" rel="">المدخل الشامل لتعلم علوم الحاسوب</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/apps/general/%D8%A7%D8%AE%D8%AA%D9%8A%D8%A7%D8%B1-%D8%A7%D9%84%D8%B9%D8%AA%D8%A7%D8%AF-%D9%88%D8%A7%D9%84%D8%A8%D8%B1%D8%A7%D9%85%D8%AC-%D9%81%D9%8A-%D8%A7%D9%84%D8%B9%D8%A7%D9%84%D9%85-%D8%A7%D9%84%D8%B1%D9%82%D9%85%D9%8A-r372/" rel="">اختيار العتاد والبرامج في العالم الرقمي</a>
	</li>
	<li>
		النسخة العربية الكاملة من كتاب <a href="https://academy.hsoub.com/files/24-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%84%D9%84%D9%85%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D9%86/" rel="">أنظمة التشغيل للمبرمجين</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1723</guid><pubDate>Fri, 28 Oct 2022 16:05:00 +0000</pubDate></item><item><title>&#x623;&#x646;&#x638;&#x645;&#x629; &#x627;&#x644;&#x645;&#x639;&#x627;&#x644;&#x62C;&#x627;&#x62A; &#x641;&#x64A; &#x645;&#x639;&#x645;&#x627;&#x631;&#x64A;&#x629; &#x627;&#x644;&#x62D;&#x627;&#x633;&#x648;&#x628;</title><link>https://academy.hsoub.com/programming/os-embedded-systems/%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D9%84%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A7%D8%AA-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1722/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2022_09/633577b8f3586_----.png.eb4f043046d0b3a4cbb633096017e0ec.png" /></p>
<p>
	نَمت قوة الحوسبة بوتيرة سريعة دون ظهور أيّ علامات على التباطؤ كما توقّع <a href="https://ar.wikipedia.org/wiki/%D9%82%D8%A7%D9%86%D9%88%D9%86_%D9%85%D9%88%D8%B1" rel="external nofollow">قانون مور Moore</a>، فليس مألوفًا أن تحتوي أيّ <a href="https://academy.hsoub.com/devops/servers/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%AE%D8%A7%D8%AF%D9%85-%D8%A7%D9%84%D9%88%D9%8A%D8%A8-r574/" rel="">خوادم</a> عالية الجودة على <a href="https://academy.hsoub.com/certificates/comptia/%D9%88%D8%AD%D8%AF%D8%A9-%D8%A7%D9%84%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D9%85%D8%B1%D9%83%D8%B2%D9%8A%D8%A9-r58/" rel="">وحدة معالجة مركزية</a> واحدة فقط مع إمكانية تحقيق ذلك باستخدام عدد من الأساليب المختلفة.
</p>

<h2>
	المعالجة المتعددة المتماثلة Symmetric Multi-Processing
</h2>

<p>
	تُعَدّ المعالجة المتعددة المتماثلة Symmetric Multi-Processing -أو SMP اختصارًا- الإعداد الأكثر شيوعًا حاليًا لتضمين <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%88%D8%AD%D8%AF%D8%A9-%D8%A7%D9%84%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D9%85%D8%B1%D9%83%D8%B2%D9%8A%D8%A9-%D9%88%D8%B9%D9%85%D9%84%D9%8A%D8%A7%D8%AA%D9%87%D8%A7-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1716/" rel="">وحدات المعالجة المركزية CPU</a> المتعددة في نظام واحد، ويشير المصطلح متماثل Symmetric إلى حقيقة أنّ جميع وحدات المعالجة المركزية في النظام هي نفسها من حيث المعمارية وسرعة الساعة مثلًا، كما توجد في نظام SMP معالجات متعددة تشترك في جميع موارد النظام الأخرى مثل الذاكرة والقرص الصلب وغير ذلك.
</p>

<h3>
	ترابط الذواكر المخبئية Cache Coherency
</h3>

<p>
	تعمل وحدات المعالجة المركزية في النظام بصورة مستقلة عن بعضها بعضًا، فلكل منها مجموعته الخاصة من المسجلات وعدّاد البرنامج وغير ذلك، ولكن يوجد مكوِّن واحد يتطلب تزامنًا صارمًا بالرغم من تشغيل وحدات المعالجة المركزية بصورة منفصلة عن بعضها بعضًا، وهذا المكوِّن هو <a href="https://academy.hsoub.com/programming/c/%D8%A7%D9%84%D9%81%D8%B5%D9%84-%D8%A7%D9%84%D8%B3%D8%A7%D8%A8%D8%B9-%D9%81%D9%87%D9%85-%D8%B9%D9%85%D9%84%D9%8A%D8%A9-%D8%A7%D9%84%D8%AA%D8%AE%D8%A8%D8%A6%D8%A9-caching-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r995/" rel="">الذاكرة المخبئية Cache</a> الخاصة بوحدة المعالجة المركزية.
</p>

<p>
	تذكّر أنّ الذاكرة المخبئية هي مساحة صغيرة من الذاكرة يمكن الوصول إليها بسرعة وتعكس القيم المخزّنة في ذاكرة النظام الرئيسية، فإذا عدّلت إحدى وحدات المعالجة المركزية البيانات في الذاكرة الرئيسية وكان لدى وحدة معالجة مركزية أخرى نسخة قديمة من تلك الذاكرة في ذاكرتها المخبئية، فلن يكون النظام في حالة متناسقة، ولاحظ أنّ هذه المشكلة تحدث عندما تكتب المعالجات في الذاكرة فقط، إذ ستكون البيانات متناسقةً إذا كانت القيمة للقراءة فقط.
</p>

<p>
	يستخدِم نظام SMP عملية التنصت Snooping لتنسيق الحفاظ على ترابط الذواكر المخبئية على جميع المعالجات، إذ يُعَدّ التنصت العمليةَ التي يستمع فيها المعالج إلى ناقل تتصل به جميع المعالجات لمعرفة أحداث الذاكرة المخبئية، ثم يحدّث الذاكرة المخبئية وفقًا لذلك.
</p>

<p>
	يمكن تحقيق ذلك باستخدام بروتوكول واحد هو بروتوكول MOESI الذي يرمز إلى الكلمات مُعدَّل Modified ومالك Owner وحصري Exclusive ومشارَك Shared وغير صالح Invalid التي تمثّل الحالة التي يمكن أن يكون فيها خط الذاكرة المخبئية على معالج في النظام، كما توجد بروتوكولات أخرى لذلك، ولكن تشترك جميعها في مفاهيم متشابهة، وسنوضح فيما يلي بروتوكول MOESI.
</p>

<p>
	إذا طلب المعالج قراءة خط ذاكرة مخبئية من الذاكرة الرئيسية، فيجب عليه أولًا التنصت على جميع المعالجات الأخرى في النظام لمعرفة ما إذا كانت تعرف حاليًا أيّ شيء عن تلك المنطقة من الذاكرة مثل تخزينها في الذاكرة المخبئية، فإذا لم تكن موجودةً في أيّ عملية أخرى، فيمكن للمعالج تحميل الذاكرة في الذاكرة المخبئية وتمييزها على أنها حصرية Exclusive، ويغير الحالة إلى معدَّلة Modified عند الكتابة في الذاكرة المخبئية.
</p>

<p>
	تلعب هنا تفاصيل الذاكرة المخبئية دورًا أساسيًا، إذ ستعيد بعض الذواكر المخبئية مباشرةً كتابة الذاكرة المخبئية المعدَّلة إلى ذاكرة النظام المعروفة باسم الذاكرة المخبئية من النوع Write-through، لأن عمليات الكتابة تنتقل إلى الذاكرة الرئيسية، في حين لن تفعل ذلك الذواكر المخبئية الأخرى، بل ستترك القيمة المُعدَّلة في الذاكرة المخبئية فقط حتى التخلص منها عندما تمتلئ الذاكرة المخبئية مثلًا.
</p>

<p>
	الحالة الأخرى هي المكان الذي يطبّق فيه المعالج عملية التنصت ويكتشف أن القيمة موجودة في ذاكرة مخبئية خاصة بمعالجات أخرى، فإذا كانت هذه القيمة مميَّزةً بوصفها مُعدَّلةً Modified، فسينسخ المعالج البيانات في ذاكرته المخبئية ويميّزها على أنها مشتركة Shared، كما سيرسل رسالةً إلى المعالج الآخر الذي حصلنا على البيانات منه لتمييز خط ذاكرته المخبئية بوصفه المالك Owner، لنفترض الآن أن معالجًا ثالثًا في النظام يريد استخدام تلك الذاكرة أيضًا، فسيتنصت ويبحث عن نسخة مشتركة ونسخة مالكة، وبالتالي سيأخذ قيمته من قيمة المالك.
</p>

<p>
	تقرأ جميع المعالجات الأخرى القيمة فقط، ولكن يبقى خط الذاكرة المخبئية مشتركًا في النظام، فإذا احتاج معالج ما تحديث القيمة، فإنه يرسل رسالة إلغاء صلاحية Invalidate عبر النظام، كما يجب على أيّ معالج له هذا الخط الخاص بالذاكرة المخبئية تمييزه بوصفه غير صالح Invalid لأنه لم يَعُد يعكس القيمة الحقيقية، ويميز المعالج خط الذاكرة المخبئية بوصفه معدَّلًا في ذاكرته المخبئية عندما يرسل رسالة إلغاء الصلاحية وستميّزه المعالجات الأخرى على أنه غير صالح.
</p>

<p>
	لاحظ أنه إذا كان خط الذاكرة المخبئية حصريًا، فسيعلم المعالج أنه لا يوجد معالج آخر يعتمد عليه، لذا يمكنه تجنّب إرسال رسالة إلغاء صلاحية، وتبدأ بعدها العملية من جديد، وبالتالي يتحمل أيُّ معالج له القيمة المعدّلة مسؤوليةَ كتابة القيمة الحقيقية مرةً أخرى إلى الذاكرة RAM عند التخلص منها من الذاكرة المخبئية، ولاحظ أنّ هذا البروتوكول يضمن تناسق خط الذاكرة المخبئية بين المعالجات.
</p>

<p>
	هناك العديد من المشاكل في هذا النظام عند زيادة عدد المعالجات، إذ يمكن التحكم في تكلفة التحقق من وجود معالج آخر يحتوي على خط ذاكرة مخبئية (التنصت على عملية القراءة) أو إلغاء صلاحية البيانات في كل معالج آخر (إلغاء عملية التنصت) عند استخدام عدد قليل من المعالجات، ولكن تزداد حركة النواقل مع زيادة عدد المعالجات وهذا هو السبب في أن أنظمة SMP تصل إلى حوالي 8 معالجات فقط.
</p>

<p>
	يعطي وجود جميع المعالجات في الناقل نفسه مشاكل فيزيائية أيضًا، إذ تسمح خصائص الأسلاك الفيزيائية بوضعها على مسافات معينة من بعضها بعضًا وتسمح بأن يكون لها أطوال معينة فقط، وتبدأ سرعة الضوء في أن تصبح أحد الجوانب التي يجب مراعاتها في المدة التي تستغرقها الرسائل للتنقل في النظام مع المعالجات التي تعمل بسرعة مقدَّرةً بالجيجاهيرتز.
</p>

<p>
	لاحظ أنّ برمجيات النظام ليس لها أيّ جزء من هذه العملية، بالرغم من أنّ المبرمجين يجب أن يكونوا على دراية بما يطبّقه العتاد استجابةً للبرمجيات التي يصمّمونها لزيادة الأداء إلى الحد الأقصى.
</p>

<h4>
	حصرية الذاكرة المخبئية في أنظمة SMP
</h4>

<p>
	شرحنا في <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D9%86%D8%B8%D8%B1%D8%A9-%D8%B9%D9%85%D9%8A%D9%82%D8%A9-%D8%B9%D9%84%D9%89-%D8%AA%D8%B3%D9%84%D8%B3%D9%84-%D8%A7%D9%84%D8%B0%D9%88%D8%A7%D9%83%D8%B1-%D8%A7%D9%84%D9%87%D8%B1%D9%85%D9%8A-%D9%88%D8%A7%D9%84%D8%B0%D8%A7%D9%83%D8%B1%D8%A9-%D8%A7%D9%84%D9%85%D8%AE%D8%A8%D8%A6%D9%8A%D8%A9-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1720/" rel="">مقال سابق</a> الذواكر المخبئية الشاملة Inclusive والحصرية Exclusive، إذ تكون الذواكر المخبئية L1 شاملةً، أي أن جميع البيانات الموجودة في الذاكرة المخبئية L1 موجودة في الذاكرة المخبئية L2، وتعني الذاكرة المخبئية L1 الشاملة أنّ الذاكرة المخبئية L2 يجب أن تتنصت حركة مرور الذاكرة للحفاظ على ترابطها في نظام متعدد المعالجات، إذ ستضمن L1 عكس أيّ تغييرات في الذاكرة L2، مما يقلل من تعقيد ذاكرة L1 ويفصله عن عملية التنصت، وبالتالي سيسمح لها بأن تكون أسرع.
</p>

<p>
	تحتوي معظم المعالجات الحديثة المتطورة مثل المعالجات التي ليست مدمَجة على سياسة كتابة الذاكرة المخبئية L1 من النوع Write-through وسياسة الكتابة من النوع Write-back في الذواكر المخبئية ذات المستوى الأدنى، وهناك عدة أسباب لذلك، فبما أنّ ذواكر L2 المخبئية في هذا الصنف من المعالجات تكون حصريةً تقريبًا على الشريحة وسريعةً جدًا عمومًا، فليست العقوبات المفروضة على كتابة الذاكرة المخبئية L1 من النوع Write-through الأمر الرئيسي، كما يمكن أن تتسبّب مجمّعات البيانات المكتوبة التي لا يُحتمَل قراءتها في المستقبل في تلوث مورد L1 المحدود لأن أحجام L1 صغيرة.
</p>

<p>
	ليس هناك داع للقلق بشأن الكتابة في L1 من النوع Write-through إذا احتوت على بيانات متسخة معلَّقة، وبالتالي يمكن أن تمرّر منطق الترابط الإضافي إلى ذاكرة L2 التي لديها دور أكبر تلعبه في ترابط الذاكرة المخبئية.
</p>

<h3 id="hyperthreading">
	تقنية خيوط المعالجة الفائقة Hyperthreading
</h3>

<p>
	يمكن أن يقضي المعالج الحديث كثيرًا من وقته في انتظار أجهزة أبطأ بكثير في تسلسل الذواكر الهرمي لتقديم البيانات للمعالجة، وبالتالي فإن إستراتيجيات الحفاظ على خط أنابيب المعالج ممتلئًا لها أهمية قصوى، وتتمثل إحدى الإستراتيجيات في تضمين عدد كاف من المسجلات ومنطق الحالة بحيث يمكن معالجة مجريين من التعليمات في الوقت نفسه، مما يجعل وحدة معالجة مركزية واحدة تبحث عن جميع النوايا والأهداف المطلوبة كأنها وحدتان CPU.
</p>

<p>
	تحتوي كل وحدة معالجة مركزية على مسجلاتها الخاصة، ولكن يجب عليها مشاركة منطق المعالج الأساسي والذاكرة المخبئية وحيز النطاق التراسلي للإدخال والإخراج من وحدة المعالجة المركزية إلى الذاكرة، لذا يمكن أن يحافظ مجريان من التعليمات على المنطق الأساسي للمعالج أكثر انشغالًا، ولكن لن تكون زيادة الأداء كبيرةً بسبب وجود وحدتَي CPU منفصلتين فيزيائيًا، ويكون تحسين الأداء أقل من 20%، ولكن يمكن أن يكون أفضل أو أسوأ كثيرًا اعتمادًا على الحِمل.
</p>

<h3>
	الأنوية المتعددة Multi Core
</h3>

<p>
	أصبح وضع معالِجَين أو أكثر في الحزمة الفيزيائية نفسها ممكنًا مع زيادة القدرة على احتواء مزيد من الترانزستورات على شريحة واحدة، ولكن المعالجات الأكثر شيوعًا هي المعالجات ثنائية النواة، إذ توجد نواتان للمعالج على الشريحة نفسها، وتُعَدّ هذه الأنوية -على عكس تقنية خيوط المعالجة الفائقة Hyperthreading- معالجات كاملةً، وبالتالي تبدو على أنها معالجات منفصلة فيزيائيًا مثل نظام SMP.
</p>

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

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

<p>
	تُعَدّ متطلبات الطاقة للمعالجات متعددة الأنوية أقل بكثير من المعالجات المنفصلة عن بعضها بعضًا، وهذا يعني أن هناك حاجة أقل لتبريد الحرارة والتي يمكن أن تكون ميزةً كبيرةً في تطبيقات مراكز البيانات حيث تُجمَّع الحواسيب مع وجود حاجة كبيرة للتبريد، كما يجعل وجود الأنوية في الحزمة الفيزيائية نفسها المعالجةَ المتعددة عمليةً في التطبيقات التي لن تكون فيها كذلك مثل الحواسيب المحمولة، كما يُعَدّ إنتاج شريحة واحدة بدلًا من شريحتين أرخص بكثير.
</p>

<h2>
	العناقيد Clusters
</h2>

<p>
	تتطلب العديد من التطبيقات أنظمةً أكبر بكثير من عدد المعالجات التي يمكن لنظام SMP التوسع إليها، وتُعَدّ العناقيد Clusters إحدى الطرق لتوسيع النظام أكثر، وهي عدد من الحواسيب التي لديها بعض القدرة على التواصل مع بعضها بعضًا، كما لا تعرف الأنظمة بعضها بعضًا على مستوى العتاد، إذ تُترَك مهمة ربط هذه الحواسيب للبرمجيات.
</p>

<p>
	تسمح البرمجيات مثل MPI للمبرمجين بكتابة برامجهم ثم وضع أجزاء منها على حواسيب أخرى في النظام مثل تمثيل حلقة تُنفَّذ عدة آلاف من المرات وتطبّق إجراءً مستقلًا، أي لا يوجد تكرار للحلقة يؤثر على أيّ تكرار آخر، ويمكن للبرمجيات جعل كل حاسوب يشغّل 250 حلقة لكل منها مع وجود أربعة حواسيب في العنقود.
</p>

<p>
	يختلف الترابط بين الحواسيب، إذ يمكن أن يكون بطيئًا مثل روابط شبكة الإنترنت أو سريعًا مثل الناقلات المخصَّصة والخاصة مثل روابط إنفيني باند Infiniband، ومهما كان هذا الترابط، فسيبقى في المستوى الأخفض من تسلسل الذواكر الهرمي وسيكون أبطأ بكثير من الذاكرة RAM، وبالتالي لن يقدّم العنقود أداءً جيدًا في الموقف الذي تتطلب فيه كل وحدة معالجة مركزية الوصول إلى البيانات المُخزَّنة في الذاكرة RAM الخاصة بحاسوب آخر، إذ ستحتاج البرمجيات في كل مرة أن تطلب نسخةً من البيانات من الحاسوب الآخر، وتنسخها عبر الرابط البطيء إلى الذاكرة RAM المحلية قبل أن يتمكن المعالج من إنجاز أيّ عمل.
</p>

<p>
	لا تتطلب العديد من التطبيقات هذا النسخ المستمر بين الحواسيب، وأحد الأمثلة الشائعة عن ذلك هو SETI@Home، إذ تُحلَّل البيانات التي جرى جمعها من هوائي راديو بحثًا عن علامات على وجود كائن فضائي، ويمكن توزيع كل حاسوب لبضع دقائق للحصول على البيانات لتحليلها ويعطي تقريرًا ملخصًا لما وجده، إذ يُعَدّ SETI@Home عنقودًا مخصَّصًا وكبيرًا جدًا.
</p>

<p>
	يوجد تطبيق آخر هو تطبيق تصيير الصور Rendering of Images الذي يُستخدَم خاصةً للتأثيرات الخاصة في الأفلام، إذ يُسلَّم كل حاسوب إطارًا واحدًا من الفيلم يحتوي على نماذج إطارات شبكية وخامات Textures ومصادر إضاءة يجب دمجها أو تصييرها في التأثيرات الخاصة المذهلة التي نحصل عليها، كما يُعَدّ كل إطار ساكنًا، لذلك لا يحتاج الحاسوب بمجرد حصوله على الدخل الأولي لمزيد من الاتصال حتى يصبح الإطار النهائي جاهزًا لإرساله ودمجه في الحركة، فقد كان لفيلم سيد الخواتم مثلًا تأثيرات خاصة مصيَّرة على عنقود ضخم يعمل بنظام لينكس.
</p>

<h2>
	الوصول غير الموحد للذاكرة Non-Uniform Memory Access
</h2>

<p>
	يُعَدّ الوصول غير الموحد للذاكرة Non-Uniform Memory Access -أو NUMA اختصارًا- عكس نظام العناقيد السابق تقريبًا، ولكنه -كما هو الحال في نظام العنقود- يتكون من عقد فردية مرتبطة ببعضها بعضًا، إلا أنّ الارتباط بين العقد شديد التخصص ومكلف، ولا يمتلك العتاد أيّ معرفة بالربط بين العقد في نظام العنقود، في حين لا تمتلك البرمجيات في نظام NUMA معرفةً جيدةً أو تمتلك معرقةً أقل حول تخطيط النظام، إذ يطبّق العتاد كل العمل لربط العقد مع بعضها بعضًا.
</p>

<p>
	يأتي مصطلح الوصول غير الموحّد إلى الذاكرة من حقيقة أن الذاكرة RAM ليست محلية بالنسبة لوحدة المعالجة المركزية، وبالتالي يمكن أن هناك حاجة لأن تصل عقدة على بعد مسافة ما إلى البيانات، إذ يستغرق ذلك وقتًا أطول على النقيض من معالج واحد أو نظام SMP حيث يمكن الوصول إلى الذاكرة RAM مباشرةً، ويستغرق ذلك دائمًا وقتًا ثابتًا أو موحّدًا.
</p>

<h3>
	تخطيط نظام NUMA
</h3>

<p>
	يُعَدّ تقليل المسافة بين العقد أمرًا بالغ الأهمية مع وجود العديد من العقد التي تتواصل مع بعضها في النظام، إذ يُفضَّل أن يكون لكل عقدة رابط مباشر بكل عقدة أخرى لأنه يقلّل المسافة التي تحتاجها أيّة عقدة للعثور على البيانات، لكن لا يُعَدّ ذلك موقفًا عمليًا عندما ينمو عدد العقد إلى المئات والآلاف كما هو الحال مع الحواسيب العملاقة الكبيرة، فالأساس في هذا النمو هو مجموعة مؤلفة من عقدتين تتواصلان مع بعضهما بعضًا ثم ستنمو إلى <code>n!/2*(n-2)!‎</code>.
</p>

<p>
	تُستخدَم التخطيطات البديلة لمقايضة المسافة بين العقد مع الوصلات المطلوبة بهدف التقليل من هذا النمو الأسي، فأحد هذه التخطيطات الشائعة في معماريات NUMA الحديثة هو المكعب الفائق Hypercube الذي يحتوي على تعريف رياضي صارم، ويكون المكعب الفائق هو نظير رباعي الأبعاد للمكعب الذي هو نظير ثلاثي الأبعاد للمربع.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="108798" href="https://academy.hsoub.com/uploads/monthly_2022_09/01_hypercube.png.f0da08ae744171a986b4fc15c335dd2e.png" rel=""><img alt="01_hypercube.png" class="ipsImage ipsImage_thumbnailed" data-fileid="108798" data-unique="5o553qrr6" style="width: 400px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2022_09/01_hypercube.png.f0da08ae744171a986b4fc15c335dd2e.png"></a>
</p>

<p style="text-align: center;">
	مثال عن المكعب الفائق Hypercube الذي يوفر مقايضةً جيدةً بين المسافة بين العقد وعدد الوصلات المطلوب.
</p>

<p>
	يمكننا أن نرى في الشكل السابق أن المكعب الخارجي يحتوي على 8 عقد، والحد الأقصى لعدد المسارات المطلوبة لأي عقدة للتواصل مع عقدة أخرى هو 3، فإذا وضعنا مكعبًا آخر داخل هذا المكعب، فسيكون لدينا ضعف عدد المعالجات ولكن زادت التكلفة القصوى للمسار إلى 4، مما يعني نمو تكلفة المسار القصوى خطيًا فقط عند نمو عدد المعالجات بمقدار 2‎<sup>n‎‎</sup>‎.
</p>

<h3>
	ترابط الذاكرة المخبئية Cache Coherency
</h3>

<p>
	لا يزال الحفاظ على ترابط الذاكرة المخبئية في نظام NUMA ممكنًا، إذ يشار إلى ذلك باسم نظام NUMA مع ترابط الذاكرة المخبئية Cache Coherent NUMA System أو ccNUMA اختصارًا، ولا يتوسّع المخطط القائم على البث الإذاعي المُستخدَم للحفاظ على ترابط ذاكرة المعالج المخبئية في نظام SMP إلى مئات أو حتى آلاف المعالجات في نظام NUMA كبير.
</p>

<p>
	يشار إلى أحد المخططات الشائعة لترابط الذاكرة المخبئية في نظام NUMA باسم النموذج المستند إلى الدليل Directory Based Model الذي تتصل فيه المعالجات الموجودة في النظام بعتاد دليل الذاكرة المخبئية، إذ يحافظ عتاد الدليل على صورة متناسقة لكل معالج، كما يخفي هذا التجريد عمل نظام NUMA عن المعالج.
</p>

<p>
	يحتفظ المخطط المستند إلى الدليل لصاحبيه Censier و Feautrier بدليل مركزي، إذ تحتوي كل كتلة ذاكرة على بِت راية يُعرَف بالبِت الصالح Valid Bit لكل معالج وبِت واحد يُسمَّى بالبِت المتسخ Dirty Bit، ويضبط الدليل البِت الصالح للمعالج الذي يقرأ الذاكرة إلى ذاكرته المخبئية.
</p>

<p>
	إذا أراد المعالج الكتابة إلى خط الذاكرة المخبئية، فيجب أن يضبِط الدليل البِتَّ المتسخ لكتلة الذاكرة من خلال إرسال رسالة إلغاء صلاحية إلى تلك المعالجات التي تستخدِم خط الذاكرة المخبئية والمعالجات التي جرى ضبط رايتها فقط بهدف تجنب حركة مرور البث broadcast traffic.
</p>

<p>
	يجب بعد ذلك أن يحاول أيّ معالج آخر قراءة كتلة الذاكرة، وسيجد الدليل ضبط البِت المتسخ، كما يجب أن يحصل الدليل على خط الذاكرة المخبئية المُحدَّث من المعالج مع البِت الصالح المضبوط حاليًا، ويعيد كتابة البيانات المتسخة إلى الذاكرة الرئيسية ثم إعادة هذه البيانات إلى المعالج المطلوب، مما يؤدي إلى ضبط البِت الصالح للمعالج الطالب في هذه العملية، ولاحظ أنّ هذا الأمر واضح للمعالج الطالب ويمكن أن يحتاج الدليل الحصول على تلك البيانات من مكان قريب جدًا أو من مكان بعيد جدًا.
</p>

<p>
	لا يمكن أن يتوسع المخطط المؤلَّف من آلاف المعالجات التي تتصل بدليل واحد بصورة جيدة، إذ تتضمن توسّعات المخطط وجود تسلسل هرمي من الدلائل التي تتواصل فيما بينها باستخدام بروتوكول منفصل، كما يمكن أن تستخدِم الدلائل شبكة اتصالات ذات أغراض أعم للتواصل فيما بينها بدلًا من ناقل وحدة المعالجة المركزية، مما يسمح بالتوسع إلى أنظمة أكبر بكثير.
</p>

<h3>
	تطبيقات NUMA
</h3>

<p>
	تُعَدّ أنظمة NUMA الأنسب لأنواع المشاكل التي تتطلب قدرًا كبيرًا من التفاعل بين المعالج والذاكرة، فمن المصطلحات الشائعة في محاكاة الطقس مثلًا هو تقسيم البيئة إلى صناديق صغيرة تستجيب بطرق مختلفة، بحيث تعكس المحيطات والأرض أو تخزن كميات مختلفة من الحرارة مثلًا، ويجب تغذية الاختلافات الصغيرة لمعرفة النتيجة الإجمالية أثناء تشغيل عمليات المحاكاة.
</p>

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

<p>
	ليس للبرمجيات معرفة مباشرة بأن النظام الأساسي هو نظام NUMA، ولكن يجب أن يتوخّى المبرمجون الحذر عند البرمجة لهذا النظام للحصول على أفضل أداء، وسيؤدي الاحتفاظ بالذاكرة بالقرب من المعالج الذي سيستخدِمها إلى أفضل أداء، ولكن يجب أن يستخدِم المبرمجون تقنيات مثل التشخيص Profiling لتحليل مسارات الشيفرة البرمجية المتّبَعة والعواقب التي تسببها الشيفرة البرمجية للنظام لاستخراج أفضل أداء.
</p>

<h2>
	ترتيب الذاكرة وقفلها
</h2>

<p>
	تجلب الذاكرة المخبئية متعددة المستويات والمعمارية متعددة المعالجات الفائقة بعض المشاكل المتعلقة بكيفية رؤية المبرمج لشيفرة المعالج البرمجية التي تكون قيد التشغيل.
</p>

<p>
	لنفترض أنّ شيفرة البرنامج البرمجية تعمل على معالجَين في الوقت نفسه، وأنّ كلا المعالجين يشتركان بفعالية في منطقة واحدة كبيرة من الذاكرة، فإذا أصدر أحد المعالجَين تعليمات تخزين لوضع قيمة مسجّل في <a href="https://academy.hsoub.com/certificates/comptia/%D8%A7%D9%84%D8%B0%D8%A7%D9%83%D8%B1%D8%A9-%D9%88%D8%A3%D9%86%D9%88%D8%A7%D8%B9%D9%87%D8%A7-r59/" rel="">الذاكرة</a>، فلا بد أنك تتساءل عن الوقت الذي يمكن فيه التأكد من أن المعالج الآخر يحمّل تلك الذاكرة التي سيرى قيمتها الصحيحة.
</p>

<p>
	يمكن للنظام في أبسط الحالات أن يضمن أنه في حالة تنفيذ أحد البرامج لتعليمات التخزين، وبالتالي سترى أيّ تعليمات تحميل لاحقة هذه القيمة، إذ يُشار إلى ذلك باسم ترتيب الذاكرة الصارم Strict Memory Ordering، لأن القواعد لا تسمح بأيّ مجال للحركة، كما يجب أن تدرك أنّ هذا النوع من الأشياء يُعَدّ عائقًا خطيرًا أمام أداء النظام.
</p>

<p>
	لا يُطلَب من ترتيب الذاكرة أن يكون صارمًا جدًا في كثير من الأحيان، إذ يمكن للمبرمج تحديد النقاط التي يحتاجها للتأكد من رؤية جميع العمليات المُعلَّقة بطريقة عامة، ولكن يمكن أن يكون هناك العديد من التعليمات من بين هذه النقاط حيث لا تكون الدلالات Semantics مهمة، ولنفترض الموقف التالي مثلًا الذي يمثل ترتيب الذاكرة:
</p>

<pre class="ipsCode prettyprint lang-javascript prettyprinted" id="ips_uid_1676_13" style=""><span class="kwd">typedef</span><span class="pln"> </span><span class="kwd">struct</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> a</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> b</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> a_struct</span><span class="pun">;</span><span class="pln">

</span><span class="com">/*
 * مرّر مؤشرًا لتخصيصه بوصفه بنيةً جديدةً
 */</span><span class="pln">
</span><span class="kwd">void</span><span class="pln"> get_struct</span><span class="pun">(</span><span class="pln">a_struct </span><span class="pun">*</span><span class="pln">new_struct</span><span class="pun">)</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">void</span><span class="pln"> </span><span class="pun">*</span><span class="pln">p </span><span class="pun">=</span><span class="pln"> malloc</span><span class="pun">(</span><span class="kwd">sizeof</span><span class="pun">(</span><span class="pln">a_struct</span><span class="pun">));</span><span class="pln">

  </span><span class="com">/* لا نهتم بترتيب التعليمتين التاليتين
         * اللتين ستُنفَّذان في النهاية */</span><span class="pln">
  p</span><span class="pun">-&gt;</span><span class="pln">a </span><span class="pun">=</span><span class="pln"> </span><span class="lit">100</span><span class="pun">;</span><span class="pln">
  p</span><span class="pun">-&gt;</span><span class="pln">b </span><span class="pun">=</span><span class="pln"> </span><span class="lit">150</span><span class="pun">;</span><span class="pln">

  </span><span class="com">/* .لكن يجب أن تُنفَّذا قبل التعليمة التالية
  * p وإلّا فسيتمكن معالج آخر ينظر إلى قيمة 
  * .من أن يجدها تؤشّر إلى بنية قيمها غير مملوءة 
  */</span><span class="pln">
  new_struct </span><span class="pun">=</span><span class="pln"> p</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	لدينا في هذا المثال عمليتَي تخزين يمكن تطبيقهما بأيّ ترتيب معيّن بما يناسب المعالج، ولكن يجب في الحالة الأخيرة تحديث المؤشر فقط بمجرد التأكد من اكتمال عمليتَي التخزين السابقتين، وإلّا فيمكن أن ينظر معالج آخر إلى قيمة <code>p</code> ويتبع المؤشر إلى الذاكرة ويحمّلها ويحصل على قيمة غير صحيحة تمامًا، لذا يجب أن تحتوي عمليات التحميل والتخزين على دلالات تصف سلوكها.
</p>

<p>
	توصَف دلالات الذاكرة من حيث الأسوار Fences التي تحدّد كيفية إعادة ترتيب عمليات التحميل والتخزين، كما يمكن افتراضيًا إعادة طلب عملية التحميل أو التخزين في أيّ مكان، ويشبه اكتساب الدلالات Acquire Semantics السورَ الذي يسمح فقط لعمليات التحميل والتخزين بالتحرك للأسفل عبره، أي يمكنك ضمان أنّ أيّ عملية تحميل أو تخزين لاحقة سترى القيمة -لأنه لا يمكن نقلها فوقها- عند اكتمال هذا التحميل أو التخزين.
</p>

<p>
	يُعَدّ تحرير الدلالات Release Semantics عكس ذلك، أي يسمح السور بأي عملية تحميل أو تخزين أن تكتمل قبله -أي التحرك للأعلى-، ولكن لا يوجد شيء قبلها للتحرك للأسفل. وبالتالي يمكنك تخزين أيّ عملية تحميل أو تخزين سابقة مكتملة عند معالجة التحميل أو التخزين باستخدام تحرير الدلالات.
</p>

<p style="text-align: center;">
	<img alt="bitmap.png" class="ipsImage ipsImage_thumbnailed" data-fileid="108842" data-unique="sw5tv8pzb" style="" src="https://academy.hsoub.com/uploads/monthly_2022_09/bitmap.png.93d7560d3133820f8d4762f39b7c902d.png">
</p>

<p>
	رسم توضيحي يمثّل عمليات إعادة الترتيب الصالحة للعمليات باستخدام اكتساب الدلالات وتحريرها
</p>

<p>
	سور الذاكرة الكامل full memory fence هو مزيج من اكتساب الدلالات وتحريرها، حيث لا يمكن إعادة ترتيب عمليات التحميل أو التخزين في أيّ اتجاه حول عملية التحميل أو التخزين الحالية، كما يستخدِم نموذج الذاكرة الأكثر صرامة سور ذاكرة كامل لكل عملية، في حين سيترك النموذج الأضعف كل عملية تحميل وتخزين على أساس تعليمات عادية قابلة لإعادة الترتيب.
</p>

<h3>
	المعالجات ونماذج الذاكرة
</h3>

<p>
	تطبّق المعالجات المختلفة نماذج ذاكرة مختلفة، إذ يحتوي معالج x86 ومعالج AMD64 على نموذج ذاكرة صارم تمامًا، حيث تحتوي جميع عمليات التخزين على تحرير دلالات، أي يجب أن ترى أيّة عملية تحميل أو تخزين لاحقة نتيجةَ عملية التخزين، ولكن جميع عمليات التحميل لها دلالات عادية، كما تعطي بادئة القفل سورًا للذاكرة، في حين يسمح المعالج إيتانيوم Itanium لجميع عمليات التحميل والتخزين بأن تكون عاديةً ما لم يُجرَى إخباره صراحةً بغير ذلك.
</p>

<h3>
	القفل
</h3>

<p>
	ليست معرفة متطلبات ترتيب الذاكرة لكل معمارية عمليةً ومناسبةً لجميع المبرمجين وسيجعل ذلك نقل البرامج وتنقيحها عبر أنواع المعالجات المختلفة أمرًا صعبًا، إذ يستخدِم المبرمجون مستوًى أعلى من التجريد يسمى القفل Locking للسماح بالتشغيل المتزامن للبرامج عندما يكون هناك وحدات معالجة مركزية متعددة، كما لا يمكن لأيّ معالج آخر الحصول على القفل حتى يُحرَّر عندما يحصل برنامج ما عليه لجزء من شيفرة برمجية، كما يجب أن يحاول المعالج أخذ القفل قبل أيّ أجزاء مهمة من الشيفرة البرمجية، فإذا لم يستطع الحصول عليه، فلن يستمر في عمله.
</p>

<p>
	يمكنك رؤية كيف أنّ ذلك مقيَّد بتسمية دلالات ترتيب الذاكرة الموضَّحة سابقًا، كما نريد التأكد من أنه لن يُعاد طلب أيّ عمليات يجب أن يحميها القفل قبل الحصول عليه، وهذه هي الطريقة التي تعمل بها عملية اكتساب الدلالات، في حين يجب التأكد من أنّ كل عملية طبّقناها أثناء احتفاظنا بالقفل مكتملة عندما نحرره مثل مثال تحديث المؤشر الموضَّح سابقًا، وهذا ما يسمى بتحرير الدلالات.
</p>

<p>
	هناك العديد من المكتبات البرمجية المتاحة التي تسمح للمبرمجين بعدم القلق بشأن تفاصيل دلالات الذاكرة واستخدام المستوى الأعلى من تجريد القفل <code>lock()‎</code> وإلغاء القفل <code>unlock()‎</code>.
</p>

<h4>
	صعوبات الأقفال
</h4>

<p>
	تجعل أنظمة القفل البرمجة أكثر تعقيدًا، إذ يمكنها أن تؤدي إلى تعطيل البرامج، ولنفترض أنّ معالجًا ما يحتفظ بقفل على بعض البيانات، وينتظر قفلًا على بيانات أخرى حاليًا، فإذا انتظر معالج آخر البيانات التي يحتفظ بها المعالج الأول وكان قبل ذلك وقبل دخوله في حالة قفل يحتفظ ببيانات يريدها المعالج الأول ذاك لفك قفله، فسنواجه حالة تعطل تام، بحيث ينتظر كل معالج المعالج الآخر ولا يمكن لأيّ منهما الاستمرار بدون قفل المعالج الآخر.
</p>

<p>
	ينشأ هذا الموقف بسبب حالة التسابق Race Condition في أغلب الأحيان التي تُعَدّ إحدى أصعب الأخطاء التي يمكن تعقّبها، فإذا كان هناك معالِجان يعتمدان على عمليات تحدث بترتيب معيّن في الوقت، فهناك دائمًا احتمال حدوث حالة تسابق، كما يمكن أن تصطدم أشعة جاما المنبعثة من نجم متفجر في مجرة أخرى بأحد المعالجات، مما يؤدي إلى الخروج عن ترتيب العمليات، ثم ستحدث حالة تعطل تام كما رأينا سابقًا، لذا يجب ضمان ترتيب البرامج باستخدام الدلالات وليس عبر الاعتماد على سلوكيات محددة لمرة واحدة.
</p>

<p>
	يوجد وضع مماثل يسمى المنع Livelock وهو عكس التعطل Deadlock، إذ يمكن أن تكون إحدى الاستراتيجيات لتجنب التعطل أن يكون لديك قفل مؤدب Polite يرفض إعطاء القفل لكل مَن يطلبه، وقد يتسبب هذا القفل المؤدّب في جعل <a href="https://academy.hsoub.com/programming/c/%D8%A7%D9%84%D9%81%D8%B5%D9%84-%D8%A7%D9%84%D8%AA%D8%A7%D8%B3%D8%B9-%D9%85%D9%81%D9%87%D9%88%D9%85-%D8%A7%D9%84%D8%AE%D9%8A%D9%88%D8%B7-threads-%D9%81%D9%8A-%D8%B9%D9%85%D9%84%D9%8A%D8%A9-%D8%A7%D9%84%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-r1012/" rel="">خيطين Threads</a> يمنحان بعضهما القفل باستمرار دون الحاجة إلى أخذ القفل لفترة كافية لإنجاز العمل المهم والانتهاء من القفل، إذ يمكن أن يكون هناك وضع مشابه في الحياة الواقعية لشخصين يلتقيان عند الباب في الوقت نفسه، ويقول كلاهما: "لا، أنت أولًا، أنا أصر على ذلك" دون المرور عبر الباب نهائيًا.
</p>

<h4>
	استراتيجيات القفل
</h4>

<p>
	هناك العديد من الاستراتيجيات المختلفة لتطبيق سلوك الأقفال، إذ يُشار إلى القفل البسيط الذي يحتوي ببساطة على حالتين -مقفل Locked أو غير مقفل Unlocked- على أنه كائن مزامنة Mutex، وهو اختصار للاستبعاد المتبادل Mutual Exclusion الذي يعني أنه إذا كان لدى شخص ما قفلًا، فلا يمكن لشخص آخر الحصول عليه، وهناك عدد من الطرق لتطبيق قفل كائن المزامنة، إذ لدينا في أبسط الحالات ما يسمى بالقفل الدوار Spinlock إذ يبقى المعالج ضمن حلقة في انتظار أخذ القفل مثل طفل صغير يطلب من والديه شيئًا ويقول "هل يمكنني الحصول عليه الآن؟" باستمرار.
</p>

<p>
	تكمن مشكلة هذه الاستراتيجية في أنها تضيع الوقت، إذ لا ينفّذ المعالج أيّ عملٍ مفيد بينما يكون متوقفًا ويطلب القفل باستمرار، وقد يكون ذلك مناسبًا للأقفال التي يُحتمَل أن تُقفَل لفترة قصيرة جدًا من الوقت فقط، ولكن يمكن أن يكون مقدار الوقت الذي يستغرقه القفل أطول بكثير في كثير من الحالات.
</p>

<p>
	الاستراتيجية الأخرى هي السكون Sleep، حيث إذا لم يتمكن المعالج من الحصول على القفل، فسينفّذ بعض الأعمال الأخرى في انتظار إشعار بأن القفل متاح للاستخدام، وسنرى في المقالات القادمة كيف يمكن لنظام التشغيل تبديل العمليات وإعطاء المعالج مزيدًا من العمل لتنفيذه.
</p>

<p>
	يُعَدّ كائن المزامنة حالةً خاصةً من <a href="https://academy.hsoub.com/programming/c/%D8%A7%D9%84%D9%81%D8%B5%D9%84-%D8%A7%D9%84%D8%AD%D8%A7%D8%AF%D9%8A-%D8%B9%D8%B4%D8%B1-%D9%85%D8%AA%D8%BA%D9%8A%D8%B1%D8%A7%D8%AA-%D8%AA%D9%82%D9%8A%D9%8A%D8%AF-%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-semaphores-%D9%81%D9%8A-%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-%D8%B3%D9%8A-c-r1014/" rel="">متغير تقييد الوصول Semaphore</a> الذي اخترعه عالم الحاسوب الهولندي ديكسترا Dijkstra، إذ يمكن ضبط متغير تقييد الوصول Semaphore لحساب عدد مرات الوصول إلى الموارد في حالة توفر العديد منها، في حين يكون لديك كائن المزامنة Mutex في الحالة التي يكون فيها عدد الموارد يساوي واحدًا فقط.
</p>

<p>
	لكن لا تزال أنظمة القفل هذه تواجه بعض المشاكل، إذ يرغب معظم الأشخاص في قراءة البيانات التي تُحدَّث في حالات نادرة فقط. يمكن أن يؤدي وجود جميع المعالجات التي ترغب في قراءة البيانات فقط التي تتطلب قفلًا إلى تنازع القفل حيث يُنجَز القليل من العمل لأن الجميع ينتظر الحصول على القفل نفسه لبعض البيانات.
</p>

<p>
	ترجمة -وبتصرُّف- للقسم <a href="https://www.bottomupcs.com/small_to_big_systems.xhtml" rel="external nofollow">Small to big systems</a> من الفصل <a href="https://www.bottomupcs.com/chapter02.xhtml" rel="external nofollow">Computer Architecture</a> من كتاب <a href="https://www.bottomupcs.com/" rel="external nofollow">Computer Science from the Bottom Up</a> لصاحبه Ian Wienand.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%AF%D9%88%D8%B1-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D9%88%D8%AA%D9%86%D8%B8%D9%8A%D9%85%D9%87-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1723/" rel="">دور نظام التشغيل وتنظيمه في معمارية الحاسوب</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/os-embedded-systems/%D8%A7%D9%84%D8%A3%D8%AC%D9%87%D8%B2%D8%A9-%D8%A7%D9%84%D8%B7%D8%B1%D9%81%D9%8A%D8%A9-peripherals-%D9%88%D9%86%D9%88%D8%A7%D9%82%D9%84%D9%87%D8%A7-buses-%D9%81%D9%8A-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%D9%8A%D8%A9-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8-r1721/" rel="">الأجهزة الطرفية Peripherals ونواقلها Buses في معمارية الحاسوب</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/certificates/comptia/%D9%88%D8%AD%D8%AF%D8%A9-%D8%A7%D9%84%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D9%85%D8%B1%D9%83%D8%B2%D9%8A%D8%A9-r58/" rel="">وحدة المعالجة المركزية</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/general/%D8%B9%D9%84%D9%88%D9%85-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8/" rel="">المدخل الشامل لتعلم علوم الحاسوب</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/apps/general/%D8%A7%D8%AE%D8%AA%D9%8A%D8%A7%D8%B1-%D8%A7%D9%84%D8%B9%D8%AA%D8%A7%D8%AF-%D9%88%D8%A7%D9%84%D8%A8%D8%B1%D8%A7%D9%85%D8%AC-%D9%81%D9%8A-%D8%A7%D9%84%D8%B9%D8%A7%D9%84%D9%85-%D8%A7%D9%84%D8%B1%D9%82%D9%85%D9%8A-r372/" rel="">اختيار العتاد والبرامج في العالم الرقمي</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">1722</guid><pubDate>Sat, 22 Oct 2022 16:08:00 +0000</pubDate></item></channel></rss>
