Capturing data from a Tektronix 1230 logic analyzer by emulating a parallel port printer

5.00 avg. rating (94% score) - 1 vote

UPDATE: Refer to my latest article for a full review of the Tektronix 1230 logic analyzer.

As a fan of vintage test equipments such as oscilloscopes and logic analyzers, I sometimes encounter the problem of extracting data from these machines onto external devices for storage or further analysis. While some of these old devices allow saving data to floppy drives or feature serial or GPIO ports and associated protocols to communicate with PCs or other devices in order to extract measurement data or capture screenshots, many other devices only support printing data in hard-copy to parallel or serial printers, which are hard to find nowadays. Recently while working with an old Tektronix 1230 logic analyzer, I spent some time tackling this problem and this article will share some of the achievements I have made and other interesting findings.

The device

I acquired this Tektronix 1230 from eBay, a vintage logic analyzer in the 1980s but still useful for troubleshooting old 8-bit designs. The following photos show the logic analyzer, with a Centronics parallel port and a DB25 RS-232 port at the back:

A word of warning here for those intending to collect this vintage equipment. Make sure that your 1230 comes with probes (also known as pods) – you will want the P6444 or P6443 16-channel probe. Probes can be hard or expensive to purchase separately. It should also preferably come with RS-232 or Centronics ports for data output.

The challenge: transferring captured data

My challenge came when I wanted to export the capture data from this logic analyzer. Although it has a RS-232 port supporting up to 9600bps, communication with the device requires the S43R101 1230/PC application software made by Tektronix. During my research, a serial protocol for custom-made application to work with the logic analyzer via the serial port seems to be available and documented in the manual. Unfortunately, I could never locate a copy of the manual or the application software for this device available for download, apart from this information sheet. There is, however, plenty of information on the Internet for the Tektronix 1240, a later model. Extracting data via the serial port therefore seems infeasible.

The only other way is to print data via the Centronics parallel port. Although I do not have any parallel port printer nowadays, a thought suddenly came across my mind that I might be able to program a PIC microcontroller to act as a parallel port printer and save the output data to an SD-card for further actions. Well, as they say, thoughts are dangerous and within minutes I found myself soldering wires to a DB25 parallel connector to interface the logic analyzer with a PIC24FJ64GA002 microcontroller.

The Centronics printer protocol

This is the Centronics parallel port pinout:

Attempting this project requires knowledge of the Centronics protocol used for communication with parallel port printers, described in details on this page. For our purposes of emulating the parallel port printer. we will only need to care about the ACK, STROBE, BUSY signals and the D0-D7 lines. In the simpler polled mode of the Centronics protocol on a standard parallel port, the host (referring to the logic analyzer in our case) would send a pulse on the STROBE line to indicate it’s going to send printing data. After that, the printer (or the PIC microcontroller in our scenario) will need to set the BUSY line high while at the same time reading for an input byte from the D0-D7 lines. When processing is completed, the printer will send a pulse on the ACK line and set the BUSY line low, indicating it is ready for the next command. The process is illustrated in the following timing diagram:

To indicate that the emulated printer is available and ready for printing, Paper End (pin 12) should be connected to GND while Error (pin 15) and Select (pin 13) should be connected to 5V.

Result: a PIC-based virtual parallel port printer

Using the ST7735 1.8″ color LCD (see my previous post) and the Microchip SD card library, I was able to build a working virtual printer. The device would listen for data being sent from the parallel port and save the print job to a .PRN file on the SD card. The following photos show the printer in action:


The 1.8″ LCD shows the SD card volume label, file system type, total capacity and free space. The name of the file containing the last print job is also displayed on the LCD. 

As the PIC does not understand the data being sent and simply writes the data received on the SD card, there is an issue of telling when the print job finishes in order to start a new output file. On a real printer, the printer would detect the paper feed command and eject the page when a page has finished printing. In my case, I have chosen a simplified approach – assume that printing has ended and close the output file if no data is received after a certain period, e.g. 5 seconds. This would be sufficient for most purposes.

Reading the printer output

This emulated printer should work well with any application expecting a generic parallel port printer. It may not work if the application is expecting a specific modern parallel port printer model, in which case customized identification data might be sent via the parallel port in ECP or EPP mode to communicate with the application. For a simple test, executing the DOS command DIR > LPT1 or DIR > PRN with the printer connected to the LPT1 port should result in a .PRN file containing the list of files and sub-directories in the current directory being written to the SD card.

On the Tektronix 1230, printing can be done by double-pressing the NOTES key (to print a screen capture) or by pressing the D key (to print memory contents), as described in the help screen:


