أزرار الضغط في الدارات الرقمية

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

ما هو زر الضغط؟
زر الضغط هو مفتاح ميكانيكي يقوم بإغلاق أو فتح الدارة مؤقتًا عند الضغط عليه. عادةً ما يكون من النوع "مفتوح في الوضع الطبيعي" (NO)، أي أن الدارة تكون مفتوحة ولا يُمرر التيار حتى يتم الضغط.
عند توصيله بميكروكنترولر مثل Arduino، يتم ربطه إلى أحد أطراف الإدخال الرقمية، حيث يتم قراءة حالته إما كـ HIGH (1) أو LOW (0)، بناءً على كيفية توصيله.


المقاومات المسحوبة لأعلى (Pull-Up) أو لأسفل (Pull-Down)
لا يمكن ترك طرف الإدخال الرقمي معلقًا بدون اتصال، لأن ذلك يؤدي إلى قراءات غير مستقرة أو عشوائية. يتم استخدام مقاومة تسحب الجهد نحو HIGH أو LOW لتثبيت الحالة في وضع الزر غير مضغوط.
التوصيل باستخدام مقاومة مسحوبة لأسفل
- التوصيل: أحد أطراف الزر إلى 5V، الطرف الآخر إلى دبوس الإدخال ومقاومة إلى GND.
- النتيجة:
- الزر غير مضغوط: القراءة LOW.
- الزر مضغوط: القراءة HIGH.

التوصيل باستخدام مقاومة مسحوبة لأعلى
- التوصيل: أحد أطراف الزر إلى GND، والطرف الآخر إلى دبوس الإدخال والمقاومة إلى 5V.
- النتيجة:
- الزر غير مضغوط: القراءة HIGH.
- الزر مضغوط: القراءة LOW.
هذا هو الأسلوب المُفضل عند استخدام Arduino لأنه يحتوي على مقاومات سحب داخلية يمكن تفعيلها برمجيًا.

استخدام المقاومة الداخلية المسحوبة لأعلى في Arduino
يمكن تفعيل المقاومة الداخلية بكل سهولة باستخدام السطر التالي:
1pinMode(buttonPin, INPUT_PULLUP);
عند استخدام هذا الخيار، يتم توصيل الزر بين الدبوس و GND فقط، دون الحاجة لمقاومة خارجية.
اختيار قيمة المقاومة المناسبة
إذا كنت تستخدم مقاومات خارجية:
- القيمة النموذجية: 10kΩ
- أقل من 4.7kΩ: استهلاك طاقة زائد.
- أكبر من 50kΩ: قد تؤدي إلى ضعف في ثبات الإشارة.
10kΩ هي الخيار الآمن والمناسب لمعظم التطبيقات.

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

كيفية التعامل مع الاهتزاز (Debounce)
لمنع القراءة الخاطئة أو التكرار غير المقصود، يمكن استخدام أحد الخيارين التاليين:
الخيار 1: إزالة الاهتزاز عبر قطع إضافية (Hardware Debouncing)
يمكن استخدام دارة بسيطة مكونة من مقاومة ومكثف لتصفية الاهتزاز.
الدارة:
- مقاومة 10kΩ توصل بين الزر ودبوس الإدخال.
- مكثف 100nF يوصل بين دبوس الإدخال و GND.
هذا يمنع تغير الجهد المفاجئ الناتج عن الاهتزاز ويُنعّم الإشارة المقروءة.
هذه الطريقة بسيطة وفعالة، وتُستخدم عندما تكون الموارد البرمجية محدودة.


الخيار 2: إزالة الاهتزاز عبر البرمجة (Software Debouncing)
يتم تأخير قراءة الزر لعدة ميلي ثانية بعد اكتشاف تغير في حالته للتأكد من ثباتها، قبل اعتبارها قراءة صحيحة.
مثال عملي: زر للعد وآخر لإعادة التعيين (لإعادة العداد إلى الصفر)
سنقوم باستخدام زرين مع الأردوينو:
- الزر A (الدبوس 2): لزيادة العداد.
- الزر B (الدبوس 3): لإعادة العداد إلى الصفر.
التوصيل
يتم توصيل كل زر على النحو التالي:
أحد أطراف الزر إلى GND.
الطرف الآخر إلى دبوس الإدخال في الأردوينو.
لا حاجة لمقاومات خارجية بفضل استخدام INPUT_PULLUP.
عند عدم الضغط، يقرأ الأردوينو HIGH، وعند الضغط يقرأ LOW.
الكود البرمجي (مع شرح)
1const int buttonA = 2;2const int buttonB = 3;34const unsigned long debounceDelay = 50;5int counter = 0;67// هيكل لتتبع حالة كل زر وزمن الاهتزاز8struct Button {9 int pin;10 int lastState;11 unsigned long lastDebounceTime;12};1314Button btnA = {buttonA, HIGH, 0};15Button btnB = {buttonB, HIGH, 0};1617void setup() {18 pinMode(btnA.pin, INPUT_PULLUP);19 pinMode(btnB.pin, INPUT_PULLUP);20 Serial.begin(9600);21}2223bool debounce(Button &btn) {24 int reading = digitalRead(btn.pin);25 bool pressed = false;2627 if (reading != btn.lastState) {28 btn.lastDebounceTime = millis();29 }3031 if ((millis() - btn.lastDebounceTime) > debounceDelay) {32 if (reading == LOW && btn.lastState == HIGH) {33 pressed = true;34 }35 }3637 btn.lastState = reading;38 return pressed;39}4041void loop() {42 if (debounce(btnA)) {43 counter++;44 Serial.print("Count: ");45 Serial.println(counter);46 }4748 if (debounce(btnB)) {49 counter = 0;50 Serial.println("Counter Reset");51 }52}53

شرح الكود
- يتم تعريف هيكل (struct) لتخزين معلومات كل زر.
- دالة debounce:
- تقرأ حالة الزر.
- تتحقق مما إذا تغيرت الحالة.
- تنتظر 50 ميلي ثانية ثم تتحقق من أن الضغط حقيقي (تحول من HIGH إلى LOW).
- في loop:
- إذا تم الضغط على الزر A، يزداد العداد ويتم طباعته.
- إذا تم الضغط على الزر B، يتم إعادة تعيين العداد.
ما تراه في الشاشة التسلسلية:
1Count: 12Count: 23Count: 34Counter Reset5Count: 16...7
يتم تسجيل كل ضغطة حقيقية مرة واحدة فقط بفضل نظام إزالة الاهتزاز.
الخلاصة
- أزرار الضغط بسيطة ولكنها ضرورية في الأنظمة الرقمية.
- لا تترك دبابيس الإدخال معلقة — استخدم مقاومات سحب لأعلى أو لأسفل.
- استخدم INPUT_PULLUP لتسهيل التوصيل في أردوينو.
- إزالة الاهتزاز ضرورية للحصول على قراءة دقيقة.
- يمكنك استخدام دارة RC لإزالة الاهتزاز عبر العتاد.
- أو استخدم التأخير الزمني عبر البرمجة لتحقيق نفس الهدف.
- تنظيم الكود يجعل من السهل إضافة المزيد من الأزرار أو الميزات لاحقًا.