# Read from Arduino's serial interface. # Requires pySerial (http://pyserial.sourceforge.net/) # David Elworthy, January 2 2015. http://www.friendlymoose.com/. import serial import struct import time PORT='COM5' TIMEOUT=1 class SerialFetcher: OK = 0 CHECKSUM_ERROR = 1 def __init__(self, port=PORT, timeout=TIMEOUT): self.serial_port = None self.port = port self.timeout = timeout def WaitForPort(self): """Wait until serial port connects, if necessary.""" # The dtr settings prevent the initial serial connection from resetting the Arduino. if self.serial_port == None or not self.serial_port.isOpen(): # print "Wait for port" while True: try: self.serial_port = serial.Serial(port=self.port, baudrate=9600, timeout=self.timeout, dsrdtr=True) except serial.serialutil.SerialException: self.serial_port = None if self.serial_port: self.serial_port.setDTR(False) # print "Port ready" return def GetFromPort(self): """Get all the data that is available on the serial port (blocking).""" self.WaitForPort() # Read value, expected to be the size buffer = self.serial_port.read(1) if len(buffer) != 1: # Bad size field return None size = struct.unpack("B", buffer)[0] print "Size %s" % size # Read the checksum buffer = self.serial_port.read(1) if len(buffer) != 1: return None expected_checksum = struct.unpack('B', buffer)[0] # Read the data data = self.serial_port.read(size) actual_checksum = 0 for b in data: actual_checksum += ord(b) actual_checksum = actual_checksum % 256 #print "Check expected %s actual %s" % (expected_checksum, actual_checksum) # Send the response if expected_checksum == actual_checksum: self.serial_port.write([SerialFetcher.OK, actual_checksum]) else: print "Check expected %s actual %s" % (expected_checksum, actual_checksum) self.serial_port.write([SerialFetcher.CHECKSUM_ERROR, actual_checksum]) data = [] self.serial_port.close() return data fetcher = SerialFetcher() s = struct.Struct('hhh') try: while True: data = fetcher.GetFromPort() if data: print "Data:" datalen = len(data) offset = 0 while offset < datalen: values = s.unpack_from(data, offset) offset += s.size print " %s" % repr(values) except KeyboardInterrupt: if fetcher != None and fetcher.serial_port != None: fetcher.serial_port.close() print "Done"