I started from [cy384]'s excellent repository for an Arduino Pro Micro based adapter for a PPK. Unfortunately, I found that the pinout on my keyboard was different and had a much finer contact pitch (0.8mm!). I ended up needing to fabricate a small PCB to break-out the pads to something hand-solderable. The PCB also allowed me to mechanically interface to the alignment pins and metal retaining clips originally intended to keep your PDA attached. I made several 3D printed mock-ups of the mounting interface before committing to dimensions for the PCB.
The PCB was machined using my MPCNC with some single-sided copper clad board. I was extremely happy that the machine could attain this level of precision, but anything finer and I'd likely send it out for fab. I used some cheap 30 degree V bits ( https://amzn.to/3krEvZt) for the engravings and some slightly-less-cheap 1/32" end mills for the mechanical hole interfaces and the board cutout (https://amzn.to/3EH6EUz). Each was run at ~6mm/s and 0.15mm depth per pass, though the engraving really only needed 0.08mm depth to get through the copper.
Next up was the programming. I was able to find a pinout reference for the M500 series of Palm Pilots, which saved a lot of reverse engineering (https://pinoutguide.com/dev/Palm/m500/). I added my new pinout assignments, replaced some of the libraries with ESP32-friendly versions, changed some handshake routines, and gave it a go. It turns out, the ESP32 cannot act as a hardware HID, only a bluetooth HID. This is resolved in the ESP32-S2, but I was not aware of that. I was able to connect to my tablet and it was time to move on.
I added some battery management, monitoring, and reporting (via the RGB LED) to the code. Now, on startup, it will blink blue until the keyboard is booted up. Then, it'll blink every 5 seconds with a color representing the battery state (red up to 15%, yellow up to 30%, green above 30%). Every 5 minutes, the battery voltage is checked using an internal analog pin, and then the reading is compared to an array of increasing voltages spaced at 5% increments. This allows any arbitrary voltage curve to be checked against and edited with relative ease. The remaining battery percentage is simply 5*(array index). This percentage is used to set the heartbeat color and is reported to the hosting bluetooth device.
float batVolt_lookup[] = {3.27, 3.61, 3.69, 3.71, 3.73, 3.75, 3.77, 3.79, 3.80, 3.82, 3.84, 3.85, 3.87, 3.91, 3.95, 3.98, 4.02, 4.08, 4.11, 4.15, 4.20};
float batVolt = 0.0; //volts
int batLevel = -1; //0 to 100 (percent as int)
batVolt = tp.GetBatteryVoltage();
for (int n=0; n<=21; n++)
{
if (batVolt < batVolt_lookup[n])
{
batLevel = 5*n;
break;
}
}
The complete code can be found here: https://gist.github.com/T3hWombat/889ddb50863ac82e46ec27c594a203cb#file-ppk_ble-ino-L3
In theory this should be a fork of [cy384]'s code, but I'm really bad at git, and I didn't want to break anything so gist-it-is!
Next up was the enclosure, which was (of course) 3D printed. I split the enclosure into 4 separate pieces to allow for appropriate print orientations without using supports. Unfortunately, this took some 5 or 6 iterations to get right - I kept having mechanical interference problems with the awkwardly shaped keyboard socket.
The STLs can be downloaded from thingiverse: https://www.thingiverse.com/thing:4973314
My CAD designs can be viewed and copied from OnShape:
Some interesting notes from the journey:
- A pull-down resistor is required on the Rx line. I thought that the ESP32 included pull-down resistors that could be enabled via software, but I was not able to get this feature to work, so I added an external pull-down.
- [cy384] powered his keyboard directly from an IO pin, which is generally frowned upon....