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