您现在的位置是:首页 > 文章详情

键盘手焊还不够,里面跑Python更过瘾

日期:2020-07-01点击:577

谁要自己做个键盘呢?还是要手焊的键盘~

如果,你日常写的是软件,最接近硬件制板的一次是大学时焊接收音机,那你跟我一样,当然可以试试做个键盘;或者,你平时设计的是硬件,手焊个键盘当然不在话下,写个Python让键盘跑起来也许会让你兴奋;亦或,你刚学完朋友圈里Python课程,正准备大展身手,你的第一个Python项目,可以是个键盘,感受把Python握在手里的感觉……

焊接本文中的键盘,笔者从早到晚花了一整天,而第一版让键盘跑起来的Python程序仅用了2小时,于是就有一个支持USB和蓝牙的键盘,再给键盘装上斑斓的色彩!

如果你只关心跑在键盘里的Python长什么模样,可以直接跳到文章的倒数第100行,代码放了在最后~

涉及硬件,准备材料少不了。

准备材料

  1. 黄铜线5米+(直径0.8mm),也可以用普通导线,但黄铜更酷一些
  2. 定位板,选了60%的,因为选择多,键还少~ (比如睫毛外设的铝合金卫星轴定位板)
  3. 卫星轴,因为不用PCB,只能选定位板类型的
  4. 轴61个,为了办公室炫耀(挨打),当然选清脆(扰人)的青轴啦
  5. 二极管61个,这是防多按键冲突(Anti-ghost),如果很少用3及以上键同时按的组合键(比如 ctrl + shift + c),这个可以省掉(立创商城购买挺方便)
  6. 还需要个带蓝牙和USB的主控Pitaya Go,后面Python就跑在这个开发板里面

键盘材料

当然还需要一些工具:

  1. 烙铁、焊锡
  2. 钳子,用来剪黄铜线
  3. 镊子,万一没有,剪刀也可以
  4. 万用表,如果眼力足够好,这也可以省掉~

开始动手

  1. 安装卫星轴

把卫星轴安装在定位板上,可以用润滑脂把润滑一下,可以减少按键的噪声,润滑脂是半固体状的,不是润滑油哦

2. 安装机械键盘轴

3. 焊接矩阵键盘

矩阵键盘分行、列,先把用二极管把轴的一个脚跟行线连接,并焊接好,二极管的方向可以行到列,也可以是列到行,但整个矩阵要保持二极管的方向一致。

把焊好一条行线后,可以用万用表测一下二极管的方向是否都是一致的,或者是否有虚焊。这里用的是黑色贴片二极管,因为小,肉眼分辨方向相当考验眼力,特别是焊接之后还有焊迹。也可以选用插件的二极管,焊接更简单一些,也买回了,不过,贴片的看起来更整洁一些,为了颜值,还是挑战了难度系数更高的贴片的二极管。

然后再焊接列线,可以在行上面用额外的黄铜线垫一下,再焊接,让列线架空,避免行跟列短接了。

列队完毕,等待集结~

4. 将行、列线连接到主控Pitaya Go的IO口

这里矩阵键盘有5行、14列,Pitaya Go有20个可用的IO,剩下的1个IO还可以接个灯。矩阵键盘和主控焊接完成后,最好用万用表检测一下各行各列是否短接,至少目测一下。

以上硬件算搭好了,Python要登场了。

用键盘跑Python——实现USB+蓝牙键盘

电脑端Python通常是跑在CPython解释器里面,而嵌入式MCU中的Python起源7年前,Damien George开始写的轻量级Python解释器——MicroPython,我们今天要用到是基于MicroPython的CircuitPython。

