I was having problems reading sensor information from my Irobot Create 2 and sent an email asking for help from the Irobot staff. They were super helpful and gave me an answer(the next day!!!) that helped push along my project. I was requesting data from the create2 to print to the screen so I could figure out how to write a code that would read the data. I started with this section of code that was not working for me (I trimmed some of the code off that controlled other functions):
from Tkinter import *
from subprocess import call
import datetime
import serial
import ttk
import struct
import thread
port = '/dev/ttyUSB0' #sets the com port for Atlas
baud = 115200 #sets the baud rate
connection = serial.Serial(port, baud) #starts the serial communication
#program to read communication from create2
def program2(threadName):
while True:
x = connection.read()
print x
#program to write to create2
def program1(threadName):
atlas = Tk() #starts a new GUI for atlas control
atlas.geometry('1000x500') #sets the size of the control window
atlas.title('Atlas Control Panal') #sets the name of the control window
def sendCommandASCII(command):#used to send a command to the create2
cmd = ""
for v in command.split():
cmd += chr(int(v))
sendCommandRaw(cmd)
def sendCommandRaw(command):#used to send a command to the create2
global connection
try:
if connection is not None:
connection.write(command)
else:
tkMessageBox.showerror('Not connected!', 'Not connected to a robot!')
print "Not connected."
except serial.SerialException:
print "Lost connection"
tkMessageBox.showinfo('Uh-oh', "Lost connection to the robot!")
connection = None
def test():#sets a test command up to check connection
global buttonpress
buttonpress='test'
sendCommandASCII('142 7')
#makes a button on the GUI that starts the test command
button1 = Button(atlas, text = 'test mode', command=test)
button1.place(x=600, y=400)
button1.config(width=10, height=5)
atlas.mainloop() #runs the GUI as a loop to keep the window open.
#runs the read and the write program at the same time
try:
thread.start_new_thread(program1, ("program1",))
thread.start_new_thread(program2, ("program2",))
except Exception, e:
print str(e)
They told me that the code was actually working fine but I was trying to print out the value of the sensor packet without parsing it in any way. They then recommended I change the code in program2 to this:
while True:
def toHexFromByte(val):
return hex(ord(val))[2:}.rjust(2, '0').upper()
x = connection.read()
for b in x:
print toHexFromByte(b)
this works beautifully and prints to the screen if the bumper is pressed or a wheel drops. My question is how to deal with responses that are longer than one byte (ie Packet ID: 22 for voltage)?
When I try Packet ID: 22 it prints to screen and it sends the high byte of 3F and a low byte of D7. I can manually combine them to get 3FD7 and convert it to a decimal of 16.343 Volts but I would like to figure a way to print to screen the the voltage by having my program do this for me. Many of the sensors send data in 2 bytes and I need a way to make sure that it is combined automatically.
Robb