3

I know it's still used for many industrial microcontrollers but that's not what I am asking; I also know that it's quite slow. It's just that I hate seeing an unused port on my desktop pc, while all other ports (USB, Sata, PCIe...) are busy. So, please suggest me some creative use for a serial port, even through an adapter, just for fun.

Edit: Thank you for all the answers and comments. Some are very interesting, especially the audio-related ones. I'm sorry if this question is likely to attract "opinion-based" answers, but this is exactly what I was looking for with my open question.

17
  • 4
    I'm voting to close this question as off-topic because it's not about retrocomputing.
    – user722
    May 19, 2019 at 0:57
  • 3
    @DrSheldon Changing the intent of the question isn't an appropriate way to fix a question.
    – user722
    May 19, 2019 at 3:23
  • 4
    @DrSheldon Not all questions are fixable. Ultimately it's the original poster's job to fix the question to be on-topic. That's why off-topic questions are closed rather than immediately deleted.
    – user722
    May 19, 2019 at 3:31
  • 3
    @manassehkatz Well, that wasn't quite what the question was edited to ask. Either way though it would still leave the question too broad, which was the reason I was originally going to vote to close. The question also had two votes for being primarily opinion-based before I voted, which I think is an objection the word "creative". Given all the problems with the post I don't think it's worthwhile to try read the poster's mind here. It's really up the original poster to salvage the question, or perhaps find a better place to ask it.
    – user722
    May 19, 2019 at 4:02
  • 4
    I also think this question does not fit QA format for this site, as it is mostly opinion based (how do you evaluate which answer is the most creative use for serial port). However not downvoting nor flagging since the topic is highly interesting and relevant, also very entertaining
    – tuomas
    May 19, 2019 at 11:16

3 Answers 3

2

If you want to be very creative:

The serial port can be considered a 1-bit PCM stream (not 100% controllable, as you have at least 1 constant start bit from an UART, synchronous transmit would be better for this application). You could thus use the serial port for 1-bit audio. If you run it fast enough, you could probably achieve acceptable quality (Atari's TIA or the ZX Spectrum's sound output didn't work much differently).

2

GPIO

Handshaking lines (CTS, DTR, etc.) can be used as a status monitor for a simple boolean value (e.g., switch open/close) without transferring any "normal" data. However, I'm not sure (and can't research right now) where this has been done except in conjunction with data transfer (e.g., detect drop of CD to trigger port monitoring process reset/automatic logout). A little searching found this reference:

  1. Using the Modem status lines as GPIO

In addition to the Tx and Rx signals many UARTs provide modem signals that may or may not be used by the application. Console ports in my experience rarely use these additional signals so they can often be used for some other purpose, assuming they are available and routed to the connector. One thing they’re often useful for is general-purpose outputs for debugging and timing. There are two outputs: RTS, DTR, and 4 inputs: CTS, DSR, DCD, RI. The state of the inputs is read from a status register and the state of the outputs is set by writing to a control register.

In a 16550-compatible UART this is the Modem Status Register (MSR) and Modem Control Register (MCR) respectively. In an ARM PrimeCell UART this is the Flag Register (UARTFR) and the Control Register (UARTCR) respectively.

For example, if you need to time how long it takes to handle a particular interrupt, it’s easy enough to insert code that toggles the state of a modem output at the entry and exit of the interrupt handler. You can then measure the execution time easily on a scope.

The trick is finding where this has been done on retro systems.

1
  • 1
    This gadget, aw-el.com/60manual.pdf, had a Geiger counter tube whose output went through a simple pulse-shaping circuit, and connected to the RI (Ring Indicator) input pin on a PC's COM port. May 21, 2019 at 15:39
2

Well, slow is not really a thing. I remember we used PC COM ports as fast I/O as the speeds of the handshaking bits where faster than LPT ... The PC transmit speeds are limited to 115200 Baud but the control/handshaking lines are faster. Also on MCU you can have even 33 MBaud... Here are some PC based non traditional use for COM RS232 examples:

  1. PWM

    the transmitted data can be used as HW PWM generator with 8 or 9 levels. Simply transmit number with number of set bits equal to your wanted level... If you use RC filter or non linear load it will create a sort of DAC.

  2. sound

    as others suggested, you can use RS232 as a sound generator, even PCM. As the USART is buffering you can use it more comfortably without the need for accurate timing code making it much more easier and even faster in comparison to in build speaker. Take a look at this:

  3. signal generator

    the frequency of RS232 COM port on PC is driven by 16 bit divider from 115200 Hz. So if you continuously send alternating zeros and ones in binary (start/stop/parity bit included) then you have HW frequency generator...

  4. voltage generator

    This is wild stuff but I am using this for programming MCUs. as the RS232 protocol has +/-10V or +/-15V voltages you can use them as a source of power in applications that has just single voltage power supply like +5V or +3.3V without the need for voltage multipliers ... Simply use the TxD output from PC as AC power supply, so rectify it by diodes filter with capacitor and you have +/- 10V voltages ... Of course, to be able to work this way you need to be sending data from PC continuously and the load must not be too big. I usually use it for 3.3V/RS232 voltage converters (without MAX232)

    For example, today's MCUs have really small power requirements if used properly, so this can be also used to power MCU applications alone without the need for additional power supply. It can get handy time to time ...

