6 Replies - 4265 Views - Last Post: 16 November 2012 - 01:13 PM Rate Topic: -----

#1 SlapYourBaby  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 13-November 12

Arduino Python Serial Communication Issue

Posted 14 November 2012 - 06:13 AM

Hey everyone, this is my first post so if there is anything I need to change please let me know.

Main issue:
I am trying to use pySerial to communicate with my Arduino and everything works for about 5-30 seconds. It appears to be a timing issue.

I am getting this error when the Python script crashes in the terminal:

Traceback (most recent call last):
File "maincontrol1.py", line 76, in <module>
val3 = ser.readline()
File "/usr/local/lib/python2.7/dist-packages/serial/serialposix.py", line 453, in read
buf = os.read(self.fd, size-len(read))
OSError: [Errno 11] Resource temporarily unavailable


or a similar error that says "device reports readiness to read but returned no data".


The Project:
Control servos while sending pictures and text files to a remote server using two Arduinos (Mega connected to computer via USB and Uno connected to mega via UART) and a Python script.

There is also code for the Arduino Uno that is connected to the Mega which controls the servos. I didn't post it because all it does is receive a command from the Mega to move servos and I didn't want to flood the page with more code. Let me know if it is needed and I'll put it up.

Here is the python code:

import serial
import nltk   
from urllib import urlopen
import time
import os

serialport = "/dev/ttyACM6"
ser = serial.Serial(serialport, 115200)
time.sleep(1)
print "we are connected"

while (1):

	
	
#***************************Servo***************************************
	# URL for servo position
	url = "server url"  
	html = urlopen(url).read()    				# Read HTML
	raw = nltk.clean_html(html) 				# Gets conent only
	
	#url1 = "server url"	
	#html1 = urlopen(url1).read()
	#html2 = urlopen(url2).read()
	#print("while statement")
	
	if(raw != 'off'):			# Only want 3 digits
		# Send position to arduino
		#print("Move to:")
		#print(raw)
		ser.write(raw)
		#time.sleep(.005)
	elif(raw == 'off'):
		print("Elif statement")
		url = "server url"  
		html = urlopen(url).read()    			# Read HTML
		raw = nltk.clean_html(html) 			# Clean HTML
	else:
		print("Position out of range or invalid")
		#time.sleep(.005)
	
	#print("after if")
#******************************Camera***********************************
	# Get state of command
	url = "server url"   
	html = urlopen(url).read()    # Get HTML
	raw = nltk.clean_html(html) 	# Clean HTML
	
	if (raw == '1'):
		print("**Taking Photo**") 	# Does user want to take pictures
		x = 'streamer -c /dev/video1 -o to directory'
		y = 'convert image' 
		z = 'scp file to server'
		os.system(x)
		os.system(y)
		os.system(z)

	elif (raw == '0'):
		print("**Camera Off**")
	#else :
		#print("Invalid Camera Value")
	
#****************Read Temp*************	
#***************************Read Values***************************************
	alertVal = ser.read()			
	val1 = ser.read()
	val2 = ser.read()
	val3 = ser.readline() 
#*************************Analyze**************************************	
	if(alertVal == '1'):
		x = 'scp file to server'
		os.system(x)
		print("alert")
     
	#else : 
		#print(alertVal)
		
	finVal = val1 + val2 + val3
	#print(finVal)
	
	#time.sleep(.1)
	#print(alertVal)
	#print (val1)
	#print (val2)
	#print (val3)
	try:
# This will create a new file or **overwrite an existing file**.
		f = open("temp.txt", "w")
		try:
			f.write(finVal) # Write a string to a file
			#f.writelines(finVal) # Write a sequence of strings to a file
		finally:
			f.close()
	except IOError:
		pass
#Send the file to the server
	x = 'scp file to server'
	os.system(x)     
	
print "goodbye"	


Here is the Arduino Mega Code:

