Interesting Python Comms Problem

I have spent a whole afternoon trying to figure out why my Python code would sometimes fail to establish communication with my Uno.

In the demo at the top of this section I had used a baudrate of 9600 and had not noticed any problems.

In another project, using similar comms code, I have been using a higher baudrate and I found that on some occasions I could not begin Python communications with the Uno until after I had opened and closed the Arduino Serial Monitor.

Eventually I tracked down the problem to the case where I unplug and re-plug the USB cable for the Uno. After doing that my Python program would not start communicating if the baud rate was 57600 or 115200.

There was never any problem getting the Arduino Serial Monitor to work and I also tried an earlier JRuby program (which also uses the JVM) and had no problem with it either.

From looking through documentation for JSSC (the Java serial library) and PySerial it seems that they have different defaults for CTSRTS and DSRDTR. After a lot of experimenting I believe I have found a reliable solution by adding to the Python program the line ser.rtscts = True immediately after the line that opens the serial port.

I would be very interested to hear if anyone else has experienced this problem or if anyone has any insights into the solution I think I have found.

Edit to add ... I have just upgraded from Xubuntu 12.04 to 14.04 and I can't be certain whether the problem existed before the upgrade but I am 75% certain that it did.

For anyone who wishes to experiment I am posting two very short programs that illustrate the problem when the line ser.rtscts = True is commented out.

I will update the demo at the top of the section if nobody points out any foolishness in this Post.

Arduino Code

void setup() {
	Serial.begin(57600);
	Serial.println("<Arduino is ready>");
}

void loop() {

}

Python Code

# 18 Dec 2014
# short program to illustrate problem starting comms with Arduino


def recvFromArduino():
	global startMarker, endMarker, ser
	
	print "top of recvB"
	
	ck = ""
	x = "z" # any value that is not an end- or startMarker
	byteCount = -1 # to allow for the fact that the last increment will be one too many
	
	# wait for the start character
	while  ord(x) != startMarker: 
		x = ser.read()
		print ord(x)
	
	# save data until the end marker is found
	while ord(x) != endMarker:
		if ord(x) != startMarker:
			ck = ck + x 
			byteCount += 1
		x = ser.read()
	
	return(ck)

#========================

import serial

startMarker = 60 # <
endMarker = 62   # >

serPort = "/dev/ttyACM0"
baudRate = 57600
ser = serial.Serial(serPort, baudRate)

ser.rtscts = True # this is the interesting line

msg = ""
while msg.find("Arduino is ready") == -1:

	while ser.inWaiting() == 0:
		pass
		
	print "char in buffer"
	msg = recvFromArduino()

	print msg
	print

...R

I just experienced this exact issue on Ubuntu 12.04 as well. If I were to exit the python script, unplug then replug the USB, and restart the python script, the script wouldn't return what I would expect. It seemed to me a baudrate issue, so I did the following:

arduino = serial.Serial('/dev/ttyACM0', 9600)
arduino.setBaudRate(57600)

and the issue went away. Very strange.

Your solution also worked for me.

arduino = serial.Serial('/dev/ttyACM0', 57600)
arduino.rtscts = True

Thabks for pointing out this issue. As OP knows, I am experimenting with serial port and python. I wonder if by using c you can avoid this problem. I will give it some test when I have time. My c code opens serial port at 38400 for ir cameras. I have debian wheezy and raspberry pi. My goal is to use a non common baud rate of 200,000 to speed up file transfer between arduino and a win pc. But with my recent focus shifting to deploying rpi with arduino, speed is no longer an issue. Nobody needs to stand in the cold to download files on usb port any more, remote access is replacing that.

liudr:
Thabks for pointing out this issue. As OP knows, I am experimenting with serial port and python. I wonder if by using c you can avoid this problem.

I think it will be easier to help if you keep your discussion in your own Thread - even if you want to refer to this Thread. (Link added for other Readers' benefit)

I pointed out this Thread because I thought that you may be able to make constructive use of the behaviour that was a problem for me. Using C to "avoid" the problem rather defeats the idea.

In any case I have now lost track of exactly what stage you are at, and what problem you are now trying to solve. Perhaps you can give a summary of the latest situation in your own Thread.

...R