back to index

Picocom enhancements

      Command syntax
      Autoargs, loose matches
            Autoargs from port name
            Named autoarg sets
            Loose port names
      Code notes


Picocom is a lightweight, simple terminal software for working with serial ports. It is good, almost perfect for most tasks dealing with embedded electronics. However, some features are missing in the stock version. When bad data come to the port, they are echoed in binary form and the random control characters then can break the terminal setting and result in weird character mapping and other oddities; this was a problem especially with the ESP8266 chip, which sends garbage on reset. There was also missing control of the RTS pin.


Several functions were added in the form of a patch:

Command syntax

Example: run picocom on /dev/ttyUSB0, at 115200 bps, with local echo and colors, with DTR high and RTS low:

 picocom -b 115200 -c -C --dtr 1 --rts 0 /dev/ttyUSB0


picocom v1.8-Shad-200714-0147
Usage is: picocom [options] <tty device>
Options for port settings:
  --<b>aud <baudrate>
  --<f>low <s|h|n>       (s=soft=XON/XOFF, h=hardware, n=none=default)
  --<p>arity <o|e|n>     (o=odd, e=even, n=none=default)
  --<d>atabits <5|6|7|8> (8=default)
  --<S>topbits <1|2>     (1=default, 1.5 not supported)
Options for control lines:
  --<D>tr <1|0>          (set DTR to value)
  --<R>ts <1|0>          (set RTS to value)
  --nomodem              (do not check for control lines changes)
Options for terminal:
  --<e>scape <char>      (ctrl-char as escape, default 'a')
  --e<c>ho               (local echo)
  --no<i>nit             (do not initialize port)
  --no<r>eset            (do not reset port)
  --no<l>ock             (do not lock port)
  --color (-C), --colorbright (-B)
  --baudadd <list_of_baudrates|set_name>
  --baudlist <list_of_baudrates|set_name>
  --lf<w>ait <msec>      (forced wait after CR/LF from terminal)
  --autol<f> <msec>      (newline after inactivity, for chunked data)
  --nohex, --hexall      (disable hex byte display or force for all)
  --imap <map> (input mappings)
  --omap <map> (output mappings)
  --emap <map> (local-echo mappings)
  --<s>end-cmd <command>
  --recei<v>e-cmd <command>
General options:
  --<A>utoargs <name> (set arguments by name from picocom_autoport)
  --<a>utoport  (set by keyword match on port name from picocom_autoport)
<map> is a comma-separated list of one or more of:
  crlf   : map CR --> LF
  crcrlf : map CR --> CR + LF
  igncr  : ignore CR
  lfcr   : map LF --> CR
  lfcrlf : map LF --> CR + LF
  ignlf  : ignore LF
  bsdel  : map BS --> DEL
  delbs  : map DEL --> BS
  swcase : lowercase <--> uppercase
  hexmap : show unprintable (or all) bytes as hex values
  msb    : bit order MSB first (usual LSB first)
  inv    : invert bit values
<?> indicates the equivalent short option.
Short options are prefixed by "-" instead of by "--". Long are all lowercase.

Autoargs, loose matches

Sets of commandline arguments can be predefined to automatically match desired devices. The definitions are stored in configuration file that can be placed in three locations; ./.picocom-autoargs, ~/.picocom-autoargs, and /etc/picocom-autoargs, looked up in this order.

Autoargs from port name

For match of options to port name, use argument -a.

The directives are placed in the files in the format of <match-spec><match-string> <...arguments...>.

The match spec for port name determines if the keyword has to match the port name partially anywhere (**), or if it has to match only the end part of the string (*). "*ttyUSB1" will match /dev/ttyUSB1 but not /dev/ttyUSB12, while "**ttyUSB1" will match both.

This is especially useful for meaningful port names, e.g. those populated as symlinks in /dev/serial/by-id/.

With configurable device namem strings in some USB-serial chips, matching names and rules conventions can be established. Eg. match on "_2400bps_" can be set to automatically specify -b 2400. (Todo, allow more submatches, do not stop on the first one.)

Named autoarg sets

One or more option sets to match can be specified by -A <name>.

The match spec for named argument has to match fully, and starts with "$". "$esp" can be used for a set of configs usual for the ESP8266 modules.

For more than one name, comma is used as a delimiter.

Parameter sets are looked up in the order of their specification. If a match on port should be done, _PORT is used as an equivalent of -a, in forced sequence position.

For more detailed reporting of matches and files accessed, -v or -V can be added to the beginning of the names string.

Loose port names

If there is no direct match on the port name specified, a keyword match gets performed in /dev/serial/by-id/ directory.

Exactly one match has to exist. More or less, and the program fails with listing of the possibilities available.


Version compiled at Tue Jul 14 01:47:54 CEST 2020

The binary is compiled for PC Linux, using gcc-4.9.2.

Compiling for Raspberry Pi (armhf architecture) was uneventful; make did the job smoothly. Binaries of the version of code compiled at Sat Mar 3 10:24:27 CET 2018:


A fault was found in the select() call, where the timeout for checking modem flags was specified in microseconds instead of in nanoseconds (some odd specs shenanigans). The changes were therefore read 10,000 times per second instead of 10 times. This was very noticeably slowing the code on slower machines, namely raspberry pi.

The term_get_modem_flags was unnecessarily calling term_find, iterating through the term structure without need to.

250000 and 500000 were added to list of default baudrates.

Reading from port was done via a 64-byte buffer, to significantly increase speed at 115k2.

Code notes

No warranty, it's software and so it has more bugs than an anthill. Original code is GPLv2, this naturally follows.

Custom baud rates are implemented by using term.c from jmesmon's fork, here. The files are:


If you have any comments or questions about the topic, please let me know here:
Your name:
Your email:
Leave this empty!
Only spambots enter stuff here.