#include <Servo.h> 
//Must display the string value of the digits produced
//Check for the stars 
Servo horServo;  // create servo object to control a servo 
Servo verServo; 
//*********************THIS does servo, ping, and temp
boolean lastVal; 
boolean curVal; 
char sendVal[3];
char change; 
//char testVal[2];
const int pingPin = 53;
int pos           = 0;    // variable to store the servo position 
int i             = 0;
int j             = 0; 
int switchPin     = 47;
int tempC         = 0; 
int len; 

void setup() {

  // initialize serial communication:
  Serial.begin(115200);
  Serial1.begin(115200); 
  Serial.println("We are Connected");
  //verServo.attach(9);  // attaches the servo on pin 9 to the servo
  //horServo.attach(10); 
  
  //verServo.write(90);
  //horServo.write(90); 
  
//  attachInterrupt(0, alert, RISING); //Arduino interrupt library
}

void loop()
{

//***********************Ping Distance Sensor**********************
  long duration, inches, cm;
    // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
  // The same pin is used to read the signal from the PING))): a HIGH
  // pulse whose duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  // convert the time into a distance
  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);
  

//  Serial.print(inches);
//  Serial.print("in, ");
//  Serial.print(cm);
//  Serial.print("cm");
//  Serial.println();
//*************************************************************************  
  
  
  
  // int incomingByte=0;
  //int outByte[3];
  // int outSum; 
  char inByte; 

//******************Read Direction Command**************************
 if (Serial.available() > 0) {
      
  // Read Servo Value 
    inByte = Serial.read();
    Serial1.println(inByte);
 } 
   
//*************Testing Button Read*******************
//  curVal = debounce(lastVal); 
//  if (curVal == HIGH){
//    count++; 
//  }
  int a = analogRead(A5);
  tempC = convert(a); 
 /* Serial.print("Temp: "); 
  Serial.println(tempC); 
  Serial.print("Reading: "); 
  Serial.println(a); */
  
  
 
  if (length(tempC) == 2){
    if (tempC > 90){
      sendVal[0] = '0';
      sendVal[1] = '9'; 
      tempC = tempC - 90; 
    }
    else if (tempC >= 80){
      sendVal[0] = '0';
      sendVal[1] = '8';  
      tempC = tempC - 80; 
    }
    else if (tempC >= 70){
      sendVal[0] = '0';
      sendVal[1] = '7'; 
      tempC = tempC - 70; 
    }
    else if (tempC >= 60){
      sendVal[0] = '0';
      sendVal[1] = '6'; 
      tempC = tempC - 60;  
    }
    else if (tempC >= 50){
      sendVal[0] = '0';
      sendVal[1] = '5';
      tempC = tempC - 50;        
    }
    else if (tempC >= 40){
      sendVal[0] = '0';
      sendVal[1] = '4'; 
      tempC = tempC - 40;
    }
    else if (tempC >= 30){
      sendVal[0] = '0';
      sendVal[1] = '3'; 
      tempC = tempC - 30;
    }
    else if (tempC >= 20){
      sendVal[0] = '0';
      sendVal[1] = '2'; 
      tempC = tempC - 20;
    }
   else if (tempC >= 10){ 
      sendVal[0] = '0';
      sendVal[1] = '1'; 
      tempC = tempC - 10;
      
   } 
   
  }
  

   else if (length(tempC) == 1){
     sendVal[0] = '0';
     sendVal[1] = '0'; 
     
   }
  tempC = tempC + '0'; 
  sendVal[2] = tempC; 
  
  if (cm > 10){
    Serial.print("1"); 
  }
  else Serial.print(0); 
  
  
  if (length(tempC) < 3){
    //Serial.println("length 2"); 
    Serial.print(sendVal[0]); 
    Serial.print(sendVal[1]);
    Serial.println(sendVal[2]); 
   
  }
  
  else if (length(tempC) == 3){
    Serial.println("Length 3"); 
    Serial.println(tempC); 
  }
  /*Serial.print("Temp: "); 
  Serial.println(tempC); */ 
  //Serial.println(sendVal); 
  lastVal = curVal; 
  delay(1); 
}

