تعلم الوحدات · الدرس 2.2

الصمام متعدد الألوان (RGB LED)

العودة إلى الدروس

نظرة عامة ومكونات LED

يضيف RGB LED ألوانًا للمشروعات بسهولة، لأنه يجمع ثلاثة LEDs في حزمة واحدة. يوجد نوعان شائعان: المصعد المشترك (Common Anode) ويتصل طرفه المشترك بـ 5V، والمهبط المشترك (Common Cathode) ويتصل بالأرضي. نحتاج ثلاث مقاومات على التوالي، واحدة لكل لون، لتحديد التيار.

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

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

بنية RGB

يشبه LED عاديًا، لكن بداخله ثلاثة صمامات: أحمر وأخضر وأزرق. التحكم في سطوع كل منها يتيح مزج الألوان. يمكن تغيير المقاومات كما في درس LED، لكن ذلك يتطلب عملاً أكثر؛ وتتيح analogWrite() على منافذ UNO ذات العلامة ~ التحكم في القدرة المرسلة لكل لون.

للحزمة أربع أرجل: موجب لكل لون وطرف سالب مشترك. الطرف المشترك هو الثاني من جهة الحافة المسطحة، وهو الأطول ويوصل بالأرضي. يحتاج كل موجب مقاومة 220Ω مستقلة بينه وبين منفذ خرج UNO.

ترتيب أطراف RGB LED ومخططه الداخلي
ترتيب أطراف RGB LED ومخططه الداخلي

مزج الألوان وتعديل عرض النبضة

اللون

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

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

مزج الضوء الأحمر والأخضر والأزرق
مزج الضوء الأحمر والأخضر والأزرق

PWM

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

نبضات PWM عند نسب تشغيل مختلفة
نبضات PWM عند نسب تشغيل مختلفة

نبضة تنتج تقريبًا كل 1/500 ثانية. تتحكم analogWrite() في طولها؛ القيمة 0 تعني عدم وجود نبضة، و 255 تعني بقاء الخرج مفعّلًا طوال الفترة حتى النبضة التالية. القيم بينهما تعطي عرض نبضة متوسطًا. عند HIGH لمدة 5% يصل نحو 5% من القدرة، وعند 5V لمدة 90% يصل نحو 90%. سرعة التشغيل والإطفاء أعلى من قدرة العين على التمييز، فتبدو كاختلاف في السطوع.

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

المخطط الكهربائي

توصيل الألوان الثلاثة بمقاومات ومنافذ UNO
توصيل الألوان الثلاثة بمقاومات ومنافذ UNO

مخطط الأسلاك

توصيل RGB LED بلوحة التجارب (Breadboard)
توصيل RGB LED بلوحة التجارب (Breadboard)

فتح البرنامج وتعريف المنافذ

افتح ملف البرنامج RGB_LED.ino من ملفات الدرس في بيئة Arduino IDE. بعد إتمام التوصيلات، وصّل لوحة أردوينو (UNO R3 Board) بالحاسوب بكابل توصيل (USB Cable)، ثم اضغط زر Upload (رفع) لنقل البرنامج إلى اللوحة وتشغيله عليها.

إذا تعذر نقل البرنامج إلى اللوحة، فراجع قسم «رفع البرنامج ومعالجة خطأ الاتصال» في الدرس 1.5 «وميض LED وإضافة المكتبات» للتحقق من اتصال USB واختيار نوع اللوحة والمنفذ التسلسلي في بيئة Arduino IDE.

يبدأ البرنامج بتحديد منافذ الألوان:

مقتطف من الشرح
#define BLUE 3

#define GREEN 5

#define RED 6

#define

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

الصيغة #define constantName value، حيث constantName اسم الماكرو و value قيمته. لا تضع فاصلة منقوطة أو علامة =؛ فهما قد يسببان أخطاء ترجمة تظهر في مواضع لاحقة:

مقتطف من الشرح
#define ledPin 3; // this is an error

#define ledPin = 3 // this is also an error

setup() و pinMode()

تعمل setup() مرة بعد إعادة الضبط. تهيئ هنا المنافذ الثلاثة OUTPUT، وتشغل الأحمر وتطفئ الأخضر والأزرق. تضبط pinMode(pin, mode) المنفذ دخلًا أو خرجًا. منذ Arduino 1.0.1 يدعم INPUT_PULLUP تفعيل مقاومة السحب الداخلية، بينما INPUT يعطلها صراحة.

المتغيرات والتحكم في السطوع

معاملا pinMode() هما pin، رقم المنفذ، و mode، أحد INPUT أو OUTPUT أو INPUT_PULLUP. يشير الدرس إلى صفحة Digital Pins للتفصيل.

النوع int

