**If you just want to see this in action, skip down to [[The Self-Typing Typewriter#Let's see it already]].** **If you're interested in purchasing one, see [[The Self-Typing Typewriter#I want one!]]** Before screens, computers use teleprinters for input and output. These were basically self-typing typewriters. You typed a command, and the computer would type back. ![[Pasted image 20240808123230.png]] Teletype Model 33 ASR^[Photograph by Rama, Wikimedia Commons, Cc-by-sa-2.0-fr, CC BY-SA 2.0 fr, https://commons.wikimedia.org/w/index.php?curid=17821795] The goal of this project is to create a modern version of this. Imagine waking up to the sound of your IBM Selectric typing out the day's weather forecast, or punching in a question, and having ChatGPT answer back. I want it to look just like a normal typewriter, but when someone tries to use it, they have a surprising experience. So where do I begin? Well I need a typewriter first. I don't really know anything about typewriters, but I find this one and the price is right. A few days later it arrives on my doorstep. ![[Pasted image 20240808124808.png]] ## Reverse engineering the typewriter My first thought is to create something that interfaces with the existing circuit and emulates the keyboard. I'm hoping that I can both inject my own keypresses and eavesdrop for actual keypresses on the keyboard. So my first task is to understand how it works. ![[Pasted image 20240808125043.png]] Immediately, I get the sense that I actually have a shot at reverse engineering this thing. It looks simple! Most modern printed circuit boards (PCBs) have at least two layers--one on the top and one on the bottom. This one only has copper on the bottom and the top just has a few solid wire jumpers to make circuit layout tractable. Not having any hidden internal layers will make understanding this board much easier. ![[Pasted image 20240808132140.png]] Anyway, I start googling numbers printed on the circuit board and can immediately tell that the big IC in the center is a microcontroller made by Mitsubishi. The data sheet is easy to find. ![[Pasted image 20240808125429.png]] I recently watched Ben Eater's YouTube series on the 6502 processor (of Apple II fame), so I actually feel right at home reading through this retro processor's data sheet. I take some front and back pictures of the PCB and load them into my iPad to start labeling the traces with my stylus. ![[Pasted image 20240808132216.png]] There are a few basic things I want to figure out first. (1) What voltage level does it operate at? (2) How does the keyboard work and how does it interface with the microcontroller? The first question is pretty simple. I trace the wires coming from the power supply at the back of the typewriter and measure the output with my multimeter. It's 12 volts. The microcontroller runs on 5 volts though, so there must be a voltage regulator somewhere. I see the 12 volt trace is connected to what looks like a voltage regulator and sure enough the IC labeled L78LR05 (Q2) outputs 5 volts at a maximum of 150 mA. Moving on to the keyboard, I pop it open and see that it's just a flexible PCB with membrane switches. The traces on the keyboard terminate at 16 pins that connect to the main board (the connector is labeled "keyboard" in the images above). There are no active components. When a key is pressed, two of the 16 pins are shorted together. Most likely the IC implements standard keyboard scanning ([wiki](https://en.wikipedia.org/wiki/Keyboard_matrix_circuit)). ![[Pasted image 20240808132150.png]] Visually inspecting the traces on the PCB reveals that the 16 pins on the keyboard are divided into two groups of 8 pins. The first group goes to an input port on the microcontroller and the second group goes to an output port. A port on a microcontroller is just a set of pins that can be read from or written to. "Writing" just means setting the pin to 5 volts (high) or 0 volts (low), usually achieved by setting a register or special memory address. "Reading" works the same way, but instead it tests if a pin is set to high or low. So my hypothesis is the keyboard works like this: ![[Pasted image 20240809115452.png]] The input pins and output pins are the two sets of eight pins coming out of the keyboard, each labeled from zero to seven. Each line is a wire/trace on the flexible PCB. Imagine at each intersection there is a switch that shorts the column wire to the row wire. When the key is pressed, it closes the switch and causes a short. The microcontroller can detect closed switches by setting a voltage on an output pin and then seeing if it can detect that voltage on one of the input pins. If it can, then it knows the switch at the intersection of that column and row is currently pressed. What would make understanding this easier is if I could connect a scope to each of these pins while the typewriter is on and just watch what happens when I press a key. Sadly, I don't own a scope, but who needs fancy equipment when you have an Arduino Mega? I connect up the Arduino like this: ![[Pasted image 20240809120128.png]] ![[Pasted image 20240809120140.png]] I write a little program that monitors what's going on with the wires and sends the results over USB/serial to my laptop. Basically, my hypothesis is correct, and you can skip this paragraph if you don't care about the gory details. But here's how it actually works: the eight pins on the microcontroller's input port are pulled high with a pull up resistor. The output port starts with all pins high, and then one by one flips a single pin to low. It then reads from the input port to see if any of the input pins have been pulled low due to a key press. If any have, it can tell which key is being pressed. I press each key one-by-one and can construct this from the output of my arduino, which is a table that tells me which pair of pins corresponds to which key. | ↓ Input Output → | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | ---------------- | --- | --- | --- | --- | --- | ---- | -------- | ----- | | 0 | , | . | ½ | ; | [ | ' | Space | Shift | | 1 | / | ± | q | z | w | a | Ret | Cp Lk | | 2 | 1 | 2 | e | f | r | g | Index | Alt | | 3 | 3 | 4 | t | h | y | j | Reloc | | | 4 | 7 | 8 | o | s | p | d | Wrd Out | | | 5 | 5 | 6 | u | k | i | l | Bk Space | | | 6 | - | = | n | x | m | Open | Correct | | | 7 | 9 | 0 | v | c | b | Tab | Code | | The rest of this story is software. Getting it to type is pretty straightforward. I start by removing the keyboard entirely and just connecting the arduino straight to the main board's keyboard connector. ![[Pasted image 20240809122107.png]] Now suppose I want to type the letter "a", which corresponds to output pin 5 and input pin 1. My arduino waits for the typewriter to set its output pin low, and, when it does, the Arduino sets the corresponding input pin low. The microcontroller thinks those pins are getting shorted together, and it types an "a". I'm not done yet, though, because I still want the typewriter to function as a normal typewriter and I want the arduino to be able to read the keys being pressed. This is critical to making the typewriter interactive. How do I achieve this? Well the Arduino Mega has 54 digital pins, and I might as well use them, so I connect the keyboard to another 16 pins on the arduino in this arrangement: ![[Pasted image 20240809122041.png]] I then implement my own keyboard scanning and pass the key presses directly through to the typewriter, while also sending them out on the USB/Serial interface. There are also some fiddly bits: I need to implement debouncing, key repeats, etc. Finally, I replace my laptop with a raspberry pi running a python script and I have myself a self-typing typewriter. ## Let's see it already Here it is answering my questions. <div style="position: relative; width: 100%; max-width: 560px; padding-bottom: 56.25%;"> <iframe style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;" src="https://www.youtube.com/embed/njlShZE-i0Q?si=etA52xCes8wgruyl" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> </div> In that video, I'm still tweaking the timing between keypresses and newlines, which is why it feels a bit slow. And here it is acting as a clock. Every hour, it chimes out the hour by typing periods, and writes a poem about the time and weather. <div style="position: relative; width: 100%; max-width: 560px; padding-bottom: 56.25%;"> <iframe style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;" src="https://www.youtube.com/embed/nEeR5eDdFUw?si=aZqQUfAKxy80kWTu" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen ></iframe> </div> I've been trying to make the typing feel as human as possible. My goal is to make it sound like it's a person at the typewriter. In the second video, the pauses between keypresses are randomly distributed according to a poisson distribution, which I like. ## I want one! Right now this is held together with jumper cables and dev boards, but I'm working on refining this and perhaps offering a few for sale depending on interest. Right now I'm working on getting some PCBs fabricated. Given the custom nature of the project, I probably can't scale this up too much, but if there's interest, I could crank them out until I get bored. If you're interested, please fill out the google form [here](https://forms.gle/FBPkAQ8PEYwwtwSS8). ![[Pasted image 20240809141338.png]]