/*void alert(){
  Serial.println("1"); 
  while (Serial.available() == 0); 
  int ackVar = Serial.read(); 
    if (ackVar == '1'){
       Serial.println("1"); 
    }  
} 
*/
boolean debounce(boolean last)
{
boolean current = digitalRead(switchPin);
if (last != current)
{
  delay(5);
  current = digitalRead(switchPin);
}
return current;
}

int length(int someValue){
int valLen = 0;

if(someValue > 9999)
   valLen = 5;
else if(someValue > 999)
   valLen = 4;
else if(someValue > 99)
   valLen = 3;
else if(someValue > 9)
   valLen = 2;
else
   valLen = 1;
   
return valLen; 
   
}

int convert(int reading){
  float calc = (reading*205)/307;
  int rCalc = round(calc); 
  return rCalc; 
}

long microsecondsToInches(long microseconds)
{
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds)
{
  return microseconds / 29 / 2;
}


Is This A Good Question/Topic? 0
  • +

Replies To: Arduino Python Serial Communication Issue

#2 Python_4_President  Icon User is offline

  • D.I.C Regular

Reputation: 53
  • View blog
  • Posts: 321
  • Joined: 13-August 11

Re: Arduino Python Serial Communication Issue

Posted 14 November 2012 - 02:20 PM

I remember when I was building my RC car that when I was running an OSEPP mega 2560, I would sometimes get errors when communicating with the arduino when my power supply voltage was <= 9 volts. The closer to 12v volts I got, the less I encountered those issues.

Something else you might want to try is wrapping your read statements in an try/except block with a continue statement after the except. (since you're doing a considerable amount of processing within a large while loop, it will simply skip over everything following the reads and resume at the top of the while loop for the next iteration.)

Intermittent problems may be ignorable, but that depends on your application.


Example:

            try:
                alertVal = ser.read()          
	        val1 = ser.read()
	        val2 = ser.read()
	        val3 = ser.readline()
            except Exception, e:
                print "Failed to read in the usual spot: ", e
                continue



Also, it looks like you're probably using Serial (in the mega code) to print stuff out on the Arduino IDE serial monitor, but you're also trying to read data from the arduino in your Python script. Presumably, that's what you want to use Serial1 for (in your mega code, to send sendVal[0:3]), but I don't see that you ever used Serial1.

Instead of using println to mark the end of a transmission, you could transmit your own terminator.


Why I suggest that is because, per the pySerial documentation,

Quote

readline(size=None, eol='\n')
Parameters:

size – Max number of bytes to read, None -> no limit.
eol – The end of line character.

Read a line which is terminated with end-of-line (eol) character (\n by default) or until timeout.



per the Arduino Println documentation:

Quote

Description

Prints data to the serial port as human-readable ASCII text followed by a carriage return character (ASCII 13, or '\r') and a newline character (ASCII 10, or '\n'). This command takes the same forms as Serial.print().



So, pySerial is reading until \n, and arduino is giving it \r\n. Could cause some problems depending on what you end up doing with the file you write.

This post has been edited by Python_4_President: 14 November 2012 - 02:56 PM

Was This Post Helpful? 1
  • +
  • -

#3 SlapYourBaby  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 13-November 12

Re: Arduino Python Serial Communication Issue

Posted 14 November 2012 - 03:02 PM

Thank you for your reply. I am working on it now.

Quick question, though, is "ser.read()/ser.readline() an equivalent for Arduino's Serial.available() function? Somebody recommended that I let Python wait until Arduino has something to send and from what I can tell that's what the ser.read() function is doing.
Was This Post Helpful? 0
  • +
  • -

#4 Python_4_President  Icon User is offline

  • D.I.C Regular

Reputation: 53
  • View blog
  • Posts: 321
  • Joined: 13-August 11

Re: Arduino Python Serial Communication Issue

Posted 14 November 2012 - 03:36 PM

View PostSlapYourBaby, on 14 November 2012 - 03:02 PM, said:

Thank you for your reply. I am working on it now.

Quick question, though, is "ser.read()/ser.readline() an equivalent for Arduino's Serial.available() function? Somebody recommended that I let Python wait until Arduino has something to send and from what I can tell that's what the ser.read() function is doing.



By default, ser.read() will read 1 byte of data, or timeout (if a timeout is set). Whichever comes first(or never, in the case of no timeout, which is the default).

I think you're after ser.inWaiting(), which returns the number of bytes in the receive buffer (if any exist).

I meant to mention that, but I got promoted at work (READ: HR lady interrupted my posting time to tell me I get more money) right before I got off work.

something like:
if ser.inWaiting():
    #stuff is available to read.




Give a thorough read to the pySerial classes documentation


Pay special attention to the very first part (re: __init__) which tells you what the default settings are when you do something like:
ser = serial.Serial(port, baud)





EDIT: Ok, got my arduino running on of the serial examples and pyserial trying to send it a bit of data and then read a line back clumsily like you do.

Got the same error.

Traceback (most recent call last):
  File "/home/devman/workspace/dic_serial/src/dic_serial_arduino.py", line 9, in <module>
    print ser.readline()
  File "/usr/local/lib/python2.7/dist-packages/serial/serialposix.py", line 460, in read
    raise SerialException('device reports readiness to read but returned no data (device disconnected?)')
serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected?)



