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

前言

作為一名程序員,鍵盤在手,天下我有啊,不整把高大上的鍵盤怎么提升B格。之前一直想買個(gè)機(jī)械鍵盤,聽說(shuō)機(jī)械鍵盤敲代碼和玩游戲都特別爽,也是裝B神器。同時(shí)也覺得普通的鍵盤打字打久了手腕會(huì)有點(diǎn)酸酸的,因?yàn)榍面I盤時(shí)都是要彎著手腕的,一點(diǎn)也不符合人體工程學(xué)。于是乎就想買一個(gè)分體的機(jī)械鍵盤,結(jié)果找了半天都沒有比較中意的,找到幾個(gè)人體工程學(xué)鍵盤,都是薄膜的,而且價(jià)格高得離譜,不就多個(gè)人體工程學(xué)光環(huán)嘛。。。身為程序員中的屌絲,豈能被金錢這種東西降低自身B格呢

普通機(jī)械鍵盤



帶 * “人體工程學(xué)光環(huán)” * 鍵盤


為了不要這么糾結(jié),就自己diy一個(gè)咯,正好有臺(tái)3D打印機(jī)(又一個(gè)裝B神器,你值得擁有,O(∩_∩)O哈哈~),全部外殼自己打印,控制板用Arduino Leonardo,原生支持鍵盤鼠標(biāo)驅(qū)動(dòng),軸體考慮到成本,先買了80顆國(guó)產(chǎn)黑軸做實(shí)驗(yàn),鍵帽也簡(jiǎn)單打印一下,說(shuō)干就干

3D打印的分體黑軸機(jī)械鍵盤

符合人體工程學(xué)的分體式設(shè)計(jì),全鍵無(wú)沖,可任意自定義快捷鍵,甚至可任性滴修改鍵位布局哦(重新設(shè)計(jì)外殼即可)

準(zhǔn)備

  • 工具
    • 3D打印機(jī) (打印外殼)
    • 電烙鐵
    • 熱熔膠 (固定按鍵用)
    • 萬(wàn)用表
  • 硬件
    • Arduino Leonardo板 (驅(qū)動(dòng)板)
    • 黑軸軸體
    • 二極管+電阻+杜邦線+萬(wàn)能板
    • 小螺絲 (外殼裝配)
  • 軟件
    • SolidWorks (3D建模,設(shè)計(jì)外殼,可用任何3D建模軟件代替哦)
    • Arduino IDE (寫鍵盤驅(qū)動(dòng)程序)

是時(shí)候上點(diǎn)圖了。。。
自己組裝的三角洲式3D打印機(jī)



淘寶買的工具



步驟

先設(shè)計(jì)鍵位排布,使用 ** SolidWorks ** (任何3D建模軟件都o(jì)k的,只是我比較熟系SolidWorks哦)畫出簡(jiǎn)單的按鍵布局,先從左手開始,先完整的搞定左手能使用了,再做右手。設(shè)計(jì)好布局后制作支撐軸體的面板,然后設(shè)計(jì)電路,用飛線焊接,寫代碼測(cè)試按鍵是否都正常。電路正常后設(shè)計(jì)整個(gè)外殼,然后整體組裝。這就完工啦

  • 鍵位設(shè)計(jì)

右手之所以外形扭曲,是因?yàn)?D打印機(jī)打印面積有限

  • 電路設(shè)計(jì)

    由于Arduino板io口有限,必須使用矩陣掃描來(lái)實(shí)現(xiàn)按鍵。掃描方式就是:定義n個(gè)io口為掃描口,m個(gè)接收口,組成一個(gè)n*m的矩陣。掃描口默認(rèn)全部都是低電壓,然后依次將每個(gè)掃描口單獨(dú)置為高電壓(即掃描動(dòng)作),當(dāng)這個(gè)高電壓的掃描口上連接的某個(gè)按鍵有按下時(shí),對(duì)應(yīng)的接收口電壓就也是高電壓,這時(shí)就可以定位到是哪個(gè)按鈕按下了,矩陣如圖所示:


Arduino有6個(gè)模擬口,14個(gè)數(shù)字口。我要做的鍵盤不超過(guò)80個(gè)鍵,所以使用8個(gè)數(shù)字口進(jìn)行脈沖掃描,6個(gè)模擬口加4個(gè)數(shù)字口用來(lái)接收脈沖來(lái)定位按鍵,這樣就實(shí)現(xiàn)了8*10的矩陣,支持80個(gè)鍵。還有2個(gè)數(shù)字鍵是空閑的,可以用于特殊按鍵定制。

  • 按鍵沖突處理

如果按上圖簡(jiǎn)單實(shí)現(xiàn)會(huì)存在沖突問(wèn)題,當(dāng)接收口上有多個(gè)按鍵被按下時(shí),會(huì)存在回路,高電壓的掃描口和低電壓的掃描口發(fā)生短路,就不知道是哪個(gè)按鍵被按下了。一般鍵盤都是5鍵左右不沖突,也就是這個(gè)鍵盤有5個(gè)接收口,只要保證在同一個(gè)接收口上的按鍵不會(huì)同時(shí)按下就不會(huì)有沖突。

使用矩陣掃描方式就會(huì)有按鍵沖突問(wèn)題,我使用二極管來(lái)處理沖突,保證不會(huì)出現(xiàn)回路問(wèn)題,如圖(R是掃描口,C是接收口):


  • 電壓動(dòng)蕩處理
    二極管解決了沖突問(wèn)題,但是不能解決電壓動(dòng)蕩,電壓不穩(wěn)定有兩方面,第一就是當(dāng)掃描口高電壓變?yōu)榈碗妷簳r(shí),接收口電壓不會(huì)立即變成低電壓,所以在接收口都需要加一個(gè)下拉電阻,讓電壓立馬降下來(lái)。第二就是按鍵按下時(shí)接觸片碰撞時(shí)導(dǎo)致的電壓不穩(wěn),這個(gè)最好是通過(guò)加電容(和按鍵并聯(lián))去過(guò)濾波動(dòng)電壓,買元件時(shí)忘了買電容了,這里就簡(jiǎn)單粗暴了

  • 最終電路設(shè)計(jì)


  • 外殼設(shè)計(jì)(第一期簡(jiǎn)單點(diǎn),不把電路板放到外殼內(nèi))

    • 左手


    • 右手


    • 側(cè)面


  • 鍵帽設(shè)計(jì)


  • 程序設(shè)計(jì)

#include "Keyboard.h"
#include "HID.h"

#define scanPin_len 8
int scanPin[] = {4,5,6,7,0,1,2,3}; // 掃描pin,(默認(rèn)低電平,逐個(gè)輸出高電平)
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]; // 臨時(shí)按鈕狀態(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() {
  // 輪詢?cè)O(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; // 下一個(gè)
}

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ī)精度還是有點(diǎn)欠缺,特別是處理弧線):


  • 打印機(jī)底板想換成玻璃的,結(jié)果新買的毛玻璃打印時(shí)受熱不均,碎了。。。還是乖乖用回美紋紙吧


  • 在打印中,加熱頭松動(dòng)掉落,還好機(jī)器有自動(dòng)保護(hù),沒有造成火災(zāi)。幸虧代碼不是我寫的,要不然肯定會(huì)火災(zāi)的,_

  • 打印過(guò)程中底座脫落,都打成鳥窩了。。。一路坎坷啊


  • 軸體安裝,再次簡(jiǎn)單粗暴的沒有使用衛(wèi)星軸


  • 飛線,這是第一版沒加二極管的連線,沒有做pcb,直接飛線連,簡(jiǎn)單高效,適合屌絲程序員,O(∩_∩)O哈哈~


  • ArduinoLeonardo還沒到貨,拿uno測(cè)試按鍵


  • 外殼組裝效果


  • 第一版鍵帽(字母是用美紋紙貼上去的,就是這么簡(jiǎn)單粗暴)


  • Leonardo到貨,測(cè)試驅(qū)動(dòng)


  • 右手組裝成功(黑色更有感覺?。?/p>

  • 新版鍵帽(白色),美紋紙弱爆了,必須整高端點(diǎn),然后發(fā)現(xiàn)白色材料打印效果很贊,光滑度也高了不少,打印材料還是相當(dāng)重要的


  • 電路板,裸露在鍵盤外還是挺有極客范的哦


  • 最后效果,鍵盤在手,天下我有


總結(jié)

做完整個(gè)鍵盤感覺非常有成就感,也非常實(shí)用,截止目前已經(jīng)用了快半年時(shí)間了,已經(jīng)非常喜歡機(jī)械鍵盤的按鍵反饋,也非常習(xí)慣分體鍵盤的布局,手腕也不再?gòu)澲瑳]有酸過(guò)了。最后來(lái)大致匯總下花費(fèi)吧(屌絲程序員裝B有望啦。。。)

  • 80顆國(guó)產(chǎn)黑軸 104元
  • 元器件 24元(郵費(fèi)貴,還有很多二極管和萬(wàn)能板沒用到)
  • Leonardo 30元
    大概材料花費(fèi)在160元左右,比普通的機(jī)械鍵盤便宜多了,而且還是分體的,所有按鍵可隨意自定義(驅(qū)動(dòng)程序都自己寫的,還有啥不能改的,O(∩_∩)O哈哈~)

最后曬一下我在小黑屋的辦公桌(這鍵盤是不是B格最高的? O(∩_∩)O~~)


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容