Arduino爱好者

 找回密码
 立即注册

QQ登录

只需一步,快速开始

楼主: eagler8

[经验] 【Arduino】108种传感器模块系列实验(26)---4X4矩阵键盘模块

[复制链接]
 楼主| 发表于 2020-2-28 18:09 | 显示全部楼层
程序之四:测试按键'*'和 '#'控制LED灯(板载13脚)
  运行:'#'键控制LED灯自锁开关,'*'键按下时LED闪烁,松开熄灭

[mw_shl_code=arduino,true]/*
  【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)
  实验二十六:4X4矩阵键盘模块
  下载库:(需要下载库文件 https://github.com/Chris--A/Keypad),
  然后手动添加到IDE中
  程序之四:测试按键'*'和 '#'控制LED灯(板载13脚)
  运行:'#'键控制LED灯自锁开关,'*'键按下时LED闪烁,松开熄灭
*/

#include <Keypad.h>

const byte ROWS = 4; //四行
const byte COLS = 3; //三列
//定义键盘按钮上的符号
char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {2, 3, 4, 5}; //连接到键盘的行插脚
byte colPins[COLS] = {6, 7, 8};  //连接到键盘的列插脚

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
byte ledPin = 13;

boolean blink = false;
boolean ledPin_state;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);              // 将数字管脚设置为输出
  digitalWrite(ledPin, HIGH);           // 打开LED
  ledPin_state = digitalRead(ledPin);   // 存储初始LED状态。当LED亮起时为高
  keypad.addEventListener(keypadEvent); // 为此键盘添加事件侦听器
}

void loop() {
  char key = keypad.getKey();

  if (key) {
    Serial.println(key);
  }
  if (blink) {
    digitalWrite(ledPin, !digitalRead(ledPin));   // 将LED引脚从Hi2Lo或Lo2Hi更改
    delay(100);
  }
}

// 处理一些特殊事件
void keypadEvent(KeypadEvent key) {
  switch (keypad.getState()) {
    case PRESSED:
      if (key == '#') {
        digitalWrite(ledPin, !digitalRead(ledPin));
        ledPin_state = digitalRead(ledPin);        // 记住LED状态,亮或不亮
      }
      break;

    case RELEASED:
      if (key == '*') {
        digitalWrite(ledPin, ledPin_state);   // 从开始闪烁前恢复LED状态
        blink = false;
      }
      break;

    case HOLD:
      if (key == '*') {
        blink = true;    // 按住*键时,LED闪烁
      }
      break;
  }
}[/mw_shl_code]

 楼主| 发表于 2020-2-28 19:34 | 显示全部楼层
程序之五:测试按键的循环计数器

[mw_shl_code=arduino,true]/*
  【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)
  实验二十六:4X4矩阵键盘模块
  下载库:(需要下载库文件 https://github.com/Chris--A/Keypad),
  然后手动添加到IDE中
  程序之五:测试按键的循环计数器
*/

#include <Keypad.h>

const byte ROWS = 4; //四行
const byte COLS = 3; //三列
//定义键盘按钮上的符号
char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {2, 3, 4, 5}; //连接到键盘的行插脚
byte colPins[COLS] = {6, 7, 8};  //连接到键盘的列插脚

Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
unsigned long loopCount = 0;
unsigned long timer_t = 0;

void setup(){
  Serial.begin(9600);
  
  // 尝试使用不同的去噪时间设置来查看其影响
  // 每秒循环运行的次数
  // 设定在1毫秒以下
  kpd.setDebounceTime(10);  // 设置时间(mS)
}

void loop(){
  char key = kpd.getKey();
  
  // 报告1秒内通过循环的次数
  // 你比较清楚的知道时间改变了多少
  // 代码的速度。如果你设置了一个很高的清除时间,你的循环计数将
  // 看起来不错,但你的按键会开始感觉迟钝
  if ((millis() - timer_t) > 1000) {
    Serial.print("Your loop code ran ");
    Serial.print(loopCount);
    Serial.println(" times over the last second");
    loopCount = 0;
    timer_t = millis();
  }
  loopCount++;
  if(key)
    Serial.println(key);
}[/mw_shl_code]
 楼主| 发表于 2020-2-28 19:35 | 显示全部楼层