Reading the output from Arduino in both the serial monitor and the python script is the culprit.

Also confirms my suspicions that you'll be getting data you weren't expecting, too.

You'll probably want to revise your Python code to give you the output you're currently watching through the IDE's serial monitor. To isolate informational messages from the data in the sendVal array, you'll probably want to do something like:

debug msg...
debug msg...
~sendval data~ <-- note the ~'s before and after, these will let you know where the data is.
debug msg...
debug msg...




You can test for the start and end of the valuable data based on the delimiters you choose, and route that data (in your example, to a file) as appropriate.

This post has been edited by Python_4_President: 14 November 2012 - 05:19 PM

Was This Post Helpful? 1
  • +
  • -

#5 SlapYourBaby  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 13-November 12

Re: Arduino Python Serial Communication Issue

Posted 15 November 2012 - 04:22 PM

Congratulations on your promotion.

What you are saying in your post makes sense. I'll post the results later on tonight or tomorrow.
Was This Post Helpful? 0
  • +
  • -

#6 SlapYourBaby  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 13-November 12

Re: Arduino Python Serial Communication Issue

Posted 16 November 2012 - 12:54 PM

I got it to work yesterday with the following code:

Python

import serial
import nltk   
from urllib import urlopen
import time
import os

serialport = "/dev/ttyACM0"
ser = serial.Serial(serialport, 115200)
time.sleep(1)
print "we are connected"
alertVal = 0
val1 = '0'
val2 = '0'
val3 = '0'
finVal = '0'

while (1):

	
	
#***************************Servo***************************************
	# URL for servo position
	url = "http://lamp.cse.fau.edu/~mneal11/text/position.txt"  
	html = urlopen(url).read()    				# Read HTML
	raw = nltk.clean_html(html) 				# Gets conent only
	
	#url1 = "http://lamp.cse.fau.edu/~mneal11/text/verPos.txt"	
	#html1 = urlopen(url1).read()
	#html2 = urlopen(url2).read()
	#print("while statement")
	
	if(raw != 'off'):			# Only want 3 digits
		# Send position to arduino
		#print("Move to:")
		print(raw)
		ser.write(raw)
		#time.sleep(.005)
	elif(raw == 'off'):
		print("Elif statement")
		url = "http://lamp.cse.fau.edu/~mneal11/text/buttonPos.txt"  
		html = urlopen(url).read()    			# Read HTML
		raw = nltk.clean_html(html) 			# Clean HTML
	else:
		print("Position out of range or invalid")
		#time.sleep(.005)
	
	#print("after if")
