Go Down

Topic: FYI - Arduino to Linux serial communications (Read 2823 times) previous topic - next topic


Dec 04, 2012, 09:45 pm Last Edit: Dec 04, 2012, 11:15 pm by celem Reason: 1
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:

Code: [Select]
** 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.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){
   LightLevel &= 255; // limit variable to 1-byte

Code: [Select]
# 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"
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"

Code: [Select]
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"

Code: [Select]
# 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


Dec 04, 2012, 11:57 pm Last Edit: Dec 04, 2012, 11:59 pm by robtillaart Reason: 1
Thanks for sharing! (bookmarked)
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)


Apr 16, 2013, 10:14 am Last Edit: Apr 16, 2013, 10:20 am by ptrakk Reason: 1
I used this code and it displays, but the sting comparison doesn't end/break ?

Arduino code:
Code: [Select]

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

void loop()                      

bash script:
Code: [Select]


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
      echo success        
done < /dev/ttyACM0

echo IHateSandcastles.jpg

Code: [Select]

oHai World!

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


when i use
Code: [Select]
if [[ "$line" = "END"* ]]; then
it works? i guess the newline character is being sent to the terminal?

Go Up