الأعداد الصحيحة نوع أساسي لتخزين الأرقام. على UNO ولوحات ATmega يخزن int مقدارًا من 16 بت، أي بايتين، بمدى -32768 إلى 32767، أي من -2^15 إلى 2^15-1. على Due ولوحات SAMD مثل MKR1000 و Zero يكون 32 بت، أي أربعة بايتات، بمدى -2147483648 إلى 2147483647، أي من -2^31 إلى 2^31-1.

تُمثَّل الأعداد السالبة بمتمم الاثنين؛ يدل البت الأعلى على الإشارة. للحصول على تمثيل عدد سالب، اعكس جميع بتات العدد الموجب المقابل ثم أضف 1.

الصيغة int var = val، حيث var اسم المتغير و val قيمته. يعرف البرنامج redValue و greenValue و blueValue من النوع int.

تبدأ القيم بـ redValue = 255 و greenValue = 0 و blueValue = 0. يمكن تحديد ثلاث قيم سطوع، واحدة لكل لون، بين 0 للإطفاء و 255 لأقصى سطوع، ثم استدعاء analogWrite() لكل لون. جرّب إضافة ألوان خاصة بك.

في حلقة الانتقال من الأحمر إلى الأخضر، ينخفض redValue بمقدار 1 ويرتفع greenValue بمقدار 1، وتكتب القيمتان باستخدام analogWrite() ثم ينتظر البرنامج delayTime.

الحلقات والمعاملات

for

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

مقتطف من الشرح
for (initialization; condition; increment) {

  // statement(s);

}

تحدث initialization أولًا مرة واحدة. تختبر condition في كل دورة: إذا كانت صحيحة تنفذ الكتلة ثم increment ويعاد الاختبار؛ وإذا صارت خطأ تنتهي الحلقة. ينفذ increment بعد كل دورة يكون شرطها صحيحًا.

الإسناد =

علامة = المفردة معامل إسناد في C++؛ تقيم التعبير يمينها وتحفظ نتيجته في المتغير يسارها. ليست معادلة أو اختبار مساواة كما في الجبر.

+= و -=

صيغة مختصرة لجمع قيمة مع متغير أو طرحها منه. يمكن أن تكون x متغيرًا، و y متغيرًا أو ثابتًا، ومن الأنواع int أو float أو double أو byte أو short أو long.

مقتطف من الشرح
x += y; // equivalent to x = x + y

x -= y; // equivalent to x = x - y

الكود

RGB_LED/RGB_LED.ino

//www.elegoo.com
//2016.12.8

// define pins
#define BLUE 3
#define GREEN 5
#define RED 6

void setup()
{
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);
  digitalWrite(RED, HIGH);
  digitalWrite(GREEN, LOW);
  digitalWrite(BLUE, LOW);
}

// define variables
int redValue;
int greenValue;
int blueValue;

// main loop
void loop()
{
#define delayTime 10 // fading time between colors

  redValue = 255; // choose a value between 1 and 255 to change the color.
  greenValue = 0;
  blueValue = 0;

  // this is unnecessary as we've either turned on RED in SETUP
  // or in the previous loop ... regardless, this turns RED off
  // analogWrite(RED, 0);
  // delay(1000);

  for (int i = 0; i < 255; i += 1) // fades out red bring green full when i=255
  {
    redValue -= 1;
    greenValue += 1;
    // The following was reversed, counting in the wrong directions
    // analogWrite(RED, 255 - redValue);
    // analogWrite(GREEN, 255 - greenValue);
    analogWrite(RED, redValue);
    analogWrite(GREEN, greenValue);
    delay(delayTime);
  }

  redValue = 0;
  greenValue = 255;
  blueValue = 0;

  for (int i = 0; i < 255; i += 1) // fades out green bring blue full when i=255
  {
    greenValue -= 1;
    blueValue += 1;
    // The following was reversed, counting in the wrong directions
    // analogWrite(GREEN, 255 - greenValue);
    // analogWrite(BLUE, 255 - blueValue);
    analogWrite(GREEN, greenValue);
    analogWrite(BLUE, blueValue);
    delay(delayTime);
  }

  redValue = 0;
  greenValue = 0;
  blueValue = 255;

  for (int i = 0; i < 255; i += 1) // fades out blue bring red full when i=255
  {
    // The following code has been rearranged to match the other two similar sections
    blueValue -= 1;
    redValue += 1;
    // The following was reversed, counting in the wrong directions
    // analogWrite(BLUE, 255 - blueValue);
    // analogWrite(RED, 255 - redValue);
    analogWrite(BLUE, blueValue);
    analogWrite(RED, redValue);
    delay(delayTime);
  }
}

ملفات الدرس والمكتبات

ملفات الدرس

100%

عرض الصورة

استخدم + و− للتكبير والتصغير، أو اضغط Esc للإغلاق.