Sunday, 10 April 2011

Sending And Receiving

For this post, we're going to send some characters out the serial port, which is then looped back, so we can read what we sent, and we're going to do it just using command line tools.

To do this, we're going to have to do a little hardware. It's very minor, though. What you'll need is a connector that plugs into your serial port. On that connector, join pins 2 & 3 together, which are the send and receive pins. This is the case for both D9 and D25 connectors. Most connectors have each pin numbered.

If you're handy with a soldering iron, a connector with solder buckets can be used. These are easily linked with a blob of solder, or a short piece of wire. Make sure that no solder spikes touch any other pins, though.

If soldering seems a bit daunting, then connectors that accept crimp connectors can be used.

With the hardware sorted out, let's look at the software.

If you need to set the permissions to use your serial port, then this was covered in a previous post, here.


This is what to type, at a terminal, replacing /dev/ttyS0 with the name of your serial port:

stty -F /dev/ttyS0 -icrnl -echo clocal

exec 3<> /dev/ttyS0

echo 'Hello' >&3

read -t 1 response <&3

echo "$response"

exec 3>&-

Let's break that down, and explain what all the parts do.

We need to configure the serial port to the settings we need for our experiment. For this, we use the stty command.

stty -F /dev/ttyS0 -icrnl -echo clocal

stty configures a serial port parameters for use as a terminal, i.e. it can change how some of the characters passing through are interpreted.

-F [device]
allows us to say which serial device we want to talk to.

switches off conversion of the carriage return character to the new lines character.

switches off local character echo.

clocal Some of those other pins on the connector can start and stop the flow of data in and out of the serial port. We don't want anything to stop our characters from popping out and back in again, so this command ensures we ignore what are often called the modem control signals.

That's the configuration done.

The following commands use the I/O redirection system quite a lot. 

exec 3<> /dev/ttyS0

The exec command 'opens' the serial port for use. This is an oversimplification. exec allocates a file descriptor to a file, and our serial port is treated as just another file. A file descriptor is used rather than a file name as it's just a number, an index into a table, and so is easily used by the programs using the file.

The <> opens the serial port for reading or writing, and is part of the the I/O redirection system.

The 3 is the file descriptor we are going to use. Normally, when opening a file, the number is allocated for us, but here we want to know what the number is, so we allocate a number that we know won't be used by anything else.

And, of course the /dev/ttyS0 is the serial port we are going to use.

echo 'Hi there' >&3

echo sends out the characters that are in the single quotes. The >&3 is our redirection, to send the characters out the serial port. Single quotes must be used. If double quotes are used, some characters will be interpreted as instructions, rather than characters to send.

read -t 1 response <&3

We've looped back out transmit line to the receive line, so hopefully those characters are going to reappear back in our computer, and this is the line that reads the serial port. Again redirection is used with the <&3 , but notice there is a < rather than the > when we were sending characters out. I've also put in -t 1. This is a timeout of one second, so, if the loopback doesn't work, rather than waiting for ever for characters to appear, it gives up after one second. The response is a variable we store our characters in.

echo "$response"

We use echo, again, but this time to print out the contents of the variable response, which, if all went well, are the same characters that we sent out. This time, we need double quotes, as we want this to be interpreted as a variable. Also, there is no redirection in this command, so the output appears on our screen.

exec 3>&-

This little command 'closes' the port, and frees up file descriptor 3 for anything else to use. You only need to do this once you have finished playing with your serial port. Alternatively, you can keep using the echo read echo commands to send out all sorts of messages, to your hearts content.



  1. Thank you so much! I've looking for something like this for 2 weeks.

  2. Hi, I don't know if I'll get an answer because of the age of this post... I'll try!
    After the echo "$response" command, I should read back what I sent to the ttyS0, if all went well. So, I don't get anything: what could be wrong? (pin 2&3 are correctly connected and I have permissions on ttyS0)
    Thank you!