RS-232

From Noah.org
Revision as of 02:02, 11 May 2014 by Root (Talk | contribs) (stty)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

RS-232

RS-232 is the serial communications protocol that won't die. It's been around since the 60's.

RS-232 is also known as RS232, RS-232-C, RS-232-D, EIA-232, TIA-232E, TIA-232-F -- and even V.28/V.24. These standards are not identical, but RS-232 will get you close to what you want. In theory, the RS-232C standard only specifies the signaling, not how you actually wire it up. The pinouts given in this article are common.

The RS-232C standard requires the transmitter to use +12V (0, logic low) and -12V (1, logic high). The receiver needs only see over +3V and under -3V. Most transmitting ports use only +5V and -5V. Those levels are compatible with most devices and host computers. Maxim is one of the more popular suppliers of RS-232 level shifters or level converters.

DE-9 pinout (AKA: D-sub9, TIA-574, DE-9, DB-9, and DB9)

diagram of a DE-9 connector

Technically this connector is called a D-sub 9 or a DE-9, but it is often incorrectly referred to as a DB-9. The D refers to the shape of the connector. The E specifies the size of the connector shell. I'm not sure why you couldn't just get that from the number of pins, but whatever...

DE-9 (DB-9) connector
facing you
 1 2 3 4 5
  6 7 8 9

DB-25 pinout

diagram of a DB-25 connector

The D specifies the shape of the connector. The B specifies the size of the connector shell. Note that DB-25 may carry two RS-232 lines, but this is rare.

DB-25 connector facing you
 1   2   3   4   5   6   7  8   9  10  11  12  13

  14  15  16  17  18  19  20  21  22  23  24  25

5-wire RS-232

This is the most common RS-232 connection wiring. It consists of data and hardware flow control lines: TxD, RxD, SGND, RTS, and CTS.

pins 3,2,5,7,8 on DE-9
pins 2,3,7,4,5 on DB-25

line DE-9 pins DB-25 pins
TxD 3 2
RxD 2 3
SGND 5 7
RTS 7 4
CTS 8 5

3-wire RS-232

A minimal 3-wire RS-232 connection wiring. It consists only of TxD, RxD, and SGND. You see this a lot in embedded systems.

pins 3,2,5 on DE-9
pins 2,3,7 on DB-25

line DE-9 pins DB-25 pins
TxD 3 2
RxD 2 3
SGND 5 7


DE-9 (DB-9) connector
facing you
 . R T . G
  . . . .

RS-232 DB-25 to DE-9 pinout table

DB-25
DE-9
line
description
direction
DTE is the computer
DCE is the device
1

shield
ground shield

2
3
TxD
Transmit Data
OUT: DTE -> DCE
3
2
RxD
Receive Data
  IN: DTE <- DCE
4
7
RTS
Request To Send
OUT: DTE -> DCE
5
8
CTS
Clear To Send
 IN: DTE <- DCE
6
6
DSR
Data Set Ready
 IN: DTE <- DCE
7
5
SGND
signal ground
< - >
8
1
DCD
Data Carrier Detect
 IN: DTE <- DCE
9




10




11




12




13




14




15




16




17




18




19




20
4
DTR
Data Terminal Ready
OUT: DTE -> DCE
21




22
9
RI
Rind Indicator
 IN: DTE <- DCE
23




24




25




Common speeds

   110
   150
   300
   600
  1200
  2400  3000 feet
  4800  1000 feet
  9600   500 feet  "This is the most commonly used speed."
 19200    50 feet
 38400
 56000
 57600
115200 

Auto Baud Rate detection -- ABR

Some systems use a convention to automatically determine baud rate. This is known as Auto Baud Rate detection, or ABR. This is uncommon, but it is useful to know about in case your serial device supports it. Most ABR systems are primitive and working by sending a predetermined character such as carriage return or U (0b01010101) until the other side responds favorably.

Linux serial port device names

Linux knows of several types of serial devices. Some devices are not true RS-232 devices in terms of signal levels, but they are the same at the bit level.

True RS-232 serial ports on the machine will have sequentially numbered device names like /dev/ttyS0 and /dev/ttyS1.

USB-to-RS-232 adapters that implement the USB standard CDC-ACM device class will have sequentially numbered names like /dev/ttyACM0 and /dev/ttyACM1.

USB-to-RS-232 adapters that use the FTDI chipset will have sequentially numbered names like /dev/ttyUSB0 and /dev/ttyUSB1.

using screen as a serial terminal

