2

I am trying to write a bash script that is able to interpreter data coming from a serial device. I configure the port in raw and then I am able to do a simple cat of /dev/ttyUSB0 and see the data. My issue is how to get the single line of data that the device sends in a bash variable so I can freely manipulate it.

I would like to have it in bash before going to Python so I always have a script that I know it works on every linux machine.

The data I receive has the following format: STX<26 x 4Bit-Nibbles codded as ASCII Payload>ETX

Ideally I could just store the new payload (so without STX and ETX) in a Bash variable every time I get a new string of data.

Solution

with the help of @icarus answer, I cooked up something that works like a charm. First I configure the serial port to generate the interrupt with STX value:

stty /dev/ttyUSB0 115200 intr 0x02

then to get the info I wanted, I use this loop:

ETX=$'\003'
while read -d "$ETX" line; do echo $line; done < /dev/ttyUSB0

Thanks again for the help, really great first experience in this website. Cheers

  • 1
    Do you really have to use bash (or a shell) for this? See https://unix.stackexchange.com/q/10801/117549 – Jeff Schaller Jul 01 '19 at 12:49
  • The edited remark about setting the tty interrupt character to control-b rather than the normal control-c doesn't make sense. – icarus Jul 05 '19 at 00:20

1 Answers1

3

Untested!

 #!/bin/bash
 ETX=$'\003'
 STX=$'\002'
 # Open /dev/ttyUSB0 open on FD9
 exec 9< /dev/ttyUSB0
 # do any stty stuff needed on fd9
 # e.g.
 # stty 9600 < /proc/self/fd/9 > /proc/self/fd/9
 # now loop, reading from the device,
 while IFS= read -rd "$ERX" -u 9 wibble
 do
    wibble=${wibble#"$STX"}
    printf 'Got %q\n' "$wibble"
    # Do something
 done

With bash, that won't work if the data includes NUL bytes. You'd need to use zsh instead if that were the case.

icarus
  • 17,920
  • thanks, I will check and come back to it! – rec0nf1g Jul 01 '19 at 14:31
  • thanks again @icarus, this worked fine after I configure the port to generate an interrupt only when 0x02 char was received:

    stty /dev/ttyUSB0 115200 intr 0x02

    Then this worked like a charm, in fact I only had to do this:

    while read -d "$ETX" line; do; echo $line; done < /dev/ttyUSB0

    – rec0nf1g Jul 04 '19 at 15:13
  • @rec0nf1g The usual way to express thanks is to vote up answers which are helpful or useful. In addition as you asked the question you can accept an answer (you can change your mind later and accept a different answer, and you probably ought not accept an answer straight away unless it is obviously correct and therefore no one else is going to answer). – icarus Jul 05 '19 at 00:18
  • thanks for info! Done and Done. Like I said on my updated post, this was a first time for me actively participating, before only lurking around ;) thanks again! – rec0nf1g Jul 05 '19 at 09:47