LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Bash and serial port (https://www.linuxquestions.org/questions/programming-9/bash-and-serial-port-4175718392/)

Wawa 11-02-2022 02:41 PM

Bash and serial port
 
Hello there !

I try to use bash for send datas to an external computer.

I have try this :

Code:

#!/bin/bash

file=$1
port="/dev/ttyUSB0"

while IFS= read -r line
do
        echo -n "$line" > $port
        sleep 0.5
done < "$file"

This work well but is to slow.

As soon the external computer has get the datas and made his job he send a single ">" (no crlf, no eol, etc...) to the serial port.
I think I can read the serial port and as soon as I get a ">" send the next line.

So I try

Code:

#!/bin/bash

file=$1
port="/dev/ttyUSB0"

while IFS= read -r line
do
        echo -n "$line" > $port
        while read -N1 char; do
                echo $char # just for debug purpose
        done < $port
done < "$file"

First problem I see is that the "read" instruction read again the data which just has been send by the previous line. So if by hazard the send data include a ">" the program will fail... Also this seems to remove datas from the serial port buffer.

And the "while read... done < $port" look to be an endless loop.

How could I change the code to do the job ?

Thanks for the help.
Philippe

michaelk 11-02-2022 05:58 PM

IMHO bash is not the best language for accessing serial port data and can be unreliable. Here is a quick python script. Change serial port parameters as necessary. It will wait for a single character response and then continue sending data. The serial module is not installed by default.

Code:

#!/usr/bin/python3

import serial
import sys

if len(sys.argv) == 1:
    print("Missing command line argument")
    quit()

myfile=sys.argv[1]

serialport=serial.Serial(port="/dev/ttyUSB0",baudrate=9600,bytesize=8,timeout=2,stopbits=serial.STOPBITS_ONE)

file1 = open(myfile, 'r')
while True:
    # Get next line from file
    line = file1.readline()
    serialport.write(line.encode())
    # if line is empty
    # end of file is reached
    if not line:
        break
    while (serialport.in_waiting == 0):
          pass
file1.close()


NevemTeve 11-03-2022 01:27 AM

@OP I guess you should open the device only once, e.g.
Code:

#!/bin/bash

file="$1"
port="/dev/ttyUSB0"
exec 7<>"$port"
# stty <&7 some-serial-options

while IFS= read -r line
do
    echo -n "$line" >&7
    while read -u7 -N1 char; do
        echo $char # just for debug purpose
    done
done <"$file"


sundialsvcs 11-03-2022 09:38 AM

I heartily agree with @michaelk: "use a real language." Also, avail yourself fully of the many packages that are available for use in those languages.

Quote:

Originally Posted by wisdom:

Actum Ne Agas: Do Not Do A Thing Already Done.

If you mark the script file as "executable" and it begins with a so-called "shebang" #! in the first line, specifying the location of a language interpreter, then that interpreter will silently be invoked to run the script and the user will be none the wiser. (The env command exists to make this easier.)

While "bash" has very rudimentary scripting capability, it never was intended to be used for "real work." (Only the Korn shell, "ksh," had a serious built-in language.) The elegantly-simple "shebang" mechanism means that it doesn't need to.


All times are GMT -5. The time now is 12:40 AM.