PIC 16C84 VT-52 Emulator for Linux

A project to make an interactive front panel
mounting (drive bay) LCD display with selection buttons.

vtpic02.jpg (4365 bytes)


Please Note!:

I don't sell these devices - this project is described here for the budding enthusiast!



If you have read the other pages on this site you'll know that I've got a Linux machine on a shelf in my room that provides all sort of useful services. It's got no monitor or keyboard, and sometimes this can be annoying. What I wanted was a small display that I could check on that state of the machine and perform some useful actions - like a controlled shutdown, mount or un-mount devices - that type of stuff.

I like electronics and a few years ago began experimenting with Microchip's PIC16C84. I bought five of these devices for a knock down price and so I'm now putting them to use. The '84 isn't the best tool for the job as it lacks a UART, this is no big deal really - it just makes the software on the PIC more interesting.

lcdfnt.jpg (7469 bytes)

Work Outstanding

Just some fine crafting in the Linux daemon driver, nothing much else.


Problems and Limitations

Reading RS232 is quite a CPU intensive operation for the '84 as you must poll and sample the RS232 waveform in software in order to determine the whole byte. As soon as the PIC detects that a transmission is on its way it uses CTS to inform the host device not to send any more data until it is ready for more. This gives the PIC enough time to control the LCD or perform other in house tasks. Unfortunately there is a problem with this. 16550A PC serial port chipsets under Linux send 8 bytes then see if the remote device can handle any more. If you use this PIC on one of these serial ports only every 8th byte is correct, the rest are corrupt because they were sent while the PIC wasn't ready. The solution to this problem is fortunately very easy to fix. You need to tell Linux to control the serial port like an old style 8250 that had no fancy buffers. So.

setserial /dev/ttyS1 uart 16450

will fix this problem on Linux, I'm not sure about other Unix's.

Because of the polled serial reading it is possible for the start bit to arrive while the PIC is in the middle of the interrupt routine to poll the buttons. A corrupted byte (or two) is likely to be read. This doesn't happen very often, if fact I've not seen it happen yet - but it's statistically likely to happen. The solution to the is to use a real UART or a PIC with a UART. I've recently made some adjustment to the code to tighten the timing up, it's now very unlikely to get corrupted characters.

What needs changing or fixing when you build the next version?

  1. Button repeat in the PIC code.
  2. Use round buttons to match the round holes!
  3. The display does not scroll, I'd need an extra control line to the LCD to do this which with the current PIC I don't have. However, there are ways to get round this by multiplexing the LCD data lines with the buttons.
  4. Full duplex using a lower baud rate, and that should eliminate the need for hardware handshaking. 2400 baud might be OK...


What VT-52 codes does it understand?

ESC E Clear display and reset cursor to top left.

ESC T not a VT code. This is something I've put in that displays a test pattern, used to check the RS232 output serial code in the PIC.

ESC H Resets the cursor to the top left, but does not clear the display.

ESC Y Position the cursor, format of the command is ESC Y (32+Y) (32+X) so ESC Y !! sets the cursor to 1,1.

Cursor visible.

ESC f Cursor off.

That's it, there isn't very much point implementing the rest, some code are impossible to do with the LCD anyway - like inverse video and colours.

What does the PIC code do?

The pic code is responsible for reading the RS232 signal, generating RS232, polling the buttons and converting the received VT-52 commands into the native format for the LCD display.

What does the Linux driver software do?

Briefly speaking the daemon does the following:

  1. Sets the serial port to hardware handshaking and the right baud rate: 19,200 baud.
  2. Waits for button presses and launches a controlling shell script to perform the required actions.

This code is very simple, especially when compared to the PIC code. The daemon driver will spend most of it's time idle just waiting for characters to become available on the serial port. The buttons on the front of the LCD are arranged in the following way:

    1  LCD  3
    2  LCD  4

There are a couple of functions available that are fairly useful - one is the ListSelect() function. Pass this a string of '\n' delimited text and it will construct a list box style display. If the text is too long to fit the software will scroll the text left to right (and back again) so you can see it all. Here is an example:

vtpic03.jpg (3375 bytes)

You use button 3,4 to scroll up and down, 2 to select the line and 1 to abort. The function returns the line number selected.

This ListSelect() function worked so nicely, I even have an MP3 player!

vtpic04.jpg (3373 bytes)

So next project will be the PSU to run a PC in the car...

How's it put together...?

I nolonger use a 5.25" to 3.5" drive converter bay to mount the controller PCB. Instead, a thin sheet of aluminium was bent to fit the rails inside the PC's case; which is fastened to the sides of the controller module. This leaves sufficient room to mount a disk drive behind the LCD.

lcdback.jpg (7991 bytes)

back1.jpg (8382 bytes)

back2.jpg (8614 bytes)


Serial cable

You need a null modem cable wired in the following way. The PIC uses CTS to tell Linux when to send data, but the PIC doesn't use any flow control back to the PC. We're using 9 pin D connectors here...

CD   1 --+           +-- 1   CD
         |           |
DTR  4 --+           +-- 4   DTR
         |           |
DSR  6 --+           +-- 6   DSR

RX   2 -----\     /----- 2    RX
              \ /
TX   3 -------/ \------- 3    TX

RTS  7 -----\     /----- 7   RTS
              \ /
CTS  8 -------/ \------- 8   CTS

Which is a pretty standard null modem cable.


Circuit Diagram

Quickroute doesn't seem to have any switches for PCB design so they are shown here as "Push", they should pull the PIC pins low when pressed.

vt52_cir.gif (13370 bytes)


PCB Boards

I decided to break the boards into two, one is the front mount display with the LCD and 4 buttons, while the PIC and power is delivered from the other. The push buttons are now connected through the IDC connector this is not clear on the above schematic - just in case you were wondering.

vt52pcb1.gif (5071 bytes)
View from above.

Front panel display PCB, holds the LCD, 4 buttons and pull-up resistors. Notice that the LCD screw hole is too close to the data line tracks. I had to work round this by using a nylon washer.

vt52pcb3.gif (13899 bytes)
View from above.

Main board, holds 9 Way D connector, MAX232, PIC and IDC connector to font panel PCB.



You must agree to the following statement before downloading and using this software:

You should understand that the code made available here must only be used for educational and non commercial purposes, as such, no warranty is provided for the suitability and functionality of the software. The software is provided free without technical support, and therefore you agree to use it entirely at your own risk.

PIC Code:

PIC code: Version 1.0b

Linux Daemon:

Linux gcc code: Version 0.1 - Still unfinished - you will need to make considerable modifications to this code to suit your needs.


LCDProc Home Page
Andrew McMeikan LCD Project


Last updated: 23rd January 2000