Skip to content

Commit

Permalink
Merge pull request #11 from Williangalvani/python
Browse files Browse the repository at this point in the history
Improve Python interface
Add example
  • Loading branch information
Williangalvani authored Oct 29, 2016
2 parents 47934df + 5707dd8 commit b982e43
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 30 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ before_install:
script:
- arduino --board arduino:avr:nano:cpu=atmega328 --pref build.path=$PWD/Exposer/build --verify $PWD/Exposer/Exposer.ino
- sudo sh .travisScripts/start_simavr.sh
- sudo python Exposer/tester.py /tmp/simavr-uart0
- sudo python Exposer/python/exposer.py /tmp/simavr-uart0
- sudo pkill -9 simduino.elf
16 changes: 16 additions & 0 deletions python/example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from exposer import SerialExposer # Imports the communication module

# Instantiate a "SerialExposer" object named "comm"
comm = SerialExposer("/tmp/simavr-uart0")

# Setup phase, this requests all the variable names and types to the other side
comm.requestAll()

# This will print all of the received variable names
print(comm.getVarNames())

# Equivalent to "testuint8 = 0;"
comm.setVar("testuint8",10)

# Equivalent to "testuint8 = 0;"
print(comm.getVar("testuint8"))
111 changes: 82 additions & 29 deletions tester.py → python/exposer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import sys
import struct

class SerialTester:
xrange = range

class SerialExposer:
WAITING_HEADER = 0 # '<'
WAITING_OPERATION = 1 # request_All, read, write
WAITING_TARGET = 2 # 0-255. variable register
Expand Down Expand Up @@ -55,7 +57,12 @@ def __init__(self, port):
def serialize8(self, a):
if isinstance(a, int):
a = chr(a)
self.byte_buffer += a
try:
self.byte_buffer += a
except TypeError:
#print("a", ord(a), a, bytearray([ord(a)]))
self.byte_buffer += bytearray([ord(a)])
#print(self.byte_buffer)

def unpack(self, a, vtype):

Expand Down Expand Up @@ -88,10 +95,13 @@ def unpack(self, a, vtype):

elif vtype == "_float":
b = struct.pack('<f', a)
return [ord(b[i]) for i in xrange(0, 4)]

try:
return [b[i] for i in xrange(0, 4)]
except TypeError:
return [ord(b[i]) for i in xrange(0, 4)]

elif vtype == "_string":
return [b for b in bytearray(a)]
return [b for b in a.encode("UTF-8")]
return

def send_16(self, value):
Expand Down Expand Up @@ -121,10 +131,15 @@ def packu8(self, operation, target=0, data=[]):
self.serialize8(size)
crc ^= size
for item in data:
crc ^= item
try:
crc ^= item
except:
crc ^= ord(item)

self.serialize8(item)

self.serialize8(crc)
#print(self.byte_buffer, [a for a in self.byte_buffer])
self.ser.write(self.byte_buffer)

def repack(self, data, varType):
Expand All @@ -151,10 +166,13 @@ def repack(self, data, varType):
return data

elif varType == "_float":
b = struct.unpack('<f', str(data))
try:
b = struct.unpack('<f', str(data))
except TypeError:
b = struct.unpack('<f', data)
return b[0]
elif varType == "_string":
return data
return data.decode("UTF-8")

def waitForMsg(self, op, target, timeout=0.2):
self.messageBuffer.pop((op, target), None)
Expand All @@ -168,6 +186,30 @@ def waitForMsg(self, op, target, timeout=0.2):
data = self.messageBuffer.pop((op, target), None)
return self.repack(data, self.variables[target][1])

def requestAll(self):
while len(self.variables) == 0:
self.packu8(self.REQUEST_ALL)
self.waitForMsg(self.REQUEST_ALL, 0)

def getVarNames(self):
return [a[1][0].decode("UTF-8") for a in self.variables.items()]

def setVar(self,varname,value):
for i, var in self.variables.items():
name, typ = var
if name == varname:
self.packu8(self.WRITE, i, self.unpack(value, typ))

def getVar(self,varname):
varname = varname.encode("UTF-8")
for i, var in self.variables.items():
name, typ = var
if name == varname:
self.packu8(self.READ, i, [0])
received = self.waitForMsg(self.READ, i)
#print(i,received)
return received

def processMessage(self):
operationNames = ["REQUEST ALL", "WRITE", "READ"]
operationName = operationNames[self.operation - 33]
Expand All @@ -181,31 +223,35 @@ def processMessage(self):
self.messageBuffer[(self.operation, self.target)] = self.dataBuffer

def processByte(self, char):
#print(self.status)
if not type(char) is int:
char = ord(char)
if self.status == self.WAITING_HEADER:
if char == '<':
if char == ord('<'):
self.status = self.WAITING_OPERATION
self.crc = 0 ^ ord('<')
else:
sys.stdout.write(char)
pass
#sys.stdout.write(chr(char))

elif self.status == self.WAITING_OPERATION:
self.operation = ord(char)
self.operation = char

if self.operation in (self.REQUEST_ALL, self.READ, self.WRITE):
self.status = self.WAITING_TARGET
self.crc ^= self.operation
else:
print "bad operation!", self.operation
print ("bad operation!", self.operation)
self.status = self.WAITING_HEADER

elif self.status == self.WAITING_TARGET:
self.target = ord(char)
self.target = char
if self.target in range(50): # bad validation
self.status = self.WAITING_PAYLOAD
self.crc ^= self.target

elif self.status == self.WAITING_PAYLOAD:
self.payloadSize = ord(char)
self.payloadSize = char
self.payloadLeft = self.payloadSize

self.dataBuffer = bytearray()
Expand All @@ -214,17 +260,17 @@ def processByte(self, char):

elif self.status == self.WAITING_DATA:
if self.payloadLeft > 0:
self.dataBuffer += char
self.crc ^= ord(char)
self.dataBuffer += bytearray([char])
self.crc ^= char
self.payloadLeft -= 1
if self.payloadLeft == 0:
self.status = self.WAITING_CRC

elif self.status == self.WAITING_CRC:
if self.crc == ord(char):
if self.crc == char:
self.processMessage()
else:
print "bad crc!", self.crc, ord(char)
print("bad crc!", self.crc, ord(char))
self.status = self.WAITING_HEADER


Expand All @@ -235,15 +281,22 @@ def processByte(self, char):
port = sys.argv[1]
else:
port = "/dev/ttyUSB0"
comm = SerialTester(port)

while len(comm.variables) == 0:
comm.packu8(comm.REQUEST_ALL)
comm.waitForMsg(comm.REQUEST_ALL, 0)

for key, value in comm.variables.iteritems():
print key, value
for index, var in comm.variables.iteritems():
comm = SerialExposer(port)
comm.requestAll()

try:
itera = comm.variables.iteritems()
except:
itera = comm.variables.items()
for key, value in itera:
print (key, value)

try:
itera = comm.variables.iteritems()
except:
itera = comm.variables.items()

for index, var in itera:
name, vartype = var
varRange = comm.testValues[vartype]

Expand All @@ -252,11 +305,11 @@ def processByte(self, char):
comm.packu8(comm.READ, index, [0])
received = comm.waitForMsg(comm.READ, index)
if vartype != "_string":
print ((value - received) < 0.01), ", Type: ", vartype, "sent: ", value, "received: ", received, ", Bytes: ", comm.unpack(value, vartype)
print (((value - received) < 0.01), ", Type: ", vartype, "sent: ", value, "received: ", received, ", Bytes: ", comm.unpack(value, vartype))
if (value - received) > 0.01:
errors += 1
else:
print value, received
print (value, received)
if value != received:
errors += 1
exit(errors)

0 comments on commit b982e43

Please sign in to comment.