FYI - Arduino to Linux serial communications

FYI - A recent project was to test and characterize the performance of a bag of inexpensively obtained LDRs (Light Defined Resistors). These particular LDRs were a special assembly of a GL5528 LDR, infrared blocking glass filter and a rubber housing. They are specifically designed for video camera use. I created a dark chamber (a shoebox) with a white-light LED at one end and the subject LDR at the other. The Arduino NANO controls the white-light LED and measures the LDR at various light levels. The test data is output over the Arduino serial port to a shell script running on my Linux desktop. The shell script accepts a file creation name, restarts the Arduino and captures the Arduino's serial output into a file. When the Arduino signals that its data set is complete, the Linux shell script draws a line graph of the LDR's performance curve with a second line of a control performance.

I paste the code of the whole thing in hopes that someone may see something within that will help them in their own project. If you want to read more about my LDR project, refer to my blog:

ldrtest.ino

/* 
 ** Plot photoresistor(LDR) response curve
 ** Edward I. Comer December 2012
 */
// Defines
#define DELAYTIME 10000		// Delay 10 seconds
#define	MAXLIGHTLEVEL 25	// Max brightness level
#define STARTLIGHTLEVEL 9      // Starting point
#define	INCREMENT 1		// increment to boost light

// constants won't change. Used here to 
// set pin numbers:
const int localLEDPin =  13;         // the number of the LED pin
const int ldrPin = 1;                // pin number with LDR
const int lightPin = 3;              // pin for flashlight
int LightLevel = STARTLIGHTLEVEL;    // light brightness 0-to-255
int ldrValue = 0;                    // Value read

void setup() {
    // set the digital pin as output:
    pinMode(localLEDPin, OUTPUT); // set pin 13 as output
    Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
    //  Serial.println("ldrtest.ino running");
    //  Serial.println("waiting 60 seconds");
    analogWrite(lightPin,0);    // settle at starting light level
    delay(10000);		// wait 10 secs for LDR to settle
    //  delay(30000);		// wait 30 secs for LDR to settle
    //Serial.println("\"Light value\",\"LDR value\"");
}

void shutdown()
{
    analogWrite(lightPin,0);	// Turn light off
    Serial.print("END");
    Serial.write(0x0a);			// newline character for Linux
    // Rapid blink indicates completion of test
    while(1){  // endless loop
        digitalWrite(localLEDPin, HIGH);   // sets the LED on
        delay(500);                  // waits for a second
        digitalWrite(localLEDPin, LOW);    // sets the LED off
        delay(500);                  // waits for a second
    }
}

void loop()
{
    // Turn on local LED to indicate test start
    digitalWrite(localLEDPin, HIGH);		// local LED on
    analogWrite(lightPin,LightLevel);	// set light brightness
    delay(DELAYTIME);					// wait for LDR to settle
    ldrValue = analogRead(ldrPin);		// read LDR value
    // Turn on local LED to indicate test stopped
    digitalWrite(localLEDPin, LOW);		// local LED off

    Serial.print(LightLevel, DEC);		// Print CSV format X-axis
    //Serial.print(", ");
    Serial.print(" ");
    Serial.print(ldrValue, DEC);		// Print CSV format Y-axis
    Serial.write(0x0a);					// newline character for Linux

    LightLevel += INCREMENT;			// increment light brightness
    if(LightLevel > MAXLIGHTLEVEL){
        shutdown();
    }
    LightLevel &= 255;					// limit variable to 1-byte
}

ldrtest.sh

#!/bin/bash
# Acquire LDR data and plot results from Arduino script ldrtest.ino
# Reads two column data from Arduino into a file, then
# creates a graph using gnuplot
# NOTE: stty raw keeps port open
# Edward Comer - December 2012
#
echo -n "Type device name and press [ENTER]: "
read device
echo -n > ${device}.txt

# Toggle DTR to restart Arduino, then set baud=9600 and RAW mode to keep port open
stty -F /dev/ttyUSB0 hupcl
stty -F /dev/ttyUSB0 cs8 9600 raw ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts

# Read Arduino serial port until text END is received
while read line; do
     if [ "$line" != "END" ]; then
          echo "$line" >> ${device}.txt
	  echo "Received $line"
     else
          break
     fi
done < /dev/ttyUSB0

# create gnuplot graph of LDR results
echo Plotting $device.txt
gnuplot -e "source=\"$device.txt\"; set output \"$device.png\"" plotscript.gp
echo Graph "$device.png" created
# Display plot on screen
eog "$device.png"

plotscript.gp

set terminal png nocrop font small size 1024,768
set title "LDR Response"
set xlabel "LIGHT-SETTING"
set ylabel "LDR-VALUE"
set grid
plot  source using 1:2 with linespoints notitle , "control.txt" using 1:2 with linespoints title "Control"

control.txt

# control data set for GL5528 LDR
9 1015
10 996
11 841
12 431
13 188
14 96
15 51
16 42
17 37
18 34
19 31
20 30
21 23
22 22
23 23
24 22
25 22

Thanks for sharing! (bookmarked)

:~
I used this code and it displays, but the sting comparison doesn't end/break ?

Arduino code:

void setup()                  
{
  Serial.begin(9600);     
  Serial.println("oHai World!");}

void loop()                       
{     
     delay(1000);
     Serial.println("END");
 }

bash script:

#!/bin/bash

stty -F /dev/ttyACM0 hupcl
stty -F /dev/ttyACM0 cs8 9600 raw ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts
 
while read line; do
     if [ "$line" != "END" ]; 
       then echo $line
     else 
       echo success         
       break
     fi
done < /dev/ttyACM0


echo IHateSandcastles.jpg

output:

oHai World!
END
END
END
END
END
END
END
END
END
END
END

seems the if/then string comparison isn't working?

when i use

if [[ "$line" = "END"* ]]; then

it works? i guess the newline character is being sent to the terminal?