前言
作為一名程序員,鍵盤在手钉答,天下我有啊希痴,不整把高大上的鍵盤怎么提升B格砌创。之前一直想買個機(jī)械鍵盤嫩实,聽說機(jī)械鍵盤敲代碼和玩游戲都特別爽甲献,也是裝B神器慨灭。同時也覺得普通的鍵盤打字打久了手腕會有點酸酸的球及,因為敲鍵盤時都是要彎著手腕的吃引,一點也不符合人體工程學(xué)朦佩。于是乎就想買一個分體的機(jī)械鍵盤语稠,結(jié)果找了半天都沒有比較中意的颅筋,找到幾個人體工程學(xué)鍵盤,都是薄膜的桃熄,而且價格高得離譜,不就多個人體工程學(xué)光環(huán)嘛瞳收。碉京。。身為程序員中的屌絲螟深,豈能被金錢這種東西降低自身B格呢
普通機(jī)械鍵盤
帶 * “人體工程學(xué)光環(huán)” * 鍵盤
為了不要這么糾結(jié)谐宙,就自己diy一個咯,正好有臺3D打印機(jī)(又一個裝B神器界弧,你值得擁有,O(∩_∩)O哈哈~)垢箕,全部外殼自己打印划栓,控制板用Arduino Leonardo,原生支持鍵盤鼠標(biāo)驅(qū)動条获,軸體考慮到成本忠荞,先買了80顆國產(chǎn)黑軸做實驗,鍵帽也簡單打印一下帅掘,說干就干
3D打印的分體黑軸機(jī)械鍵盤
符合人體工程學(xué)的分體式設(shè)計委煤,全鍵無沖,可任意自定義快捷鍵修档,甚至可任性滴修改鍵位布局哦(重新設(shè)計外殼即可)
準(zhǔn)備
- 工具
- 3D打印機(jī) (打印外殼)
- 電烙鐵
- 熱熔膠 (固定按鍵用)
- 萬用表
- 硬件
- Arduino Leonardo板 (驅(qū)動板)
- 黑軸軸體
- 二極管+電阻+杜邦線+萬能板
- 小螺絲 (外殼裝配)
- 軟件
- SolidWorks (3D建模碧绞,設(shè)計外殼,可用任何3D建模軟件代替哦)
- Arduino IDE (寫鍵盤驅(qū)動程序)
是時候上點圖了萍悴。头遭。。
自己組裝的三角洲式3D打印機(jī)
淘寶買的工具
步驟
先設(shè)計鍵位排布癣诱,使用 ** SolidWorks ** (任何3D建模軟件都o(jì)k的计维,只是我比較熟系SolidWorks哦)畫出簡單的按鍵布局,先從左手開始撕予,先完整的搞定左手能使用了鲫惶,再做右手。設(shè)計好布局后制作支撐軸體的面板实抡,然后設(shè)計電路欠母,用飛線焊接,寫代碼測試按鍵是否都正常吆寨。電路正常后設(shè)計整個外殼赏淌,然后整體組裝。這就完工啦
- 鍵位設(shè)計
右手之所以外形扭曲啄清,是因為3D打印機(jī)打印面積有限
- 電路設(shè)計
由于Arduino板io口有限六水,必須使用矩陣掃描來實現(xiàn)按鍵。掃描方式就是:定義n個io口為掃描口,m個接收口掷贾,組成一個n*m的矩陣睛榄。掃描口默認(rèn)全部都是低電壓,然后依次將每個掃描口單獨置為高電壓(即掃描動作)想帅,當(dāng)這個高電壓的掃描口上連接的某個按鍵有按下時场靴,對應(yīng)的接收口電壓就也是高電壓,這時就可以定位到是哪個按鈕按下了港准,矩陣如圖所示:
Arduino有6個模擬口旨剥,14個數(shù)字口。我要做的鍵盤不超過80個鍵叉趣,所以使用8個數(shù)字口進(jìn)行脈沖掃描泞边,6個模擬口加4個數(shù)字口用來接收脈沖來定位按鍵,這樣就實現(xiàn)了8*10的矩陣疗杉,支持80個鍵阵谚。還有2個數(shù)字鍵是空閑的,可以用于特殊按鍵定制烟具。
- 按鍵沖突處理
如果按上圖簡單實現(xiàn)會存在沖突問題梢什,當(dāng)接收口上有多個按鍵被按下時,會存在回路朝聋,高電壓的掃描口和低電壓的掃描口發(fā)生短路嗡午,就不知道是哪個按鍵被按下了。一般鍵盤都是5鍵左右不沖突冀痕,也就是這個鍵盤有5個接收口荔睹,只要保證在同一個接收口上的按鍵不會同時按下就不會有沖突。
使用矩陣掃描方式就會有按鍵沖突問題言蛇,我使用二極管來處理沖突僻他,保證不會出現(xiàn)回路問題,如圖(R是掃描口腊尚,C是接收口):
電壓動蕩處理
二極管解決了沖突問題吨拗,但是不能解決電壓動蕩,電壓不穩(wěn)定有兩方面婿斥,第一就是當(dāng)掃描口高電壓變?yōu)榈碗妷簳r劝篷,接收口電壓不會立即變成低電壓,所以在接收口都需要加一個下拉電阻民宿,讓電壓立馬降下來娇妓。第二就是按鍵按下時接觸片碰撞時導(dǎo)致的電壓不穩(wěn),這個最好是通過加電容(和按鍵并聯(lián))去過濾波動電壓活鹰,買元件時忘了買電容了哈恰,這里就簡單粗暴了-
最終電路設(shè)計
-
外殼設(shè)計(第一期簡單點坟桅,不把電路板放到外殼內(nèi))
-
左手
-
右手
-
側(cè)面
-
-
鍵帽設(shè)計
程序設(shè)計
#include "Keyboard.h"
#include "HID.h"
#define scanPin_len 8
int scanPin[] = {4,5,6,7,0,1,2,3}; // 掃描pin,(默認(rèn)低電平蕊蝗,逐個輸出高電平)
int scanPos = 0; // 當(dāng)前掃描位
#define btnPinA_len 6
#define btnPinD_len 4
int btnPinA[] = {5,4,3,2,1,0}; // 按鈕pin,模擬端口
int btnPinD[] = {8,9,10,11}; // 按鈕pin赖舟,數(shù)字端口
#define btn_len 10
byte btn[scanPin_len][btn_len]; // 按鈕狀態(tài)
byte btnTmp[btn_len]; // 臨時按鈕狀態(tài)
#define KEY_FN KEY_RIGHT_SHIFT // FN鍵
// 8*10的按鍵映射矩陣
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();
// 初始化掃描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);
}
// 初始化按鈕狀態(tài)
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() {
// 輪詢設(shè)置scanPin
for(int i=0; i<scanPin_len; i++) {
if(i == scanPos) {
digitalWrite(scanPin[i], HIGH);
} else {
digitalWrite(scanPin[i], LOW);
}
}
delay(5);
// 讀取按鍵信息
readBtn();
// 處理狀態(tài)有改變的btn
for(int i=0; i<btn_len; i++) {
if(btn[scanPos][i] != btnTmp[i]) {
btn[scanPos][i] = btnTmp[i];
if(btnTmp[i] == 1) {
Keyboard.press(keyMap[scanPos][i]);
} else {
Keyboard.release(keyMap[scanPos][i]);
}
}
}
scanPos = (scanPos + 1) % scanPin_len; // 下一個
}
void readBtn() {
// 先讀模擬口蓬戚,再讀數(shù)字口
// 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;
}
index ++;
}
for(int i = 0; i < btnPinD_len; i ++) {
btnTmp[index] = digitalRead(btnPinD[i]);
index ++;
}
}
制作圖集
-
第一版鍵帽(3D打印機(jī)精度還是有點欠缺,特別是處理弧線):
-
打印機(jī)底板想換成玻璃的宾抓,結(jié)果新買的毛玻璃打印時受熱不均子漩,碎了。石洗。幢泼。還是乖乖用回美紋紙吧
-
在打印中,加熱頭松動掉落讲衫,還好機(jī)器有自動保護(hù)缕棵,沒有造成火災(zāi)。幸虧代碼不是我寫的涉兽,要不然肯定會火災(zāi)的招驴,_
-
打印過程中底座脫落,都打成鳥窩了枷畏。别厘。。一路坎坷啊
-
軸體安裝拥诡,再次簡單粗暴的沒有使用衛(wèi)星軸
-
飛線触趴,這是第一版沒加二極管的連線,沒有做pcb渴肉,直接飛線連,簡單高效宾娜,適合屌絲程序員批狐,O(∩_∩)O哈哈~
-
ArduinoLeonardo還沒到貨前塔,拿uno測試按鍵
-
外殼組裝效果
-
第一版鍵帽(字母是用美紋紙貼上去的贰谣,就是這么簡單粗暴)
-
Leonardo到貨吱抚,測試驅(qū)動
-
右手組裝成功(黑色更有感覺鞍儆睢)
-
新版鍵帽(白色),美紋紙弱爆了秘豹,必須整高端點携御,然后發(fā)現(xiàn)白色材料打印效果很贊,光滑度也高了不少既绕,打印材料還是相當(dāng)重要的
-
電路板啄刹,裸露在鍵盤外還是挺有極客范的哦
-
最后效果,鍵盤在手凄贩,天下我有
總結(jié)
做完整個鍵盤感覺非常有成就感誓军,也非常實用,截止目前已經(jīng)用了快半年時間了疲扎,已經(jīng)非常喜歡機(jī)械鍵盤的按鍵反饋昵时,也非常習(xí)慣分體鍵盤的布局,手腕也不再彎著评肆,沒有酸過了债查。最后來大致匯總下花費吧(屌絲程序員裝B有望啦。瓜挽。盹廷。)
- 80顆國產(chǎn)黑軸 104元
- 元器件 24元(郵費貴,還有很多二極管和萬能板沒用到)
- Leonardo 30元
大概材料花費在160元左右久橙,比普通的機(jī)械鍵盤便宜多了俄占,而且還是分體的,所有按鍵可隨意自定義(驅(qū)動程序都自己寫的,還有啥不能改的,O(∩_∩)O哈哈~)
最后曬一下我在小黑屋的辦公桌(這鍵盤是不是B格最高的钠乏? O(∩_∩)O~~)