#******************************Camera***********************************
	# Get state of command
	url = "http://lamp.cse.fau.edu/~mneal11/text/camera.txt"   
	html = urlopen(url).read()    # Get HTML
	raw = nltk.clean_html(html) 	# Clean HTML
	
	if (raw == '1'):
		print("**Taking Photo**") 	# Does user want to take pictures
		x = 'streamer -c /dev/video1 -o /home/michael/public_html/pics/camtest.jpeg > /dev/null 2>&1'
		y = 'convert /home/michael/public_html/pics/camtest.jpeg -rotate 90 /home/michael/public_html/pics/camtest.jpeg' 
		z = 'scp /home/michael/public_html/pics/camtest.jpeg mneal11@lamp.cse.fau.edu:/home/mneal11/public_html/'
		os.system(x)
		os.system(y)
		os.system(z)
	elif (raw == '0'):
		print("**Camera Off**")
	#else :
		#print("Invalid Camera Value")
	
#***************************Read Values***************************************
	if (ser.inWaiting() > 0):
		try:
			alertVal = ser.read()         
			val1 = ser.read()
			val2 = ser.read()
			val3 = ser.readline()
			#finVal = ser.readline(size=3)
			ser.flushInput()
			#print(finVal)
		except Exception, e:
			print "Failed to read in the usual spot: ", e
			continue
#*************************Analyze**************************************	
	if(alertVal == '1'):
		x = 'scp /home/michael/public_html/alertFile.txt mneal11@lamp.cse.fau.edu:/home/mneal11/public_html/text/'
		os.system(x)
		print("alert")
     
	#else : 
		#print(alertVal)
		
	finVal = val1 + val2 + val3
	print(finVal)
	
	#time.sleep(.1)
	#print(alertVal)
	#print (val1)
	#print (val2)
	#print (val3)
	try:
# This will create a new file or **overwrite an existing file**.
		f = open("temp.txt", "w")
		try:
			f.write(finVal) # Write a string to a file
			#f.writelines(finVal) # Write a sequence of strings to a file
		finally:
			f.close()
	except IOError:
		pass
#Send the file to the server
	x = 'scp /home/michael/public_html/temp.txt mneal11@lamp.cse.fau.edu:/home/mneal11/public_html/text/'
	os.system(x)     
	
print "goodbye"	




Arduino mega connected to the computer

#include <Servo.h> 
//Must display the string value of the digits produced
//Check for the stars 
Servo horServo;  // create servo object to control a servo 
Servo verServo; 
//*********************THIS does servo, ping, and temp
boolean lastVal; 
boolean curVal; 
char sendVal[3];
char change; 
//char testVal[2];
const int pingPin = 53;
int pos           = 0;    // variable to store the servo position 
int i             = 0;
int j             = 0; 
int switchPin     = 47;
int temp         = 0; 


void setup() {

  // initialize serial communication:
  Serial.begin(115200);
  Serial1.begin(115200); 
}

void loop()
{
//*******************YOU ARE WORKING HERE************************
//***********************Ping Distance Sensor**********************
  long duration, inches, cm;
    // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
  // The same pin is used to read the signal from the PING))): a HIGH
  // pulse whose duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  // convert the time into a distance
  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);

  char inByte; 

//******************Read Direction Command**************************
 if (Serial.available() > 0) {
      
  // Read Servo Value 
    inByte = Serial.read();  
    Serial1.println(inByte);
 } 
   
  int a = analogRead(A5);
  temp = convert(a); 
  //Serial.print(temp);
  if (length(temp) == 2){
    if (temp > 90){
      sendVal[0] = '0';
      sendVal[1] = '9'; 
      temp = temp - 90; 
    }
    else if (temp >= 80){
      sendVal[0] = '0';
      sendVal[1] = '8';  
      temp = temp - 80; 
    }
    else if (temp >= 70){
      sendVal[0] = '0';
      sendVal[1] = '7'; 
      temp = temp - 70; 
    }
    else if (temp >= 60){
      sendVal[0] = '0';
      sendVal[1] = '6'; 
      temp = temp - 60;  
    }
    else if (temp >= 50){
      sendVal[0] = '0';
      sendVal[1] = '5';
      temp = temp - 50;        
    }
    else if (temp >= 40){
      sendVal[0] = '0';
      sendVal[1] = '4'; 
      temp = temp - 40;
    }
    else if (temp >= 30){
      sendVal[0] = '0';
      sendVal[1] = '3'; 
      temp = temp - 30;
    }
    else if (temp >= 20){
      sendVal[0] = '0';
      sendVal[1] = '2'; 
      temp = temp - 20;
    }
   else if (temp >= 10){ 
      sendVal[0] = '0';
      sendVal[1] = '1'; 
      temp = temp - 10;
      
   } 
   
  }
  

   else if (length(temp) == 1){
     sendVal[0] = '0';
     sendVal[1] = '0';   
     sendVal[2] = temp; 
   }
  //temp = temp + '0'; 
  //sendVal[2] = temp; 
  
  if (cm > 10){
    Serial.print("1"); 
    //Serial.print("/n");
  }
  else{
    Serial.print("0"); 
    //Serial.print("\n");
  }
  
  if (length(temp) < 3){
    //Serial.println("length 2"); 
    Serial.print(sendVal[0]); 
    Serial.print(sendVal[1]);
    Serial.print(sendVal[2]); 
    Serial.print("\n");
  }
  
  else if (length(temp) == 3){
    //Serial.println("Length 3"); 
    Serial.print(temp); 
    Serial.print("\n");
  }

  delay(5); 
}

boolean debounce(boolean last)
{
boolean current = digitalRead(switchPin);
if (last != current)
{
  delay(5);
  current = digitalRead(switchPin);
}
return current;
}

int length(int someValue){
int valLen = 0;

if(someValue > 9999)
   valLen = 5;
else if(someValue > 999)
   valLen = 4;
else if(someValue > 99)
   valLen = 3;
else if(someValue > 9)
   valLen = 2;
else
   valLen = 1;
   
return valLen; 
   
}

int convert(int reading){
  float calc = (reading*205)/307;
  float calc1 = calc*9/5 + 32; 
  int calc2 = round(calc1); 
  
  //int calcF = round(calc1); 
  
  return calc2;
}

long microsecondsToInches(long microseconds)
{
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds)
{
  return microseconds / 29 / 2;
}


Arduino Uno connected to the mega

#include <Servo.h> d

char inByte;
int pos       = 0;    // variable to store the servo position 
int i         = 0;
int j         = 0; 

Servo horServo;  // create servo object to control a servo 
Servo verServo;  

void setup() {
  // initialize serial communication:
  Serial.begin(115200);
  
  verServo.attach(9);  // attaches the servo on pin 9 to the servo
  horServo.attach(10); 
  
  verServo.write(90);
  horServo.write(90);
}

void loop()
{
  if (Serial.available() > 0) {
      
  // Read Servo Value 
    inByte = Serial.read();
    Serial.println(inByte); 
    if(inByte == 'l'){
      //Serial.println(inByte);
      
      //360 Servo 
      //horServo.write(87); 
      for (int x = 0; x<10; x++){
        if (i<=180){
          horServo.write(i);
          i = i + 3;
        }
      }
      
    }
    else if (inByte == 'r'){
      
      //Serial.println(inByte);
      
      //360 Servo 
      //horServo.write(93);
      //180 Servo
      for (int x = 0; x<10; x++){
        if (i>=0){
          horServo.write(i);
          i = i - 3; 
        }
      }
    }
    else if(inByte == 'u'){
      //Serial.println(inByte);
      //180 Servo
      for (int x = 0; x<10; x++){
        if (j<=180){
          verServo.write(j);
          j = j + 3;
        }
      }
   
      
    }
    else if (inByte == 'd'){
      //Serial.println(inByte);
      if (j>=0){
        for (int x = 0; x<10; x++){
          if (i<=180){
            verServo.write(j);
            j = j - 3; 
          }
        }
      }
    }
    else if (inByte == 'c'){
        horServo.write(0);
        verServo.write(0);
    }
  }
}