Screen makes a very good RS-232 serial terminal. You can connect a screen window to any serial device in /dev (see #Linux serial port device names).

The communication settings are a comma separated list of control modes as would be passed to `stty`. See the man page for `stty` for more info. The most common settings are 8N1 (8-bits per character, no parity, and 1 stop bit). The most common speeds are 9600, 19200, 115200 baud. The serial console on a lot of network equipment uses 9600 baud. A lot of people like to run serial consoles at 115200 because it makes the terminal feel more responsive and zippy. The downside of using this speed is that 115200 can be noisy. I usually settle on 19200. It's good enough and gives a more more reliable and consistent connection. 9600 baud is the most common default speed used in a lot of networking and server equipment. This speed is just barely tolerable for editing with vi or watching displays being updated periodically from tools like `top` or `kismet`.

Old, slow-speed serial devices usually like 9600 8N1 (9600 baud, 8-bits per character, no parity, and 1 stop bit):

The Coyote Point E450si load balancer manual calls for the following settings:

screen /dev/ttyS0 9600,cs8,-parenb,-cstopb,-hupcl

*9600 baud
*8 data bits
*no parity
*one stop bit
*VT100 terminal emulation
*ignore hang-ups (if supported); this allows a single terminal session to continue running even if Equalizer restarts.

These settings are for the serial console of an embedded computer board (115200 8N1):

screen /dev/ttyS0 115200,cs8,-parenb,-cstopb,-hupcl

The following defines a Bash shell function to simplify `screen` startup. Put this in your .bashrc.

serial () {
        SPEED=${1}
        SERIAL_DEVICE=${2:-GUESS}
        if [ -z "${SPEED}" ]; then
                echo "You must specify a speed as the first option."
                echo "Common speeds are:"
                echo "    300 9600 19200 38400 57600 115200"
                return 1
        fi
        if [ "${SERIAL_DEVICE}" = "GUESS" ]; then
                if [ -c /dev/ttyUSB0 ]; then
                        SERIAL_DEVICE=/dev/ttyUSB0
                elif [ -c /dev/ttyS0 ]; then
                        SERIAL_DEVICE=/dev/ttyS0
                else
                        echo "Could not find a serial device."
                        echo "Tried /dev/ttyUSB0 first, then /dev/ttyS0."
                        echo "Specify the serial device as the second option."
                        return 1
                fi
        fi
        SCREEN_OPTS="${SERIAL_DEVICE} ${SPEED},cs8,parenb,-cstopb,-hupcl"
        screen -t "${SCREEN_OPTS}" ${SCREEN_OPTS}
}

Linux serial TTY communications -- stty

This section shows various ways to watch the serial ports to see what is going on with the signals.

stty

This demonstrates how to set speed, character size, parity, and stop bits on a serial port.

The example is based on a Geiger Counter shell script I wrote. I like Linux. You can interface to a GM-45 Radiation Detector and log ionization events using only a shell script. This is hardly even a shell script. It's just a couple commands;`stty` is used to setup the serial port; and a shell loop is used to log date-time stamps when a byte is available on the serial port. Each ionization event prints a date-time stamp. A beep or click is played using the `amixer` and `beep` commands (remove those lines if you don't have `amixer` or `beep`).

stty -F /dev/ttyUSB0 raw ispeed 57600 ospeed 57600 cs8 -ignpar -cstopb -echo
# Print the speed:
stty -F /dev/ttyUSB0 speed
# Print GM-45 ionization events (log as irregular time series events):
while true; do read -n 1 serial_byte < /dev/ttyUSB0; date --utc "+%C%y%m%d %H%M%S UTC"; done
# Here is a 'click' Geiger counter. The first command makes sure the "beep" device is not muted.
# This also shows an alternate way to read the serial port with the `dd` command.
amixer -q set "Beep" 50% unmute
amixer -q set "PC Beep" 50% unmute
while true; do dd if=/dev/ttyUSB0 count=1 bs=1 >/dev/null 2>/dev/null; beep -f 4000 -l 1; done

/proc/tty/driver/serial

watch -n 1 cat /proc/tty/driver/serial

Every 1.0s: cat /proc/tty/driver/serial                 Tue Nov 17 11:39:23 2009

serinfo:1.0 driver revision:
0: uart:16550A port:000003F8 irq:4 tx:334 rx:214898 fe:2636 brk:254 RTS|DTR
1: uart:16550A port:000002F8 irq:3 tx:181 rx:12 RTS|CTS|DTR
2: uart:unknown port:000003E8 irq:4
3: uart:unknown port:000002E8 irq:3

`setserial`

watch -n 1 setserial -avg /dev/ttyS*

Every 1.0s: setserial -avg /dev/ttyS0 /dev/ttyS1 /d...  Tue Nov 17 11:40:02 2009

/dev/ttyS0, Line 0, UART: 16550A, Port: 0x03f8, IRQ: 4
        Baud_base: 115200, close_delay: 50, divisor: 0
        closing_wait: 3000
        Flags: spd_normal skip_test

/dev/ttyS1, Line 1, UART: 16550A, Port: 0x02f8, IRQ: 3
        Baud_base: 115200, close_delay: 50, divisor: 0
        closing_wait: 3000
        Flags: spd_normal skip_test

/dev/ttyS2, Line 2, UART: unknown, Port: 0x03e8, IRQ: 4
        Baud_base: 115200, close_delay: 50, divisor: 0
        closing_wait: 3000
        Flags: spd_normal skip_test

/dev/ttyS3, Line 3, UART: unknown, Port: 0x02e8, IRQ: 3
        Baud_base: 115200, close_delay: 50, divisor: 0
        closing_wait: 3000
        Flags: spd_normal

`statserial`

statserial /dev/ttyS0

Device: /dev/ttyS0

Signal  Pin  Pin  Direction  Status  Full
Name    (25) (9)  (computer)         Name
-----   ---  ---  ---------  ------  -----
FG       1    -      -           -   Frame Ground
TxD      2    3      out         -   Transmit Data
RxD      3    2      in          -   Receive  Data
RTS      4    7      out         1   Request To Send
CTS      5    8      in          0   Clear To Send
DSR      6    6      in          0   Data Set Ready
GND      7    5      -           -   Signal Ground
DCD      8    1      in          0   Data Carrier Detect
DTR     20    4      out         1   Data Terminal Ready
RI      22    9      in          0   Ring Indicator

Reading data from a GM-10 or GM-45 radiation detector

The GM-10 and GM-45 are radiation detectors made by Black Cat Systems. These devices are Geiger-Müller counters. They count ionization events. Every time an alpha or beta particle or a gamma photo zips through the chamber the device will transmit a byte over its RS-232 output port. You just need to read the output and count the bytes. Note that the value of the byte is meaningless. You just need to count the fact that a byte of any value has been transmitted.

  • Serial port settings: 57600 8N1 (57600 baud, 8 data bits, no parity, 1 stop bit).
  • Set the DTR line high (DTR = 1). This is usually automatic, but if this is not done for some reason then the device will not receive power. It taps power from the DTR line.

The GM10 and GM45 come in RS-232 and USB versions. I chose the RS-232 version because I use Linux exclusively, so it was important to me that these devices work with Linux. The USB version will work with Linux, but not as easily as the RS-232 version. I decided that the RS-232 version made more sense because:

  • I already own several FTDI FT232 based USB-to-RS232 converters that work great every RS-232 device I have tested.
  • the USB versions of the GM10 and GM45 cost $50 more.
  • the USB versions of the GM10 and GM45 are basically the RS-232 versions with a built-in FT232 converter.
  • the FT232 converters in the USB GM10 and GM45 have custom USB VID number and PID number, so the Linux ftdi-usb-sio device driver does not recognize the serial device by default! Argh! This means you have to patch and recompile your device driver.
  • the RS-232 version seemed more hackable because Black Cat systems provides details on how to interface directly to the GM-10 and GM-45 signal lines available right through the RS-232 port. Basically, the RS-232 version just conditions the internal amplifier signals to be compatible with RS-232. There is no hand-shaking or wire protocols to deal with. You could basically hook up a battery and an LED to the GM-45 to blink for each ionization event. You can't do that with the USB version.

The weird thing about my GM-45 is that I received it in the mail on Friday March 11th, 2011. That was the day the Japanese Fukushima Nuclear Reactors were damaged by a tsunami and suffered a core meltdown. After that the Black Cat Systems had a rush on all their radiation detectors... For the record, I've detected no significant increase in background radiation in San Francisco, California.

The Black Cat Systems GM-45 is probably the most sensitive and most cost effective radiation detector you can find for under $400. I strongly recommend it. The quality of the device is good and the sensitivity is amazing. If you tried to buy research laboratory grade equipment with detectors this good then you would be spending much more. The Black Cat Systems devices also have decent documentation and support. The only device that I've found that comes close is the International Medcom Inspector Alert. This device costs almost twice as much as the GM-45; it doesn't include software; and it has little technical documentation; and it has zero Linux or Mac support. I have no firsthand experience with their products.

See also the gm4lin-ng project. I didn't use this because it seemed like it didn't give me much that I couldn't do myself just by opening the serial port and counting bytes.