Find the answer to your Linux question:
Results 1 to 6 of 6
Hi all, OS : Ubuntu 12.04.1 server X64 Hardware : UDIN-44, using FT232 USB-Serial UART Well, I need to detect if an external button has been pressed, then lauch an ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Jul 2005
    Location
    New-Caledonia
    Posts
    29

    Question Bash: read output from tty


    Hi all,

    OS : Ubuntu 12.04.1 server X64
    Hardware : UDIN-44, using FT232 USB-Serial UART

    Well, I need to detect if an external button has been pressed, then lauch an action.

    The UDIN-44 has 4 relays and 4 opto-coupled inputs.

    The state of an input is answered by device using this command (for opto #4):
    Code:
    i4
    it answers
    Code:
    0
    for no input and
    Code:
    1
    if a signal is present.

    Here is a commented code I use to detect if the button is pressed:
    Code:
    #!/bin/bash
    # variables
    port='/dev/myttyUSB0'
    log_file='/var/log/myttyUSB0.log'
    # init tty, needed for this device
    stty -F /dev/myttyUSB0 9600 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke min 1 time 5
    # empty log file
    echo '' > $log_file
    # launch service to parse tty port to log file
    cat < $port > $log_file &
    # do forever
    while [ true ]; do
    	# -e (enable interpretation of backslash escapes) and -n (do not output the trailing newline)
    	# \r : carriage return to validate the command
    	echo -en "i4\r" > $port
    	# tac=cat reverse, -a:treat as text(not binary), -m 1:only one line, .:not empty line
    	last_line=`tac $log_file | egrep -a -m 1 .`
    	echo "last_line=$last_line"
    	if [[ $last_line == *"1"* ]]; then
    		echo '***** DETECTED BUTTON PRESSED *****'
    	fi
    	sleep 0.1
    done
    The main problem is with the last_line read, the results are not accurate, here is the ouput of the script :
    Code:
    last_line=i4
    last_line=00i4
    i4st_line=0i4
    i4st_line=00
    last_line=00i4
    last_line=00i4
    i4st_line=0i4
    last_line=i4
    last_line=0
    last_line=0
    last_line=0
    last_line=0
    last_line=0
    last_line=0
    last_line=0
    last_line=0
    last_line=0
    last_line=0
    last_line=0
    last_line=0
    last_line=0
    last_line=0
    last_line=0
    last_line=00
    last_line=00
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    00st_line=
    it should be only :
    Code:
    last_line=0
    or
    Code:
    last_line=1
    1 when the button is pressed.

    I'm not a bash expert, so thanks in advance for any advice you could give.

    Edition : here is the /var/log/myttyUSB0.log
    Code:
    i4
    0
    i4
    0
    i4
    0
    i4
    0
    i4
    0
    4i
    0
    i44
    1
    i4
    1
    i4
    1
    i4
    0
    i4
    0
    i4
    0
    4i4
    0
    i
    0
    i4
    i44
    0
    i4
    0
    0
    i4
    0i4
    0
    i4
    0
    i4
    i
    i4
    0
    i4
    1
    i4
    1
    i4
    1
    i4
    1
    i4
    0
    i4
    0
    i4
    0
    i4
    0
    i4
    0
    i4
    0
    i4
    0
    i4
    0
    i4
    1
    i4
    i4
    0
    i4
    0
    Button has been pressed several times (i4=>1)
    Last edited by electronico; 10-24-2012 at 07:21 AM. Reason: Added log file

  2. #2
    Trusted Penguin
    Join Date
    May 2011
    Posts
    4,353
    could it be the carriage return in the logfile? Try piping the output of tac to dos2unix, as a test, e.g.:

    Code:
    last_line=`tac $log_file | dos2unix | egrep -a -m 1 .`

  3. #3
    Just Joined!
    Join Date
    Oct 2007
    Posts
    15
    I myself wouldn't be using cat as much as I'd be using 'tail' and specifying the number of lines I want from the log file (tail -1) then I'd only be seeing the last value that appeared there as a reply. You may also be running into some form of kernel driver I/O wait issue that is causing the (seemingly) out of sequence bytes in your output.

  4. $spacer_open
    $spacer_close
  5. #4
    Just Joined!
    Join Date
    Jul 2005
    Location
    New-Caledonia
    Posts
    29
    Quote Originally Posted by atreyu View Post
    could it be the carriage return in the logfile? Try piping the output of tac to dos2unix, as a test, e.g.:

    Code:
    last_line=`tac $log_file | dos2unix | egrep -a -m 1 .`
    Thanks for your answer !
    dos2unix is now (ubuntu 12.04) in the 'tofrodos' package and is called 'fromdos'.
    I've tried this solution but it doesn't seem to parse last line correctly neither.

  6. #5
    Just Joined!
    Join Date
    Jul 2005
    Location
    New-Caledonia
    Posts
    29
    Quote Originally Posted by waynemot View Post
    I myself wouldn't be using cat as much as I'd be using 'tail' and specifying the number of lines I want from the log file (tail -1) then I'd only be seeing the last value that appeared there as a reply. You may also be running into some form of kernel driver I/O wait issue that is causing the (seemingly) out of sequence bytes in your output.
    Thanks for your answer !
    tail -1 was the first thing I've tried, it doesn't seem to work as expected neither.
    But i think you're right about the kernel driver wait I/O, because even the logfile is not correctly fed by tty.
    I'll make deeper tests including date in the logs to try to fix this issue.

    I thought to only log numbers to logfile, but I haven't found the right syntax for this:
    Code:
    cat < $port | grep [0-1] > $log_file &
    doesn't output only numbers to logfile, any help with this ?

  7. #6
    Just Joined!
    Join Date
    Jul 2005
    Location
    New-Caledonia
    Posts
    29
    Thanks a lot for your answers !
    I had several problems, as as an idiot I was killing the main script by CTRL+C, but the cat tty to logfile was still running in background, so I ended up with a lot of cat operations that were confusing the system after several main script launch.
    About main problem, timing was well the solution.
    The 'tail -1' or 'tac' produce the same result.
    The sleep command had to be just after the echo to tty, to let time to the device to answer.
    Here is the code thart works :
    Code:
    #!/bin/bash
    # variables
    port='/dev/myttyUSB0'
    log_file='/var/log/myttyUSB0.log'
    # init tty, needed for this device
    stty -F /dev/myttyUSB0 9600 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke min 1 time 5
    # empty log file
    echo '' > $log_file
    # launch service to parse tty port to log file
    cat < $port > $log_file &
    # do forever
    while [ true ]; do
    	# -e (enable interpretation of backslash escapes) and -n (do not output the trailing newline)
    	# \r : carriage return to validate the command
    	echo -en "i4\r" > $port
    sleep 0.1
    	# tac=cat reverse, -a:treat as text(not binary), -m 1:only one line, .:not empty line
    	last_line=`tac $log_file | egrep -a -m 1 .`
    	echo "last_line=$last_line"
    	if [[ $last_line == *"1"* ]]; then
    		echo '***** DETECTED BUTTON PRESSED *****'
    	fi
    done
    Last edited by electronico; 10-25-2012 at 10:55 PM. Reason: typos

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •