Dragon keyboard conversion to USB HID (XRoar)

For the discussion of all hardware related topics.
wayland
Posts: 39
Joined: Mon Nov 28, 2022 6:28 pm

Dragon keyboard conversion to USB HID (XRoar)

Post by wayland »

Project Summary
To use a REAL Dragon 32 keyboard on XRoar

I've probably damaged my broken Dragon 32 too much which leaves me with a nice yellowed case and an idea.
Can I fit a Raspberry PI running XRoar in the case? Yes I can, there is plenty of room.
Next question, can I attach the Dragon keyboard to the PI?

Well that one really is the question and sent me down some rabbit holes over Easter. I could use the Pi GPIO pins to scan they keyboard matrix but then what? It turns out there is a whole modding scene where people are making their own Custom Keyboards and Macro Button Pads. By far the most popular keyboard controller is the Raspberry PI Pico.

With suitable libraries the Pico can present itself as a USB Keyboard to the host computer. It also has libraries for reading a simple keyboard matrix such as the Dragon uses.

These are the resources I have discovered so far; This is not the only way to do it, I found three broad ways of doing this, years ago someone did it for the CoCo in a different way. Other people are using something called QMK which seems a bit hard core to me. This way seems the easiest because the actual program you need to modify is a file of 66 lines and seems pretty obvious how it works. Lee Smith has even provided Gerber files, I reckon the C64 one will do the trick. I uploaded this to PCBway and have 5 boards on order.

I got to grips with Thonny and programmed the Pico with the C64 version which I will later modify for the Dragon layout. When I short a ROW pin with a COLUMN pin I get letters from the keyboard matrix appearing on my PC as if I'd just typed them. This shows the Pico is acting like a 2nd keyboard.

Success!

I will leave the keyboard side of things there and concentrate on turning a PI into a Dragon using XRoar.
Last edited by wayland on Tue Apr 18, 2023 6:55 pm, edited 4 times in total.
wayland
Posts: 39
Joined: Mon Nov 28, 2022 6:28 pm

Re: Dragon keyboard conversion to USB HID

Post by wayland »

I forgot to mention, I ordered the keyboard connector PCBs from PCBway on the 10th and now they're here.
Tomorrow I will connect my Dragon keyboard to my PC and program The Matrix. I will be going to the pharmacy for the red pills first though.
wayland
Posts: 39
Joined: Mon Nov 28, 2022 6:28 pm

Re: Dragon keyboard conversion to USB HID

Post by wayland »

Code: Select all

# Dragon 32 Keyboard to USB Keyboard
# 2023/04/15 Mostly working. Problems with some symbols, £ @ * =

import board

from kmk.kmk_keyboard import KMKKeyboard
from kmk.keys import KC
from kmk.scanners import DiodeOrientation

from kmk.modules.layers import Layers


print("Starting")
keyboard = KMKKeyboard()
keyboard.modules.append(Layers())
#c64
keyboard.debug_enabled = True
keyboard.col_pins = (
 board.GP8,#9
 board.GP9,#10
 board.GP10,#11
 board.GP11,#13
  board.GP12,#12
 board.GP13, #14
 board.GP14,#15
 board.GP15,#16
)
keyboard.row_pins = (
  board.GP26, #ok 0
  board.GP22,#ok 8
   board.GP20,#ok a


  board.GP16,#ok h
board.GP17, #ok p 
  board.GP18, #ok xyz


board.GP19, #6
  board.GP21,#
)

keyboard.diode_orientation = DiodeOrientation.ROW2COL

#MOMENTARY = KC.MO(1)