The COM port on PC has one big advantage over other interfaces on Windows, and that is it does not require additional drivers for access. You simply open file with name COM1,COM2,... and that is it ... In comparison with USB LPT the SW implementation is much much much easier, free of charge and comfortable.

If it helps, here is my ancient COM example for MS-DOS in Borland Turbo C++:

//---------------------------------------------------------------------------
//--- Includy: --------------------------------------------------------------
//---------------------------------------------------------------------------
#include <iostream.h>
//----------------------------------------------------------------------------
//--- Global data: -----------------------------------------------------------
//----------------------------------------------------------------------------
typedef unsigned char byte;
typedef unsigned int word;
word far *memw=0x00000000;
byte far *mem=0x00000000;
char    key;
word    keyhi;

word    com;
//----------------------------------------------------------------------------
//--- I/O: -------------------------------------------------------------------
//----------------------------------------------------------------------------
void inkey()
    {
    key=0;
    keyhi=0;
    asm {
        mov ax,256
        int 0x16
        jz  esc
        mov ax,0
        int 0x16
        mov key,al
        mov keyhi,ax
        }
esc:
    }
//---------------------------------------------------------------------------
void inkeyw()
    {
    asm {
        mov ax,0
        int 0x16
        mov key,al
        mov keyhi,ax
        }
    }
//---------------------------------------------------------------------------
byte in(word adr)
    {
    byte    x;
    asm {
        mov dx,adr
        in  al,dx
        mov x,al
        }
        return x;
    }
//---------------------------------------------------------------------------
void out(word adr,byte x)
    {
    asm {
        mov dx,adr
        mov al,x
        out dx,al
        }
    }
//---------------------------------------------------------------------------
//--- com: ------------------------------------------------------------------
//---------------------------------------------------------------------------
void com_init(word x)
    {
    com=memw[(0x400>>1)+x-1];   // adr portu z DOS TAB 0000:0400h
    out(com+1,0);           // ziadne int
    out(com+3,3);           // 1 start, 8 data, 1 stop, 0 parity
    }
//---------------------------------------------------------------------------
void com_speed(word f)
    {
    word x,h,l;
    x=115200/f;
    h=(x >> 8) & 255;
    l=x & 255;
    x=in(com+3) & 127;
    out(com+3,x+128);
    out(com+0,l);
    out(com+3,x+128);
    out(com+1,h);
    out(com+3,x);
    }
//---------------------------------------------------------------------------
byte com_in()
    {
    byte s;
//  do s=in(com+5); while ((s&1)!=1);
    s=in(com+0);
    return s;
    }
//---------------------------------------------------------------------------
void com_out(byte d)
    {
    byte s;
    do s=in(com+5); while ((s&32)!=32);
    out(com+0,d);
    }
//---------------------------------------------------------------------------
//--- Subroutines: ----------------------------------------------------------
//---------------------------------------------------------------------------
void couthex(word x)
    {
    word    a,i;
    char    c;

    for (i=0;i<4;i++)
        {
        a=(x >> 12) & 15;
        x=x << 4;
        if (a<10) c=a+'0';
        if (a>=10) c=a-10+'A';
        cout << c;
        }
    cout << 'h';
    }
//---------------------------------------------------------------------------
//--- Main: -----------------------------------------------------------------
//---------------------------------------------------------------------------
void main()
    {
    asm {
        mov ax,3
        int 0x10
        }

    char    x=0;

    com_init(1);
    com_speed(1404);        // common i8051 / 24 MHz and PC USART frequency
    cout << "COM adress = "; couthex(com);  cout << endl;

    do      {
        inkey();
        x=com_in();
        couthex(x);
        cout << endl;
        } while (keyhi==0);


    cout << "COM adress = "; couthex(com);  cout << endl;
    inkeyw();

    }
//---------------------------------------------------------------------------
//--- End. ------------------------------------------------------------------
//---------------------------------------------------------------------------
4
  • Point #3 is simply not possible. The UART is in no way dependable on the PIT timer chip, which only drives the timer, the speaker and initially the memory refresh DMA (later replaced by better refresh methods). On PC:s the discrete UART chips were commonly driven by a separate 1.8432MHz crystal oscillator (115200*16), and later on integrated multi-IO controllers used single 24MHz for everything inside them, so in those systems UART clock was in fact sligthly different, 24MHz divided by 13 (a 0.16% difference).
    – Justme
    May 19, 2019 at 10:02
  • @Justme I am pretty sure I changed the baud rate generator frequency of USART on PC (x386) with 16bit divider so it matches common frequency with different devices. But you might be right it could be USART/UART separate clock instead of PIT it was a long time ago.
    – Spektre
    May 19, 2019 at 10:06
  • @Justme Yep youre right its not PIT just found my source in the archive ... reediting answer
    – Spektre
    May 19, 2019 at 10:15
  • Yes the baud rate divisor is internal to the UART.
    – Justme
    May 19, 2019 at 10:16

Not the answer you're looking for? Browse other questions tagged .