Electronic – Arduino emulating a keyboard that has a demultiplexer

arduinokeyboardmultiplexer

I have a old typewriter which I want to automate with an Arduino. The way I am trying to do it is to replace its keyboard with the Arduino and make the Arduino emulate the keyboard i/o.

The keyboard of the typewriter is using a demultiplexer https://pdf.direnc.net/upload/74154-datasheet.pdf So the original keyboard setup has:

  • 4 pins mainboard outputs > demultiplexer input
  • 8 pins demultiplexer output > switches > mainboard inputs

My plan so far:

  • remove the keyboard (so also the demultiplexer) completely
  • the "8-pins" demultiplexer output > switches > mainboard inputs
    • replace them with Arduino digital INPUT pins > mainboard inputs
  • the "4-pins" mainboard outputs > demultiplexer input
    • replace them with mainboard outputs > Arduino analog INPUT pins
  • constantly read data from 4-pins
  • depending on their value (0001, 0101, 1011, etc) I would know which row is being "scanned" currently
  • if I need to type a character from that row – I would set an appropriate pin from the 8-pins to OUTPUT LOW and turn it back to INPUT after some milisecons *[1]

Where I am stuck:

  • If the previous are correct, it would mean that at any time that I "ping" any pin from the 8-pins, it should type on random character
  • What happens is – it types specific 6 characters depending on which one from the 8-pins I "ping"
  • Extra note: I can set for how long to "ping" the 8-pin and I have tried different values down to 1ms which does not trigger anything

Notes:

[1] The 8-pins being set to INPUT as initial state and being set to OUTPUT LOW for triggering, because of what is mentioned here https://arduino.stackexchange.com/a/31672/58139 in second paragraph

Update 1:

Instead of:

  • the "4-pins" mainboard outputs > demultiplexer input
    • replace them with mainboard outputs > Arduino analog INPUT pins

I now did

  • the "4-pins" mainboard outputs > demultiplexer input
    • replace them with mainboard outputs > Arduino DIGITAL INPUT pins

Because the values being read with analog input are not absolute at all, so I left the decision making regarding LOW/HIGH input on Arduino's digital input.

I created a sketch of the circuit, which can be found here https://drive.google.com/file/d/1_wD8KBaPlxmDAdlcpvnD1HFUdFOpWP84/view?usp=sharing

Y0 and Y8 connect to modifier buttons (like shift, bold, letter spacing, etc) and IIUC that's why they are also connected through diodes to mainboard input pins 2, 6, 10, 12, 14 and 16. Because the typewriter has "record and re-print" functionality, when it's being done – those modifier buttons are probably disabled so you can not invervene with styling options.

And some graphs of the input that I receive from the mainboard https://plot.ly/~artemkloko/1/

Regarding what phil-g commented, if you have a look at the graphs you will see that the enable pins are triggered rarely at (random?) moments.

Regarding what hacktastical answered, I think is on correct path. But I stuggle to detect the stobe.

Current situation:

I changed my timing library to a more precise one, and set the "input detection" timing to 0.1ms

So far I have managed to print random single character, but at totaly random momments by sending OUTPUT LOW of 1ms duration to a mainboard input pin. Usually it still prints 6 characters.

My current questions/problems:

  • How to detect / understand which of my inputs from mainboard signify the strobe?
    • Also regarding the strobe – in the bit sequence that hacktastical included in the answer, if the outmost right column leads to 6 buttons and one of them is pressed, wouldn't it mean that mainboard would detect LOW when row 0 is scanned, and HIGH all the other times no matter if stobbing or other row being scanned?
      • If the previous is correct, doesn't it mean that I should not care about the strobe? As that column will output 1 0 1 1 1 1 to specific mainboard input and all the other columns will not output anything to any mainboard inputs because their buttons are not pressed.
  • Since columns are connected to buttons and then to mainboard input, when no buttons are pressed, it means that no current is passed to mainboard inputs. So in this situation I am setting the Arduino pins to INPUT is order to act as disconnected. Does that sound ok?
  • My computation of the demultiplexer output shows that also Y10 – Y15 are being triggered quite often, but they are not connected to anything. So why the mainboard doesn't try to trigger only Y0 – Y9?

Best Answer

The demultiplexer is selecting the row. The select inputs probably run continuously, cycling through each row one-by-one. The E0/E1 inputs are probably pulsed so that the outputs show one low bit with a blank in between.

So you get a sequence like this from the mux:

1 1 1 1 1 1 1 1 - idle
1 1 1 1 1 1 1 0 - row 0
1 1 1 1 1 1 1 1 - blank
1 1 1 1 1 1 0 1 - row 1
1 1 1 1 1 1 1 1 - blank
1 1 1 1 1 0 1 1 - row 2

etc.

Seems like you have to do two things:

  • follow the row-scanning activity from the host. That is, watch the mux select state
  • output the column bit when the correct row ‘comes around’

If they’re strobing the row-select (as I suspect they are) you would also follow that, only outputting the column bit when the row bit is low, otherwise outputting all 1's for column.

As you have access to the mux inputs (4 bits, 16 rows) you can use them directly and reduce the number of Arduino I/O needed from 24 down to 12, or 13 if you need the strobe.