An electronic typewriter transformed into a serial terminal

[todo FOTO]


In this document I describe the project in which I modified an electronic typewrites to that it will function as a serial printer or a serial terminal. [todo WIDEO]


There was the typewriter SHARP PA-3000H in our house. In the year 2013 I had the first idea to do something with it. At that time I was a student of electronics in the Wrocław University of Technology.

My thought was: "Why should it only print what is typed on the keyboard? It would be much cooler if a computer could tell it what to print." And then: "The typewriter always obeys the keyboard. What if I cheat and make a device that pretends to be the keyboard?"

So I decided to make a device that does exactly this. Instead of the real keyboard I would make a device that simulates key presses.

I used the MSP430F1232 microcontroller connected to the computer through the RS-232 interface and some logic gates connected to the typewriter in place of the keyboard.

(the page in the typewriter was not printed by the typewriter.)

It could print the characters that are present on the keyboard and additionally the Polish characters ĄĆĘŁŃÓŚŹŻąćęłńóśźż. The Polish characters where encoded as in 8859-2 or CP1250 (there is no collision).

I showed it at university, got a grade for it, and then I left it unfinished, for later. Until finally in 2022 I decided to finish this project and do it properly.

Goals and requirements

This time I wanted more than just print some characters from the computer. My requirements were:

Keyboard operation

The typewriter has an M50747-2A8SP microcontroller which is connected to the keyboard matrix as shown below.

The assignment of what is a row and what is a column on a keyboard matrix is arbitrary. I decided to call the P0 (CN5) outut pins "rows" and the P2 (CN6) input pins "columns". Also the numbering of the rows and columns is my arbitrary choice. The key numbers are in base 8.

The typewriter is scanning the keyboard in a sequence shown below.

Keyboard interface circuit

This is the circuit to interface between the typewriter and its keyboard.

This circuit requires some explanation.

I have unsoldered the connectors CN5 and CN6 from the typewriter. Instead I added horizontal "goldpin" connectors to which I connect my board. The original connectors are installed on my board so that the keyboard connects directly to it. My device consists of a main controller ATmega1284 and some 74HC gates.

The P0 port of the M50747 is its keyboard output. Originally, the "row" signals would go through diodes to CN5 and then to the keyboard. I have removed the diodes and replaced them with wire. Instead I installed the diodes on my board. This allows to connect the signals not only to the keyboard but also to other things. And so the signal is connected to the port A of the ATmega1284 so that it can know which row is active at each time.

"After" the keyboard the "column" signals would go to CN6 and from there to port P2 of the M50747. There they are also connected to pulldown resistors. I replicated the pulldown on my board and connected the signals to a 74HC244 instead. This allows to connect or disconnect the signals to CN6, thus enabling or disabling the typewriter's keyboard. The "column" signals are also connected to port C of the ATmega1284 so that it can know on which column a key press is detected.

There are 54 keys on the keyboard. But there is no need to add 54 transistor switches to simulate every possible key press. With the exception of 2 special keys only 1 key at a time is used for typing. The 8 "row" signals go into the 74HC151 multiplexer. From there the signal for only 1 row goes out, selected by 3 address bits controlled by pins B3, B4, B5. It goes into the 74HC238 demultiplexer from which it goes to 1 of the 8 column signals, selected by 3 address bits controlled by pins B0, B1, B2. The enable inputs of the 74HC151 and 74HC238, connected to pin D5, allow the signal to go through or not, thus simulating pressing or releasing the key.

There are 2 special keys which can change the meaning of other keys, SHIFT and CODE. These are routed separately through AND (7408) and OR (7432) gates, controlled by pins B6 and B5. Together with the multiplexing this simulates the entire keyboard.

As with the real keyboard, also the simulated keyboard is not connected directly to CN6 but through the 74HC244. This allows to enable or disable the simulated keyboard.

The +5V power supply is taken from pin 1 of CN5. The ground is taken from unpopulated jumpers JP1, JP2. The (caps lock) LED is connected through the 7708 AND gate so that it will turn on if either the P10 pin on the M50747 or D5 on the ATmega1284 is in the low state.

The 7408 and 7432 are on a separate small board because of a design mistake which I made. Instead of making a new board from the beginning again I fixed it by only making a small adapter to install the 2 chips into the socket dedicated for a single chip.

Serial interface circuit

This is the serial interface circuit

The SP3232 chip is used as the level converter.

Should the terminal be a DTE or DCE device? By definition, a terminal should be a DTE. But a computer is also a DTE and expects a DCE at the other end of the cable. So I added 2 connectors: a DB-23 for the DCE interface and a DE-9 for the DTE interface.

There are more control signals than the SP3232 can handle. On the DTE interface I completely ignored the RI and DCD signals. The DTR is always asserted, meaning the terminal is always "ready" and only the RTS is used for flow control. DSR and CTS are merged into 1 signal such that both must be asserted or disconnected to register as a single asserted signal. A very similar design is for the DCE interface.

Software design

In a most general overview the software is made of multiple single task engines connected by pipelines. Data is entering on one side, gets transformed while going through it and leaves on the other side.

Keyboard scanning

The row and column signals are sampled at about 6kHz. If

then the previous sampled column signal is checked.

Some debounce is performed through multiple iterations to check if in next repeats of the same row still the same columns are active. If the signal is stable for 30ms (3 full scans) and is correct (only a single column active, not counting the special keys CODE and SHIFT) an event is generated and sent further. After 700ms the event will be repeated every 120ms as long as the keyboard signal stays the same.

The key press event consists of a single byte which identifies the key pressed. Lowest 3 bits encode the column number, next 3 bits encode the row number, the highest bits encode the state of the special keys SHIFT and CODE.

Keyboard decoding

The key presses have to be converted to actual characters. This is the layout I have chosen:

On a key the top part represents SHIFT pressed and right part represents CODE pressed.

The main goal behind this choice was to keep all characters at their original positions and add new ones in the places that make the most sense. So \ | was added to Ü, [ { was added to Ö, and ] } was added to Ä. The characters ĄĆĘŁŃÓŚŻŹ were added to their "base" characters with 2 exceptions: Ź was added to Y (where on QWERTY keyboards is the place for Z), because Z was already occupied by Ż. uppercase Ś was added to D instead of S because of the keyboard matrix layout. Pressing CODE+SHIFT+S makes the machine also detect the K and the typewriter ignores it. Also other keys in columns 1 and 3 are unavailable for such combinations.

The key code (8 bit value) is used as an index in a keymap table which stores the values for each key. There is a separate keymap for each of the supported character encodings. For single byte encodings the decoded value is an 8 bit number which goes straight to the serial output queue. For UTF-8 the decoded value is a 16 bit number which gets converted to a sequence of 1 or more bytes in the UTF-8 encoding.

Some key combinations have special functions and are handled separately instead of being converted by the keymap. This is described in a later chapter related to the menu and settings.

The "ESC" key sends the code 0x1B (Esc). Pressing a normal key afterwards is the equivalent of pressing the key with ALT on some terminals. The "CTRL" key changes the code of the next pressed key by performing a logical AND with the value 0x1F on it. This is the equivalent of pressing the key with CTRL on some terminals.

Serial communication

to do to do