Adafruit为CircuitPython开发了非常多硬件相关的库,基于这些库,我们可以快速实现一个键盘,这里用到adafruit_bleadafruit_hid这两个库。实现一个USB+蓝牙键盘100行就行,Talk is cheap,看代码:

 import time from board import * import digitalio import usb_hid import adafruit_ble from adafruit_ble.advertising import Advertisement from adafruit_ble.advertising.standard import ProvideServicesAdvertisement from adafruit_ble.services.standard.hid import HIDService from adafruit_hid.keyboard import Keyboard from adafruit_hid.keycode import Keycode as _ ROWS = (P27, P13, P30, P20, P3) COLS = (P26, P31, P29, P28, P5, P4, P24, P25, P23, P22, P14, P15, P16, P17) KEYMAP = ( _.ESCAPE, _.ONE, _.TWO, _.THREE, _.FOUR, _.FIVE, _.SIX, _.SEVEN, _.EIGHT, _.NINE, _.ZERO, _.MINUS, _.EQUALS, _.BACKSPACE, _.TAB, _.Q, _.W, _.E, _.R, _.T, _.Y, _.U, _.I, _.O, _.P, _.LEFT_BRACKET, _.RIGHT_BRACKET, _.BACKSLASH, _.CAPS_LOCK, _.A, _.S, _.D, _.F, _.G, _.H, _.J, _.K, _.L, _.SEMICOLON, _.QUOTE, None, _.ENTER, _.LEFT_SHIFT, _.Z, _.X, _.C, _.V, _.B, _.N, _.M, _.COMMA, _.PERIOD, _.FORWARD_SLASH, None, _.RIGHT_SHIFT, None, _.LEFT_CONTROL, _.LEFT_ALT, _.LEFT_GUI, None, None, _.SPACE, None, None, _.RIGHT_ALT, _.RIGHT_GUI, _.APPLICATION, _.RIGHT_CONTROL, None, None) class Matrix: def __init__(self, rows=ROWS, cols=COLS): self.rows = [] for pin in rows: io = digitalio.DigitalInOut(pin) io.direction = digitalio.Direction.OUTPUT io.drive_mode = digitalio.DriveMode.PUSH_PULL io.value = 0 self.rows.append(io) self.cols = [] for pin in cols: io = digitalio.DigitalInOut(pin) io.direction = digitalio.Direction.INPUT io.pull = digitalio.Pull.DOWN self.cols.append(io) self.pressed_keys = [] def scan(self): new_keys = [] pressed_keys = [] released_keys = self.pressed_keys for r in range(len(self.rows)): self.rows[r].value = 1 for c in range(len(self.cols)): if self.cols[c].value: key = r * len(self.cols) + c pressed_keys.append(key) if key in released_keys: released_keys.remove(key) else: new_keys.append(key) self.rows[r].value = 0 self.pressed_keys = pressed_keys return pressed_keys, released_keys, new_keys def main(): hid = HIDService() advertisement = ProvideServicesAdvertisement(hid) advertisement.appearance = 961 ble = adafruit_ble.BLERadio() if ble.connected: for c in ble.connections: c.disconnect() ble.start_advertising(advertisement) advertising = True ble_keyboard = Keyboard(hid.devices) matrix = Matrix() usb_keyboard = Keyboard(usb_hid.devices) while True: pressed_keys, released_keys, new_keys = matrix.scan() if released_keys: released_keycodes = list(map(lambda i: KEYMAP[i], released_keys)) print('released keys {}'.format(released_keycodes)) usb_keyboard.release(*released_keycodes) if ble.connected: advertising = False ble_keyboard.release(*released_keycodes) if new_keys: new_keycodes = list(map(lambda i: KEYMAP[i], new_keys)) print('new keys {}'.format(new_keycodes)) usb_keyboard.press(*new_keycodes) if ble.connected: advertising = False ble_keyboard.press(*new_keycodes) if not ble.connected and not advertising: ble.start_advertising(advertisement) advertising = True time.sleep(0.001) if __name__ == '__main__': main()

这个是一个最简单的Python版本键盘,我们还可以跟进一步

让键盘更具生产力

这是一个 60% 键盘,缺少了包括 F1~F12、 方向键、小键盘等键位。

但通过引入 TMK 中的层级切换和组合按键功能,并融入 Toward a more useful keyboard 中把手指尽量停留在 A、S、D、F  J、K、L、; 等起始键位的理念,我们可以让这个小键盘更具生产力。

这里引入 Tap-key 功能,即按某个按键不放激活另外的功能。

比如把 d 用作 Tap-key,即短按 d 输出 d, 按住 d 不放则激活移动光标功能,H、J、K、L被映射为方向键,而 U  N 则为 PgUp 和 PgDn。

以上功能的实现见: https://gitee.com/makerdiary/python-keyboard

原文链接:https://my.oschina.net/u/4557749/blog/4331607
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章