There are different names for the serial port of a PC. On the IBM PC they are simply called COM. In the UNIX/Linux world tty (TeleTypewriter) From the electronic point of view they are RS232 connections making use of an UART (Universal asynchronous receiver/transmitter). Nowadays a Sub D 9pin male connector on the PC has become the standard:
Pin |
Name |
Dir |
|
1 |
DCD |
in |
Data Carrier Detect |
2 |
RXD |
in |
Receive Data |
3 |
TXD |
out |
Transmit Data |
4 |
DTR |
out |
Data Terminal Ready |
5 |
Ground |
||
6 |
DSR |
in |
Data Set Ready |
7 |
RTS |
out |
Request To Send |
8 |
CTS |
in |
Clear To Send |
9 |
RI |
in |
Ring Indicator () |
Connecting two computers having Sub D 9pin male connectors requires a cross cable (aka Null Modem) so inputs will go to outputs and outputs to inputs. Obviously RX will be connected to TX and Ground to Ground. RTS is connected to CTS. DTR is connected to the two remaining inputs DSR and DCD. RI is left un-connected.
There are two programs to do settings with the ports setserial and stty.
stty -a shows the settings in human readable form and
stty -g in computer readable form, what comes out with it can be used to store current setting and to restore it later. Either what is coming out can be stored in a file or simply passed on command line that can then look as stty -F /dev/ttyUSB0 1:4:da7:a30:3:1c:7f:15:4:10:0:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0
setserial uses a config file /etc/serial.conf
.
For the more heavy stuff setserial is used and for the simple things stty
Serial ports have been designed for speeds up to 115200 baud. when exceed ing this baudrate e.g. as setting something for 250000 baud Linux might refuse this.
setserial -a /dev/ttyUSB0
/dev/ttyUSB0, Line 0, UART: unknown, Port: 0x0000, IRQ: 0 Baud_base: 24000000, close_delay: 0, divisor: 0 closing_wait: infinte Flags: spd_hi low_latency
Shows that the uart (FTDI chip on USB) has a baudbase frequency of 24MHz.
setserial -a /dev/ttyUSB0 spd_cust
Now it is set for custom speed, verify it setserial -a /dev/ttyUSB0
/dev/ttyUSB0, Line 0, UART: unknown, Port: 0x0000, IRQ: 0 Baud_base: 24000000, close_delay: 0, divisor: 0 closing_wait: infinte Flags: spd_cust low_latency
Calculate the divisor for the as example for the target 250000 baud
divisor= 24MHz / 250000 = 96
then set it and verify setserial -a /dev/ttyUSB0 divisor 96
setserial -a /dev/ttyUSB0
/dev/ttyUSB0, Line 0, UART: unknown, Port: 0x0000, IRQ: 0 Baud_base: 24000000, close_delay: 0, divisor: 96 closing_wait: infinte Flags: spd_cust low_latency
This gets a bit ugly, you need to activate it but stty gets confused and must be made happy by passing a fake baudrate
stty -F /dev/ttyUSB0 38400
stty: /dev/ttyUSB0: unable to perform all requested operations finally test it
stty -F /dev/ttyUSB0
The user should be in the uucp group to have access to the serial port hardware.
/dev/ttyS0
corresponds to Com1
putty is well known and appreciated by the Windows users for SSH connections. However what most Linux users do not know, it works also under Linux and can be used as simple well working gui terminal program
minicom is the classic RS232 Terminal program that runs in a console. It can be used to connect serial devices. It has an historic user interface and using the default settings, it tries to connect to a modem and dials telephone numbers. It will therefore fail on any other devices that are no modems.
Ctrl + A to get the status line, then Z will bring up help screen
Type minicom -s to go directly into setup (useful when you have done previously wrong settings).
To have minicom working on something else than a modem, go to menu item "cOnfigure Minicom" then "Modem and dialing" and delete the "Init string" and "Reset string". After that it works as expected.
"cOnfigure Minicom" hold also the "Serial Port setup"
Simple alternatives is using example programs that come with pyserial as the console program miniterm.py or see https://pyserial.readthedocs.io/en/latest/examples.html. Obviously pyserial must be installed to have it running.
pyserial comes also with other useful programs as the gui program wxterminal.py, tcp_serial_redirect.py, rfc2217_server.py and port_publisher.py that allow controlling serial links on remote computers. Some of those example programs might not be installed when installing pyserial. On Gentoo the examples useflag must be set. Having the examples installed does not mean that the run, since they might not have executable permission.
Alternatives:
moserial is gui canonical (line) based. A line need to be entered and can then be sent to the serial link. The echo function might not work as expected since if sends back what has received and is therefore useful for early tests. Other terminals just show what has been sent on the screen.
serialtalk /dev/ttyACM0 is a simple console program
picocom is a console program (Ctrl+a, Crtl+h) or man picocom for help
It is always a hassle when there is a problem with RS232. Do I have a SW problem? Do I have a cable problem? Is the problem on my local side or the other? Is the driver loaded in the kernel? Has an other program already used it? Has just root permission?
To find out:
Start a terminal Program and configure the port
Make a jumper from pin 3 to pin 2 on the sub D 9pol connector. Or better make a plug for that.
Type a character and it echoes back, remove jumper and it does not work. Proof it is not a local echo, the characters went through the cable!
If this does not help there might be a hardware problem. Unfortunately there are many hardware hacks.
The RS232 requires a voltage swing of greater than ±3V and smaller than 12V. This means a negative voltage and a large positive voltage needs to by available by the peripheral device. Simple devices having just a battery have just one single voltage and maybe even to small for creating even a nice positive voltage level. It is possible to create the correct voltages out of a single voltage, but this adds additional cost to peripheral devices: Even chips as the MAX232 might be to costly. Therefore often such devices make use of a hack. They abuse the DTR (pin 4) and the RTS (pin 7) handshake lines as additional (or as the one and only) power supply. This causes the software to initialize those pins correctly to have the device functioning. As example: Simple multi-meters require DTR to have a high and RTS to have a low voltage level on its pins.
Even more radical devices as the simples form of the serial LIRC receiver speculate that an open serial input is considered to have a low level (negative voltage) and therefore produce just the positive level.
Since nobody is proud of those hacks, they are usually bad or not at all documented.The result is bad communication with occasionally data loss or no communication at all.
In a professional environment is a must to respect the RS232 specification and have proper signals.
An other issue is that /dev/ttyS0
belongs to the user root and the uucp group. You are not root so you need to modify /etc/group
to put your name to the uucp group. If the uucp group does not exist, you have to add it, however don't do that manually since you probably do not know the number that corresponds to the uucp group.
Nowadays RS232 ports disappear from PCs, Laptops and the one present are probably already used. Luckily there are USB to RS232 converter cables:
Fist you need to make a kernel that supports your USB serial converter (e.g Prolific Technologies)
Start udevadm monitor --env
Plug it in and check in what udevadm puts on the console:
DEVNAME=/dev/ttyUSB0
Check also what is been reported by usbview
Scan trough /dev and notice /dev/ttyUSB0 appears and disappears (udevadm monitor does not point straight to this location).
Start minicom, gtkterm or komport and configure to /dev/ttyUSB0 (no HW handshake)
Test it as described in: Troubleshooting serial links
To program serial links in c, the termios high level interface should be used. The header file can be found at /usr/include/bits/termios.h
.
If some hacked hardware is being used that needs special handling on the control lines, then termios might not be the way to go, since it is written to use the serial link the clean way. Direct hardware access to the UART chip is then the way to go. The definitions of the chip can be found at
/usr/include/linux/serial_reg.h
. However accessing the hardware directly is normally just available for the kernel, so your code should end up in a device driver.
To get access to the hardware on a root level and not as device driver, the function ioperm needs to be called to get the permission. It checks if this hardware is not occupied by some other program. When programming a device driver modprobe<device driver>
would do the same check. To access the hardware afterwards, the functions as inb and outb can be used to write to the chip. Those functions are usually used in kernel module programming. For details see
/usr/include/sys/io.h
.
You need to set the option -O or -O2 to have the functions inb, outb successfully available, since they are inline makros.
If you want to call this code not as device driver and not as root, you have to get the file the root ownership and you have to set the set user ID flag (s):
chown root:root<my code>
chmod a+s<my code>
This way a user can call this program, but the program will not run under the users ownership, it will use its own ownership that are set as root.
Programming the serial link under python is possible after emerge pyserial. Different example code and the terminal program miniterm come with it.
miniterm is a single python file with around 500 lines of code. It is a good start to write your own code, just delete everything not necessary and then add your own functionality. However you need certain python skills, since miniterm makes use of multi-threading, object oriented programming, termios for the console and optparse for the command line arguments. So if you handle this exercises successfully you can call yourself a python programmer.
ser2net allows a remote computer to use a IP port of an other computer to connect its serial link. man ser2net shows the documentation. ser2net is a daemon that has its config file at /etc/ser2net.conf
that can have an entry as
3333:raw:0:/dev/ttyS0:115200,8DATABITS,NONE,1STOPBIT
This means the server having the serial port and the daemon wait on port 3333 for an income request. They use then the raw mode to pass everything to the serial link. 0 means there is no time out so the connection stays until a power down. an other value would terminate the connection when not traffic for the number of seconds given appears. The rest is self explanatory.
Now a program as telnet need to be used to connect to the remote machines port and than everything is passed to the serial link.
Alternatively the program socat can be used to create a virtual serial link /dev file. When accessing this file then /dev on the remote computer is accessed instead.
The ser2net daemon can be started via init script or systemd
Links are http://techtinkering.com/2013/04/02/connecting-to-a-remote-serial-port-over-tcpip/ https://sourceforge.net/projects/ser2net/