以前一直想买个机械键盘,据说机械键盘敲代码和玩游戏都特别爽,也是装B神器。同时也以为普通的键盘打字打久了手腕会有点酸酸的,由于敲键盘时都是要弯着手腕的,一点也不符合人体工程学。因而乎就想买一个分体的机械键盘,结果找了半天都没有比较中意的,找到几我的体工程学键盘,都是薄膜的,并且价格高得离谱,不就多我的体工程学光环嘛。。。git
为了避免要这么纠结,就本身diy一个咯,正好有台3D打印机,所有外壳本身打印,控制板用Arduino Leonardo,原生支持键盘鼠标驱动,轴体淘宝,考虑成本,先买了80颗国产黑轴作实验,键帽也简单打印一下,说干就干工具
工具oop
3D打印机布局
电烙铁测试
热熔胶ui
万用表spa
硬件操作系统
Arduino Leonardo板设计
黑轴轴体3d
二极管+电阻+杜邦线+万能板
小螺丝
软件
SolidWorks 3D建模
Arduino IDE 写Arduino键盘驱动
是时候上点图了。。。
先设计键位排布,使用SolidWorks画出简单的按键布局,先从左手开始,先完整的搞定左手能使用了,再作右手。设计好布局后制做支撑轴体的面板,而后设计电路,用飞线焊接,写代码测试按键是否都正常。电路正常后设计整个外壳,而后总体组装。这就完工啦
键位设计
左手
右手(之因此外形扭曲,是由于3D打印机打印面积有限)
电路设计
因为Arduino板io口有限,必须使用扫描来实现按键,Arduino有6个模拟口,14个数字口。我要作的键盘不超过80个键,因此使用8个数字口进行脉冲扫描,6个模拟口加4个数字口用来接收脉冲来定位按键,这样就实现了8*10的矩阵,支持80个键。还有2个数字键是空闲的,能够用于特殊按键定制。
冲突处理
使用脉冲扫描方式就会有按键冲突问题,我使用二极管来处理冲突,如图(R是扫描口,C是接收口):
电压动荡处理
二极管解决了冲突问题,可是不能解决电压动荡,电压不稳定有两方面,第一就是当扫描口高电压变为低电压时,接收口电压不会当即变成低电压,因此在接收口都须要加一个下拉电阻,让电压立马降下来。第二就是按键按下时接触片碰撞时致使的电压不稳,这个最好是经过加电容去过滤波动电压,买元件时忘了买电容了,这里就简单粗暴了
最终电路设计
外壳设计
左手
右手
侧面
键帽设计
程序设计
#include "Keyboard.h" #include "HID.h" #define scanPin_len 8 int scanPin[] = {4,5,6,7,0,1,2,3}; // 扫描pin,(默认高电平,逐个输出低电平) int scanPos = 0; // 当前扫描位 #define btnPinA_len 6 #define btnPinD_len 4 int btnPinA[] = {5,4,3,2,1,0}; // 按钮pin,模拟端口 int btnPinD[] = {8,9,10,11}; // 按钮pin,数字端口 #define btn_len 10 byte btn[scanPin_len][btn_len]; // 按钮状态 byte btnTmp[btn_len]; // 临时按钮状态 #define KEY_FN KEY_RIGHT_SHIFT // FN键 uint8_t keyMap[scanPin_len][btn_len] = { {'y','n','7','8',KEY_F6,'h','m','u','j',' '}, {'o','.','0','9',KEY_F7,'l',',','i','k',KEY_FN}, {'p','/','-',KEY_LEFT_ARROW,KEY_F8,';',KEY_UP_ARROW,'[','\'',KEY_DOWN_ARROW}, {KEY_F10,KEY_DELETE,'=',KEY_BACKSPACE,KEY_F9,KEY_F11,KEY_RETURN,']','\\',KEY_RIGHT_ARROW}, {KEY_ESC,KEY_LEFT_GUI,'`',KEY_LEFT_CTRL,KEY_TAB,'a','q','z',KEY_CAPS_LOCK,KEY_LEFT_SHIFT}, {KEY_F1,KEY_LEFT_ALT,'1',KEY_F2,'2','s','w','x','d','c'}, {KEY_F3,' ','4',KEY_F4,'3','e','r','b','f','v'}, {KEY_F5,'6','5',0,0,0,'t','g',0,0} }; void setup() { Keyboard.begin(); Keyboard.releaseAll(); Serial.begin(9600); // 初始化扫描pin for(int i=0; i<scanPin_len; i++) { pinMode(scanPin[i], OUTPUT); } // 初始化按钮pin for(int i=0; i<btnPinD_len; i++) { pinMode(btnPinD[i], INPUT); } // 初始化按钮状态 for(int i=0; i<scanPin_len; i++) { for(int j=0; j<btn_len; j++) { btn[i][j] = 0; } } for(int j=0; j<btn_len; j++) { btnTmp[j] = 0; } } void loop() { // 轮询设置scanPin for(int i=0; i<scanPin_len; i++) { if(i == scanPos) { digitalWrite(scanPin[i], HIGH); } else { digitalWrite(scanPin[i], LOW); } } delay(5); // 读取按键信息 readBtn(); // 处理状态有改变的btn for(int i=0; i<btn_len; i++) { if(btn[scanPos][i] != btnTmp[i]) { btn[scanPos][i] = btnTmp[i]; // Serial.print("["); // Serial.print(scanPos); // Serial.print(" : "); // Serial.print(i); if(btnTmp[i] == 1) { Keyboard.press(keyMap[scanPos][i]); // Serial.print("] pressed"); } else { Keyboard.release(keyMap[scanPos][i]); // Serial.print("] released"); } // Serial.println(""); } } scanPos = (scanPos + 1) % scanPin_len; // 下一个 } void readBtn() { // 先读模拟口,再读数字口 // 5 -> 0 int index = 0; for(int i = 0; i < btnPinA_len; i ++) { int val = analogRead(btnPinA[i]); if(val > 600) { btnTmp[index] = 1; } else { btnTmp[index] = 0; } // Serial.print(btnTmp[index]); index ++; } for(int i = 0; i < btnPinD_len; i ++) { btnTmp[index] = digitalRead(btnPinD[i]); // Serial.print(btnTmp[index]); index ++; } }
初版键帽:
新买的毛玻璃打印时受热不均,碎了。。。
在打印中,加热头松动掉落,还好机器有自动保护,没有形成火灾
打印过程当中底座脱落,一路坎坷啊
轴体安装
飞线
ArduinoLeonardo还没到货,拿uno测试按键
外壳组装效果
初版键帽(字母是用美纹纸贴上去的)
Leonardo到货,测试驱动
右手组装成功(黑色更有感受啊)
新版键帽(白色)
电路板
最后效果
作完整个键盘感受很是有成就感,也很是实用,截止目前已经用了快半年时间了,已经很是习惯机械键盘的按键反馈,手腕也再也不弯着,没有酸过了。最后来大体汇总下花费吧
80颗国产黑轴 104元
元器件 24元(邮费贵,还有不少二极管和万能板没用到)
Leonardo 30元
大概材料花费在160元左右,比普通的机械键盘便宜多了,并且仍是分体的,全部按键可随意自定义(驱动程序都本身写的,O(∩_∩)O哈哈~)
最后晒一下我在小黑屋的办公桌
若是你以为内容意犹未尽,若是你想了解更多相关信息,请扫描如下二维码,关注咱们的公众帐号,能够获取更多技术类干货,还有精彩活动与你分享~
腾讯 Bugly是一款专为移动开发者打造的质量监控工具,帮助开发者快速,便捷的定位线上应用崩溃的状况以及解决方案。智能合并功能帮助开发同窗把天天上报的数千条 Crash 根据根因合并分类,每日日报会列出影响用户数最多的崩溃,精准定位功能帮助开发同窗定位到出问题的代码行,实时上报能够在发布后快速的了解应用的质量状况,适配最新的 iOS, Android 官方操做系统,鹅厂的工程师都在使用,快来加入咱们吧!