16.jpg
 楼主| 发表于 2020-2-28 19:49 | 显示全部楼层

程序之五:测试按键,报告活动键状态:空闲、按下、保持或释放
Program 5: test key, report active key status: idle, press, hold or release


[mw_shl_code=arduino,true]/*
  【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)
  实验二十六:4X4矩阵键盘模块
  下载库:(需要下载库文件 https://github.com/Chris--A/Keypad),
  然后手动添加到IDE中
  程序之六:测试按键,报告活动键状态:空闲、按下、保持或释放
*/

#include <Keypad.h>

const byte ROWS = 4; //四行
const byte COLS = 3; //三列
//定义键盘按钮上的符号
char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {2, 3, 4, 5}; //连接到键盘的行插脚
byte colPins[COLS] = {6, 7, 8};  //连接到键盘的列插脚

Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

unsigned long loopCount;
unsigned long startTime;
String msg;


void setup() {
  Serial.begin(9600);
  loopCount = 0;
  startTime = millis();
  msg = "";
}


void loop() {
  loopCount++;
  if ( (millis() - startTime) > 5000 ) {
    Serial.print("Average loops per second = ");
    Serial.println(loopCount / 5);
    startTime = millis();
    loopCount = 0;
  }

  // 使用最多10个活动键填充kpd.key[]数组
  // 如果有任何活动键,则返回true
  if (kpd.getKeys())
  {
    for (int i = 0; i < LIST_MAX; i++) // 扫描整个密钥列表
    {
      if ( kpd.key.stateChanged )   // 只查找已更改状态的密钥
      {
        switch (kpd.key.kstate) {  // 报告活动键状态:空闲、按下、保持或释放
          case PRESSED:
            msg = " PRESSED.";
            break;
          case HOLD:
            msg = " HOLD.";
            break;
          case RELEASED:
            msg = " RELEASED.";
            break;
          case IDLE:
            msg = " IDLE.";
        }
        Serial.print("Key ");
        Serial.print(kpd.key.kchar);
        Serial.println(msg);
      }
    }
  }
}  // 结束循环[/mw_shl_code]
 楼主| 发表于 2020-2-28 19:50 | 显示全部楼层
17.jpg
 楼主| 发表于 2020-2-29 08:52 | 显示全部楼层
[mw_shl_code=arduino,true]/*
  【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)
  实验二十六:4X4矩阵键盘模块
  下载库:(需要下载库文件 https://github.com/Chris--A/Keypad),
  然后手动添加到IDE中
  程序之七:按键转换
*/

#include <Keypad.h>

const byte ROWS = 2; // 两种情况下都使用4X4键盘
const byte COLS = 2;
char keys[ROWS][COLS] = {
  {'1','2'},
  {'3','4'}
};
byte rowPins[ROWS] = {5, 4}; //连接到键盘的行插脚
byte colPins[COLS] = {7, 6}; //连接到键盘的列插脚
Keypad kpd( makeKeymap(keys), rowPins, colPins, ROWS, COLS );


const byte ROWSR = 2;
const byte COLSR = 2;
char keysR[ROWSR][COLSR] = {
  {'a','b'},
  {'c','d'}
};
byte rowPinsR[ROWSR] = {3, 2}; //连接到键盘的行插脚
byte colPinsR[COLSR] = {7, 6}; //连接到键盘的列插脚
Keypad kpdR( makeKeymap(keysR), rowPinsR, colPinsR, ROWSR, COLSR );


const byte ROWSUR = 4;
const byte COLSUR = 1;
char keysUR[ROWSUR][COLSUR] = {
  {'M'},
  {'A'},
  {'R'},
  {'K'}
};
// 数字键盘,PCF8574 i/o端口位号
byte rowPinsUR[ROWSUR] = {5, 4, 3, 2}; //连接到键盘的行插脚
byte colPinsUR[COLSUR] = {8}; //连接到键盘的列插脚

Keypad kpdUR( makeKeymap(keysUR), rowPinsUR, colPinsUR, ROWSUR, COLSUR );


void setup(){
//  Wire.begin( );
  kpdUR.begin( makeKeymap(keysUR) );
  kpdR.begin( makeKeymap(keysR) );
  kpd.begin( makeKeymap(keys) );
  Serial.begin(9600);
  Serial.println( "start" );
}

