DL1416SmarTerm LED Computer/Terminal

Old and new come together for an old school intelligent terminal.

Similar projects worth following
This project came about for three reasons. I had resurrected a old hall-effect keyboard (, a friend at my local hackerspace had given me several tubes of an old intelligent LED display and others there who were part of the retro-computing scene and reminded me of the joy that personal computers gave in the early days. I decide to combine the keyboard and intelligent displays into a terminal that would be used with the retro-mainframe. I remembered that the IBM 5100 "Portable Computer" had a switch on it that allowed selection between BASIC and APL programming languages and I decided my terminal would also support a paddle switch selecting between fundamental operating modes.

The DL1416SmarTerm is a mishmash of various old and new components that presents itself as either a VT102-ish compatible terminal or a Tiny Basic computer both using a 12 line x 48 character LED display. It gets its name from the intelligent LED module its based around.

The Siemens DL1416B is an 8-bit parallel write-only device that can display 64 ASCII characters from a built-in ROM on its 17 LED segments. It also supports a cursor that can appear, non-destructively, over any character position. Five of these displays were used on the Rockwell AIM 65 computer for a 20-character display. I decided to take a modular approach to building the terminal display by putting 4 display modules on a board controlled by a local micro-controller (16 characters). I chose the Microchip PIC16F1459 because I had experience with it and it could support both a CDC-class USB serial interface as well as a TTL serial port. It didn't have enough pins to drive data, address and control to the display so I used a pair of shift registers. The boards are designed so that they can be daisy chained via the TTL serial signal.

My friend had given me 213 displays so I decided I'd design for a 64 character by 16 line display which was at the low end, but common for some devices in the 1970s. Each board could be strapped for one of 4 column positions and one of 16 line positions. Firmware running on the PIC keeps track of the cursor position across the entire display and only updates its displays if it "owns" the cursor. The firmware also interprets several control characters for special functions and an escape sequence for cursor positioning.

I ordered parts for the full display and had a nasty surprise when I started assembling and testing. A couple of the tubes of displays contained nothing but bad parts. I had expected some fallout but now had no-where near enough displays to build the full 64 x 16 screen. I tried to disassemble a display but the entire thing was potted and there was no way to fix anything. So after testing all displays and discarding the completely dead ones and the ones with bad segments, the project was scaled back to 12 lines of 48 characters each. An additional complication was that the displays came in 7 different brightness grades. I tried to disperse them in a gradient across the display. Visually the result is ok although the different brightnesses are more apparent in photographs.

During firmware test, I found an error in the spec. It claims that the cursor position is controlled by the address lines but I found that I had to put a bitmask on the data lines. Later firmware testing revealed a few bugs related to cursor updating on a bunch of boards in parallel but overall it was fairly quick to get the displays up and running.

We used the shop-bot at Solid State Depot to route a piece of plastic to hold the displays in an array and also provide access to the ICSP programming port (for which I was thankful because I did one firmware update after all the displays were assembled together).

Next up was starting to assemble an enclosure. I decided to try to use only materials I had or I found at the hackerspace which turned out to be HDPE plastic. The motor controller for the shop-bot got damaged so I ended up hand cutting and routing. One interesting thing was having to deal with static electricity. I ended running a strip of conductive tape around both the terminal and keyboard enclosure and tying it (at least in the computer) to ground. I ordered a cut piece of transparent red plastic for the front bezel. A pair of old paddle switches and neon power indicator rounded off a look that I hope is reminiscent of the plastic and mod looks of machines from the 70s.

I choose a PJRC Teensy 3.1 as the brains of the device since it had plenty of RAM and 3 serial ports in addition to the USB host port. One serial port was dedicated to the DL1416B displays and keyboard. A second as a host RS232 port and the third as a printer RS232 port. I put an op-amp...

Read more »


The original BSD Unix banner program. Feast on the glory of two hand-crafted font tables and c-code machinations.

C Source File - 71.26 kB - 10/29/2018 at 00:20



ELIZA listing - how programs used to be distributed!!!

Adobe Portable Document Format - 680.11 kB - 02/10/2018 at 21:39


Eagle files for DL1416B board.

Zip Archive - 323.08 kB - 11/05/2016 at 20:08


Microchip MPLAB-X project for DL1416B display board. Uses C compiler.

Zip Archive - 794.77 kB - 11/05/2016 at 20:07



Scan of Siemens DL1416B specification.

Adobe Portable Document Format - 224.41 kB - 11/05/2016 at 20:06


  • Virtual Hosts and BSD banner

    Dan Julio10/29/2018 at 00:18 0 comments

    Ever since including a printer with this project, I've been interested in somehow having the system able to print out old-school banners on the printer.  My BSD-derived Mac still has the program (type "banner" in a terminal).  Over the last couple of years I have been showing the computer at various shows and exhibits and have created a demo version of the firmware that does stuff like reset itself to a known state and display inviting information after a period of inactivity.  Recently I also introduced the idea of "virtual host" programs into the firmware.  The feature is intended to make it possible to have programs run locally and interface to the built-in terminal emulator as though it was connected to some external system (without having to have an external system).  I moved the Eliza module over to the new system and then went out search for the source to banner which I found in an online repository of an ancient version of BSD unix (which I can't seem to find again as I write this).

    Porting it was fairly straightforward.  As discussed in the wiki article about the program, the original program (included in the downloads section) is a pretty big hack with two hand-crafted tables of font and index information.  It expects to run as a command line program outputting directly to stdout.  I had to change it into cooperative multitasking process interfacing with the printer buffer in the main firmware (and relearning - yet again - about buffer management and flow-control...).  I ended up having it load all the lines for one character at a time and waiting for a token passed through all the buffers to be returned by the printer (via my serial_to_parallel sketch that interfaces the parallel-port printer to the computer's serial output).

    The virtual hosts are now selected via the terminal's configuration menu.  Code for anyone who is interested is in github (dl1416SmartTerm_demo).

  • Sound, ELIZA and bug-fixes

    Dan Julio02/10/2018 at 21:35 0 comments

    An opportunity to show the computer in a local maker show provided incentive to make some changes.  All code and documentation changes are in the github repository.  I finally finished adding sound capability by using the Teensy Audio library to provide three new Tiny Basic commands: DRUM, NOTE and WAV.  DRUM and NOTE use the 'drum' and 'waveform' library functions and WAV allows playback of a 44.1 kHz .wav file loaded from the SD-Card.  WAV playback occurs in the background allowing the program to continue.  The PLAYING? command allows a program to see if a wav file is currently being played.  In addition a few bugs were fixed, UPDIR and DNDIR were made to be operable inside a program (to make it possible to store sounds in a different directory than the Tiny Basic program was run from) and Autorun functionality was enabled (Tiny Basic will execute a file called "AUTORUN.BAS" if it exists when it boots).

    I also added a bottom panel with speaker connected to the internal LM380-based amplifier connected to the Teensy DAC output.

    I toyed with the idea of leaving a Raspberry Pi connected to the terminal input but figured that was asking for trouble in a public installation.  Since the exhibit was stressing the "retro" nature of this computer I had the idea of running ELIZA and after exploring a bunch of ways of getting it running settled on porting the Creative Computing BASIC version (listed included here in files section) of it to C running directly on the Teensy replacing the Terminal's serial communication.  In effect, the terminal is connected to a process running Eliza.  

    The code can now be compiled with the "DEMO_MODE" compiler directive to include Eliza.

    Perhaps the C port of Eliza might be amusing to include in your own project.  It should be fairly easy to adapt by providing your own versions of the TB_TX_AVAIL, POP_TB_TX, TX_RX_FULL and PUSH_TB_RX macros.  

  • Tiny Basic V1.0

    Dan Julio11/06/2016 at 05:06 0 comments

    The idea of writing a BASIC interpreter seemed overwhelming so I immediately hit search. There are a lot of BASIC interpreters/compilers out there but the one that was an initial perfect fit was Scott Lawrence's version of Mike Field's port of Tiny Basic. It ran on an Arduino (albiet, barely) and it looked easily modifiable (which turned out to be true). I started by just getting it to run on the Teensy 3 instead of an Arduino. Then I made a simple port for it to communicate with my terminal code via a pair of FIFOs. Eventually I started adding commands and a more sophisticated interface.

    As of this post it runs the commands documented below. Based on feedback from fellow hackerspace members, I will change the PCHR command to a set of CHR and ASC functions to more closely match early BASIC environments. Beyond this device, I think both the terminal code and the Tiny Basic interpreter could be combined with a new library, perhaps using DMA, on the Teensy to drive NTSC/PAL or VGA displays with commonly available PS2 or even USB keyboards.

    Input can come from keyboard or any of the serial interfaces (e.g. USB host IF) to load programs from a host computer using a terminal emulator. Output may be directed to any serial interface as well as the display (e.g. to save programs via a terminal emulator). Tiny Basic communicates to the outside world through a set of virtual (or physical) serial ports. The local keyboard and display appear to it logically as a terminal (and can be interacted with using escape sequences if desired).

    Each line must have a numeric line number (e.g. 10, 20, 30…). Commands may be separated by the colon character (‘:’) on a single line. Commands which immediately goto another line (GOTO, RETURN) cannot have subsequent commands on the same line. Each command is stored as an ASCII representation in memory (no tokenization).

    There are 26 variables, A-Z. Each variable is a 16-bit signed number (-32768 to 32767). Variables or literal numbers may be used in expressions.

    Tiny Basic provides 32 Kbytes of program memory. Variables and the stack live at the high end of program memory and the program starts from location zero. The MEM command returns how many bytes are available for program code. DATA@, PEEK and POKE can access the entire range but not outside of the program memory (e.g. other DL1416SmartTerm memory in the Teensy address space). There is room for 8 nested FOR loops on the stack or more GOSUBs in this version of Tiny Basic.

    The EOT key is used as BREAK to stop execution of a Tiny Basic program.

    File names follow the 8.3 rule (a maximum of 8 filename characters and 3 file type characters which should be .BAS for Tiny Basic programs). This version of Tiny Basic is limited to 16 levels of directories on the SD card.


    • BYE - exits Basic, soft reboot of Tiny Basic
    • END - stops execution from the program, also "STOP"
    • MEM - displays memory usage statistics
    • NEW - clears the current program
    • RUN - executes the current program
    • LIST [start line number [, end line number]] - list to end with one line number argument or range between two line numbers to current OUTDST mask
    • HLIST [start line number [, end line number]] - list only to host ports
    • PLIST [start line number [, end line number]] - list only to printer port
    • CLS - clear screen
    • INSRC mask expression - sets input (keyboard: bit 0, usb host: bit 1, serial host: bit 2, printer port: bit 3) defaults to keyboard + usb host (1 + 2 = 3). Be careful to not lock yourself out.
    • OUTDST mask expression - sets output (screen: bit 0, usb host: bit 1, serial host: bit 2, printer port: bit 3) defaults to screen + usb host (1 + 2 = 3)
    • REBOOT - reset computer (deletes current program)
    • HELP - list commands and functions

    File IO/SD Card

    • FILES - lists the files on the SD card
    • LOAD filename.bas - loads a file from the SD card
    • CHAIN filename.bas - equivalent of: new, load filename.bas, run
    • SAVE filename.bas - saves the current program to the SD card, overwriting
    • ERASE filename.bas - delete...
    Read more »

  • V1.0 Terminal Functionality

    Dan Julio11/06/2016 at 04:38 0 comments

    I started the project without any clearly defined goals for the terminal functionality other than it had to scroll. I wanted a terminal to connect to a nebulously defined future computer project but was stuck with testing with modern computer...which still speak to command line environments with ANSI escape sequences. Why not emulate the classic computer terminal progenitors then? I started with the VT100 but soon found I liked the additional features that DEC added with the VT102 such as the ability to support printers and more efficient editing capabilities. This meant a lot of escape sequence decoding. I ended up wading through a lot of websites describing various ANSI escape sequences but finally found as the best source. Obviously I couldn't deal with commands to change the font or font-size so I ignored those but I tried to deal with everything else and I added a couple of escape sequences from more advanced terminals that supported some function (like cursor blink) that my display could also support. I tested my code using both a Raspberry Pi running Raspian and my Mac OS X laptop. Interestingly the OS X system wanted a much more modern set of ANSI escape sequences even when I thought I told it to limit to the old VT102 set. I ended up adding code to ignore entire classes of escape sequences such as "Operating System" types. My main test was bash shell interactivity and the vi text editor. I used a diagnostic mode in my code to dump the incoming stream to the USB serial port so I could see what the terminal had seen when the display didn't match what I expected (which, at least at first, was a lot). It was entertaining if nothing else. A lot of modern code thinks nothing of sending the same escape sequence multiple times in a row.

    Ultimately for my first go-around I ended up with the following control character and escape sequence "command set" for the terminal. I made the conscious decision not to support all the control characters in the same way DEC terminals did to match some more "stupid" terminals that I had run across over the years.

    Control Characters Implemented
         CTRL-C                           EOT - Break command for Tiny Basic (ignored in Terminal mode)
         CTRL-G                           BELL - sends BELL to keyboard (rings keyboard bell)
         CTRL-H                           BS - backspace cursor
         CTRL-I                           TAB - forwardspace cursor to next tab position (default values: 1, 2, 4
                                                or 8 positions, configurable)
         CTRL-J                           LF - Linefeed character (moves cursor down one row; may also
                                               be configured to include a CR)
         CTRL-K                           VT - Vertical tab (moves cursor up one position) (**)
         CTRL-L                           FF - Formfeed (clear screen) (**)
         CTRL-M                           CR - Carriage return (moves cursor to start of line; may also
                                               be configured to include a LF)
         ESC (*)                          Escape - starts escape sequence
         DEL                              Delete - backspace cursor, deleting character first (**)
          *  The EOT key on the keyboard is treated as an Escape in terminal mode and a CTRL-C
             (break) in Tiny Basic mode.
          ** These control characters are not VT100/ANSI compliant.  They exist for compatibility with
             other, more primitive, terminals.
    ANSI Sequences Implemented (numeric arguments in decimal ASCII notation are contained with <>)
         ESC[;H                           Cursor Position
         ESC[;f                           Horizontal and Vertical Position (same as Cursor Position)
         ESC[A                            Cursor Up
         ESC[B                            Cursor Down
         ESC[C                            Cursor Forward
         ESC[D                            Cursor Backward
         ESC[s                            Save Cursor Position
         ESC[u                            Restore Cursor Position
         ESC7                             Save Cursor Position, origin mode and cursor attributes (*)
         ESC8                             Restore Cursor Position, origin mode and cursor attributes (*)
         ESC[J                            Erase Down
         ESC[1J                           Erase Up
         ESC[2J                           Erase Display
         ESC[K                            Erase End of Line
         ESC[1K                           Erase Start of Line
         ESC[2K                           Erase Line
         ESC[L                            Insert Line
         ESC[M                            Delete Line
         ESC[P                            Delete Character
         ESC[c / ESC[0c / ESCZ            Query Device Attributes (responds with VT102 ESC[?6c)
         ESC[5n                           Query Device Status (responds with Report Read, no malfunctions ESC[0n)
         ESC[6n                           Query Cursor Position (responds with Report Cursor Position ESC[;R)
    Read more »

  • DL1416B Display Module (PCB) Command Set

    Dan Julio11/06/2016 at 04:08 0 comments

    The DL1416 display firmware running on the PIC16F1459 takes input data from either the USB Interface or a TTL-level Serial input. The USB Interface appears as a CDC Class communications device to the host PC. The TTL-level Serial input runs at 57,600 baud. The DL1416 echoes all incoming serial data from either the USB or Serial input to a TTL-level serial output for connection to subsequent display boards.

    ASCII characters are displayed directly. Lower case letters are converted to upper case letters by the display.

    Some control characters and sequences have special meaning and can be used to control the display or the cursor position on the display.

       ^H - Backspace : backspace cursor on same line (no change at position 0)
       ^I - Tab : forward space cursor
       ^J - Line Feed : move cursor to next line (no change on last line)
       ^L - Form Feed : clear display
       ^M - Carriage Return : move cursor to position 0 on the current line
       ^N - Shift Out : set destination to shadow memory
       ^O - Shift In : set destination to display
       ^Q - DC1 : enable cursor (applies only when destination is display)
       ^R - DC2 : disable cursor (applies only when destination is display)
       ^S - DC3 : enable cursor blink (applies only when destination is display)
       ^T - DC4 : disable cursor blink (applies only when destination is display)
       ^V - SIDLE : Display firmware version
       ^Z - Substitute : Load shadow memory
       DEL - Delete : Change previous character to a blank and backspace
       ^[ - Escape : Set Cursor Position
          COL;ROW'H'  (special case: 'H' set to home (0,0)

    The display has two memories. ^N and ^O control access to the two memories. The default memory is immediate display mode. Any received character data is immediately displayed. The second memory is called shadow memory and writing to it does not immediately change the display. ^N sets the destination to shadow memory. ^O sets the destination to immediate display mode. ^Z copies the shadow memory to immediate memory and updates the display. Two sets of cursor positions are maintained, one for each memory.

View all 5 project logs

Enjoy this project?



Mitsuru Yamada wrote 01/15/2021 at 08:27 point

It's a great terminal !. I didn't know that you made your own terminal until now. I made a terminal with 5x7 dot matrix LEDs.

  Are you sure? yes | no

Dan Julio wrote 01/15/2021 at 16:50 point

Thank you Yamada-san.  Your terminal is very cool as well!  And I appreciate your build techniques.  Very smart.

  Are you sure? yes | no

Mitsuru Yamada wrote 01/15/2021 at 23:31 point

Thank you for your reply and liking my #6802 Serial Terminal . Your 12x48 = 576 character LED display is amazing. My 4x24 = 96 characters could be made into a small stand-alone terminal, but I would like more characters for practical use.

  Are you sure? yes | no

TinLethax wrote 12/18/2017 at 11:24 point

Where did  you get them all !

  Are you sure? yes | no

Dan Julio wrote 12/19/2017 at 20:00 point

I was very lucky.  A generous friend from my local hackerspace had them and gave them to me after his storage space burned down.  They weren't damaged but he didn't want to store them again and thought I might be able to make use of them.

  Are you sure? yes | no

davedarko wrote 11/06/2016 at 10:42 point

Duuuude, that's a small fortune in LED displays!

  Are you sure? yes | no

Yann Guidon / YGDES wrote 11/06/2016 at 11:49 point

Duuuuuuuuude yeah...
But that's the price to pay for a vintage flat display :-P

  Are you sure? yes | no

davedarko wrote 11/06/2016 at 12:21 point

and still better than storing them in a drawer like I do :D I have 10 of these beauties, well 10 of the DL1414s, but still.

  Are you sure? yes | no

Dan Julio wrote 11/06/2016 at 16:47 point

Yeah, it was a helluva gift. Didn't seem right to just sell them off.

  Are you sure? yes | no

Yann Guidon / YGDES wrote 11/06/2016 at 16:54 point

A gift ??? You have really awesome friends :-D

  Are you sure? yes | no

ziggurat29 wrote 11/07/2016 at 04:22 point

yeah, save them to fund retirement.  or at least a /really/ nice vacation.

213; crazy.  I myself am down to 6, which is terrible because I love them so much that I can't bring myself to kiss them goodbye in actually using them in something....

  Are you sure? yes | no

Alain Mauer wrote 11/05/2016 at 21:51 point

I love this DL1416B displays, great project.

  Are you sure? yes | no

Dan Julio wrote 11/05/2016 at 21:59 point

Thank you.  I was worried - and took some guff before it was finished - how the final display would look because of the spacing between lines but it's surprisingly readable and useful.

  Are you sure? yes | no

Alain Mauer wrote 11/05/2016 at 22:18 point

Sometimes trying something gives surprising results, like my last project. And even if it does not work like it should, we have learned something :)

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates