We all need to hack around with hardware from time to time. A highly useful way
to gain access is the RS-232 serial connector to a terminal interface, where
console output is dumped, and command access is often available.
This is available on virtually all digital circuit boards as an
optional pin header and virtually always at a 3V3 level. Why not agree on a simple
way to unleash these with a carefully specified jack plug, and be compatible?
..
This article is about hacking hardware. Note that the term hacking has been hijacked by misguided journalists to refer to illegal conduct; the real term for that would be cracking. Hackers make things, crackers break things, as ESR famously put it. Usually, we do this on store-bought devices in an attempt to tinker with the way it works, and possibly improve on it, download our own software, and so on.
We are bound to call for hardware work in the time to come. If that is done, we will use this article as a reference point for the developers, so we can replay any hacks that they applied to devices on behalf of us. Useful enough to spell it all out.
Hardware Hacking 101
Got a neat device that you'd like to master? Chances are, if it's digital, that it
runs on Linux, and if you open the casing you will find a set of three soldering islands
(or sometimes more)
on the circuit board, sometimes even with pins sticking out. Depending on the manufacturer's
taste, it may have print next to it saying DEBUG
or similar. Or, it may use terms like
RXD
, TXD
and GND
or just RX
, TX
and GND
. Bingo, you've found an RS-232
serial interface.
What you don't know yet, is if the device acts as an endpoint (DTE) or as a
communications device (DCE). These are normally connected directly without any
swapping of signals, and because of that, the directions of the TXD
and RXD
are the opposive of what you would expect for the DCE. On a DTE, TXD
sends and
RXD
receives; on a DCE, TXD
receives and RXD
sends. So make sure to test
their direction, and make no assumptions; you may have to swap the two signals
to connect two DTE systems, or two DCE systems. With the three-resistor test
given above, you would find the receiving pin halfway the supply voltage while
the transmitting pin is at the supply voltage.
When you would listen in on the connection, chances are you will see a Linux system booting over it. If you ever started a Linux system from scratch you will undoubtly remember text rolling over the screen, to disappear after all is done, and be replaced by a graphical interface.
Hardware is usually a so-called embedded system which means that it won't pop up a graphical interface, but instead continue in textual mode. This is a bit of a pain, but it mostly a gain. The pain is that you will need to know what to ask, which is not always simple. You will have to learn how to operate a shell. The gain however, is that all these systems listen to pretty much the same style of commands. So you can practice on a desktop system and continue using it on your embedded system. Also, the embedded system usually has no online manual pages installed, but they largely overlap the functions on your desktop anyway — albeit that embedded systems are usually dressed down in terms of functionality.
Connecting to Embedded Devices
It is important to realise that the voltage level of embedded devices is usually 3V3, but it does not have to be. And even though the signals may be called RS-232 after the famous serial interface, this is with the exception of the voltage levels. A PC serial port is likely to destroy these embedded connections due to the higher and even negative voltages: -12V to +12V is quite common.
The biggest challange is now to find a way to connect to either another 3V3 device; although a Raspberry Pi may seem handy, you should then avoid its normal use of the serial interface as a console and login terminal, and instead make it suitable to run terminal emulators that run against dito functionality on the other side.
Many have been lucky using a
data cable meant for an older mobile phone. In the end, there are a few chips that
are used to connect up to USB; these work well on Linux and Windows, but not so well
on Mac OS X. (We view all devices as a DTE in what follows, which may mean that
we end up swapping the names compared to what the PCB says. We mean output when
we speak of the device's TxD
and we mean input when we speak of its RxD
.)
If your circuit board doesn't tell you, you should try to measure voltages on the pins while the device is switched on. You are looking for low (0V) and high (3V3) levels relative to GND; you can often spot GND as large planes of copper, or you can hook it up to another connector on the device of which you know it is grounded.
There are bound to be three signals, namely:
GND
is fixed at 0V and won't divert from that voltageTxD
bursts out data, but might be inactive, at which time it outputs 3V3; it won't divert muchRxD
is an input, and should be quite easy to divert to another voltage
The first two can be recognised as the 0V and 3V3 levels, but the third will also show up as a concrete reading; how to split that apart? The trick is, RxD will gladly follow input signals. So, take a resistor, somewhere in the range of 100 Ohm to 10k Ohm, and connect a potential input to a point at 0V, then to 3V3. Measure to see if it follows the change. If so, it is an input and so it is RxD. The other two are now easily identified.
Resistor tester. You might connect the same resistor value, for instance 22 kOhm, between each pair of these three signals and measure what that does to their voltage. You should find:
TxD
is at 3V3RxD
is at 1V65GND
is at 0V
Note how the tip of a TRS jack plug is "hot", and the signals "cool down" on their path to the sleeve.
LED tester. An alternative (as yet untested) option is to use a red and green LED with a resistor of about 1 kOhm (to restrict currents to under 3 mA). Connect one end of the resistor, the red cathode and green anode in one dot of solder, and solder a 220 Ohm resistor to the free ends of the LEDs. Then, connect each of the free-hanging ends of the resistors to the three terminals under investigation. When a LED lights up, it has been connected properly; if not, you should suffle the wires. In the end you should find:
TxD
lights up red (assuming a DTE, so this is the data output)RxD
stays off (assuming a DTE, so this is the data input)GND
lights up green
It would be relatively easy to pour this into a jack plug to allow a quick test. Very nice if you do this a lot, or to check up on your earlier work. This can in fact be plugged into a socket that has been wired up, when it is ready to be connected to the PCB.
It has also been suggested that a piezo connected to TxD
sounds like an
old-school modem while a device is booting (to indicate that it is dumping data
over TxD
). This might turn your LED tester into a multimedia toolkit :-)
Null modem.
The trick is now to make what is called a cross cable, also described as a
null modem, because it is like connecting two PCs directly, without intermediate
modems and communications channels... RS-232 was intended for communication with
telephone line modems, you see. The cross cable is called that way because the
RxD
of one device connects to the TxD
of the other. You do connect GND
of the
two devices directly, as a shared reference voltage for the signals.
Never connect Vcc
lines, even when they area available on both. The problem with
that would be that you have two reference voltages, and they might end up competing
if they differ slightly. Signals are relative to GND
, and that should be your
approach too. (An exception can be made when the Vcc
on one device is meant to
power the other device of course, but that is not usually what we want.)
Once connected, start the device and enjoy the text scrolling over your screen.
Read it carefully, you may find many hints. And you can try to get in; many
systems don't even ask you to login but simply end in a prompt where you will
have root
access to the system. Although the mechanics of storage are quite
different on an embedded device, and you should carefully follow instructions if
you intend to upgrade your device over this interface, there is no reason why you
cannot look around, try to understand what is going on, and edit a file or two if
you are sufficiently convinced that they are not a strict requirement for a
successful reboot.
Standardised Jack Plugs
Now let's boldly propose that we be clever about this, to improve reuse and future access to those device in the future. I once started with OpenWRT, and soldered a few plugs on the PCB so I could access them. I've been making compatible pin headers ever since. But pin headers are not very practical:
- You cannot attach them to the device casing
- They can be plugged in in two ways
- They may plug into a larger pin header
- You may need to mod PCBs, including opening up soldering islands
- You might feel inclined to use DB-9 connectors and pump up voltages
Enter the 3.5 mm jack plug. A variety of manufacturers have created all sorts of plugs and sockets. Very importantly, you can easily solder these things yourself. And, given a drilled hole in the device exterior, you can make the RS-232 console accessible on the device's outside. Your cost per device stays below 1 Euro, and that easily pays back as reduced effort in easy and consistent device hacking in the future.
Terminal and "Communications Modem"
The RS-232 terminology speaks of a DTE (Data Terminal Equipment) and DCE (Data Communications Equipment). In layman terms, your computer or printer or teletype are all examples of a DTE because it is the beginning and end of the communication line, and a modem, ISP infrastructure and cross cables all make up the DCE side of things.
The terms RxD
and TxD
are defined in reference to the DTE; the TxD
signal
is transmitted by the DTE and sent to the DCE (who receives it on its TxD
input), and RxD
does the opposite (so it is output by the DCE and input by
the DTE). When you connect DTE and DCE, you will not be crossing over wires,
but connect RxD
to RxD
and TxD
to TxD
and, of course, GND
to GND
.
In terms of Jack Plugs, we can define these quite simply as follows:
- Sockets represent a DTE (they output
TxD
and inputRxD
) - Jack plugs represent a DCE (they input
TxD
and outputRxD
)
So, let's take the example of a USB data cable such as the DCA-540, which was commonly used to connect to a mobile phone over RS-232. Many variants exist, and most of these cables use the PL2303 chip for which drivers are part of stock Linux, widely available for Windows and somehow always causing trouble on Mac OS X.
Cut open the cable and find the signals that you
need, either by looking up the
mobile phone connector pinout
or doing what you also
did for the circuit board. You can connect the TxD
, RxD
and GND
signals
to a jack plug to make the cable appear like a DCE, which seems most sensible
if devices present themselves as a socket. In the concrete example of the
PL2303 given here, you should be mindful that it is configured as a DTE, so
to attach a jack plug would require swapping the TxD
and RxD
signals.
This cable will be useful to plug into a socket that you mount into
an embedded device. And you can pull it out, and plug it in elsewhere.
You should keep a list of settings somewhere, so you need not fool around
with the precise serial port settings for each device; you could print it
next to the connector. The usual format is 8N1
, meaning 8 bit words,
no parity and (at least) 1 stop bit. The speeds vary; we often see that
embedded devices use 115200 bits per second, but an older standard was
9600, and some use 384000. If you get it wrong you are not likely to
destroy anything, but the device's output will look like scrambled eggs.
The null modem is a cable with two jack plugs so it looks like a DCE
to both sides, which means that straight connections are not possible;
it needs to swap the RxD
and TxD
signals. This means that
a standard stereo connection cable cannot be used. Be careful and only
use the cable that you marked as a null modem. You would create
a short circuit if you used a plain stereo audio cable instead of a null
modem cable!
Jack Plugs and Sockets are TS, TRS or TRRS
There are some forms of 3.5 mm plugs and sockets, known as TS, TRS and TRRS. You might know them from audio applications:
- TS plugs are used to pass mono sound
- TRS plugs are used to pass stereo sound
- TRRS plugs have an extra ring for an extra signal, like mic or video
There are four positions where a socket samples the plug. These are best seen on a TRRS connector. Let's number the four positions 1,2,3,4 by going from the tip to the shaft.
- TS sockets connect to make T=1, S=3
- TRS sockets connect to make T=1, R=2, S=3
- TRRS sockets connect to make T=1, R=2, R'=3, S=4
We might as well have spoken of 13, 123 and 1234 plugs and sockets. Note that a plug with less rings than sampled by the socket will create a short-circuit between those sampling points in the socket. As a special consideration, we could use TS sockets for devices with only output but no input, such as GPS receivers or DCF77 clocks or any radio station if you have no radio transmission license.
Normally, TRS means Tip-Ring-Sleeve, but we shall use it to conveniently
means TxD
, RxD
, (signal)GND
. Note how the customary letters are hints to
the RS-232 use. As will be clear below this also makes good electrical
sense, which is much more important, but the naming is a happy coincidence.
We let sockets connect to make TxD
=1, RxD
=2, GND
=3.
A TS plug might be used to receive TxD
data from a device without
sending anything back; in fact a TRS socket
TRS would find RxD
connected to GND
by a TS plug, which
in terms of RS-232 is a constant BREAK signal. More importantly,
a TRS plug in a TS socket would simply ignore the incoming RxD
signal and that
is indeed as intended for a device that emits data but will not take
any commands back. (It may not be worth the effort to specialise that
far though. Much easier to just use a pile of TRS sockets and a few
shared TRS jack plugs, and simply leave the RxD
signal unconnected on
sockets if a device has no need for it.)
Optional Bidirection Extra Wire
There is one more option available, and that is the TRRS jack plug and
socket. These should be compatible, so they continue to have GND
=3,
but an extra signal OPT
=4 is now available. When a TS or TRS jack plug
is used with a TRRS socket, then OPT
will be connected to GND
.
When a TRRS jack plug is used in a TRS or TS socket, it will be
kept floating, because the socket does not connect on position 4.
You can easily include position 4 in the null modem as a direct connection. It may be of use to you someday. But you can just as easily simplify and use a null modem based on TRS jack plugs only. You probably are going to make one such cable, so TRRS may be worth considering, just in case.
The logic proposed below is a bit complex, but also powerful. There are safe and easy defaults. The logic is:
- Each side can supply a signal via a 4k7 Ohm resistor, so the cable holds the average of the two signals;
- An analog signal may be inserted around half the 3V3 supply, with a range of no more than 1V up or down, so 0V65 to 2V65, which will be averaged with the signal on the other side;
- A digital signal may be inserted as the extreme values 3V3 or 0V, again through a 4k7 Ohm resistor to support averaging;
- A side that sends and receives a signal would use an opamp to subtract half the local signal, and then double the outcome to find the original signal from the other side.
You can use this to signal quite a range of things, both analog and digital, which makes it very interesting. We don't specify anything but if you are looking for an easy suggestion it'd be to signal "am alive" to the other side, by simply wiring the 3V3 supply via a 4k7 Ohm resistor. Such a signal can be processed on the other side as a sign of life; how this is done depends on the configuration of the side (which is why we resorted to a general name of "am alive"):
- The DTE can send Data Terminal Ready (DTR) and the DCE can receive Data Set Ready (DSR) as a sign that the other side is online, or at least powered up;
- The DCE can send 3V3 (if it is a USB cable) or the other side's "am alive" (if it is a null modem) and the DTE can receive Data Carrier Detect (DCD).
This is quite directly how RS-232 connections do hardware handshaking. There are a few more such signals, namely Request To Send (RTS) and Clear To Send (CTS), together implementing hardware flow control. These are not directly possible in this setup, but characters XON and XOFF are often used to replace them, or on most terminal sessions the flow control problems are also regularly ignored. A few patches exist, and are common in null modems too:
- The DTE can send RTS which may be ignored;
- The DCE can receive RTS as a local copy of the other side's "am alive" signal, and pass it on as such;
- The DCE can send CTS which may be ignored, or incorporated, along with its DCD signal, into the "am alive" signal being returned;
- The DTE can receive CTS as a local copy of the other side's "am alive" signal.
A few points worth noting when passing analog signals:
- When one end passes an analog signal and the other passes a digital, there may be distortions as a result of the more extreme ranges for the digital signal, and glitches on the analog signal may also be caused by the digital signal;
- Channel separation will be limited by the precision of the resistors being used;
- The 4k7 Ohm resistence is half of what the LINE audio signals of a PC sound card are destined to drive, but the signal range is also about half, so you can drive the LINE signal in here through a 10 kOhm resistor and find half the output on the other side — unless it is aware of this fact, and compensates for it;
Feeding Circuits
The OPT
signal is protected from short-circuits but as a
result it has more resistence than could be tolerated
on a power line. As a result, it cannot be used to
supply power to an end point. But, following the stretch
of imagination that used to be common for
RS-232 circuit hacks,
we do have some possibilities to do this awful thing.
The RxD
signal comes into a DTE with less resistance, and should
be able to drive a modest load, especially when no data passes
over it. As an example, a simple DCF77 circuit might draw
3 mA, taken from RxD
. If it the circuit can run below
3V3 it may be beneficial to feed through a 100 Ohm resistance
that feeds a capacitor, to stabilise the local power.
To take this even further, there are ways of expressing the output from a DCF77 module in terms of RS-232... each second, either a low pulse of 0.1 seconds or 0.2 seconds occurs. That might be interpreted as an extremely low bitrate serial signal at 10, 20, 30 or 40 bits/second as 8N1.
A shameless use of this jack plug RS-232 specification would then
be to add a socket to a DCF77 clock, where it sucks power from RxD
and feeds its output directly into TxD
. Not that any practical
RS-232 circuit is going to be able to sample at this low bitrate...
Just a Standard...
Andrew Tanenbaum said, with a decent bit or irony, that the nice thing about standards is that there are so many to choose from; and if you don't like this year's standard you can always wait for next year's.
This specification is like that. I only wrote it because I've never seen a proposal for a cheap 'n' easy connector that makes hardware hacks more compatible. We are likely going to use this in upcoming ARPA2 projects in 2018 or 2019, as we move into the realms of hardware...
The image was found on WikiMedia Commons and edited with Gimp before addition in this article. You may use it under the original license.
Go Top