back to index

sercat


Problem
Solution approach
Command
      Features
            stdin
            stdin delay
            control lines and baudrate
            timestamping
            limited runtime
            filtering
            ESP bootloader
Examples
Download
TODO

Problem

Often it is necessary to cat data from serial port to another process. This is hindered by the sometimes cumbersome setting of speeds. With embedded platforms (Arduino, ESP8266, ...) there is a further problem with the DTR and RTS lines; these can be set for various purposes that interfere with the communication.

By default, both RTS and DTR are set high as a hippie on shrooms on port open.

In case of common ESP8266 interfaces, high RTS sends the module to reset state (and holds it there), and high DTR (connected to GPIO0) at reset time sets it to programming mode.

In case of Arduino, DTR pulsed high causes reset (and can be held high afterwards as the reset line is connected via a capacitor). Sometimes RTS is used too.

An unsolvable-in-common-software problem is with the RTS line, which on linux always goes high on open() call. That would need a kernel patch. Some are floating around.


Solution approach


Command

sercat (compiled Apr 20 2021, 01:15:40)
cat for serial ports, with RTS/DTR control, for arduino, ESP modules and microcontrollers

Usage: sercat </dev/ttySomething> [-b speed] [-dtr] [-rts] [...]
  -b <baudrate>      default 115200, 0=leave as is
  -dtr               set DTR high (default: low)
  -rts               set RTS high (default: low, unavoidably pulses high on port open due to linux kernel
  -dtrp              pulse DTR high on start, for 500 ms
  -rtsp              pulse RTS high on start, for 500 ms
  -pt <n>            pulse time in ms (default: 1000)
  -raw               no filtering of unprintable characters (default: replace with '_')
  -hex               show unprintables as [hex], replace with '_'
  -notty             don't set RTS/DTR and baudrate, for timestamping only
  -nl <n>            exit after n input lines
  -ns <n>            exit after n seconds (todo)
  -sd <n>            delay sending stdin for n milliseconds
  -sl <n>            delay sending stdin for n input lines
  -t <n>             line timestamp format, 0..7 (4=line number, 2=line time difference, 1=line time)
  -q                 quiet, no state changes
  -espboot           show ESP bootloader (start at 74880 bps until ~ld line, then switch to -b baudate
  -espboott          show ESP bootloader, with timestamps if -t is set

Features

stdin

Unline ordinary cat, data can be fed to the port from stdin, whether manually or via a pipe. Sercat can act as a rudimentary terminal.

stdin delay

Delays the start of feeding of stdin data to the port, by number of seconds or output lines

Shows sent characters as {char} on stderror unless -q.

control lines and baudrate

timestamping

Prepends line number, line delay, and/or line time to the output

limited runtime

Sometimes the operation needs only couple of input lines, or should finish after preset time.

filtering

Sometimes, especially at speed mismatch (ESP8266 power-on bootloader for example), garbage comes in. That can confuse the terminal. By default it is filtered, nonprintable characters (anything below 0x20 that's not CR or LF, anything above 0x7F) are replaced.

ESP bootloader

The ESP8266 bootloader is starting at odd baudrate, 74880 bps. This normally shows as garbage at usual speed of 115200. Switching in runtime is difficult. The bootloader usually ends with "~ld" message, which is detected and taken as the bootloader output end.


Examples

Send a command to ESP8266 running Tasmota, on /dev/ttyUSB1 port, run for at most 5 seconds, send the input on 10th line of output, full timestamping, pulsing RTS

echo fastsensor 3|./sercat /dev/ttyUSB1 -ns 5 -sl 10 -t 7 -rtsp
*** setting DTR to LOW ***
*** setting RTS to HIGH ***
*** device speed is 115200 bps.
*** sleeping for 1000 msec, with RTS=1, DTR=0
*** setting DTR to LOW ***
*** setting RTS to LOW ***
[1][0.018][0.018]r$_l__|__$_|_______$__c|______r_b__b__oo_lnn____#_p__#l`_{lp_n_______l______#_o_|__l____#__on__l__$ ____nn_$ ___nr___o__#_l`__r__o__#_$ __{l_____$l__$__n__
[2][0.266][0.285]00:00:00.014 UFS: FlashFS mounted with 1904 kB free
[3][0.060][0.345]00:00:00.075 CFG: Loaded from File, Count 160
[4][0.005][0.351]00:00:00.080 QPC: Count 1
[5][0.009][0.360]00:00:00.089 Project tasmota Tasmota Version 9.3.1.2(shad)-2_7_4_9(2021-04-17T02:35:34)
[6][0.537][0.897]00:00:00.627 WIF: Connecting to AP1 iotap Channel 6 BSSId XX:XX:XX:XX:XX:XX in mode 11n as tasmota_F2D2A8-4776...
[7][1.755][2.652]00:00:01.754 WIF: Connected
[8][0.251][2.904]00:00:02.006 mDN: Initialized
[9][0.004][2.908]00:00:02.009 HTP: Web server active on tasmota_F2D2A8-4776.local with IP address 10.0.0.223
{f}{a}{s}{t}{s}{e}{n}{s}{o}{r}{ }{3}{\n}
[10][0.038][2.946]00:00:02.048 CMD: fastsensor 3
[11][0.005][2.952]00:00:02.053 RSL: stat/tasmota_F2D2A8/RESULT = {"fastsensor":3}
[12][0.125][3.076]18:54:17.002 iGC: broadcast: IGORCONF:18FE34F2D2A8:0
[13][0.271][3.348]18:54:17.272 RSL: tele/tasmota_F2D2A8/SENSOR = {"Time":"2021-04-18T18:54:17","ANALOG":{"A0":78}}
[14][0.300][3.649]18:54:17.573 RSL: tele/tasmota_F2D2A8/SENSOR = {"Time":"2021-04-18T18:54:17","ANALOG":{"A0":79}}
[15][0.329][3.978]18:54:18.080 RSL: tele/tasmota_F2D2A8/SENSOR = {"Time":"2021-04-18T18:54:18","ANALOG":{"A0":77}}
[16][1.003][4.982]18:54:19.083 mDN: Query done. MQTT services found 0
[17][0.004][4.986]18:54:19.084 MQT: Attempting connection...

Send a command to ESP8266 running Tasmota, on /dev/ttyUSB1 port, run for at most 2 seconds, send the input on 15th line of output, full timestamping, show timestamped bootloader data and count its lines

echo fastsensor 3|./sercat /dev/ttyUSB1 -ns 2 -sl 15 -t 7 -espboott
*** setting DTR to LOW ***
*** setting RTS to LOW ***
*** device speed is 76800 bps ***
[1][0.014][0.014]
[2][0.001][0.016] ets Jan 8 2013,rst cause:2, boot mode:(3,6)
[3][0.005][0.021]
[4][0.001][0.023]load 0x4010f000, len 3584, room 16
[5][0.008][0.031]tail 0
[6][0.001][0.032]chksum 0xb0
[7][0.002][0.035]csum 0xb0
[8][0.001][0.036]v3969889e
[9][0.001][0.038]~ld
*** bootloader end detected ***
*** device speed is 115200 bps ***
[10][0.220][0.258]
[11][0.007][0.266]00:00:00.009 UFS: FlashFS mounted with 1904 kB free
[12][0.053][0.319]00:00:00.062 CFG: Loaded from File, Count 190
[13][0.005][0.324]00:00:00.067 QPC: Count 1
[14][0.009][0.333]00:00:00.076 Project tasmota Tasmota Version 9.3.1.2(shad)-2_7_4_9(2021-04-17T02:35:34)
{f}{a}{s}{t}{s}{e}{n}{s}{o}{r}{ }{3}{\n}
[15][0.045][0.379]00:00:00.123 CMD: fastsensor 3
[16][0.005][0.385]00:00:00.128 RSL: stat/tasmota_F2D2A8/RESULT = {"fastsensor":3}
[17][0.524][0.909]00:00:00.650 WIF: Connecting to AP1 apiot Channel 6 BSSId XX:XX:XX:XX:XX:XX in mode 11n as tasmota_F2D2A8-4776...

Send a command to ESP8266 running Tasmota, on /dev/ttyUSB1 port, run for at most 2 seconds, send the input on 15th line of output (which doesn't happen), full timestamping, show bootloader

echo fastsensor 3|./sercat /dev/ttyUSB1 -ns 2 -sl 15 -t 7 -espboot
*** setting DTR to LOW ***
*** setting RTS to LOW ***
*** device speed is 76800 bps ***

ets Jan 8 2013,rst cause:2, boot mode:(3,6)
load 0x4010f000, len 3584, room 16
tail 0
chksum 0xb0
csum 0xb0
v3969889e
~ld
*** bootloader end detected ***
*** device speed is 115200 bps ***
[1][0.221][0.259]
[2][0.008][0.268]00:00:00.009 UFS: FlashFS mounted with 1904 kB free
[3][0.052][0.321]00:00:00.063 CFG: Loaded from File, Count 191
[4][0.006][0.328]00:00:00.068 QPC: Count 1
[5][0.007][0.336]00:00:00.077 Project tasmota Tasmota Version 9.3.1.2(shad)-2_7_4_9(2021-04-17T02:35:34)
[6][0.589][0.925]00:00:00.666 WIF: Connecting to AP1 apiot Channel 6 BSSId XX:XX:XX:XX:XX:XX in mode 11n as tasmota_F2D2A8-4776...

Download

Sources:

Binaries (may not run on earlier or later systems, due to .so dependencies):


TODO


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