لوحة المفاتيح keypad 4x4
مقدمة
عندما نريد ربط زر واحد بلوحة الأردوينو أو أي وحكة تحكم دقيقة MCU، فإننا
نحتاج إلى قطب GPIO واحد، ولكن عندما نريد ربط العديد من الأزرار مثل 9 أو 12
أو 16 وما إلى ذلك، فيمكن أن نستهلك جميع الأقطاب الموجودة في المتحكم، ولحفظ
بعض أقطاب GPIO الخاصة بالمتحكم الدقيق، يمكننا استخدام مصفوفة لوحة مفاتيح
keypad، على سبيل المثال إذا أردنا ربط 16 زر بوحدة التحكم الدقيقة، فإننا
نحتاج إلى 16 قطب GPIO من أقطاب المتحكم، ولكن إذا استخدمنا مصفوفة لوحة مفاتيح
4x4، فإننا نحصل على 16 زر ونحتاج فقط إلى 8 أقطاب GPIO من وحدة التحكم
الدقيقة.
يتم ربط المفاتيح على شكل مصفوفة من الصفوف والأعمدة حيث أنه سوف نستخدم 4
أقطاب للصفوف و4 أقطاب للأعمدة فقط، وعند الضغط على أحد المفاتيح، يتم توصيل
الصف مع العمود وعدا ذلك لا يتم توصيل الصفوف مع الأعمدة.
آلية عمل لوحة المفاتيح Keypad
حتى يتم تحديد المفتاح الذي تم الضغط عليه نحن بحاجة لتحديد موقع المفتاح في المصفوفة وبالتالي نحتاج معرفة العامود والصف ويتم ذلك كما يلي:
تحديد العامود المضغوط
لمعرفة العامود الذي يحتوي على المفتاح الذي تم الضغط عليه يتم اتباع الطريقة
التالية، يقوم المتحكم بضبط جميع أقطاب الصفوف كأقطاب خرج وإعطاء إشارة LOW
عليها، وكأنه تم توصيلها مع الأرضي ومن ثم يضبط أقطاب العامود كأقطاب دخل مع
تفعيل مقاومة رفع ومن ثم يقوم بقراءة حالة هذه الأقطاب
- إذا كانت البيانات الموجودة على الأقطاب الخاصة بالأعمدة هي 1111 ففي هذه الحالة لم يتم الضغط على أي مفتاح أو زر وتستمر هذه القراءة حتى يتم الضغط على أحد الأزرار.
- في حال تم الضغط على الزر الموضح في الصورة (ضمن الدائرة) سوف يتم توصيل العامود الثاني مع الأرضي وسوف تتغير قراءة البيانات الموجودة على الأعمدة إلى 1011
تحديد الصف المضغوط
لمعرفة الصف الذي يحتوي على المفتاح الذي تم الضغط عليه يتم اتباع الطريقة
التالية، يقوم المتحكم بضبط كل صف بشكل منفصل على أنها أقطاب خرج وإعطاءها
إشارة LOW وكأنه تم توصيلها مع الأرضي ومن ثم يضبط أقطاب العامود كأقطاب دخل مع
تفعيل مقاومة رفع ومن ثم يقوم بقراءة حالة هذه الأقطاب
-
بدءًا من الصف الأول، سيقوم المتحكم الدقيق بتوصيله مع الأرضي من خلال إعطاءه إشارة LOW للصفR1 فقط.
-
بعدها يقوم بقراءة حالة الأعمدة، إذا كانت البيانات المقروءة كلها 1، فهذا معناه أنه لم يتم الضغط على أي مفتاح في هذا الصف وتستمر العملية للصف التالي.
-
ومن ثم إعطاء إشارة LOW للصف التالي R2، ومن ثم قراءة حالة الأعمدة، وتحقق من وجود أي صفر في البيانات، وتستمر هذه العملية على الصف R3 و R4 حتى يتم تحديد الصف.
-
على سبيل المثال في المثال السابق، سنحصل على الصف R2 الذي تكون فيه البيانات لا يساوي العمود فيه 1111.
وهكذا بعد تحديد الصف الذي تم الضغط فيه على المفتاح، يمكننا بسهولة معرفة المفتاح حسب قيمة الصف والعمود.
مواصفات لوحة المفاتيح Keypad 4×4
- شكل المصفوفة: 4 صفوف × 4 أعمدة (إجمالي 16 زر)
- جهد التشغيل: 3 فولت - 5 فولت تيار مستمر
- التوصيل: 8 أقطاب رقمية (4 للصفوف، 4 للأعمدة)
تطبيقات لوحة المفاتيح Keypad 4×4
تُستخدم لوحات المفاتيح Keypad 4×4 على نطاق واسع في العديد من التطبيقات والمشاريع، وفيما يلي بعض الأمثلة:
- أنظمة الحماية
- أنظمة إدخال البيانات
- أنظمة التحكم الصناعية
- الروبوتات
- المشاريع الإلكترونية
توصيل لوحة المفاتيح Keypad مع الاردوينو بدون إستخدام مكتبة
سوف نقوم بعمل تطبيق بسيط سوف نستخدم فيه لوحة المفاتيح لمعرفة المفتاح الذي تم الضغط عليه وعرض القيمة أو الرمز الخاص به على شاشة السيريال.
-
مخطط التوصيل
-
الكود البرمجي
سوف نقوم بالبداية بتعريف المتغيرات والثوابت التي سوف نستخدمها ضمن الكود بالشكل التالي:
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
متغيرين من نوع byte لتخزين عدد الاعمدة والصفوف الخاصة بلوحة المفاتيح Keypad الموجودة لدينا
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
مصفوفة ثنائية من نوع char لتخزين الرموز الخاصة بكل مفتاح من لوحة المفاتيح Keypad
byte rowPins[ROWS] = {13, 12, 11, 10}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {7, 6, 5, 4}; //connect to the column pinouts of the keypad
مصفوفتين أحاديات من نوع byte لتخزين أرقام الأقطاب التي سوف يتم توصيل الاردوينو مع صفوف وأعمدة لوحة المفاتيح Keypad
void setup() {
for (byte i = 0; i < ROWS; i++) {
pinMode(rowPins[i], INPUT_PULLUP);
}
for (byte i = 0; i < COLS; i++) {
pinMode(colPins[i], OUTPUT);
}
Serial.begin(9600); //initialize serial communication
}
في التابع الرئيسي سوف نقوم بضبط أقطاب الصفوف على أنها أقطاب خرج وأقطاب الأعمدة كأقطاب دخل مع تفعيل مقاومة الرفع وذلك من خلال عمل حلقة تكرارية للمرور على جميع العناصر الموجودة في كل مصفوفة، ومن ثم قمنا بتفعيل الاتصال التسلسلي بمعدل نقل 9600 لعرض البيانات على شاشة السيريال
char getKey() {
for (byte c = 0; c < COLS; c++) {
digitalWrite(colPins[c], LOW);
for (byte r = 0; r < ROWS; r++) {
if (digitalRead(rowPins[r]) == LOW) {
digitalWrite(colPins[c], HIGH);
delay(100);
return keys[r][c];
}
}
digitalWrite(colPins[c], HIGH);
}
return 0;
}
سوف نقوم بعمل تابع خاص لتحديد الصف والعمود الذي تم ضغط المفتاح فيهما وسوف يتم عمل حلقة تكرارية for بداخله بعدد الصفوف ليتم في كل صف إعطاءه إشارة LOW وبداخل هذه الحلقة يتم عمل حلقة تكرارية for بعدد الأعمدة للمرور على جميعها وقراءة حالتها وفحصها وفي حال كان احد هذه الاعمدة فيه إشارة LOW (تم توصيل العمود مع الصف وبالتالي تم الضغط على المفتاح في هذا الصف وهذا العمود) فسوف نقوم بإرجاع الرمز أو القيمة المكتفئة لهذا الصف وهذا العمود من المصفوفة keys، مع إعادة إعطاء إشارة HIGH على الصفوف وتأخير زمني قصير لتجنب حالة التشويش الميكانيكي للمفاتيح، وفي حال لم يتم الضغط على أي مفتاح سوف نقوم بإرجاع القيمة 0.
void loop() {
char key = getKey();
if (key) {
Serial.println(key);
}
}
في التابع التكراري سوف نقوم بتعريف متغير يقوم بتخزين القيمة التي سوف يتم إرجاعها من التابع getKey وسوف نقوم بفحصها في حال كانت لا تساوي الصفر (تم الضغط على أحد المفاتيح) سوف نقوم بطباعتها على شاشة السيريال.
الكود النهائي
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {13, 12, 11, 10}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {7, 6, 5, 4}; //connect to the column pinouts of the keypad
void setup() {
for (byte i = 0; i < ROWS; i++) {
pinMode(rowPins[i], INPUT_PULLUP);
}
for (byte i = 0; i < COLS; i++) {
pinMode(colPins[i], OUTPUT);
}
Serial.begin(9600); //initialize serial communication
}
void loop() {
char key = getKey();
if (key) {
Serial.println(key);
}
}
char getKey() {
for (byte c = 0; c < COLS; c++) {
digitalWrite(colPins[c], LOW);
for (byte r = 0; r < ROWS; r++) {
if (digitalRead(rowPins[r]) == LOW) {
digitalWrite(colPins[c], HIGH);
delay(100);
return keys[r][c];
}
}
digitalWrite(colPins[c], HIGH);
}
return 0;
}
رابط محاكاة المشروع اضغط هنا
توصيل لوحة المفاتيح Keypad مع الاردوينو مع إستخدام مكتبة
هنا، سوف نستخدم مكتبة لوحة المفاتيح Mark Stanley و Alexander Brevig.
قم بتحميل هذه المكتبة
من هنا وإضافتها إلى مجلد
المكتبات في Arduino IDE.
للحصول على معلومات حول كيفية إضافة مكتبة إلى Arduino IDE واستخدامها، راجع
إضافة مكتبة إلى Arduino IDE في قسم الأساسيات.
-
مخطط التوصيل
-
الكود البرمجي
#include <Keypad.h>
const byte ROWS = 4; /* four rows */
const byte COLS = 4; /* four columns */
/* define the symbols on the buttons of the keypads */
char hexaKeys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {13, 12, 11, 10}; /* connect to the row pinouts of the keypad */
byte colPins[COLS] = {7, 6, 5, 4}; /* connect to the column pinouts of the keypad */
/* initialize an instance of class NewKeypad */
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
void setup(){
Serial.begin(9600);
}
void loop(){
char customKey = customKeypad.getKey();
if (customKey){
Serial.println(customKey);
}
}
makeKeymap(keys)
يقوم ها التابع بتهيئة قيم المفاتيح الداخلية ضمن المكتبة لتكون مساوية لقيم المفاتيح المحددة من قبل المستخدم (المصفوفة التي تحتوي على الرمز الخاص بكل مفتاح).
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
-
يقوم هذا السطر بتعريف كائن customKeypad من نوع Keypad وتهيئته.
-
الأسماء RowPins و colPins هي الأقطاب الموجودة في Arduino والتي تتصل بها صفوف وأعمدة لوحة المفاتيح.
-
الأسماء rows و cols هي عدد الصفوف والأعمدة الموجودة في لوحة المفاتيح.
customKeypad.getKey()
يستخدم هذا التابع لمعرفة المفتاح الذي تم الضغط عليه وإرجاع القيمة أو الرمز
الخاص بهذا المفتاح.
رابط محاكاة المشروع
اضغط هنا