用 micro:bit 读取 PS/2 键盘

micro:bit编程、教学、展示
STEM
回复
头像
shaoziyang
帖子: 1421
注册时间: 2019年 10月 21日 13:48

用 micro:bit 读取 PS/2 键盘

#1

帖子 shaoziyang » 2020年 8月 26日 11:21

翻译自: http://www.suppertime.co.uk/blogmywiki/ ... -microbit/

图片

多年来,我一直想将普通的计算机键盘连接到 BBC micro:bit,以使无线电消息传递和加密更易于使用。我在Arduino上看到并用过类似的东西,使用了令人恐惧的C ++复杂库读取PS / 2键盘的数据,解析每个数据位。但这不是我喜欢的方式。 

以前,我将热敏打印机直接连接到micro:bit并向其发送一些串行数据,它第一时间就打印出消息。我从来没有想到过自制矩阵键盘会在第一次就工作,但是它确实就运行起来了。 有时候,不受知识和传统的束缚是有帮助的,不过我得赶紧补充一句,如果你在驾驶飞机或做手术除外。 

因此,我决定采用这种方法来解决 micro:bit PS/2 键盘问题。 

到底什么是 PS/2 键盘?PS/2 键盘是USB之前的老式键盘-它们具有圆形插头,通常用紫色塑料包裹,PS/2 鼠标往往带有绿色插头。它们并不是特别容易购买,至少不是新的,但是人们经常将它们扔掉,正如我们将看到的… 

它们只是一个按钮的矩阵,该按钮连接到一个在5伏的小型单片机(当然,micro:bit是3伏),将按键转换为串行数据。该协议非常可怕……以10到16.7 kHz之间的频率发送一个11位数据,包括: 

1个起始位(始终为0)
8个数据位(最低有效位在前)
1个奇偶校验位(奇校验)
1个停止位(始终为1) 

所以我决定忽略所有这些。 

一天,我在遛狗时发现一个PS/2键盘丢在路边,插头已经被剪断。我把它带回家并拆开了,希望通过PCB了解每种彩色电缆的功能。(对于PS/2 电缆颜色没有标准) 

搜索互联网也没有结果。幸运的是,通过剪断的插头,能够弄清楚这种特殊的戴尔键盘: 

粉色= 5v
黑色= GND
白色=数据
棕色=时钟 

图片 

我将黑色导线连接到micro:bit GND引脚,将粉红色连接到micro:bit 3v引脚。LED亮起,表明它正在执行自检。NUM LOCK指示灯甚至亮起(但没有大写锁定,我发现这是由PC用软件完成的,它将信号发送回键盘!)。因此,可以通过micro:bit 的3v电源为PS/2键盘供电,无需外部电源。 

现在,如果我忽略时钟线,并假设 PS/2键盘只是在发送串行数据。我们可以在micro:bit上读取串行数据,只需要知道波特率即可。10到16.7 kHz的范围令人恐惧,我尝试了几次,将引脚1连接到白色数据电缆,发现使用10000波特,可以获得了一些有意义的数据。

代码: 全选

import micropython
# to enable disabling of accidental keyboard interrupt
from microbit import *
​
uart.init(baudrate=10000, bits=8, parity=None, stop=1, tx=None, rx=pin1)
micropython.kbd_intr(-1)
# disable accidental keyboard interrupt, no idea if this works or is needed
​
while True:
    if uart.any():
        data = bytearray(1)
        uart.readinto(data, 1)
        display.scroll(data[0])
 


例如按下字母Q,始终产生139、248、139,按A产生142、248、142。

从阅读中我知道(确实需要一点知识),PS/2键盘在您按下一个键时发送一个代码,然后在放开时发送一个释放代码。因此139、248、139确实意味着“按Q”,“释放Q”。

因此,我要做的就是嗅探我感兴趣的每个键的代码,并创建字典以查找并将其转换为字母。到目前为止,我只关心字母,数字和一些非常基本的标点符号,但是我实现了自己的大写锁定和退格键。(大写锁定灯不亮,但是有一天……)