//字节替换=假;
char key, keyR, keyUR;
void loop(){

//备用=!候补;
  key = kpd.getKey( );
  keyUR = kpdUR.getKey( );
  keyR = kpdR.getKey( );

  if (key){
    Serial.println(key);
  }
  if( keyR ) {
    Serial.println( keyR );
  }
  if( keyUR ) {
    Serial.println( keyUR );
  }
}[/mw_shl_code]
 楼主| 发表于 2020-2-29 08:54 | 显示全部楼层
18.jpg
 楼主| 发表于 2020-2-29 09:06 | 显示全部楼层
实验二十六:4X4矩阵键盘模块
  下载库:(需要下载库文件 https://github.com/Chris--A/Keypad),
  然后手动添加到IDE中
  程序之八:一键对应多键盘  方向键和数字键切换,或者数字键和字母键切换


[mw_shl_code=arduino,true]/*
  【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)
  实验二十六:4X4矩阵键盘模块
  下载库:(需要下载库文件 https://github.com/Chris--A/Keypad),
  然后手动添加到IDE中
  程序之八:一键对应多键盘  方向键和数字键切换,或者数字键和字母键切换
*/

#include <Keypad.h>
#include <ctype.h>

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns

char alphaKeys[4][4] = {
    { 'a','d','g','A' },
    { 'j','m','p','B' },
    { 's','v','y','C' },
    { ' ','.','#','D' }//最左侧为一个空格
};

char numberKeys[4][4] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[4] = {2, 3, 4, 5}; //行所使用的针脚
byte colPins[4] = {6, 7, 8, 9}; //列所使用的针脚
boolean alpha = false;   // 标记使用哪一个键盘,仅用于如果是字母键盘时,led闪烁
char* keypadMap = (alpha == true) ? makeKeymap(alphaKeys) : makeKeymap(numberKeys);

Keypad keypad = Keypad(keypadMap, rowPins, colPins, 4, 4);

unsigned long startTime;
const byte ledPin = 13;

void setup() {
    Serial.begin(9600);
    pinMode(ledPin, OUTPUT);
    digitalWrite(ledPin, LOW);
    keypad.addEventListener(keypadEvent);   //添加监听事件
    keypad.setHoldTime(500);                 //设置长按触发时间,默认为1000ms
}

void loop() {
    char key = keypad.getKey();

    if (alpha && millis()-startTime>100) {           // 切换键盘时闪烁led   仅在alpha为真时,才进行时间比较??这语句没理解,但猜测是这意思  相当于延时100ms
        digitalWrite(ledPin,!digitalRead(ledPin));
    startTime = millis();
    }
}

void keypadEvent(KeypadEvent key) {

    switch (keypad.getState())          //获取按键
    {
    case PRESSED:                       //有键按下
        if (isalpha(key)) {              // 如果这是一个字母键,  isalpha()  检查是否为字母
           Serial.print(key);       // 用于测试
            }
        
        if (isdigit(key) || key == ' ' || key == '.')  Serial.print(key);  //如果不是字母,直接打印
        if (key == '#')  Serial.println();//如果是#,换行
        break;

    case HOLD:                                 //长按
        if (key == '#')  {                   //#键长按   在键盘映射之间切换。
            if (alpha == true)  {            // 如果现在是字母键盘
                keypad.begin(*numberKeys);   // 设置为数字键盘映射
                alpha = false;               //标记字母键盘为false
                digitalWrite(ledPin, LOW);   
            }
            else  {                          // 否则   (即现在是数字键盘)
                keypad.begin(*alphaKeys);    // 设为字母键盘映射
                alpha = true;                // 标记为true
            }
        }
        break;
    }  
}[/mw_shl_code]
 楼主| 发表于 2020-2-29 09:09 | 显示全部楼层
19.jpg
 楼主| 发表于 2022-2-26 07:38 | 显示全部楼层
矩阵键盘工作原理,高低电平翻转法

https://www.bilibili.com/video/a ... id_from=333.337.0.0

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino爱好者

GMT+8, 2022-12-7 09:12 , Processed in 0.072914 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表