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.