When I run the following python script, the arduino instantly changes ports (between ttyACM0 and ttyACM1) and the script fails because it gets disconnected. The script just waits for the user to input two numbers and then sends them over the serial port to the arduino. I can use other scripts/arduino code with serial communication (both ways) and they do not have this issue. I tried a simpler version of some old code I had and it runs better, but still the arduino changes ports after some time (maybe a couple of minutes). I am running on Ubuntu 14.04 with the newest arduino software.
Simplified Code (disconnects after a few minutes)
import serial
import struct
import time
import os
import thread
import numpy as np
default_input = 2.5
PW_buffer = 0.05
#duty_cycle = 2000
min_value = 0#PW_buffer * duty_cycle
max_value = 5#(1-PW_buffer) * duty_cycle
data_obj = {}
data_obj['stop'] = False
data_obj['input'] = default_input
def user_input_thread(data_obj):
while not data_obj['stop']:
raw_in = raw_input('Enter PWM width (%i - %i): ' %
(min_value, max_value))
if raw_in == 'q':
data_obj['stop'] = True
elif not raw_in.isdigit():
print("INVALID INPUT")
else:
raw_in = max(min(int(raw_in), max_value), min_value)
data_obj['input'] = raw_in
if os.name == 'nt':
port = 'COM4'
else:
port = '/dev/ttyACM1'
baudrate = 115200
ser = serial.Serial(port, baudrate, timeout=0)
#thread.start_new_thread(user_input_thread, (data_obj, ))
min_time = 0.005
while not data_obj['stop']:
raw_in = raw_input('Enter PWM width (%i - %i): ' %
(min_value, max_value))
#m1 = float(raw_in)
#m2 = 1000
#m3 = 1000
m1, m2= [10000 * (float(x)) for x in raw_in.split(',')]
ser_str = struct.pack('>3H', 65535, np.copy(m1),np.copy(m2))
#ser_str = struct.pack('>4H', 65535, m1, m2, m3)
ser.write(ser_str)
time.sleep(min_time)
print m1, m2
ser.close()
Full code (disconnects as soon as script is run)
import serial
import struct
import time
import os
import thread
import numpy as np
import math
startMarker1 = 0xFF#60
startMarker2 = 0xFF
endMarker = 62
#startMarker = "<"
#endMarker = ">"
default_input = 512 #position 0-2Pi == 0-1024
PW_buffer = 0.05
duty_cycle = 2000
min_value = 0#PW_buffer * duty_cycle
max_value = 3.14#(1-PW_buffer) * duty_cycle
data_obj = {}
data_obj['stop'] = False
data_obj['input'] = default_input
output_angles = {}
output_angles['start'] = startMarker1
output_angles['end'] = endMarker
flag = False
xyz_coordinates = [-.31, .25, .25, 0, 0, 0, 0, 0, 0]
input_string = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
end_reached = False
#=====================================
# Function Definitions
#---------------------------Check if input is float------------------------------
def is_float(input):
try:
num = float(input)
except ValueError:
return False
return True
#-----------------------------Receive from Arduino-------------------------------
def arduino_output_thread(data_obj):
#output_feed = "z"
prev_serial_data = [0,0,0]
angles = [0,0,0]
while True:
serial_data = ser.read(1)
if serial_data == chr(255):
serial_data = ser.read(1)
if serial_data == chr(255):
serial_data = ser.read(6)
angles = struct.unpack('<3H', serial_data)
if angles != prev_serial_data:
print angles
prev_serial_data = angles
#------------------------------Get user PW----------------------------------------
def user_input_thread(data_obj):
global flag, xyz_coordinates
while not data_obj['stop']:
raw_in = raw_input('Enter x,y,z coordinates (thousandths accuracy, q to quit): ')
if raw_in == 'q':
data_obj['stop'] = True
else:
flag = True
xyz_coordinates = [float(x) for x in raw_in.split(',')]
#=====================================
# START OF MAIN
#=====================================
try:
if os.name == 'nt':
port = 'COM4' #COM1 at home
else:
port = '/dev/ttyACM0'#port = '/dev/arduino'
baudrate = 115200
ser = serial.Serial(port, baudrate, timeout=1)
#thread.start_new_thread(user_input_thread, (data_obj, ))
thread.start_new_thread(arduino_output_thread, (data_obj, ))#(output_angles, ))
min_time = 0.005
while not data_obj['stop']:
#print 'pos : ', data_obj['input']
raw_in = raw_input('Enter joint angles rotation and translation (%i - %i, 2.5,2.5 for rest pos): ' %
(0,5))#(min_value, max_value))
try:
#m1, m2, m3, m4, m5, m6, m7, m8, m9 = [10000 * (float(x)) for x in raw_in.split(',')]
#print m1, m2, m3, m4, m5, m6, m7, m8, m9
"""ser_str = struct.pack('>10H', 65535, np.copy(m1),
np.copy(m2),
np.copy(m3),
np.copy(m4),
np.copy(m5),
np.copy(m6),
np.copy(m7),
np.copy(m8),
np.copy(m9))"""
m4, m5= [10000 * (float(x)) for x in raw_in.split(',')]
ser_str = struct.pack('>3H', 65535, np.copy(m4),
np.copy(m5))
ser.write(ser_str)
except:
print 'Invalid input.'
pass
finally:
ser = serial.Serial(port, baudrate)
ser.close()
Any thoughts as to what the problem could be? Any thoughts / ideas are greatly appreciated!