Copyright belongs to @pengzhihui
【Hanwen】HelloWord-Keyboard
Hanwen Smart Keyboard is a multifunctional, modular mechanical keyboard designed for my own needs.
The keyboard uses a modular design, and the multi-functional scene interaction module on the left can be replaced with various custom components. The default one is a Dynamic component with an electronic ink screen and FOC force feedback knob; the keyboard uses an ARM Cortex-based -M chip keyboard firmware and module firmware; the keyboard body uses a shift register to realize an optimized key scanning circuit; the module and the keyboard body can be used alone, or can communicate and call each other through the serial port protocol.
The content of open source materials in this warehouse includes:
-
10 PCB design source files of Hantext hardware design, providing the file format of EasyEDA Professional Edition
-
Shell Design Structure File
-
The firmware source code of the keyboard body (relatively perfect)
-
The firmware source code of the Dynamic component (the framework has been completed, more APP expansion WIP)
-
Keyboard secondary development SDK (under development)
For keyboard function demonstration, please refer to:
1.Project description
1.1 Project file description:
1.1.1 Hardware
The Hardware folder contains the schematic diagrams and PCB files of all circuits used in Hanwen keyboards. Currently, source files in Lichuang EDA professional format and Gerber format light drawing files are provided to manufacturers for direct processing.
hw5.png
There are a total of the following boards:
-
HelloWord-Keyboard: The PCB of the main keyboard, the controller is STM32F103, which can be used alone with the base, providing regular key input functions, with independent RGB lights for all keys.
-
HelloWord-Ctrl: The PCB of the Dynamic component on the left, the controller is STM32F405, which can be used alone with the base, providing functions such as FOC force feedback knob, electronic ink screen display, OLED display, and RGB lights.
-
HelloWord-Connector: The main keyboard is used to connect the contact PCB of the base, and connect to the keyboard PCB through the FFC cable.
-
HelloWord-Connector-Ctrl: The Dynamic component is used to connect the contact PCB of the base, and connect to the Dynamic component PCB through the FFC cable.
-
HelloWord-Encoder: Magnetic encoder PCB, used for position feedback of brushless motors, needs to work with a radially magnetized permanent magnet.
-
HelloWord-Hub1: Two additional USB-A interface transfer PCBs extended on the base, connected to the TypeC interface board through the FFC cable.
-
HelloWord-Hub2: Two additional USB-A interface female PCBs extended on the base, reserved for USB3.0 female sockets and pins, but currently only 2.0 interfaces are used, and can be upgraded to USB3.0 in the future HUB.
-
HelloWord-TypeC: The TypeC interface PCB on the base is used to connect to the computer. The board is equipped with a power charging management chip and a USB-HUB chip, and is connected to other modules through the FFC cable.
-
HelloWord-OLED: The minimum driving circuit and adapter board for the OLED screen on the Dynamic component.
-
HelloWord-TouchBar: Optional capacitive touch bar module PCB, using 6-key capacitive touch chips to form a linear sensing array, connected to the main keyboard PCB through FFC cables.
1.1.2 Firmware
Firmware provides the firmware source code of all the above boards, and the pre-compiled bin firmware can be directly burned, mainly including the following two projects:
-
HelloWord-Keyboard-fw: The firmware of the main keyboard, which mainly realizes high-speed key scanning based on hardware SPI and shift register, bus-type RGB light control based on hardware SPI&DMA, HID high-speed device keyboard enumeration & message protocol implementation, non-easy Lost storage configuration, multi-layer key mapping and other functions.
-
HelloWord-Dynamic-fw: Dynamic component firmware, which mainly implements FOC-based motor control code, configurable touch package, electronic ink screen driver, OLED driver, USB full-speed composite device enumeration and communication protocol, RGB Light control and other functions.
The projects are all implemented based on STM32HAL, so the corresponding .ioc files are provided, which can be opened with STM32CubeMX to generate corresponding keil or STM32IDE project files. Dangrang can also compile and download with CLion or STM32CubeIDE like me.
The _Release folder is a pre-compiled bin file, which can be directly downloaded to the chip with software such as ST-Link Utillity or STM32CubeProgrammer.
The implementation details of the firmware will be explained later.
1.1.3 Software
Software provides some computer-side host computer software for interacting with the keyboard, including the fool-proof host computer software for modifying the ink screen picture demonstrated in the video, and will gradually add graphical software for modifying key positions to the module in the future. APP's application store software, these are still under development.
1.1.4 Tools
Tools mainly provide some third-party tool software, such as STM32 ST-LINK Utility, zadig for driver installation, etc.
1.1.5 3D Model
In the folder are the 3D model files of all the structural parts used in the keyboard, which can be used for 3D printing.
1.1.6 Docs
Relevant reference documents, including chip Datasheet, etc.
2.Hardware architecture description
What about structural design?
The structure of Hanwen includes three parts: docking station base, keyboard input module and replaceable multifunctional interactive module, the keyboard input module and replaceable multifunctional interactive module are connected on the top of the docking station base through several contact contacts :
The keyboard body is also a standard customized keyboard layered structure design, including shock-absorbing cotton, PCBA, positioning board, shaft pad, etc.:
The structural design of the keyboard is mainly modified by Xikii based on S98, which is a 75-key layout. Students who need other layouts can modify the PCB and firmware adaptation by themselves.
Regarding the structural parts shown in the video, since it is Xikii's solution, I cannot release the source files without authorization. Moreover, the original version of the structure is for CNC machining, and the cost will be relatively high.
So I also asked Xikii to help design a simplified version of the structural parts that can be used in 3D, and open sourced it and put it in the warehouse.
About chip selection?
-
The chip used for the keyboard main control is STM32F103CBT6. In fact, C8T6 can also be used. However, considering the scalability of future firmware functions, CBT6 with twice the size of Flash is more cost-effective. Since my firmware is basically implemented using the HAL library, the main control can actually be replaced with any chip in the STM32 series. The chip needs to have two SPI hardware interfaces for button scanning and RGB light driving. , and a full-speed USB interface.
-
Dynamic component controls the STM32F4. This is because I have more of this chip on hand. In theory, it can be replaced with the more cost-effective F1 series, as long as the chip has an advanced timer for PWM generation and 2 hardware SPI interfaces for encoding. It can communicate with the e-ink screen, an I2C interface for OLED driver, and a full-speed USB interface.
-
I use AS5047P as the magnetic encoder chip of the motor. It is also a very commonly used magnetic encoding chip with good performance, but the cost is slightly higher. I just chose this one because I had it on hand. It can also be modified to other cheaper models. For example, MT6816, etc., of course, the firmware driver code also needs to be modified.
-
The shift register used for key scanning uses 74HC165. Domestic chips retail for about 0.5 yuan each. One chip can drive 8 keys. Just modify the series register chip according to the number of keys you need. Imported 165, such as the original TI chip, is more expensive than the domestic one, and the performance will be slightly better. However, since the key scanning frequency of 4MHz is completely sufficient in this project, even the domestic 16MHz chip is more than enough.
-
The capacitive touch panel is implemented using a 6-channel capacitive touch button chip XW06A. This has certain requirements for the design of the PCB induction disk. The warehouse has provided the designed PCB. The reading method of the chip is actually no different from ordinary buttons, so 74HC165 is also used for scanning and reading in this solution.
-
The motor FOC driver circuit is completely ported from my Ctrl driver, using FD8288Q as gate driver, no current sensor required.
About the burning method?
Use debuggers such as JLink and STLink to burn, and I have reserved SWD debugging ports on both the PCB and the shell. For students who have no experience in hardware development, I will release a Bootloader later, which can directly upgrade the firmware through the USB port.
About motor selection?
I am using a 2204 second-hand motor, but it seems that this motor is not easy to buy at the moment. You can choose a brushless motor of similar size to replace it. In terms of parameters, the KV value needs to be lower, preferably around 200. The motor needs to manually install a radially magnetized permanent magnet on the rotor for encoder positioning. Different models of motors require some adjustments to the FOC parameters.
3.Software architecture description
About the key mapping method of the keyboard firmware?
In order to take full advantage of the shift register scanning scheme mentioned in the video, the PCB Layout traces and key scanning sequence are decoupled in the firmware code and remapped through software. In other words, the connection of the buttons in the PCB can be arbitrary. After the wiring is completed, the mapping method can be specified in keyMap[KEYMAP_NUM][IO_NUMBER] in the hw_keyboard.h file.
This is a two-dimensional array that represents the KEYMAP_NUM layer key mapping. Each layer has IO_NUMBER keys (that is, the number of keys on your keyboard); layer 0 is special and is responsible for mapping the random layout of PCB keys to the keyboard standard. The button layout, the subsequent 1, 2, 3, 4... layers are all customized, responsible for mapping the standard button layout to any layout.
for example:
Consider the button pointed by the arrow in the schematic diagram. This button can be anywhere on the PCB, but we can see that it is the 10th one from left to right (according to the connection sequence of 74HC165, that is, the shift scan sequence). Therefore it is numbered 9 (counting from 0).
If we place it on the right Alt position on the actual PCB board, then refer to the serial number of RIGHT_ALT in the first layer mapping (that is, the standard layout) in the red box of the code below is 76, then in the 0th layer The variable number 76 of the mapping is filled with 9 (blue box).
In this way, fill in all the buttons on your PCB in the 0-layer mapping in turn, and you will get a mapped standard keyboard. You can modify and add the following layers 2, 3, 4, 5... as you need to map them. There is no need to use numerical numbers. Instead, you can directly use the enumerated button names, which is very convenient.
So for those who want to modify the keyboard layout, they only need to add or delete a few 74HC165s in series on the schematic diagram, then route the PCB as desired, and then delete or add some numbers to the layer 0 mapping in the code (for example, below In the example, my keyboard is 83 keys); the modification of the next few layers can be deduced by analogy.
In the code, the keyboard.Remap function is used to map different layers. For example, the sentence keyboard.Remap(2) uses layer 2 mapping.
About the filtering method of keyboard firmware?
Independent filtering for each button is used in the firmware, but it is implemented in a very efficient way (after all, for a 1KHz message, at least two buttons are scanned during each message, which means that 1000* 2*[number of keys] filter).
The basic principle is very simple, that is, the reason for the button shaking is that it will repeatedly jump between high and low levels after pressing. Caused by the uncertainty of the key reed contact time, which may be as long as several ms).
QMK's qmk_firmware/feature_debounce_type document describes several filtering methods used, divided into eager and defer, symmetric and asymmetric, etc.
The default is to use symmetric delay global filtering, that is to say, all buttons are filtered equally, and the scanned data is submitted after all buttons are stable and no longer change.
Corresponding to it is the aggressive filtering method, that is to say, the data is submitted once a key change is detected, but no key is responded to within N milliseconds after that (it also avoids submitting constantly shaking keys). This method has low triggering delay, but is very sensitive to noise and prone to false triggering.
I use symmetrical delay independent filtering in Hanwen's firmware, that is, to detect each key twice, if the key change is detected for the first time, then the interval is N microseconds (this parameter can be configured, greater than the typical jitter of the key time) to detect again, if the two detection results are consistent, then it is judged that the button is pressed, at this time, it can be ensured that the button has changed, and the button will not be triggered repeatedly, taking into account delay and stability.
What about HID descriptors for keyboard firmware?
This can directly refer to the usbd_customhid.c file of the source code. I configured two ReportIDs, ID-0 is to report the key scanning data (full key without punching), and ID-1 is reserved for follow-up with the host computer to change the key software For communication.
About the control of RGB?
The code uses single-bus ws2812b series lamp beads, a large number of RGB can be connected in series with one line, and the SPI-DMA analog timing is implemented in the code, and a super high refresh rate is obtained.
At present, only one demo lighting effect is written in the code (it is very simple to poll the color). If you add additional lighting effects yourself, set the RGB value through the keyboard.SetRgbBuffer function, and then SyncLights sends the data to the LED:
-
SDK design & secondary development
To be added.