Skip to content

hhkb_ble

joric edited this page Jan 14, 2023 · 63 revisions
  • New! There's a working ZMK version for HHKB Pro 2 and nice!nano https://github.com/kanru/hhkb-nicenano-zmk (Reddit). This is not Hbar pinout, everything is on one side except the top two pairs that are crossed, because Pro Micro pins go as D3/D2/GND/GND and JST connector is GND/GND/CSEL/CB2. You can use nRFMicro shield for ZMK. Battery life is about 2x better than YDKB. For 1200 mAh you can get 4 to 5 days if you let it poll continually. With more aggressive sleep you can get close to 10 days (discord), same as YDKB with the largest possible 785151 2600 mAh battery (ebay).

Upd. @kanru managed to wire a vibration sensor (SW-420) directly to two pins and setup them to wake up the board. The sensor is so sensitive you just need to type harder to wake up to board. He committed a pm-wake-sensor driver to my repository and example pin setting in the overlay file discord github.

zmk-nicenano-hhkb

Disclaimer

The nRF52840-based HHKB-BLE QMK firmware is still in progress. The work is based on the discovery by /u/yangdigi (geekhack) ("I found it could work with 3.3v while the working current 18ma"). HHKB JP still needs a capacitor to handle inrush current. Apparently, no 5V step-up regulators (boost converters) needed. Bluetooth module used in YDKB controller is mdbt40 (nrf51-based), with Adafruit Bluefruit LE UART Friend firmware.

It's NOT recommended to build QMK nrf52 branch (doesn't work), use ZMK: https://github.com/kanru/hhkb-nicenano-zmk

Related links

Mind that nRFMicro revision 0.03 (and HHKB-BLE firmware) lacks power saving mosfet (see hhkb-ble branch). You can solder your own mosfet to the GND line for now (see Hasu Alt controller schematic, it uses pin D4 and N-mosfet to disconnect external GND). Current firmware does not use it.

Firmware

Pro Micro

Regular Pro Micro wired version works just great.

I've ported Hasu pin handling code from bitmasks and AVR registers to an arbitrary pinout (Hbar):

#define HHKB_PINS_HBAR { B2, B3, D7, B1, C6, F7, D4, F6, F5 } (see hhkb_avr.h)

nRFMicro

Wireless HHKB firmware (nRFMicro-compatible alpha version, in progress).

Note that matrix_scan_impl is declared as a weak symbol, so it can be overriden in your implementation without editing the global makefile.

The rest is copied from AVR version almost verbatim. I've commented out the microsecond timer code in matrix.c:

// needs 20us timer here! // joric
//if (TIMER_DIFF_RAW(TIMER_RAW, last) > 20/(1000000/TIMER_RAW_FREQ)) {
//    matrix[row] = matrix_prev[row];
//}

It (almost) works, but there are series of trailing 22222 after each key, e.g. when I type qwerty I get something like q222w222e22r2222t222y222222), see the following video:

Video

It's not bluetooth-related because I'm using wired USB connection for debug, it's just timings (bluetooth works, and behaves the same way). Tried this:

uint32_t last = NRF_RTC0->COUNTER; // or app_timer_cnt_get() or nrf_drv_rtc_counter_get()
// ... key reading code ...
if (NRF_RTC0->COUNTER > last) { // RTC timer resolution is about 30us (32kHz)
    matrix[row] = matrix_prev[row];
}

But it just got worse. Running microsecond timer instead of RTC might also be a problem for power saving. I think I don't really need a microsecrond timer, 20us per key is just 60*20=1200us=1.2ms for the whole matrix, I can scan it in a critical section so there will be no interrupts. It still doesn't work though, probably nrf52 fork-specific but I can't locate the issue.

The '2' key appears to be COL0/ROW0 but when I try to reset it it just repeats the nearest key (qqq, wwww and so on).

    Pro/Pro2(8x8):
      COL 0     1       2       3       4       5       6       7
    ROW ---------------------------------------------------------------
      0|  2     q       w       s       a       z       x       c
      1|  3     4       r       e       d       f       v       b
      2|  5     6       y       t       g       h       n       _NONE_
      3|  1     Esc     Tab     Control LShift  LAlt    LMeta   Space
      4|  7     8       u       i       k       j       m       _NONE_
      5|  \     `       Delete  Return  Fn      RShift  RAlt    RMeta
      6|  9     0       o       p       ;       l       ,       _NONE_
      7|  -     +       ]       [       '       /       .       _NONE_

Yangdigi's comment:

The magic 2. NOT any other keys, only KEY 2.
I've come across a few times with it.
When reading key state is not stable, the magic 2 comes.
But not like your video shows that several 2 come together,
I just get one extra KEY 2 a time.

Another comment (haven't tried it yet):

I've got a board and took a quick test with your code.
matrix.c 129 to 131.
Code:
            //if (matrix_prev[row] & (1<<col)) {
                KEY_PREV_ON();
            //}
The keys should work without "222"  problem now.
Hope this helps.

Upd. checked, it does not fix the problem, unfortunately, the issue stays the same.

Microsecond timer setup

Hbar pinout

I am using a specific pinout coined by Hbar from Geekhack (Hbar pinout for short). I've decided to use it because it's tidy and allows soldering JST connector directly to the side of Pro Micro:

JST 13 Hasu Hbar Usage
1 5V 5V 5V
2 5V 5V 5V
3 PD7 B2 KEY
4 PB7* B3 HYS
5 PB0* D7 ROW_BIT0
6 PB1 B1 ROW_BIT1
7 PB2 C6 ROW_BIT2
8 PB3 F7 COL_BIT0
9 PB4 D4 COL_BIT1
10 PB5 F6 COL_BIT2
11 PB6 F5 COL_SELECT
12 GND GND GND
13 GND GND GND
  • PB7 is not supported on Pro Micro
  • PB0 is occupied by Pro Micro RX LED
controller (top view)
(VCC) 1 [ ... ] 13 (GND)
switchboard

See https://github.com/tmk/tmk_keyboard/blob/master/keyboard/hhkb/doc/HHKB.txt

Pictures

References

Clone this wiki locally