【瀚文】HelloWord-Smart Keyboard
瀚文
智能鍵盤是一把我為自己使用需求設(shè)計(jì)的 多功能郁竟、模塊化 機(jī)械鍵盤。鍵盤使用模塊化設(shè)計(jì)由境,左側(cè)的多功能場景交互模塊可以替換成各種自定義組件棚亩,默認(rèn)使用的是一個(gè)帶電子墨水屏以及FOC力反饋旋鈕的
Dynamic組件
;鍵盤使用我自己開發(fā)的基于ARM Cortex-M芯片的鍵盤固件以及模塊固件虏杰;鍵盤本體使用移位寄存器方式實(shí)現(xiàn)優(yōu)化的按鍵掃描電路讥蟆;模塊以及鍵盤本體可以單獨(dú)使用,也可以通過串口協(xié)議進(jìn)行相互通信和調(diào)用纺阔。本倉庫開源的資料內(nèi)容包括:
- 瀚文本體硬件設(shè)計(jì)的10塊PCB設(shè)計(jì)源文件瘸彤,提供立創(chuàng)EDA專業(yè)版的文件格式
- 外殼設(shè)計(jì)結(jié)構(gòu)文件
- 鍵盤本體的固件源碼(已相對完善)
- Dynamic組件的固件源碼(已完成框架,更多APP擴(kuò)展WIP)
- 鍵盤二次開發(fā)SDK(開發(fā)中)
鍵盤功能演示可以參考:
注意:Issues里面是討論項(xiàng)目開發(fā)相關(guān)話題的笛钝,不要在里面發(fā)無意義的消息质况,不然watch了倉庫的人都會收到通知郵件會給別人造成困擾的!F畔琛拯杠!灌水可以在倉庫的Discuss里討論!
1. 項(xiàng)目說明
1.0 更新說明:
22.8.31更新:
-
添加
Test-Dynamic-fw.bin
測試固件啃奴,燒錄到模塊之后可以體驗(yàn)各種不同力反饋的滾輪效果。- 注意測試版固件會在每次上電之后校準(zhǔn)電機(jī)雄妥,如果校準(zhǔn)失敗需要重新上電(未來正式使用的時(shí)候校準(zhǔn)只需要一次就行了);
- 模塊上兩個(gè)按鈕可以切換不同模式;
- 硬件上有一個(gè)地方需要注意的地方是模塊的fpc線一定要選短一點(diǎn)的最蕾,不然電阻太大會影響壓降,同時(shí)需要先自己確認(rèn)一下編碼器是正常工作的(可以用Debug查看編碼器數(shù)據(jù))老厌。
22.8.22更新:
- 添加STEP格式的3D模型文件瘟则,全套包括定位板的模型都發(fā)出來了.
22.8.20更新:
- PCB工程更新,見倉庫的工程鏈接枝秤,所有元器件能在立創(chuàng)直接下單的都改成了對應(yīng)的封裝醋拧,方便大家配置BOM.
22.8.13更新:
- 新打樣的PCB已經(jīng)收到,但是由于何同學(xué)這周發(fā)視頻,為了避免帶來不必要的壓力丹壕,所以決定錯(cuò)峰下周六再把PCB工程更新(doge).
22.7.31更新:
- 添加鍵盤硬件所有設(shè)計(jì)原理圖文件(電路還有些bug沒修復(fù)庆械,如視頻里的飛線,會晚些等新版PCB打樣收到驗(yàn)證沒問題后更新)
- 添加鍵盤固件源代碼
- 添加Dynamic組件源代碼
1.1 項(xiàng)目文件說明:
1.1.1 Hardware
Hardware文件夾內(nèi)是瀚文鍵盤里面用到的所有電路的原理圖和PCB文件菌赖,目前提供的是立創(chuàng)EDA專業(yè)版格式的源文件以及Gerber格式的光繪文件用于提供給廠家進(jìn)行直接加工缭乘。
一共有如下幾塊板子:
- HelloWord-Keyboard:主鍵盤的PCB,控制器為STM32F103琉用,可以配合底座單獨(dú)使用堕绩,提供常規(guī)按鍵輸入功能,帶全按鍵獨(dú)立RGB燈邑时。
- HelloWord-Ctrl:左側(cè)Dynamic組件的PCB奴紧,控制器為STM32F405,可以配合底座單獨(dú)使用晶丘,提供FOC力反饋旋鈕黍氮、電子墨水屏顯示、OLED顯示铣口、RGB燈等功能滤钱。
- HelloWord-Connector:主鍵盤用于連接底座的觸點(diǎn)PCB,通過FFC排線與鍵盤PCB連接脑题。
- HelloWord-Connector-Ctrl:Dynamic組件用于連接底座的觸點(diǎn)PCB件缸,通過FFC排線與Dynamic組件PCB連接。
- HelloWord-Encoder:磁編碼器PCB叔遂,用于對無刷電機(jī)進(jìn)行位置反饋他炊,需要配合一個(gè)徑向充磁的永磁鐵工作。
- HelloWord-Hub1:底座上擴(kuò)展出的兩個(gè)額外USB-A接口轉(zhuǎn)接PCB已艰,通過FFC排線和TypeC接口板連接痊末。
- HelloWord-Hub2:底座上擴(kuò)展出的兩個(gè)額外USB-A接口的母座PCB,預(yù)留的是USB3.0母座和引腳哩掺,但是目前只使用到了2.0接口凿叠,未來可以升級到USB3.0的HUB。
- HelloWord-TypeC:底座上用于連接電腦的TypeC接口PCB嚼吞,板載了電源充電管理芯片盒件,以及USB-HUB芯片,通過FFC排線連接其余模塊舱禽。
- HelloWord-OLED:Dynamic組件上OLED屏幕的最小驅(qū)動電路以及轉(zhuǎn)接板炒刁。
- HelloWord-TouchBar:可選的電容觸摸條模塊PCB,使用6按鍵電容觸摸芯片組成一個(gè)線性感應(yīng)陣列誊稚,通過FFC排線和主鍵盤PCB連接翔始。
1.1.2 Firmware
Firmware中提供了上面所有板子的固件源碼罗心,以及預(yù)編譯好的bin固件可以直接燒錄,主要包含以下兩個(gè)工程:
- HelloWord-Keyboard-fw:主鍵盤的固件城瞎,主要實(shí)現(xiàn)了基于硬件SPI和移位寄存器的高速按鍵掃描渤闷、基于硬件SPI&DMA的總線式RGB燈控制、HID高速設(shè)備鍵盤枚舉&報(bào)文協(xié)議實(shí)現(xiàn)全谤、非易失存儲配置肤晓、多層按鍵映射等功能。
- HelloWord-Dynamic-fw:Dynamic組件的固件认然,主要實(shí)現(xiàn)了基于FOC的電機(jī)控制代碼补憾、可配置觸感封裝類、電子墨水屏驅(qū)動卷员、OLED驅(qū)動盈匾、USB全速復(fù)合設(shè)備枚舉和通信協(xié)議、RGB燈控制等功能毕骡。
工程都是基于STM32HAL實(shí)現(xiàn)的削饵,所以提供了對應(yīng)的.ioc
文件,可以自行用STM32CubeMX打開未巫,生成對應(yīng)的keil或者STM32IDE工程文件窿撬。當(dāng)讓也可以像我一樣,用CLion或者STM32CubeIDE進(jìn)行編譯和下載叙凡。
_Release
文件夾里是預(yù)編譯好的bin文件劈伴,可以用ST-Link Utillity或者STM32CubeProgrammer之類的軟件直接下載到芯片。
關(guān)于固件的實(shí)現(xiàn)細(xì)節(jié)后文有講解握爷。
把CLion變成STM32的IDE的方法參考我之前發(fā)的一篇教程:配置CLion用于STM32開發(fā)【優(yōu)雅の嵌入式開發(fā)】 跛璧。
1.1.3 Software
Software中提供了一些用于和鍵盤交互的電腦端上位機(jī)軟件,包括視頻里演示的傻瓜化修改墨水屏圖片的上位機(jī)軟件新啼,以及后續(xù)會逐步補(bǔ)充用于修改鍵位的圖形化軟件給模塊添加APP的應(yīng)用商店軟件追城,這些還在開發(fā)中。
1.1.4 Tools
Tools主要是提供一些三方的工具軟件燥撞,比如STM32 ST-LINK Utility 座柱、用于安裝驅(qū)動的zadig等等。
1.1.5 3D Model
文件夾里是鍵盤用到的所有結(jié)構(gòu)件的3D模型文件物舒,可以用于3D打印辆布。
1.1.6 Docs
相關(guān)的參考文件,包括芯片的Datasheet等茶鉴。
2. 硬件架構(gòu)說明
關(guān)于結(jié)構(gòu)設(shè)計(jì)?
瀚文的結(jié)構(gòu)包括三大部分:擴(kuò)展塢底座景用、鍵盤輸入模塊和可替換的多功能交互模塊涵叮,鍵盤輸入模塊和可替換的多功能交互模塊通過若干接觸式觸點(diǎn)連接在所述擴(kuò)展塢底座頂部:
而鍵盤本體也是一個(gè)標(biāo)準(zhǔn)的客制化鍵盤層疊結(jié)構(gòu)設(shè)計(jì)惭蹂,包含減震棉、PCBA割粮、定位板盾碗、軸下墊等:
鍵盤的結(jié)構(gòu)設(shè)計(jì)主要是Xikii根據(jù)S98修改而來,為75鍵布局舀瓢,有其他布局需要的同學(xué)可以自行修改PCB和固件適配廷雅。
關(guān)于視頻中展示的結(jié)構(gòu)件,由于是Xikii的方案所以我也不好擅自把源文件放出京髓,而且原始版本結(jié)構(gòu)是用于CNC機(jī)加工的航缀,成本會比較高。
所以我也讓Xikii幫忙設(shè)計(jì)一套簡化版可用于3D的結(jié)構(gòu)件堰怨,并開源出來放到倉庫芥玉。
關(guān)于芯片選型?
- 鍵盤主控選用的芯片是STM32F103CBT6备图,實(shí)際上C8T6也可以灿巧,不過考慮到未來固件功能的擴(kuò)展性,F(xiàn)lash大一倍的CBT6性價(jià)比更高揽涮。這塊由于我固件基本都是使用HAL庫實(shí)現(xiàn)的抠藕,因此實(shí)際上也可以把主控替換成STM32系列的任何一款芯片,需要支芯片有2個(gè)SPI硬件接口分別用于按鍵掃描以及RGB燈驅(qū)動蒋困,以及一個(gè)全速USB接口即可盾似。
- Dynamic組件主控的STM32F4,這個(gè)是因?yàn)槲沂诌呥@款芯片比較多家破,理論上可以替換為性價(jià)比更高的F1系列的颜说,只要芯片具備一個(gè)高級定時(shí)器用于PWM生成、2個(gè)硬件SPI接口用于編碼器和電子墨水屏通信汰聋、一個(gè)I2C接口用于OLED驅(qū)動门粪,以及一個(gè)全速USB接口即可。
- 電機(jī)的磁編碼器芯片我是使用AS5047P烹困,也是一款很常用性能很好的磁編碼芯片玄妈,不過成本略高,我只是因?yàn)槭诌呌兴赃x了這款髓梅,也是可以修改為其他更便宜的型號的比如MT6816等拟蜻,當(dāng)然也需要修改固件驅(qū)動代碼。
- 按鍵掃描用的移位寄存器使用的74HC165枯饿,國產(chǎn)芯片零售的話大概0.5元一片酝锅,一片可以驅(qū)動8個(gè)按鍵,按照你自己需要的按鍵數(shù)目修改串聯(lián)的寄存器芯片即可奢方。進(jìn)口的165比如TI原裝的要比國產(chǎn)貴一些搔扁,性能也會稍微好點(diǎn)爸舒,不過由于本項(xiàng)目中按鍵掃描頻率4MHz已經(jīng)完全夠用了,因此哪怕國產(chǎn)的16MHz芯片也綽綽有余了稿蹲。
- 電容觸摸板使用的是一個(gè)6通道電容觸摸按鍵芯片XW06A實(shí)現(xiàn)的扭勉,這個(gè)對于PCB感應(yīng)盤的設(shè)計(jì)有一定要求,倉庫已經(jīng)提供了設(shè)計(jì)好的PCB苛聘。對于該芯片的讀取方式涂炎,其實(shí)和普通按鍵沒有區(qū)別,所以本方案中也是使用74HC165進(jìn)行掃描讀取的设哗。
- 電機(jī)FOC驅(qū)動電路完全是從我的Ctrl驅(qū)動器中移植過來的唱捣,使用FD8288Q作為柵極驅(qū)動器,無需電流傳感器熬拒。
關(guān)于燒錄方式爷光?
使用JLink、STLink之類的調(diào)試器燒錄澎粟,我在PCB和外殼上都預(yù)留了SWD調(diào)試口蛀序。對于沒有硬件開發(fā)經(jīng)驗(yàn)的同學(xué),我晚點(diǎn)也會放出一個(gè)Bootloader活烙,可以直接通過USB口進(jìn)行固件升級徐裸。
關(guān)于電機(jī)選型?
我使用的是一個(gè)2204的二手電機(jī)啸盏,不過這一款電機(jī)目前好像不太好買重贺,大家可以選取類似尺寸的無刷電機(jī)替換,參數(shù)方面需要KV值低一些回懦,最好200左右气笙。電機(jī)需要手動在轉(zhuǎn)子上安裝一個(gè)徑向充磁的永磁體用于編碼器定位,不同型號的電機(jī)需要對FOC參數(shù)進(jìn)行一些調(diào)整怯晕。
3. 軟件架構(gòu)說明
關(guān)于鍵盤固件的按鍵映射方式潜圃?
為了充分發(fā)揮視頻中提到的移位寄存器掃描方案的優(yōu)勢,固件代碼中將PCB Layout走線和按鍵掃描順序解耦舟茶,通過軟件進(jìn)行重映射谭期。也就是說PCB中按鍵的連接可以是任意的,走完線之后可以在hw_keyboard.h
文件中的keyMap[KEYMAP_NUM][IO_NUMBER]
中指定映射方式吧凉。
這是一個(gè)二維數(shù)組隧出,代表有
KEYMAP_NUM
層鍵位映射,每一層有IO_NUMBER
個(gè)按鍵(也就是你的鍵盤按鍵數(shù)目)阀捅;其中第0層是特殊的胀瞪,負(fù)責(zé)映射PCB按鍵的隨機(jī)布局到鍵盤標(biāo)準(zhǔn)按鍵布局,后續(xù)的1饲鄙、2赏廓、3涵紊、4...層都是自定義的,負(fù)責(zé)映射標(biāo)準(zhǔn)按鍵布局到任意布局幔摸。
舉個(gè)例子:
考慮原理圖中箭頭指的那個(gè)按鍵,這個(gè)按鍵可以在PCB的任意位置颤练,但是我們可以看到既忆,它是從左到右(按74HC165的連接順序,也即移位掃描順序)的第10顆嗦玖,因此它的編號為9(從0開始算).
如果我們在實(shí)際的PCB板上把它放在了右邊Alt的位置患雇,那么參考在下圖代碼紅色框中的第1層映射(也就是標(biāo)準(zhǔn)布局)中的RIGHT_ALT
的序號是76,那么在第0層映射的76號變量就填入9(藍(lán)色框).
這樣依次把你PCB上所有按鍵都填入0層映射宇挫,就得到了一個(gè)映射好的標(biāo)準(zhǔn)鍵盤了苛吱。后續(xù)2、3器瘪、4翠储、5...層需要怎么映射就隨意修改添加即可,也不需要再使用數(shù)字編號橡疼,而是可以直接用枚舉的按鍵名稱很方便援所。
所以對于想修改鍵盤配列的人,只需要再原理圖上添加或刪減幾個(gè)串聯(lián)的74HC165欣除,然后PCB隨意走線住拭,再將代碼中0層映射刪減或增加一些數(shù)字即可(比如在下面的例子中我的鍵盤是83鍵的);后面幾層的修改就以此類推了历帚。
代碼中通過keyboard.Remap
函數(shù)來映射不同層滔岳,比如keyboard.Remap(2)
這一句是使用第2層映射。
關(guān)于鍵盤固件的濾波方法挽牢?
固件中使用了每個(gè)按鍵獨(dú)立的濾波谱煤,但是是以一種非常高效的方式來實(shí)現(xiàn)的(畢竟1KHz的報(bào)文,每個(gè)報(bào)文期間至少掃描兩次按鍵卓研,意味著每秒鐘需要進(jìn)行 1000*2*[按鍵數(shù)目] 次數(shù)的濾波)趴俘。
基本原理很簡單,就是按鍵抖動的原因是按下后會在高低電平之間反復(fù)橫跳奏赘,這個(gè)穩(wěn)定時(shí)間一般是幾十us(注意是電平穩(wěn)定時(shí)間寥闪,不是按鍵觸發(fā)時(shí)間,后者是由于按鍵簧片接觸時(shí)間的不確定性導(dǎo)致的磨淌,可能長達(dá)數(shù)ms)疲憋。
在QMK的qmk_firmware/feature_debounce_type文檔中描述了其使用的幾種濾波方法,分為Eager和Defer梁只、對稱和非對稱等缚柳,
默認(rèn)是使用對稱延遲全局濾波埃脏,也就是說是對所有按鍵進(jìn)行同等的濾波,等所有的按鍵都穩(wěn)定了不再變化秋忙,再提交掃描數(shù)據(jù)彩掐。
與之對應(yīng)的是激進(jìn)濾波方法,也就是說一旦檢測到按鍵變化就提交數(shù)據(jù)灰追,但是在這之后的N毫秒時(shí)間內(nèi)不再響應(yīng)任何按鍵(也就避免了把不斷抖動的按鍵提交上去)堵幽。這種方法觸發(fā)延遲低,但是對噪聲很敏感弹澎,容易誤觸發(fā)朴下。
我在瀚文的固件中使用的是對稱延遲獨(dú)立濾波,也就是對每個(gè)按鍵進(jìn)行兩次檢測苦蒿,如果第一次檢測到了按鍵變化殴胧,那么相隔N微秒(這個(gè)參數(shù)可以配置,大于按鍵典型抖動時(shí)間即可)再檢測一次佩迟,如果兩次檢測結(jié)果一致团滥,那么判斷按鍵被按下,此時(shí)可以確保按鍵發(fā)生了變化音五,且不會重復(fù)觸發(fā)按鍵惫撰,兼顧延遲和穩(wěn)定性。
這個(gè)過程是通過異或運(yùn)算進(jìn)行高效處理的躺涝,正好按鍵buffer由于是移位寄存器掃描得到的厨钻,本身就是每一位代表一個(gè)按鍵,所以濾波效率非常高坚嗜,實(shí)測效果也挺好的夯膀。
關(guān)于鍵盤固件的HID描述符?
這個(gè)可以直接參考源碼的usbd_customhid.c
文件苍蔬,我配置了兩個(gè)ReportID诱建,ID-0是上報(bào)鍵位掃描數(shù)據(jù)的(全鍵無沖),ID-1是預(yù)留用于后續(xù)跟上位機(jī)改鍵軟件通信用的碟绑。
關(guān)于RGB的控制俺猿?
代碼中使用的是單總線的ws2812b系列燈珠,一根線就可以串聯(lián)一大堆RGB格仲,而且代碼中實(shí)現(xiàn)了SPI-DMA模擬時(shí)序押袍,得到了超高的刷新率。
目前代碼里只寫了一個(gè)demo燈效(非常簡單就是輪詢色彩)凯肋,自己添加額外的燈效的話谊惭,通過keyboard.SetRgbBuffer
函數(shù)設(shè)置RGB值,然后SyncLights
把數(shù)據(jù)發(fā)送給LED即可:
while (true)
{
/*---- This is a demo RGB effect ----*/
static uint32_t t = 1;
static bool fadeDir = true;
fadeDir ? t++ : t--;
if (t > 250) fadeDir = false;
else if (t < 1) fadeDir = true;
for (uint8_t i = 0; i < HWKeyboard::LED_NUMBER; i++)
keyboard.SetRgbBuffer(i, HWKeyboard::Color_t{(uint8_t) t, 50, 0});
/*-----------------------------------*/
// Send RGB buffers to LEDs
keyboard.SyncLights();
}
4. SDK設(shè)計(jì) & 二次開發(fā)
待補(bǔ)充。
感謝以下項(xiàng)目:
olikraus/u8g2: U8glib library for monochrome displays, version 2 (github.com)