While pressing D will print the memory contents in text format, double-pressing the NOTES key (supported only on Epson-compatible printer) will print a graphics representation of the current screen. Although printing of memory contents will not hang the logic analyzer and the printer status will be displayed as “Printing”, the logic analyzer will stop responding while the screen is being printed.  Also during my experiment, if the status lines on the Centronics parallel port report conflicting information, the logic analyzer will refuse to boot up with the POWER indicator turned off, making it seem as if the device is dead. Removing the parallel cable and the unit will power on just fine. This seems to be a bug in the device firmware.

The screen print output, as captured by my virtual printer, is in binary format and contains Epson escape codes. A quick inspection of the output file and comparison with the Epson escape codes documentation shows that only 4 escape codes are used:

  • ESC 65 and ESC 50 – set line spacing
  • ESC 108 – set left margin
  • ESC 42 – select bit image for graphics printing

I quickly managed to write a tool which converts the output escape codes back to a 450×250 bitmap file:

A check-box “optimize for printing” is provided. If checked, the output will be black-on-white (instead of green-on-black) and can be printed using a normal printer. The printout after conversion looks like below:


With the virtual PIC-based printer and the escape code converter tool, I am able to copy data from the logic analyzer to my PC for other purposes.

Replacing the RTC batteries 

As with other old electronics equipments, I needed to replace the 3V batteries which keeps the device clock and and settings. The 1230 is using two CR2330 3V batteries for this purpose:

The notice near the batteries reads, ‘CAUTION: REFER BATTERY REPLACEMENT TO QUALIFIED TECHNICIAN’. Am I a qualified technician? Well, at least not from the administrative perspective – I am not certified by Tektronix to open up this device! Would there be any implications if I am not? Are there any specific instructions to be performed before the battery is replaced or must the batteries be replaced in a specific order to avoid loss of data? Unable to find any information on this on the Internet, I proceeded to replace nevertheless and the logic analyzer still seems to be working well ever since. 

Interestingly, although the time settings on this device allow years between 1900-2099, the year would jump back to 1914 even if 2014 is selected after a reboot, indicating some sort of Y2K issues. The rest of the date and time remains correct. The day of week also needs to be selected manually and is not calculated automatically like many other devices. This was probably done to save precious code space for other stuff, or perhaps the algorithm is too complicated to be implemented on a Z80 processor (used by most Tektronix logic analyzers of this generation) efficiently.

Downloads

The source code of the printer and the bitmap converter tool can be downloaded here:
MPLAB 8 PIC24FJ64GA002 project for the virtual printer
Bitmap converter for Tektronix 1230 Epson printer output

Read my other article for a full review of the Tektronix 1230:
Tektronix 1230 Logic Analyzer

The following Youtube videos provide useful information on operating this logic analyzer:
Tektronix 1230 training (part 1)
Tektronix 1230 training (part 2)

Some interesting reverse-engineering information on the Tektronix 1240, a later model:
Repairing and understanding a Tek1240

5.00 avg. rating (94% score) - 1 vote
ToughDev

ToughDev

A tough developer who likes to work on just about anything, from software development to electronics, and share his knowledge with the rest of the world.

