黑科技:程序員如何打造屬于自己的分體鍵盤

前言

作為一名程序員,鍵盤在手钉答,天下我有啊希痴,不整把高大上的鍵盤怎么提升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~~)


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末润绵,一起剝皮案震驚了整個濱河市邢笙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鹰贵,死亡現(xiàn)場離奇詭異,居然都是意外死亡康嘉,警方通過查閱死者的電腦和手機(jī)碉输,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來亭珍,“玉大人敷钾,你說我怎么就攤上這事枝哄。” “怎么了阻荒?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵挠锥,是天一觀的道長。 經(jīng)常有香客問我侨赡,道長瘪贱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任辆毡,我火速辦了婚禮,結(jié)果婚禮上甜害,老公的妹妹穿的比我還像新娘舶掖。我一直安慰自己,他們只是感情好尔店,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布眨攘。 她就那樣靜靜地躺著,像睡著了一般嚣州。 火紅的嫁衣襯著肌膚如雪鲫售。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天该肴,我揣著相機(jī)與錄音情竹,去河邊找鬼。 笑死匀哄,一個胖子當(dāng)著我的面吹牛秦效,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涎嚼,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼阱州,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了法梯?” 一聲冷哼從身側(cè)響起苔货,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎立哑,沒想到半個月后夜惭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡刁憋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年滥嘴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片至耻。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡若皱,死狀恐怖镊叁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情走触,我是刑警寧澤晦譬,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站互广,受9級特大地震影響敛腌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜惫皱,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一像樊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧旅敷,春花似錦生棍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至晴音,卻和暖如春柔纵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背锤躁。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工搁料, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人系羞。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓加缘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親觉啊。 傳聞我的和親對象是個殘疾皇子拣宏,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容