这是产品。我理解这个想法:这 16 个按钮使用 4x4 矩阵。行 4 行,列 4 行,我们有 8 根电缆。
但:
没有任何多路复用器如何工作?
这可以准确检测多个按钮的按下吗?即使按钮使用同一行或同一列?示例:同时按下位置 (2,2) (2,3)、(3,2) 和 (3,3) 处的按钮。
它是如何工作的?
这是产品。我理解这个想法:这 16 个按钮使用 4x4 矩阵。行 4 行,列 4 行,我们有 8 根电缆。
但:
没有任何多路复用器如何工作?
这可以准确检测多个按钮的按下吗?即使按钮使用同一行或同一列?示例:同时按下位置 (2,2) (2,3)、(3,2) 和 (3,3) 处的按钮。
它是如何工作的?
如果没有任何多路复用器,这如何工作?
它没有。键盘板似乎只有开关,可能还有一些我们看不到的二极管。但是,左侧板上看起来像是有一个处理器。几乎可以肯定,多路复用是在固件中完成的。
多路复用算法的工作原理如下:
上述过程重复得足够快,以便在人类观察者仍然感觉瞬间的时间内检查所有按钮。在这种情况下,“瞬时”的人为限制约为 50 毫秒。即使是低端微控制器也可以在比这更短的时间内扫描 4x4 键盘。
这可以准确检测多个按钮的按下吗?
可能是。一种方法是在每个按钮上串联一个二极管。那些可能在你展示的白板的底部。使用二极管,上述算法就可以正常工作。
另一种方法是将电阻器与线路串联并测量其模拟电压。即使有多个按钮将多行/列线短接在一起,您最终也可以确定按下了哪些按钮。这需要微型 A/D 输入,而不仅仅是使用二极管时的数字输入。
没有二极管......你会得到幻影矩形。
例如在您的示例中 (2,2) (2,3)、(3,2) 和 (3,3); 你通过选择一个矩形选择了一个具有讽刺意味的例子。如果你真的按下所有四个,它会起作用。但是如果你按下矩形的任意三个角,第四个角也会被按下,即使它不是。
该键盘显然是用于键盘数据输入的,其中用户约定是一次按一个键。例如,您注意到加油站信用卡输入键盘上没有“shift”键。
但是,如果您将 S1 设置为 shift 键,将 S3 设置为 alt-shift 键,这样用户可以合理地按住这两个键同时按下 S13,那么 S15 似乎也被按下了。
以下是在不连续扫描的情况下如何做到这一点:
我已经在裸 Atmel AVR 微控制器上使用汇编语言完成了这项工作。
为简单起见: 键盘行:使用 Arduino 引脚 4、5、6 和 7(AVR 引脚 PD4、PD5、PD6 和 PD7) 键盘列:使用 Arduino 引脚 8、9、10 和 11(AVR 引脚 PB0、PB1、PB2 和 PB3 ) 使行引脚输入启用上拉电阻。使列引脚输出并向它们输出零。在所有行和列引脚上启用引脚更改中断。 http://playground.arduino.cc/Main/PinChangeInterrupt
按下键盘上的按钮会将 Row 引脚拉低。中断例程需要读取行引脚并找出哪个引脚为低电平。高 4 位应为 3 个 1 和 1 个 0。如果您使用 uint8_t 8 位变量,您可以将其除以 16 或 (var >> 4) 以将 4 位放在数字的低位中。您可以使用按位 OR | 使用 240 操作将高 4 位设置为 1,并进行按位 NOT ~ 操作以反转所有位,因此您只有一个位设置代表按钮按下所在的行。将此数字存储为 0、1、2 或 3。
切换引脚配置:
使能上拉的列引脚输入。使行引脚输出并向它们输出零。读取列引脚并找出哪个引脚为低电平。用这个值做一个类似的操作,除了你不必把数字向右移动。在 var ^ 240 和 ^var 之后,您有一个位来表示按键所在的列。请记住在重新配置端口之前禁用中断,因为它可能会触发不需要的中断。离开中断例程时,您可能必须清除中断标志,以防止重复的中断处理。