22 thoughts on “Capturing data from a Tektronix 1230 logic analyzer by emulating a parallel port printer

  • December 11, 2014 at 6:09 am
    Permalink

    It is possible to only send the received print data to uart interface?
    If possible it will be usefull to make parallel to serial converter without TFT and SDCard module.

    Regards.

  • December 11, 2014 at 12:18 pm
    Permalink

    Hi,

    Yes, it is possible with just a few additional lines of codes! You can simply reuse the existing UART interface which i already initialized for debugging purposes and add another call to sendUART() to send a byte via that UART interface whenever data is received from the parallel port. This way you do not need the SD card and can use a terminal program on the PC to capture the data into a file instead.

    Let me know if you have any other questions or can think of any good use for this project :)

    Cheers.

  • December 11, 2014 at 8:55 pm
    Permalink

    Great, so I just need to add :
    // write the data to SD card
    unsigned char sendBuffer[] = {PORTB >> 8};
    size_t written = FSfwrite (sendBuffer, 1, 1, pointer);
    //send to UART
    sendUART(sendBuffer);

    And then all data that received from parallel will transfered to serial?
    I will try that later when finishing my PIC24F prototype board.

    Thanks..

  • December 11, 2014 at 8:58 pm
    Permalink

    Hi,

    Effectively yes – your proposed modification will send the received data via UART. Remember to comment out the part that reads/writes to SD card, otherwise it may fail if you don't connect any SD card.

    Let me know if you manage to get it to work.

  • December 11, 2014 at 10:03 pm
    Permalink

    Yes, thanks. I will comment out the SDCard function.
    For UART, I see you are using RB2 for Ack and RB3 for Strobe.
    But for initializing the UART is using RP2 for RX and RP3 for TX that use same pin as RB2 and RB3.
    I'm new on PIC so I don't know how to use that.

  • December 11, 2014 at 10:15 pm
    Permalink

    Hi,

    I checked the code. The UART module was not used in the final code which I shared in the article as it's intended for debugging purposes only and was eventually not used due to the lack of available pins on this small PIC. You can see that the call to function InitUART() is commented out as the pins for UART was used for the SD card as you mentioned.

    To use back the UART module for output, you will need to remove the SD card connections to have some available pins. Then you can check inside function initIO(), uncomment the part which calls InitUART() and modify the pin assignments to use other pins for the UART module. For the RX pin, just set RPINR18bits.U1RXR to the # of the pin which you want to use for UART RX and modify TRISB to enable that pin as an input pin. For the TX pin, you will need to check the datasheet and find out the correct peripheral register and set it for the pin that you want to use. Or just play around with RPORxbits.RPxR until you get no compile errors :)

    Let me know how this goes :)

  • December 12, 2014 at 4:58 am
    Permalink

    I was try to build with commenting out the SDCard function and set RP4 for TX and RP5 for RX without error, I will see are the code is working when my PIC24F was arrived.
    And are you sure you are using RB7 to RB15 for data line? because the parallel is only D0 to D7, so the RB15 is not used?
    Also I dont really understand with this code :
    unsigned char sendBuffer[] = {PORTB >> 8};
    what {PORTB >> 8} function do?

    Thank you very much for your technical sharing..

  • December 12, 2014 at 8:28 am
    Permalink

    Hi,

    You're welcome, hope to see you get it working. What device are you planning to test the parallel port interface with?

    I check the code. You were right, there was a typo in the comments for the connections of the parallel port, RB8-RB15 are used for the data input, not RB7-RB15. I have fix the typo and reupload the code to prevent confusion. The rest of the code should still be working fine and not affected.

    For this line of code:

    unsigned char sendBuffer[] = {PORTB >> 8};

    It declares a char array named sendBuffer that has 1 element, hence the character { } for array declaration in C. The PORTB variable reads the data from PORTB, which is a 16-bit number. Because the parallel port are connected to RB8-RB15 (higher 8 bits of PORTB), we need PORTB >> 8 (right bit shift operation) to remove the lower 8 bits in order to get the value that we want.

    The above code is needed because the original FSfwrite function to write to the SD card requires an array input. To write a byte to UART, you can just use

    unsigned char dataByte = PORTB >> 8;
    sendUART(dataByte);

    Let me know if you have any other questions. :)

  • March 25, 2015 at 6:42 pm
    Permalink

    Hi MD,
    I need some sugestion, I have PC/Cashier connected to POS printer using parallel mod.
    When I printing to POS printer I also need soft copy using UART like discussed before.
    What do you think about that?
    What pin that i need to override to synchronize (ack, busy) so I can print the data to POS printer also can save the soft copy via UART

  • March 25, 2015 at 11:10 pm
    Permalink

    Hi TJ,

    You may want to use a parallel port splitter (not a switch) to split the original parallel from the Cashier PC to 2 parallel ports, one connected to the original POS printer and the other one connected to the custom device described in this post.

    You would only need to connect the data pins (D0-D7) and the strobe pin from the parallel port to the emulated printer. The ACK and BUSY pins should not be connected as it is already connected to the POS printer. From there you may want to use the project as-is to store the captured data onto an SD card, or modify it to transfer the captured data via UART to another computer/device.

    As mentioned in the previous comments, all pins of this PIC have already been used for the SD card, LCD and parallel port, so you may need to disable some of these existing peripherals and free some pins to be used for UART. You may want to try to remove the SD card connections (and the associated init functions) and replace them with UART function.

    Feel free to ask if you have any other questions. Let me know your progress.

    Cheers!

  • August 29, 2015 at 12:34 pm
    Permalink

    Hi MD,

    Regarding data converter EpsonToBitmap, is it possible to convert the data into ASCII Text format instead of bitmap. ?

  • August 29, 2015 at 12:36 pm
    Permalink

    Hi MD,
    Regarding data converter EpsonToBitmap, is it possible to convert the data into ASCII Text format instead of bitmap. ?

  • August 29, 2015 at 12:45 pm
    Permalink

    Hi,

    The logic analyzer prints in graphics (except for memory dumping which will be in text), so it is not possible for the data converter EpsonToBitmap to convert to ASCII – it can only save the graphics as bitmap file. On the other hand, if you perform a memory dumping, the output will be in text and can be read directly using any text editor after removing the printer control characters (line feed, formatting, etc.)

  • February 20, 2016 at 6:05 am
    Permalink

    hello
    i have a tektronix 2212 and i wonder
    could this work on this type?

  • February 20, 2016 at 6:08 am
    Permalink

    could this work on a tektronix 2212

  • February 21, 2016 at 7:10 pm
    Permalink

    Hi,

    The project emulates a parallel port printer and captures the output onto an SD card. If the host (e.g. logic analyzer or your oscilloscope) prints in text (for example, memory dump), you can simply view the output with any text viewer on your PC. If the host is printing in graphics, it could be a bit tricky to make sense of the binary output. The tool in the article assumes that the printout is meant for Epson-compatible printers at the time (e.g. late 80s) and converts it to a bitmap assuming that the printout was done using Epson escape code. So if your 2212 oscilloscope supports Epson-compatible printer, it will most likely work. You can check your oscilloscope settings to see if there is an option to change the printer type to Epson. If not, it may be possible to pass the produced binary file to a PC tool such as DOSPRN (http://www.dosprn.com/) and see if it could produced any useful graphics output.

    Let me know if you manage to get it to work.

  • May 8, 2016 at 7:34 am
    Permalink

    you know all scopes i have only output epson formats
    so i guess i am lucky

  • May 8, 2016 at 10:17 am
    Permalink

    So did you manage to get it to work? :)

  • June 18, 2016 at 11:00 pm
    Permalink

    Hi MD,
    I've found your page very interesting and would like to do the same to replace an old printer…. I need your help to connect the dots, I'm not a specialist so I can't fill the gaps…
    I understand that you use a PIC24FJ64GA002 and ST7735 but could you be more detailed about the connections between the pic and the db25 and display ?
    What kind of board do you use for the pic ? Will something like this work http://www.microchipdirect.com/ProductSearch.aspx?Keywords=DM240013-2 ?

    Thanks

  • June 20, 2016 at 12:35 pm
    Permalink

    Hi,

    Thanks for your comments. I did not use any commercial board. The entire project is soldered by hand. Nothing particularly difficult, it's just the standard development board connections for the PIC24FJ64GA002 using the internal oscillator. Most of the pins on the PIC are connected to the DB25 port for data/status input. The remaining pins are used to control the LCD module for display output and to write the data captured to the SD card for opening on the PC. The detail pin-to-pin connection are listed down as comments in the main.c file

    I couldn't open your link. However I do not think you need any special boards. Just use a stripboard/veroboard and spend some time soldering the wires :)

    Let me know if you have any other questions.

  • July 10, 2018 at 3:25 am
    Permalink

    Hi there this is a great project idea!

    I know it’s been a while but do you know if it is needed to interface the printer 5V logic using any 3.3V/5V logic level conversion. Following your comments on the latest post it seems you connected the PIC24FJ64GA002 pins direct to the 25-way, but wouldn’t this be harmful to the I/O pins that aren’t 5V tolerant?
    – thanks for any advice.

  • ToughDev
    July 10, 2018 at 10:24 am
    Permalink

    Hi, i did not use any level converter and just connected the pins directly. Most digital input pins on the PIC24FJ64HA002 (and many other similar PIC24X by Microchip) are 5V tolerant, which means they can accept 5V (5.5V to be exact) with no issue. See the datasheet for details http://ww1.microchip.com/downloads/en/DeviceDoc/39881e.pdf

    As for output, although the voltage is only 3.3V by default, the output pins can be configured into open-drain (high impedance) mode. With this configuration, if you connect a pull-up resistor around 10K to 5V to the output pin and set the output to 1 (digital high), the effective voltage at the output will be 5V due to the pull-up resistor. I used this to interface the PIC24 with 5V components.

    If the IC you’re interfacing with has a low voltage threshold for digital 1 (e.g. 2.5V), you might not even need the pull-up resistor and just connect directly, as the 3.3V output of the PIC24 will be enough to register as a digital ‘1’. The pull-up resistor is still needed for other components, e.g. parallel port input pins, which might need as high as 3.5V to register as ‘1’.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>