其他键盘的键代码会有所不同,因此,如果需要,请使用嗅探器程序创建自己的列表。您可能还需要使用不同的波特率,但是这台Dell的工作速率为10,000。


加密无线电通信项目

让我们用这个新发现的东西来建造一个超级特工通讯器!没人会看到你躲在灌木丛里用 microbit 和从垃圾桶里捞出的戴尔PS/2键盘!

将下面程序放在接收的micro:bit中:

代码: 全选

from microbit import *
import radio
radio.config(group=23)
radio.on()
storedMessage = ''
​
while True:
    message = radio.receive()
    if message:
        display.scroll(message)
        storedMessage = message
    if button_a.was_pressed():
        display.scroll(storedMessage)

对于发射器,请使用下面另外一个程序。请记住,您需要将microbit的引脚1连接到键盘的数据线 – 我的是白色的,但其它键盘可能不是白色的。还要将microbit 3v引脚连接到键盘的电源线(我的是粉红色),并将microbit GND引脚连接到键盘地线(在此Dell上为黑色)。

代码: 全选

import micropython # to enable disabling of accidental keyboard interrupt
from microbit import *
import radio
radio.config(group=23)
​
uart.init(baudrate=10000, bits=8, parity=None, stop=1, tx=None, rx=pin1)
micropython.kbd_intr(-1) # disable accidental keyboard interrupt if ctrl-C character received on serial input
dataList = []
delay = 250
capsLock = True
message = ''
​
keyCodes = {
  139: 'Q', 207: 'W', 210: 'E', 215: 'R', 150: 'T', 219: 'Y', 222: 'U', 161: 'I', 226: 'O', 231: 'P',
  142: 'A', 205: 'S', 145: 'D', 213: 'F', 154: 'G', 217: 'H', 157: 'J', 224: 'K', 224: 'K', 229: 'L',
  140: 'Z', 208: 'X', 209: 'C', 148: 'V', 152: 'B', 153: 'N', 220: 'M', 225: ',', 165: '.', 149: '_', 164: '?',
  138: '1', 206: '2', 146: '3', 147: '4', 214: '5', 218: '6', 159: '7', 158: '8', 162: '9', 163: '0'
}
​
while True:
    if uart.any():
        data = bytearray(1)
        uart.readinto(data, 1)
        dataList.append(data[0])
        if len(dataList) == 3:
            if dataList[0] in keyCodes:
                if capsLock:
                    letter = keyCodes[dataList[0]]
                else:
                    letter = keyCodes[dataList[0]].lower()
                display.show(letter)
                message = message + letter
            elif dataList[0] == 172: # toggle caps lock
                capsLock = not capsLock
                if capsLock:
                    display.show(Image.ARROW_N)
                else:
                    display.show(Image.ARROW_S)
            elif dataList[0] == 242: # backspace
                display.show(Image.ARROW_W)
                message = message[:-1]
            dataList = []
            sleep(delay)
    if button_a.was_pressed():
        display.scroll(message)
    if button_b.was_pressed():
        radio.on() # I'm in love with Massachusetts
        radio.send(message)
        radio.off()
        display.scroll('TX')
        message = ''
    display.clear()

输入消息比较慢。字母将在microbit显示屏上闪烁。Caps Lock键可切换大小写,但Shift键不起作用。如果输入有误,请按Backspace键,它将删除最后一个字符。

按microbit上的按钮A查看消息,按钮B将通过无线发送消息。这也会删除该消息,因为好间谍会掩盖他们的痕迹,不是吗?

有时在开机时需要重置,因此,如果第一次无法使用,请按一下microbit背面的复位按钮,看看是否可以对它进行排序。

如果您对此有所改进,请告诉我。如果您能在博客或我的YouTube频道上点赞,我将非常高兴。

回复

  • 随机主题
    回复总数
    阅读次数
    最新文章