code

misc

Terminalscope Serial Console

February 2010

Jan might have created a cool scope terminal,
but I've done him one better. ;-) The Terminalscope is a full, bidirectional serial terminal
that uses a PS/2 keyboard for input and displays 54x24-character output on an oscilloscope or XY display.
It can be connected to a PC via USB-to-TTL adapter or directly to another microcontroller.

Two configuration profiles (stored in EEPROM) quickly selectable with an
external switch

Close-ups of the screen. Terminalscope is connected to a Linux box as a serial console.
More photos on flickr.

hardware

A great thing about the Terminalscope is its simplicity. Other scope projects
require an expensive DAC or an inaccurate R-2R ladder. Rather than draw each
character with individual strokes, op-amps are used to generate a raster scan
across the screen (like a TV) and the Z axis (beam intensity) is modulated directly
by the microcontroller.

Two op-amps are used as integrators
to generate the X and Y linear ramps. A high slew rate, single-supply chip like
the MC34074 works. (A TL3474 might work as well.) Since the op-amps are single-supply,
a 2.4V zener diode is used to create a virtual ground. To generate the positive-going
sweep for the X axis, a constant voltage slighly below virtual ground is fed into the
X integrator. (Remember, the output of an integrator is inverted.) To generate the
negative-going sweep for the Y axis, a constant voltage slightly above virtual ground
is fed into the Y integrator. The two trimpots controlling these voltages can be
adjusted to change the size of the image or even flip it. Due to the virtual ground,
the output of the integrators has a significant dc offset. To compensate for this,
large ac-coupling capacitors are placed inline with the X and Y outputs.

The video generation and serial communication is handled by an ATmega328P.
(1296 bytes of RAM are required for a 54x24 character matrix, but if you'd like
a lower-resolution display, an ATmega168 would work just fine.) The microcontroller
sends horizontal and vertical "sync" pulses to a 4066 quad bilateral switch;
closing a switch discharges the respective integrating capacitor, resetting the sweep.
Since the timing of the video generation is critical, the ATmega328P can't read asynchronous events
from the keyboard without mangling the picture. So an ATtiny45 is used to read the
PS/2 keyboard lines. It converts scancodes to ASCII values (and non-ASCII keypresses
to special values) and stores them in a queue. After the 'mega is done outputting
a frame, it pulls the typed characters out of the 'tiny's buffer over SPI.

software

The time-critical display routine is written in assembly language. The ATmega328P
outputs one pixel every 5 clock cycles. It runs at 20MHz, thus the pixel frequency
is 4MHz. Thus, your scope or monitor must have at least 4MHz of Z-axis bandwidth.

The rest of the code, including a fairly complete video library, is written in C.
It emulates "most of" a VT100; that is, enough escape sequences are implemented so
that Unix console applications display correctly. I've made the code available at
the bottom of the page, and it might be useful for anyone looking to implement their
own terminal. Escape sequence handling are pretty much a nightmare.

connecting to a linux box

With a USB-to-TTL serial adapter (I use the one made by SparkFun),
the Terminalscope can be connected to a computer. In Linux, you can talk to it using
screen, like this:

screen /dev/ttyUSB0 38400

(assuming the adapter is at /dev/ttyUSB0 and the Terminalscope is set at 38400 baud,
8 data bits, no parity, 1 stop bit.) If you want to give Terminalscope a login process,
so you can shell into your machine from it, you'll have some configuration files to tweak.
In Ubuntu (Karmic and newer), paste the following into /etc/init/ttyUSB0.conf:

You can now start the login process with the command sudo start ttyUSB0.

One last thing. When you log in, Linux will think the terminal is 80 columns wide
(it's really 54) and will assume it supports UTF-8 (which it doesn't). To fix this, you
should add the following to your .bash_profile (assuming you use bash):

making your own

Be warned if you're going to make your own: your mileage may vary.
A big XY monitor will probably work better than an oscilloscope. I haven't been
able to get a clean picture on my Tektronix 464, but there may be something wrong
with its Z axis. Some things to note:

Due to the large ac coupling capacitors, the image will take a few seconds
to position itself on the screen. It's probably possible to eliminate the dc offset
with more op-amps, but this seems to be simple and good enough. I considered a dual-supply
design using an ICL7660 to get -5V, but it generates ripple on the negative rail that's quite
noticeable at these low voltages.

You might have to add RC networks to eliminate noise on the lines. I put
a trimpot in series with each signal lead to eliminate ringing artifacts.
(This has something to do with transmission lines, but honestly I don't know much
about that stuff. It was mainly trial and error.)

If your display has a positive-blanking Z axis input, and the picture is inverted,
(dark characters on light background) you can use the configuration menu to
reverse the image.

The receiving of characters from the USART is still interrupt-driven, so
the display will probably jump a bit when a character is received. I think it's
"good enough" the way it is, but you're welcome to modify the software to poll the USART.

code

The code is on GitHub and is released
under the msarnoff.org license. Includes
a Makefile for avr-gcc. The firmware for the ATtiny45 keyboard buffer is in the
keybuffer/ folder, and the display font (as well as a Ruby script to
create your own font from an ASCII .pgm image) is in the fonts/ folder.

Feel free to use parts of it in other projects; I've written a fairly complete
escape sequence parser that might be useful for other terminal projects. The code
is released under the "do whatever you want with it, but if you make something
cool, let me know and give me credit" license.

photos

schematic

pcb

The Terminalscope is now officially off a breadboard and on a PCB. It's a dual
layer board, but the top layer is entirely a ground plane. The circuit would
probably fit fine on a single-sided board. Here are some things I've noticed:

The three 10k trimpots are actually not needed at all on the PCB. They are just
set to 0 ohms. I'd guess it's because the BNC connectors provide the necessary impedance,
and the parasitic capacitance present on the breadboard is no longer there.

It actually works with my Tektronix oscilloscope. The image is very faint, though.
An XY monitor is still your best bet.

The X and Y sizes are derived directly from ground and the supply voltage. This means
that any fluctuations in the supply will cause the image to bounce. It's not really
an issue with a regulated power supply.

I haven't tried powering it over USB yet, though current draw doesn't seem like
it would be a problem. (As long as you don't connect a beast of a keyboard like a
Model M!)

The power and signal connector is just a 4-pin header. For ease of connection to a
PC, I should have used the 6-pin FTDI connector (for easy connection to a
SparkFun
FTDI Basic Breakout, which I don't have.)

Aside from that, it's not too bad for a first prototype. If you want to make your own,
download the following: