• Magnets

    Nguyen Vincent03/13/2023 at 12:58 0 comments

    I haven't had the time to work on this project recently, but I wanted to share the magnetic interlocking feature of the keyboard. It was quite the challenge to place the magnets with the very small clearance between the bottom of the board and the PCB. After a few redesigns of the case, it seems to work fine. You can see a video of it here

  • Memory displays

    Nguyen Vincent03/02/2023 at 09:47 0 comments

    Currently, the memory displays can give information about connection status as well as battery level. I've chosen an icon as the battery level but it is also possible to have the percentage displayed. A very slight issue with the current setup is that the LDO powering the display discharges itself very slowly when its enable pin is low (TPS7A0333DBVR). The next iteration will use the P-version of that same LDO (TPS7A0333PDBVR) which has active discharge when disabled.

  • Reducing power consumption

    Nguyen Vincent02/26/2023 at 00:22 0 comments

    After playing with the new memory displays and changing some settings, I was able to get to a steady ~65uA of current when idle, and under 30uA when in deep sleep. This is amazingly low and will allow the user to use the keyboard hopefully for multiple years with solar panels before recharging the keyboard.  There still needs to be a day-by-day battery log over multiple months to have a real estimation though.

  • Investigating navigation switch chatter

    Nguyen Vincent02/22/2023 at 10:45 0 comments

    I had written in a previous log that the navigation switch had quite heavy chatter. What's weird is that it only happened for 3 of its 5 positions. I first thought it was mechanical, but ruled it out after measuring with an oscilloscope on a standalone navigation switch. 

    The second possible cause was crosstalk between the lines. This was quite unlikely as the affected lines weren't that close to each other.

     The third cause could be bad contacts in either the 6PDT switch or the JST connector. I first thought it was the switch because bypassing it and connecting the navigation switch directly to the switch matrix eliminated chatter. The issue with this "solution" is that it was impossible to switch out to the horizontal encoder without desoldering.

    Wait a second... The horizontal encoder... Well, that was the cause of everything: both the navigation switch and the horizontal encoder were using the same interface board (presented in the first log). This interface board has capacitors between the A/C and B/C lines of the rotary encoder for very crude hardware debouncing. The thing is, when the navigation switch was selected, the capacitors were then between the UP, DOWN and CENTER lines, which meant that activating one charged the capacitor, inducing a voltage spike in the other lines.

    The solution is then very simple, which is to not populate the capacitors when soldering the navigation switch on the interface board.

    You can see below the 2 capacitors that are used when the horizontal encoder is soldered.

    They should be removed when soldering the navigation switch

  • Future improvements for the third iteration

    Nguyen Vincent02/21/2023 at 13:33 0 comments

    The second iteration is working quite well. You can see below a typing test done with Boba U4 silent tactiles:

    (35) Aloidia keyboard typing test - YouTube

    At the time of writing this log, I'm still waiting for new memory displays.

    After testing the second iteration of the board, there are a few issues that should be improved on for the third iteration:

    • Control over EXTCOMIN and EXTMODE pins for the memory displays, to toggle the VCOM signal as recommended per the datasheet.
    • Add a button to short the battery negative terminal and the board's ground. In the current iteration, the AP9101CK6-ANTRG1 protection is used to disconnect the battery in the case a fault condition is detected. This chip requires the battery negative terminal and system ground to be shorted together when the battery is first inserted. This is not very practical from a user perspective as he needs to manually short pads together when first inserting the battery.
    • Add hardware debouncing on the navigation switches. In the current iteration, there is a quite heavy chatter on the UP, CENTER and DOWN positions of the 5-way navigation switch. This can be solved by increasing the debouncing time on press and release from a software side, but as the current firmware doesn't support setting different debouncing parameters for different keys in the matrix, a hardware solution would be better. I still need to investigate this solution and see if it impacts battery life in any way.
    • It could be interesting to revamp the way hotswap switches /encoders are designed. Using pogo pins instead of a JST-SH connector could be an interesting option.

    I've also mentioned it before, but I also plan on developing a development kit for the nRF52840, with different hardware components to maximize power efficiency. The parameters that could be tested are:

    • Type of regulator: switching vs LDO vs internal DC-DC converter. The switching regulator should be more efficient than the current LDO solution. However, as the current keyboard only uses the LDO for its memory displays, it could be a good solution to use the internal DC-DC converter instead.
    • External pullups in the switch matrix. The nRF52840 uses 13k pullups, which would give a current of 3.3V / 13k = 250uA of sinking current when a key is pressed. Replacing these with external pullups could decrease the current consumption on each keypress. The rising and falling times for each edge would be increased however (tau = RC for a simple RC circuit).
    • Choice of ICs: different fuel gauges, different protection and charging circuits, ... Using a SPI device instead of I2C might reduce power consumption as no current would be dissipated in pullups.

  • Measuring the power consumption

    Nguyen Vincent02/20/2023 at 22:55 0 comments

    Currently, the three solar panels can provide up to 50uA under artificial light, and from 150-1000 uA under sunlight depending on if it is directly or indirectly exposed. The power consumption of one of the halves is 140 uA on average when idle, and down to 25uA in deep sleep. When turned off, current leakage is around 3-7 uA. Current is measured with the nRF PPK2.

    While I still need to properly measure the average power daily consumption, a simple estimation can be made. The keyboard uses around 1000-1500uAh per day, and the solar panels can provide 600-1200uAh per day depending on the lighting conditions. In the best case scenario, the battery should be able to maintain its voltage at all times. In the worst case scenario, it will consume around 900uAh per day. With a 500mAh battery, it should last 555 days, or around a year and a half on a single charge.

    One important factor to keep the power consumption down is the choice of rotary encoders. One must make sure that they are closed on every detent, which ensures that no current will be wasted in possible internal pullups. In practice, I found the EN11 and ACZ11 series of rotary encoders to do the job. The ACZ11 has fairly weak detents, which makes it prone to be stuck between two detents, increasing the power consumption. This is why I've chosen to go with the EN11 encoders. I chose the ones with a threaded bushing, which allows me to thread in a cover cap for a cleaner look.

    "Good" encoder


    "Bad" encoder


    In a future iteration, the following could be optimized for reduced consumption:

    • Use of a switching regulator instead of LDO.
    • Use of external pullups for the switch matrix. This could reduce current when a key is pressed.
    • Testing the effect of all of the protection circuitry, and find alternatives if they consume too much current.

    It could be interesting to design an evaluation board with multiple different ICs to test their performance. But that's a project for another time.

  • Dongles, dongles...

    Nguyen Vincent02/20/2023 at 22:44 0 comments

    The keyboard works wonderfully over bluetooth. However, how can I decrease its power consumption even more? The answer is simple, and has been used with many products before, such as logitech keyboards: dongles.

    With standard bluetooth, one of the halves of the keyboard acts as a central, whereas the other one acts as a peripheral. The peripheral is mostly asleep and only wakes up when an interrupt is triggered by a keypress. The central, however, has to listen to the peripheral to be ready when it sends its keypresses. It can then relay the information to the computer. The disadvantage of such a system is that the peripheral will last much longer than the central, as it is asleep most of the time. A solution, however, is to program a dongle as a central, and have both halves act as peripherals. This provides many advantages:

    - As both halves are peripherals, they are both asleep most of the time, which increases the battery life by almost an order of magnitude

    - The dongle, being plugged into the computer, acts as a USB keyboard. This means that the keyboard can still be used on computers where bluetooth is not available, or in certain situations where bluetooth cannot be used (e.g. in BIOS)

    First, to test the firmware, I used the left half of the first iteration as a dongle:

    It's however not a very compact solution...

    In the end, I chose to go with the nRF52840 MDK USB Dongle by Makerdiary. What is great about this dongle is that it has an exposed reset button, as well as broken out SWD pads.

    The integrated UF2 bootloader can only be accessed by pressing the reset button while inserting the board. Not very practical, if you ask me. Moreover, it is not compatible with the UF2 file generated when compiling the ZMK firmware, probably because of different partitions (softdevice, flash, ...). To solve both of these issues, I simply built and compiled the Adafruit nRF52 UF2 bootloader for the MDK nRF52840 dongle. It can then be flashed to the dongle with a J-Link after unlocking it with nRF Command Line Tools. I've also observed that the bootloader needed to be compiled with softdevice for it to work correctly.

  • Designing the case for the second iteration

    Nguyen Vincent02/20/2023 at 22:27 0 comments

    Designing the case is probably the hardest part of this project. There are a lot of parts: PCBs, plates, solar panels, displays, tenting feet, ... which need to fit in a fairly small form factor, while keeping a nice and clean look. Some of the parts were so close to each other that a clearance of 0.2mm was sometimes needed.

    The case

    The whole case can be 3D printed. Some interesting numbers:

    - 10 PCBs

    - 60 M3 screws/heat inserts

    - 20 M2 screws

    - 10 spacers

    - more than 20 unique 3D printed parts.

    In total around 150 parts need to be assembled (without counting the switches).

    Tenting feet

    Hotswap encoders/navigation switches

    One of the unique features of this keyboard is to give the user the choice to optionally use a navigation switch (right) or a horizontal encoder. Both are 3-parts assemblies which were quite complex to design given the small footprint that it takes on the board, and the precise fit that is required to fit inside of the mx switch footprint.

    Palm rests

    Printing the palm rests is quite tricky, as they need to be printed vertically to have good surface finish with no layer lines on the top. As they are quite thin and tall, this results in z-wobble at higher layers even after sanding. This issue is even more exacerbated because it is printed on a bed slinger type of printer (MK3S+). A core XY would likely result in less wobble as the part stays static while printing.

    A solution is to add manually generated supports and large brims:

    The result is much better but still presents z-wobble on higher layers. I guess I'll have to try to add more rigid supports...


    Failed prototypes

    After assembly:

  • How to break memory displays

    Nguyen Vincent02/20/2023 at 21:48 0 comments

    Surely, one of the most interesting features of the board are its memory displays. They are very low power, have high refresh rate and boast a fairly high resolution. But they are fragile. And I mean VERY fragile. 

    I ordered four memory displays from aliexpress, as they are the only ones from which you can order with a MOQ < 1600. Out of the four, three were defective...

    Here you can see the sole working memory display. Zephyr provides a driver for this display, but it sadly doesn't support rotation (which is crucial in my case because of how the displays are placed on the halves). I had to manually modify the driver to support flipping the display 180 degrees. Currently, I've modified the zephyr driver directly, which is not ideal as you wouldn't be able to compile locally without having the modified RTOS. Eventually, I will move the driver from Zephyr to a custom driver defined in the ZMK repo, or wait for Zephyr 3.0, which should support LVGL rotation.

    Edit: I've now moved it to its own driver. You can check the implementation in my ZMK fork.

    Right now, the display has its EXTCOMIN and EXTMODE pins low, which is not ideal. This is because sharp memory displays require the VCOM signal to be toggled periodically to prevent DC bias thus reducing lifetime of the display. In the Zephyr implementation, this is done by toggling the EXTCOMIN pin while EXTMODE is high. As can be seen below, the current implementation works but it will probably be reviewed in a future iteration. Fortunately, as the memory uses 3-wire SPI, and because I made it compatible with the e-paper display which uses 6 pins, there are 3 free pins which could be used to control both the EXTMODE and EXTCOMIN signals.

    It was working, but...

    I didn't realize how fragile the FFC cable was... I'll be ordering new ones soon...

  • Aloidia 1.0 rev2

    Nguyen Vincent02/20/2023 at 21:38 0 comments

    The second iteration of the board aims to correct all of the mistakes that were spotted when testing the first iteration:

    • Selection of a very low quiescent current LDO. This LDO also has a shutoff pin, which can be controlled by the MCU. This is very useful for example to disconnect power-hungry peripherals when the board is idle.
    • Better clearance for cables. One of the cables in the first iteration could not be plugged without cutting some of the flaps. In the new iteration, I took care to keep proper clearance between the cable housing and other components.
    • Fixed some of the hardware issues, like missing traces or misplaced connections, improper length tuning, ...
    • Use of tented vias. This made soldering a bit easier especially close to the MCU.
    • Compatible with both memory displays and e-paper displays.

    For this iteration, I used ENIG finish, which provides excellent planarity.

    As I mentioned in an older log, the e-paper display was quite noisy when exposed to direct light (and even worse with sunlight, which, for a solar-powered board, is obviously not ideal). I then chose to design a breakout for the LS011b7dh03 from Sharp Devices. This breakout is mechanically compatible with the previously designed e-paper display, with an almost identical footprint.

    Assembling the boards

    Aloidia rev2 PCB assembly - YouTube

    Left half fresh out of the oven

    After soldering the THT components:

    The two halves assembled: