Results 1 to 8 of 8

Thread: Best way to work with Arduino serial output via BASH?

  1. #1
    Join Date
    Jan 2006
    Beans
    56

    Best way to work with Arduino serial output via BASH?

    I have an Arduino Uno running a little script that reads from the SHT-15 temp / humidity sensor, then ouputs the values via serial. The output looks great in the Arduino Serial monitor, and I can even cat the output. The output looks like this:

    Code:
    temp=68.04
    humidity=54.47
    temp=68.00
    humidity=54.47
    When this same Arduino was hooked up to an Eee PC, I would run this command to pull the data off of the serial port and into a txt file:

    Code:
    ttylog -b 38400 -d /dev/ttyUSB0 | tee /home/holotone/temphumidity/results.txt 2>&1
    On the newer computer that the Arduino is connected to, this only produces garbage output, a couple weird characters repeated over and over really fast. The output looks fine via the Arduino serial monitor, and also looks fine when I use cat or picocom.

    Ultimately, I want to somehow monitor the serial output of the Arduino and log the results somewhere they are easy to access. Email notification when temp / humidity thresholds are reached is a must. Data visualization (via Google Charts, maybe?) would be awesome.

    A buddy helped me whip up a bash script (monitor.sh) to monitor the log file (results.txt) that's supposed to be generated by ttylog (which doesn't work on the new computer); Here is monitor.sh for reference:

    Code:
    #!/bin/bash
    
    # define file vars
    tempfile=/home/holotone/temphumidity/results.txt
    logfile=/home/holotone/temphumidity/logfile.log
    errorlog=/home/holotone/temphumidity/error.log
    max_temp="85.00"
    min_temp="63.00"
    
    # extract $temp and $humidity
    data=`tail -n 4 $tempfile`
    eval $data
    
    # generate timestamp
    date=`date +%Y-%m-%d,%H:%M:%S`
    
    # calculate alert threshhold
    if [[ "$temp" > "$max_temp" ]]
    then
      # send email
      echo "Currently: $temp / Max: $max_temp at $date" | mail -s "Temperature Exceeded!" "me@email.com"
      echo "$date: $temp / $max_temp" >> $errorlog
      echo "Too hot! Currently: $temp; Maximum of $max_temp exceeded!"
    else
      echo "Temp OK: Currently: $temp"
    fi
    
    # save to logfile
    string="$date,$temp,$humidity"
    echo $string >> $logfile
    
    # erase existing temp file
    echo "" > $tempfile

    Basically I moved the setup from an Eee PC on which is was working to a new computer and now nothing works. Step 1 (serial > txt via ttylog) does not work correctly. Even if it did, the monitor.sh bash script doesn't work any more either, even when I manually enter values into the results.txt file that ttylog is not creating correctly. Here's the error I get when I try to run monitor.sh:

    Code:
    holotone@piff ~/temphumidity $ sh monitor.sh 
    monitor.sh: 18: monitor.sh: [[: not found
    Temp OK: Currently:
    As may be evidenced by my clear lack of understanding, I'm not much of a coder. I get the basics, but I never would have made it this far without the significant help of a friend.

    What's going on here? Is there a better way to take the serial output from the Arduino and use it to log historical temp / humidity data and give me notifications when thresholds are reached?

    Thanks in advance for the help!

  2. #2
    Join Date
    Jan 2006
    Beans
    56

    Re: Best way to work with Arduino serial output via BASH?

    On the advice of a friend I removed the double brackets from line 18 of monitor.sh and that seems to resolve the errors that's throwing. Woohoo! Now I think I just have to get the serial output > text file thing figured out...

  3. #3
    Join Date
    Aug 2011
    Location
    47°9′S 126°43W
    Beans
    2,172
    Distro
    Ubuntu 16.04 Xenial Xerus

    Re: Best way to work with Arduino serial output via BASH?

    It should have worked. I works fo me (if I use a file containing lines with "temp=98.00"), so you must have another problem...

    The "eval" bit is dangerous, you can fall prey to whatever comes in the file. Better do a proper parsing (sed, awk or else). This could be your problem.

    You also have a glaring bug. You are comparing your temperatures using ">" which is a string comparison, so your code is very happy with input temperatures of 100F and above (because alphabetically, 100<65). You should be using numeric comparisons (-lt, -gt, -le, -ge). The work only with integers, but when you parse in your numbers you can either truncate them or transform them to hundreths of degrees (ie, deal with 6500 instead of 65.00).
    Warning: unless noted otherwise, code in my posts should be understood as "coding suggestions", and its use may require more neurones than the two necessary for Ctrl-C/Ctrl-V.

  4. #4
    Join Date
    Jan 2006
    Beans
    56

    Re: Best way to work with Arduino serial output via BASH?

    Quote Originally Posted by ofnuts View Post
    The "eval" bit is dangerous, you can fall prey to whatever comes in the file. Better do a proper parsing (sed, awk or else). This could be your problem.
    Sorry to be dense, but like I said I'm not much of a programmer - How specifically would I do that? I'm not familiar with sed, awk, or else, but I am decently comfortable using the CLI. To be honest I'm not even sure what 'eval' is doing here.

    Quote Originally Posted by ofnuts View Post
    You also have a glaring bug. You are comparing your temperatures using ">" which is a string comparison, so your code is very happy with input temperatures of 100F and above (because alphabetically, 100<65). You should be using numeric comparisons (-lt, -gt, -le, -ge). The work only with integers, but when you parse in your numbers you can either truncate them or transform them to hundreths of degrees (ie, deal with 6500 instead of 65.00).
    Wow, good eye! I understand the problem, but not specifically how to use those flags - Can you explain?

    I noticed something else that was kinda weird happening when I run monitor.sh - It echos this:

    Code:
    holotone@piff ~/temphumidity $ sh monitor.sh
    ; Maximum of 85.00 exceeded!
    ...then creates an empty file called '85.00'. wtf?

  5. #5
    Join Date
    Aug 2011
    Location
    47°9′S 126°43W
    Beans
    2,172
    Distro
    Ubuntu 16.04 Xenial Xerus

    Re: Best way to work with Arduino serial output via BASH?

    Quote Originally Posted by holotone View Post
    Sorry to be dense, but like I said I'm not much of a programmer - How specifically would I do that? I'm not familiar with sed, awk, or else, but I am decently comfortable using the CLI. To be honest I'm not even sure what 'eval' is doing here.
    Hard to give useful hints without knowing how the data looks like. Fror the code you use it seems the file contains lines like "temp=65.30" but I'd like to see a real case.
    Quote Originally Posted by holotone View Post
    Wow, good eye! I understand the problem, but not specifically how to use those flags - Can you explain?
    Instead of:
    Code:
    if [[ $temp > $max_temp ]]
    You use:
    Code:
    if [[ $temp -gt $max_temp ]]
    but this assumes that $temp and $max_temp are integers (so either you drop the fractional part earlier in the code (which, for your purposes, coud be adequate) or you use number that are hundredths of degrees.
    Quote Originally Posted by holotone View Post
    I noticed something else that was kinda weird happening when I run monitor.sh - It echos this:
    Code:
    holotone@piff ~/temphumidity $ sh monitor.sh
    ; Maximum of 85.00 exceeded!
    ...then creates an empty file called '85.00'. wtf?
    This is a direct consequence of your "fix" removing the double brackets. You have a line that bash interprets as:
    Code:
    65.00 > 85.00
    So it tries to find a command called "85.00" and sends its output to a file called "85.00".
    Warning: unless noted otherwise, code in my posts should be understood as "coding suggestions", and its use may require more neurones than the two necessary for Ctrl-C/Ctrl-V.

  6. #6
    Join Date
    Jan 2006
    Beans
    56

    Re: Best way to work with Arduino serial output via BASH?

    Quote Originally Posted by ofnuts View Post
    Hard to give useful hints without knowing how the data looks like. Fror the code you use it seems the file contains lines like "temp=65.30" but I'd like to see a real case.
    Here's an example of the data if I create it using 'cat </dev/ttyUSB0 | tee results.txt 2>&1':

    Code:
    Starting up
    temp=67.24
    humidity=56.34
    temp=67.24
    humidity=56.31
    temp=67.24
    humidity=56.31
    temp=67.23
    humidity=56.27
    temp=67.24
    humidity=56.31
    temp=67.28
    humidity=56.31
    temp=67.28
    humidity=56.34
    temp=67.30
    humidity=56.28
    temp=67.28
    humidity=56.37
    temp=67.30
    humidity=56.34
    temp=67.28
    humidity=56.34
    temp=67.30
    humidity=56.35
    temp=67.28
    humidity=56.35
    temp=67.30
    humidity=56.28
    Quote Originally Posted by ofnuts View Post
    Instead of:
    Code:
    if [[ $temp > $max_temp ]]
    You use:
    Code:
    if [[ $temp -gt $max_temp ]]
    but this assumes that $temp and $max_temp are integers (so either you drop the fractional part earlier in the code (which, for your purposes, coud be adequate) or you use number that are hundredths of degrees.
    Awesome - I'm not sure how to make sure that the values are integers or how to make them integers if they aren't, but I suspect that's something I can figure out with a bit of googling...

    Quote Originally Posted by ofnuts View Post
    This is a direct consequence of your "fix" removing the double brackets. You have a line that bash interprets as:
    Code:
    65.00 > 85.00
    So it tries to find a command called "85.00" and sends its output to a file called "85.00".
    It seems to do this whether there are double brackets or not.

    Thanks again for your patience and help!

  7. #7
    Join Date
    Aug 2011
    Location
    47°9′S 126°43W
    Beans
    2,172
    Distro
    Ubuntu 16.04 Xenial Xerus

    Re: Best way to work with Arduino serial output via BASH?

    Code:
    temp=$(tail -2 $temp_file | sed -e '/^humidity=.*$/d' -e 's/temp=//' -e 's/\.//') # yields 6580
    temp=$(tail -2 $temp_file | sed -e '/^humidity=.*$/d' -e 's/temp=//' -e 's/\.[0-9]*//') # yields 65
    In slow motion: get the last two lines of the file (tail -2) then use sed to a) delete the one with "humidity", b) remove "temp=" and c) drop the period or the period and any digits following it.

    If you have trouble with the double brackets, then maybe your bash isn't bash but a Korn-like shell... What do you get when you use "/bin/bash --version" on a command prompt? if should answer:
    GNU bash, version 4.2.37(1)-release (x86_64-pc-linux-gnu)
    Copyright (C) 2011 Free Software Foundation, Inc.
    Warning: unless noted otherwise, code in my posts should be understood as "coding suggestions", and its use may require more neurones than the two necessary for Ctrl-C/Ctrl-V.

  8. #8
    Join Date
    May 2010
    Location
    uk
    Beans
    9,249
    Distro
    Xubuntu 14.04 Trusty Tahr

    Re: Best way to work with Arduino serial output via BASH?

    Hi

    [[ is not available in dash. I believe it's a bashism.

    In your first post you were invoking the script using the dash shell.

    Kind regards
    If you believe everything you read, you better not read. ~ Japanese Proverb

    If you don't read the newspaper, you're uninformed. If you read the newspaper, you're mis-informed. - Mark Twain

    Thinking about becoming an Ubuntu Member?

Tags for this Thread

Bookmarks

Posting Permissions

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