keyboard.keymap = [
    [	KC.N0,		KC.N1,	KC.N2,	KC.N3,		KC.N4,	KC.N5,		KC.N6,		KC.N7,
        KC.N8,		KC.N9,	KC.GRV,	KC.SCLN,	KC.COMM,KC.MINS,	KC.DOT,		KC.SLSH,
        KC.ASTR,	KC.A,	KC.B,	KC.C,		KC.D,	KC.E,		KC.F,		KC.G,
        KC.H,		KC.I,	KC.J,	KC.K,		KC.L,	KC.M,		KC.N,		KC.O,
        KC.P,		KC.Q,	KC.R,	KC.S,		KC.T,	KC.U,		KC.V,		KC.W,
        KC.X,		KC.Y,	KC.Z,	KC.UP,		KC.DOWN,KC.LEFT,	KC.RIGHT,	KC.SPC,
        KC.ENTER,	KC.HOME,KC.ESC,	KC.NC,		KC.NC,	KC.NC,	KC.NC,		KC.LSFT,
        KC.Z,		KC.Z,	KC.Z,	KC.Z,		KC.Z,	KC.Z,	KC.Z,	KC.Z,
    ],
    [	KC.N0,		KC.N1,	KC.N2,	KC.N3,		KC.N4,	KC.N5,		KC.N6,		KC.N7,
        KC.N8,		KC.N9,	KC.GRV,	KC.SCLN,	KC.COMM,KC.MINS,	KC.DOT,		KC.SLSH,
        KC.ASTR,	KC.A,	KC.B,	KC.C,		KC.D,	KC.E,		KC.F,		KC.G,
        KC.H,		KC.I,	KC.J,	KC.K,		KC.L,	KC.M,		KC.N,		KC.O,
        KC.P,		KC.Q,	KC.R,	KC.S,		KC.T,	KC.U,		KC.V,		KC.W,
        KC.X,		KC.Y,	KC.Z,	KC.UP,		KC.DOWN,KC.LEFT,	KC.RIGHT,	KC.SPC,
        KC.ENTER,	KC.HOME,KC.ESC,	KC.NC,		KC.NC,	KC.NC,	KC.NC,		KC.LSFT,
        KC.Z,		KC.Z,	KC.Z,	KC.Z,		KC.Z,	KC.Z,	KC.Z,	KC.Z,
    ],
]

if __name__ == '__main__':
    keyboard.go()
wayland
Posts: 39
Joined: Mon Nov 28, 2022 6:28 pm

Re: Dragon keyboard conversion to USB HID

Post by wayland »

Code: Select all

# Dragon 32 Keyboard to USB Keyboard
# 2023/04/15 Mostly working. Problems with some symbols, £ @ * =
# 2023/04/16 Works with XRoar. Everything except @ which comes out as "

import board

from kmk.kmk_keyboard import KMKKeyboard
from kmk.keys import KC
from kmk.scanners import DiodeOrientation

from kmk.modules.layers import Layers


print("Starting")
keyboard = KMKKeyboard()
keyboard.modules.append(Layers())
#C64 pcb
keyboard.debug_enabled = True
keyboard.col_pins = (
 board.GP8,#9
 board.GP9,#10
 board.GP10,#11
 board.GP11,#13
 board.GP12,#12
 board.GP13, #14
 board.GP14,#15
 board.GP15,#16
)
keyboard.row_pins = (
  board.GP26, #ok 0
  board.GP22,#ok 8
  board.GP20,#ok a
  board.GP16,#ok h
  board.GP17, #ok p 
  board.GP18, #ok xyz
  board.GP19, #6
  board.GP21,#
)

keyboard.diode_orientation = DiodeOrientation.ROW2COL


______ = 'NO'

keyboard.keymap = [
    [	KC.N0,		KC.N1,		KC.N2,		KC.N3,		KC.N4,		KC.N5,		KC.N6,		KC.N7,
        KC.N8,		KC.N9,		KC.MINS,	KC.SCLN,	KC.COMM,	KC.EQL,		KC.DOT,		KC.SLSH,
        KC.AT,		KC.A,		KC.B,		KC.C,		KC.D,		KC.E,		KC.F,		KC.G,
        KC.H,		KC.I,		KC.J,		KC.K,		KC.L,		KC.M,		KC.N,		KC.O,
        KC.P,		KC.Q,		KC.R,		KC.S,		KC.T,		KC.U,		KC.V,		KC.W,
        KC.X,		KC.Y,		KC.Z,		KC.UP,		KC.DOWN,	KC.LEFT,	KC.RIGHT,	KC.SPC,
        KC.ENTER,	KC.HOME,	KC.ESC,		______,		______,		______,		______,		KC.LSFT,
        ______,		______,		______,		______,		______,		______,		______,		______,
    ],
 ]