Sorry if the code is sloppy.

I have a couple of questions though. You were correct that using the monitor caused issues, but when you said that I should use Serial1 to send the "sendVal[0-3]" values, I gave that a try and I was not able to send any information to the computer from Serial1. Serial seems to work fine as long as I don't use the monitor.

Also, when you said to insert tildas around the sendVal variable, do I do that in the python script. For example, when I have:

val1 = ser.read()


do I just change it to:

~val1~ = ser.read()



Thank you so much for your help again.
Was This Post Helpful? 0
  • +
  • -

#7 Python_4_President  Icon User is offline

  • D.I.C Regular

Reputation: 53
  • View blog
  • Posts: 321
  • Joined: 13-August 11

Re: Arduino Python Serial Communication Issue

Posted 16 November 2012 - 01:13 PM

Yeah, I screwed up and ended up lying to you. Serial 1 spits out data on pins 18 and 19. Disregard everything I said about Serial1.

Per the spec sheet,
Serial: 0 (RX) and 1 (TX); Serial 1: 19 (RX) and 18 (TX); Serial 2: 17 (RX) and 16 (TX); Serial 3: 15 (RX) and 14 (TX).




If I'm right, you'll hit that exception pretty often because of all the print statements in your mega code that have nothing to do with the data you're trying to capture in your Python script. In some cases, you might even get data you weren't expecting, if the conditions are right.

What I was alluding to is this (and this may not actually work, I'm at work now and can't verify on my arduino, but I've done things like this in the past and had it work out OK.)

MEGACODE
//Going to send an indication code for pending valuable data
Serial.println("~GOOD_DATA_FOLLOWS~")
//ok, here goes the data
Serial.println(good_data)
//now let Python know it can just print out everything else to the console for user's viewing pleasure
Serial.println("~NO_MORE_GOOD_DATA~")




Python code
while True:
    data = ser.readline(1024, eol="\r\n") #reads up to 1024 characters, or until \r\n or until timeout (if set)
    if data.startswith("~GOOD_DATA_FOLLOWS~")
        good_data = ""
        while True:
            got = ser.readline(1024, eol="\r\n")
            if not "~NO_MORE_GOOD_DATA~" in got:
                good_data += got
            else:
                #no more good data, back to normal operations
                break
    else:
        print "Debug message: ", data




good_data, of course, would be your sendVal information. To work with my example, do something like this

            Serial.println("~GOOD_DATA_FOLLOWS~");
	    Serial.println(sendVal[0]);
	    Serial.println(sendVal[1]);
	    Serial.println(sendVal[2]);
	    Serial.println("~NO_MORE_GOOD_DATA~");



That should give you, in python, replacing sendVal[n] with whatever is actually there

good_data = "sendVal[0]\r\nsendVal[1]\r\nsendVal[2]\r\n"



which you can parse like this:
var1, var2, var3 = good_data.split()





Once you get this stuff down, you can look at Xbee. There's an Xbee module for Python here.

It is ridiculously easy to use.

Your Arduino code probably wouldn't need to change unless you connected the Xbee to different serial pins. The shield uses 0 and 1, (Serial), IIRC.

Then you can do all of that stuff remotely =)

The cheapest Xbee module has an effective range of about 50 yards. I think the Xbee pro reaches somewhat further than that (maybe 100 yards or so). But that's in a neighborhood with lots of wifi traffic, and Xbee implements the 802.15 protocol which utilizes the same spectrum as most routers. In the country, you may get better performance.

This post has been edited by Python_4_President: 16 November 2012 - 01:51 PM

Was This Post Helpful? 1
  • +
  • -

Page 1 of 1