友情提示点击顶部放大镜 可以使用站内搜索 记住我们的地址 www.hainabaike.com
下图左是一款常见的薄膜按键模块(hex keypad),有4×4或3×4(少了最右边一行的A,B,C,D键),它的内部如同下图右边的电路所示,是由16个按键(开关)交织而成。有些按键模块直接使用按键(微触)开关组装,连接电路与程序都和本文相同。
4×4按键模块有8个接脚,分成列、行两组,可以接在Arduino的任意8个接脚,笔者将它接在数位6~13脚:
为了简化接线,可以使用「长脚型」排针,将其中两个脚用尖嘴钳稍微折弯,即可插入Arduino的排母:
排针上头的黑色塑料,可以用蛮力让它移到中间的位置,以便衔接两边的排母:
4×4薄膜键盘的Arduino按键侦测程序
撰写Arduino按键侦测程序,最简单也是最好的方式,就是采用既有的程序库。本单元将示范使用Keypad程序库,把侦测到的按键字元显示在序列端口监控视窗。请按此下载Keypad程序库(原始出处在这篇keypad介绍文),解压缩之后,置入Arduino的libraries路径:
底下的程序,修改自Keypad程序库的“HelloKeypad”示例,使用此程序库,我们的代码需要定义按键模块的行(col)、列(row)数、连接Arduino的脚位以及按键所代表的字元
#include <Keypad.h> // 引用Keypad程式庫 #define KEY_ROWS 4 // 按鍵模組的列數 #define KEY_COLS 4 // 按鍵模組的行數 // 依照行、列排列的按鍵字元(二維陣列) char keymap[KEY_ROWS][KEY_COLS] = { {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'} }; byte colPins[KEY_COLS] = {9, 8, 7, 6}; // 按鍵模組,行1~4接腳。 byte rowPins[KEY_ROWS] = {13, 12, 11, 10}; // 按鍵模組,列1~4接腳。 // 初始化Keypad物件 // 語法:Keypad(makeKeymap(按鍵字元的二維陣列), 模組列接腳, 模組行接腳, 模組列數, 模組行數) Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, KEY_ROWS, KEY_COLS); void setup(){ Serial.begin(9600); } void loop(){ // 透過Keypad物件的getKey()方法讀取按鍵的字元 char key = myKeypad.getKey(); if (key){ // 若有按鍵被按下… Serial.println(key); // 顯示按鍵的字元 } }
编译并上传代码,再开启「序列监控视窗」,按下薄膜键盘的任何按键,该字元将显示在序列端口监控视窗。
按键侦测与扫描原理
为了方便解说,笔者把4×4按键简化成3×1,像下图这样串连三个开关,连接到同一个微控制器的输入脚。此外,因为要简化开关电路,所以要启用微控器内部的上拉电阻:
假设开关的「行1」~「行3」输入端全都输入高电位,无论开关是否被按下,Arduino将接收到高电位(1)。为了检测到其中按键被按下,程序必须依序将「行1」~「行3」脚位设定成低电位。
轮到「行2」脚输入低电位,此时,微控器的输入脚也将接收到低电位(0),由此可知连接「行2」的「开关B」被按下了
轮到「行3」脚输入低电位,由于「开关C」未被按下,因此微控器的输入脚接收到高电位(1)。
到此,侦测按键的程序必须再次回到「行1」,输入低电位…如此反复循环扫描,才能持续侦测到某个按键是否被按下。实际的程序需要运用双重循环,才能分批扫描每一列:
双重循环的练习,请参阅《超图解Arduino互动设计入门》第8章「LED矩阵动画与多维数组程序设计」一节,8-28页
自行撰写扫描按键的程序
根据以上说明,自行撰写扫描按键的代码:
const byte colPins[4] = {9, 8, 7, 6}; // 設定「行」腳位 const byte rowPins[4] = {13, 12, 11, 10}; // 設定「列」腳位 const char keymap[4][4] = { // 設定按鍵的「行、列」代表值 {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'} }; byte i, j; // 暫存迴圈的索引數字 byte scanVal; // 暫存掃描到的按鍵值 void setup(){ Serial.begin(9600); for (i = 0; i < = 3; i++) { pinMode(rowPins[i], INPUT); pinMode(colPins[i], OUTPUT); digitalWrite(colPins[i], HIGH); digitalWrite(rowPins[i], HIGH); } } void loop() { for (i = 0; i <= 3; i++) { for (j = 0; j <= 3; j++) { digitalWrite(colPins[j], LOW); scanVal = digitalRead(rowPins[i]); if (scanVal == LOW) { // 如果輸入值是「低電位」… Serial.println(keymap[i][j]); // 輸出按鍵代表的字元 delay(200); // 掃描按鍵的間隔時間 digitalWrite(colPins[j], HIGH); break; // 跳出迴圈 } digitalWrite(colPins[j], HIGH); } } }
Keypad程序库的运作方式大致上面的程序相同,主要是多了消除弹跳(debounce)的程序(相关说明请参阅第四章「解决开关信号的弹跳问题」一节,4-15页),而且按键扫描的间隔时间是透过比对时间差,而非使用delay。上面的程序用于帮助理解扫描按键的原理,在实际项目制作上,请使用Keypad程序库。
via
标签: 键盘arduino教程编程level3开关轻按键开关轻触开关
评论列表