if __name__ == '__main__':
    keyboard.go()
    
OK so I've been testing this in Xroar on Linux Mint with a UK keyboard setting and everything is fantastic except one thing. I can't get the @ sign to work. The KMK Dragon keyboard returns "
I can sort of get it to return @ (AT) if I put " (QUOTE) in the keyboard map above where KC.AT is.

This is the actual Dragon matrix below;

Code: Select all

          LSB              $FF02                    MSB
        | PB0   PB1   PB2   PB3   PB4   PB5   PB6   PB7 <- column
    ----|----------------------------------------------
    PA0 |   0     1     2     3     4     5     6     7    LSB
    PA1 |   8     9     :     ;     ,     -     .     /     $
    PA2 |   @     A     B     C     D     E     F     G     F
    PA3 |   H     I     J     K     L     M     N     O     F
    PA4 |   P     Q     R     S     T     U     V     W     0
    PA5 |   X     Y     Z    Up  Down  Left Right Space     0
    PA6 | ENT   CLR   BRK   N/C   N/C   N/C   N/C  SHFT
    PA7 - Comparator input                                 MSB
     ^
     |
    row
Has anyone any suggestions to help?
Thanks.
sorchard
Posts: 531
Joined: Sat Jun 07, 2014 9:43 pm
Location: Norwich UK

Re: Dragon keyboard conversion to USB HID

Post by sorchard »

I don't really know how your setup works, but producing @ on a PC keyboard usually involving pressing shift, which may interfere with the logic at the Dragon end. Also is it coincidence that @ vs " is one of the differences between US & UK keyboards?

What happens if you type into a text editor instead of xroar?

Perhaps another approach is to map the keys into the PC keyboard keys that give the correct result when keyboard translation is off in xroar?
Stew
wayland
Posts: 39
Joined: Mon Nov 28, 2022 6:28 pm

Re: Dragon keyboard conversion to USB HID

Post by wayland »

Yes, I've been keeping XRoar translation off and that means the ( and ) are above 8 and 9 as per the Dragon. Typing into a text editor shows the same keys as XRoar and @ comes up as " just the same.
I did have it doing @ by setting the Pico code to " for the AT key but that only worked in the text editor.
XRoar also accepts shift+0 as caps lock toggle but that's a function of XRoar and does nothing in the text editor.

I know I'm close to having this perfect.
wayland
Posts: 39
Joined: Mon Nov 28, 2022 6:28 pm

Re: Dragon keyboard conversion to USB HID

Post by wayland »

OK some progress with XRoar and the @ key problem. I've replaced

Code: Select all

KC.AT
with

Code: Select all

KC.QUOT
in the Python and added

Code: Select all

kbd-bind 'apostrophe'='at'
to the xroar.conf file

It works fine with XRoar because XRoar is doing that one little translation. It't not really true to Dragon hardware but the purpose of this is to make XRoar happy to read a real Dragon keyboard.

So success!!! 8-)
wayland
Posts: 39
Joined: Mon Nov 28, 2022 6:28 pm

Re: Dragon keyboard conversion to USB HID

Post by wayland »

Final code;

Code: Select all

