-
Designing A Keyboard PCB
03/28/2023 at 06:45 • 0 comments![Designing A Keyboard PCB]()
At the beginning of my keyboard journey I was sure to make a standard 100% layout, now, as I got more into that topic, I figured out that I don't want that any more and maybe people who are more into mechanical keyboard can understand.
So ultimately, I decided to go for a split keyboard with 36 keys plus one encoder on one side. That is about the maximum I can operate with a RP2040 without the need of a port extender.
As I already made my first steps in KiCad with the PolyKB Atom, I felt confident enough that this works out.
Maybe I should have done some more studies on ergonomics, but we all have to start somewhere, so this how the left side of my keyboard will look like:
![]()
As you might be able to see, the RP Pico board can be soldered to the PCB on the backside (unfortunately it only has a Micro USB as we know :/ ) and I decided to use an RJ12 jack to connect the two boards.
I know a TRRS jack would be sufficient, but it feels a bit... "strange" to power the second board with that, as the power "pins" would be totally unprotected when disconnecting in operation. Also, I was not sure if I need another pin for bi-directional communication (maybe not, but we will see)
For the keyboard plate I'm using aluminium as I can order it together with the PCB from JLCPCB (as they are making aluminium PCBs as well) and I can design it in KiCad as well, no need for anything else.
Since it is possible to add a silk screen to the aluminium plate I wanted to have an appropriate design for my project: True to my goal to make a keyboard that speaks multiple languages I found the perfect fit, the oldest piece of multilingual history - the Rosetta Stone.
![]()
As I wanted to have the shiny side on top, I designed the plate with the silk screen directly on the front aluminium and the solder mask on the back (where you could apply another silk screen).
JLCPCB doesn't make guarantees about the quality of the silk screen on that side but I will find out :)
-
Moving to the RP2040 as MCU
03/28/2023 at 06:43 • 0 comments![Moving to the RP2040 as MCU]()
Chip shortage. Any more explanation needed? When I started, the STM32F407 was cheap, fast and had plenty of IO pins and therefore, an ideal choice I thought :)
Now you have to pay 40 bucks for the dev board I used and as I'm trying to make a dev kit out of this project I need some more accessible components.
The RP Pico (with an RP2040) comes at a price of 4 Euro, so I ordered a few boards to get started.
Next, I removed my old mainboard:
![]()
Goodbye and thank you for your service!
Here comes the new generation (and there are significantly less IO pins, actually, I need them all and some more):
![]()
Right, so I had to hard-wire the enable pin of the displays power supply to +3V3, there was just no pin left.
And it took some time with the logic analyzer to figure out the little differences in the SPI setup to finally get something showing up:
![]()
Exactly one key gave me something and that something was also distorted. But after getting the timing, reset, d/c etc. signals and default low/hight states right, ALL displays were willing to work!
![]()
Another step forward and in parallel I started with my efforts in designing a more complete keyboard PCB.... still based on my Atoms.
-
Combining all PCBs to a Macro Pad
03/28/2023 at 06:42 • 0 comments![Combining all PCBs to a Macro Pad]()
My next goal was to get a full macro pad working and since JLCPCB sends you always 5 PCBs as a minimum, there were still a few more rows with 4x1 Atoms left.
The assembly was labor intensive as I had to bake all PCBs first, solder them to the side connector and apply the fixes with some bodge wires:
![]()
Next, I extended my QMK firmware and got all diplays working (after some debugging) - Halleluja!
![]()
There were still some minor issues, not all displays worked trouble-free, extending the FFC is not easy :(
Even though my intention with the Atom's side-connectors was to make it easily buildable and affordable for everyone, it turned out quite some work. Maybe a ready made PCB would be worth a try...
Also my used MCU, the STM32F407 became unavailable, which made me think about alternatives.
Luckily the state of the RP2040 QMK branch looked already promising so that I decided to convert the macro pad to the RP Pico!
-
4x2 Proof of Concept
03/28/2023 at 06:40 • 0 comments![4x2 Proof of Concept]()
Here is the first prototype that I consider as base going forward for a bigger test setup.
That's how the PCB arrived:
![]()
And I'm very happy how they turned out (baked in an old toaster):
![]()
For the prototype: All 8 displays can be updated individually, and purely to test the system the first 4 displays (from the bottom!) and their CS lines are controlled by the first shift register (even though it could handle 8) and the second row is controlled by another shift register daisy-chained to the first.
This setup already runs QMK, you can find the firmware on my git repo: https://github.com/thpoll83/qmk_firmware/tree/PolyKeyboard/keyboards/handwired/polykb
It's not actively maintained as I moved on to another keyboard layout (and MCU) but I wanted to keep it for reference.
Thanks to QMK it already perfectly works as keyboard and I can use it's integrated layer system I can update the keys whenever a layer switch occurs.
I purchased a cheap logic analyzer to investigate all SPI and shift register signals as troubleshooting only on the software side is close to impossible (at least for me).
Here a video of the working version:
-
Atom Pinout Details and the Connector
03/28/2023 at 06:38 • 0 comments![Pinout Details and the Connector]()
Again the pin-out for reference ;)
Let's take a look at the keyboard matrix pins `c`, `r`
The `c` is used to connect all `Atoms` ortholinear or shifted by 0.25U/0.5U (compared to the next row). This pin is present two times, on the left and right and also on the front- and backside.
For the `c` pin the wiring to the next row depends on the matrix setup.
The `r` / `Row` pin should be always aligned with the next PCB and is only present on the front side.
Power Supply`+` / `VLED`
Voltage supply for the LEDs, which you should connect to a 3.8V regulator with enough Amps to drive all LEDs. `3V3` / `VCC`: Voltage supply for the display logic. `V🔋` / `VBAT`: Power supply for the OLED display's charge pump and should be between 3.5V and 4.2V (I run it at the recommended 3.8V).
`⏚` / `GND` Pin
The common ground.
LED Data Pins`o`, `i`
The only important thing to watch out is that the `o` / `LED Out` pin of a LED in use is connected to the next `i` / `LED In` pin in use. Keep that in mind when skipping some LEDs in the middle. Otherwise you can just connect every `o` pin with the following `i` pin.
SPI Pins`Rs`, `SI`, `DC` and `Clk`
These are all SPI pins used to control the OLED display. Just connect them to the `PolyKB Connector` - more detail follow below. Sorry for the short names on the PCB, but there wasn't any space to write them full length.
Chip Select Pins `1` ~ `8`
Up to 8 `PolyKB Atoms` can be connected in a row and each `Atom` needs one assigned `CS` pin. You simply do that by making a solder bridge between the number of choice and the triangular `CS` pin on the backside.
Example for connecting the `Atom` on the left with `CS` line `3`:
![]()
In a full row you would connect the first `CS` to `1`, the second `CS` to `2`, all the way up to the last with `CS` and `8`.
Connector
Any `Atom` can be directly soldered to the next `Atom` without any wire. That also works for the `Connector` which can be solder to the first `Atom` in a 90 deg angle:
![]()
The `Connector` contains the shift registers used to pick the right `CS` line to control the displays individually.
Right now there is a `Connector-R` and a `Connector-L` so that we can make a row of up to 16 `Atoms` without any gap. The first 8 `Atoms` are controlled by the `Connector-L` (of course on the left side) and the next 8 `Atoms` by the `Connector-R` (you already know it - on the right side).
The only important part is that the 8 `CS` lines (all of them) should NOT be soldered together in the middle, you should even better file/rasp of the edge in the middle to make sure there is no electric connection. The rest of the pins can be connected. Multiple `Connectors` also need to be chained so that the `Shift Out` pin from the previous `Connector` is wired with the `Data In` pin of the next one.
That's the theory, next time I will post some more facts on the hardware assembly.
-
The First Working PCB Design
03/28/2023 at 06:35 • 0 comments![The First Working PCB Design]()
Nobody is perfect...
My first take on a full size keyboard PCB failed after I realized some major design flaws (just after finishing).
So I decided doing it more step-by-step and came up with the `Poly Keyboard Atom`. One PCB per key. The `Atoms` are compatible with Cherry MX key switches (3 or 5 pins).
![]()
Yes, we are at version 2.1, I already tinkered around quite a bit and as you could see from the first picture I missed some pull-up resistors, so it took some time to get this little PCB design right.
The rendering is missing the tiny OLED display with the name `P34107` which has 72x40 pixels. It is connected to the `Atom` via a flexible cable that first goes through the RGB slit (turned out that just some key switches have a wide-enough LED slit) of the key switch and then through the PCB via the cutout.
Unfortunately, the flex cable is not long enough, so it has to be extended. To do that you need some low temperature solder paste (eg. something that melts around 138 centigrade) and a hot air rework station to solder the two flex cables together.
Some more pictures for a clearer view (here 4 Atoms in a row):
On the first photo the flexible cable was still a bit too long, I'm still experimenting here a bit, but it looks like an extra of 30mm is close to ideal.By looking at the PCB design, you will recognize that the key switch is mounted south-facing so that we can abuse the LED slit of the key switch and get the flexible cable from the OLED display through that slit (and the PCB, since the connector for the FPC is on the backside - on purpose, the flexible cable needs some space to move).
Still, I wanted to have individual LEDs so I added a "north-facing" `WS2812B-Mini` which might need a little opening in the keyboard plate if you don't have transparent key-switch housings. Of course the LED is entirely optional, everything will work without the LED, or I could just add them for the "outer-edge" keys and use them for background lightning when covered by the plate.
Here is a brief pin-out of the Poly Keyboard Atom PCB:
![]()
-
A Short History of the Project (so far...)
03/28/2023 at 06:27 • 0 comments![A Short History of the Project (so far...)]()
Yeah what a mess... but that's not how it started.
I was actually just experimenting with displays/Arduino and coincidentally found out that one of these displays had the size of a keycap (it was a 0.49" 64x32 OLED display on a PCB with an I2C interface):
![]()
The size was less than 1U (19.05mm), but still too big to fit into an ordinary keycap as the get smaller towards the top.
Therefore, I just 3D printed some custom ones with transparent PETG:
The keycaps are in fact not as blurry as they look like on the picture.After some experiments, I figured out that it was possible to control an arbitrary number of displays by settings the SCL (clock) line via a shift register so that only the displays I want to update really receive a clock impulse (that means that all shift register outputs are connected to the displays SCLs). On top of that the shift register can be controlled via SPI, which saved my from the effort of writing the bit-bang code...
Smol Display You Need!
So that worked, but I was not really satisfied with the 3D printed keycaps, as they are a bit strange if you are thinking about building a full keyboard, which at this stage became a fixed idea.
It took me some time to find even smaller displays, but luckily I came across this 0.42" OLED display which is sold in bigger quantities on Alibaba for about 1$ each!
![]()
Stripboard with ESP32
My first breadboard setup was controlled by an ESP32 I wanted to try out, and I spent a felt infinity to control the brightness. Eventually, it worked out and I decided to solder together this stripboard you saw at the beginning for a 4 key/display setup:
![]()
These 0.42" displays only support SPI and that's why I switched to used the shift register to pick the right CS line which in the end felt much better than the hack with the I2C SCL line.
Switch to STM32 MCU
After some early attempts of writing the key input and HID code myself using some Arduino libraries I did more research of what people usually use for custom keyboards and came across QMK Firmware. It has been used for countless keyboards including DIY and more commercial projects, so I figured that it would be a perfect fit for my project
As it turned out, QMK does not support the architecture of ESP32, only AVR and ARM based chips which made me switch to the quite powerful STM32F407 (for dev purpose I thought it would be good to have plenty of IO pins, at that time some STM chips were still available for 'normal' prices).
Unfortunately, I had to add support for the STM32F407 myself, but the QMK community was very helpful and provided enough guidance to get that chip support into the repository. Yay!
![]()
Just before the chip shortage started to ramp up I got my board, 2 years later the price tag has reached heights beyond comprehension.
Maybe it's not a surprise, but I switched again the MCU to the RP2040, but that will be part of another post!
thpoll


















On the first photo the flexible cable was still a bit too long, I'm still experimenting here a bit, but it looks like an extra of 30mm is close to ideal.


The keycaps are in fact not as blurry as they look like on the picture.