# Dragon 32 Keyboard to USB Keyboard suitable for XRoar with translate OFF
#	Wayland
#
# Uses KMK Librarys for PI Pico.
# Uses Lee Smith's C64 PCB layout https://github.com/midicdj1000/RETRO-PICO-KMK-Keyboards
#
# The symbol keys do not actually return what's printed on them except in XRoar 
# which knows what they are supposed to do on the Dragon.
# 2023/04/15 Mostly working. Problems with some symbols, £ @ * =
# 2023/04/16 Works with XRoar. Everything except @ which comes out as "
# 2023/04/18 Finished for XRoar. All keys working.

import board

from kmk.kmk_keyboard import KMKKeyboard
from kmk.keys import KC
from kmk.scanners import DiodeOrientation
from kmk.modules.layers import Layers


print("Starting")
keyboard = KMKKeyboard()
keyboard.modules.append(Layers())
#C64 pcb
keyboard.debug_enabled = True
keyboard.col_pins = (
 board.GP8,#9
 board.GP9,#10
 board.GP10,#11
 board.GP11,#13
 board.GP12,#12
 board.GP13, #14
 board.GP14,#15
 board.GP15,#16
)
keyboard.row_pins = (
  board.GP26, #ok 0
  board.GP22,#ok 8
  board.GP20,#ok a
  board.GP16,#ok h
  board.GP17, #ok p 
  board.GP18, #ok xyz
  board.GP19, #6
  board.GP21,#
)

#keyboard.diode_orientation = DiodeOrientation.ROW2COL

#   Dragon 32 Matrix from Dragon schematic
#
#          LSB              $FF02                    MSB
#        | PB0   PB1   PB2   PB3   PB4   PB5   PB6   PB7 <- column
#    ----|----------------------------------------------
#    PA0 |   0     1     2     3     4     5     6     7    LSB
#    PA1 |   8     9     :     ;     ,     -     .     /     $
#    PA2 |   @     A     B     C     D     E     F     G     F
#    PA3 |   H     I     J     K     L     M     N     O     F
#    PA4 |   P     Q     R     S     T     U     V     W     0
#    PA5 |   X     Y     Z    Up  Down  Left Right Space     0
#    PA6 | ENT   CLR   BRK   N/C   N/C   N/C   N/C  SHFT
#    PA7 - Comparator input                                 MSB
#     ^
#     |
#    row


______ = 'NO'
# So that KC.QUOT = @  please start XRoar; xroar -kbd-bind 'apostrophe'='at' 

keyboard.keymap = [
    [	KC.N0,		KC.N1,		KC.N2,		KC.N3,		KC.N4,		KC.N5,		KC.N6,		KC.N7,
        KC.N8,		KC.N9,		KC.MINS,	KC.SCLN,	KC.COMM,	KC.EQL,		KC.DOT,		KC.SLSH,
        KC.QUOT,	KC.A,		KC.B,		KC.C,		KC.D,		KC.E,		KC.F,		KC.G,
        KC.H,		KC.I,		KC.J,		KC.K,		KC.L,		KC.M,		KC.N,		KC.O,
        KC.P,		KC.Q,		KC.R,		KC.S,		KC.T,		KC.U,		KC.V,		KC.W,
        KC.X,		KC.Y,		KC.Z,		KC.UP,		KC.DOWN,	KC.LEFT,	KC.RIGHT,	KC.SPC,
        KC.ENTER,	KC.HOME,	KC.ESC,		______,		______,		______,		______,		KC.LSFT,
        ______,		______,		______,		______,		______,		______,		______,		______,
    ],
 ]

if __name__ == '__main__':
    keyboard.go()
wayland
Posts: 39
Joined: Mon Nov 28, 2022 6:28 pm

Re: Dragon keyboard conversion to USB HID (XRoar)

Post by wayland »

I have some of the PCBs that plug into the Dragon keyboard connector that accept a PI Pico. Requires a 16 pin connector, a Pico and a Micro USB cable.
User avatar
robcfg
Posts: 1532
Joined: Sat Apr 04, 2009 10:16 pm
Location: Stockholm, Sweden
Contact:

Re: Dragon keyboard conversion to USB HID (XRoar)

Post by robcfg »

I got my mounted PCB from Wayland (thanks!) and had to check the code, but arrived at a nice configuration that allows full use on XRoar including the @ symbol without need to modify XRoar's config file.

Here it is for those interested:

Code: Select all

# Dragon 32/64 Keyboard to USB Keyboard suitable for XRoar with translate OFF
#	Wayland, Robcfg
#
# Uses KMK Librarys for PI Pico.
# Uses Lee Smith's C64 PCB layout https://github.com/midicdj1000/RETRO-PICO-KMK-Keyboards
#
# The symbol keys do not actually return what's printed on them except in XRoar 
# which knows what they are supposed to do on the Dragon.
# 2023/04/15 Mostly working. Problems with some symbols, £ @ * =
# 2023/04/16 Works with XRoar. Everything except @ which comes out as "
# 2023/04/18 Finished for XRoar. All keys working.
# 2023/06/29 Modified config so that it works with all keyboards and doesn't need
#            to modify XRoar's config to get the @ symbol.

import board

from kmk.kmk_keyboard import KMKKeyboard
from kmk.keys import KC
from kmk.scanners import DiodeOrientation
from kmk.modules.layers import Layers


print("Starting")
keyboard = KMKKeyboard()
keyboard.modules.append(Layers())
#C64 pcb
keyboard.debug_enabled = True
keyboard.col_pins = (
 board.GP8 ,#9
 board.GP9 ,#10
 board.GP10,#11
 board.GP11,#13
 board.GP12,#12
 board.GP13,#14
 board.GP14,#15
 board.GP15,#16
)
keyboard.row_pins = (
  board.GP26,#1
  board.GP22,#2
  # Note: Pin #3 is not assigned as it's the GND pin
  board.GP20,#4
  board.GP16,#5
  board.GP17,#6
  board.GP18,#7
  board.GP19,#8
)

keyboard.diode_orientation = DiodeOrientation.COL2ROW

#   Dragon 32/64 Matrix from Dragon schematic
#
#          LSB              $FF02                    MSB
#        | PB0   PB1   PB2   PB3   PB4   PB5   PB6   PB7 <- column
#    ----|----------------------------------------------
#    PA0 |   0     1     2     3     4     5     6     7    LSB
#    PA1 |   8     9     :     ;     ,     -     .     /     $
#    PA2 |   @     A     B     C     D     E     F     G     F
#    PA3 |   H     I     J     K     L     M     N     O     F
#    PA4 |   P     Q     R     S     T     U     V     W     0
#    PA5 |   X     Y     Z    Up  Down  Left Right Space     0
#    PA6 | ENT   CLR   BRK   N/C   N/C   N/C   N/C  SHFT
#     ^
#     |
#    row

# XRoar keymap
keyboard.keymap = [
    [ KC.N0,  KC.N1,   KC.N2,   KC.N3,   KC.N4,   KC.N5,   KC.N6,   KC.N7, 
      KC.N8,  KC.N9,   KC.MINS, KC.SCLN, KC.COMM, KC.EQL,  KC.DOT,  KC.SLSH, 
      KC.LBRC,KC.A,    KC.B,    KC.C,    KC.D,    KC.E,    KC.F,    KC.G, 
      KC.H,   KC.I,    KC.J,    KC.K,    KC.L,    KC.M,    KC.N,    KC.O, 
      KC.P,   KC.Q,    KC.R,    KC.S,    KC.T,    KC.U,    KC.V,    KC.W, 
      KC.X,   KC.Y,    KC.Z,    KC.UP,   KC.DOWN, KC.LEFT, KC.RIGHT,KC.SPC, 
      KC.ENT, KC.HOME, KC.ESC,  KC.NO,   KC.NO,   KC.NO,   KC.NO,   KC.LSFT
    ]
]

if __name__ == '__main__':
    keyboard.go()

Last edited by robcfg on Fri Jun 30, 2023 4:06 pm, edited 1 time in total.
Post Reply