Skip to content

Commit 86f847c

Browse files
committed
Protocol actuate output modified
The actuate method now returns a dictionary with values on keys with names as "D%d" or "A%d" (D for digital and A for analog) Added constant collection for report mode selection
1 parent 559996c commit 86f847c

File tree

3 files changed

+77
-49
lines changed

3 files changed

+77
-49
lines changed

MLC/arduino/protocol.py

Lines changed: 67 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,39 @@
1+
import collections
12

2-
_PROTOCOL_CMDS = { "ANALOG_PRECISION": '\x01\x01%s',
3-
"SET_INPUT" : '\x02\x01%s',
4-
"SET_OUTPUT" : '\x03\x01%s',
5-
"PIN_MODE" : '\x04\x02%s%s',
6-
"REPORT_MODE" : '\x05\x03%s%s%s',
7-
"ANALOG_WRITE" : '\x06\x03%s%s%s',
8-
"ACK" : '\xFF\x00',
9-
"ACTUATE" : '\xF0',
10-
"PROT_VERSION" : '\xF2\x00',
11-
"RESET" : '\xFE',
12-
"ACTUATE_REPORT" : '\xF1' }
3+
_PROTOCOL_CMDS = {"ANALOG_PRECISION": '\x01\x01%s',
4+
"SET_INPUT": '\x02\x01%s',
5+
"SET_OUTPUT": '\x03\x01%s',
6+
"PIN_MODE": '\x04\x02%s%s',
7+
"REPORT_MODE": '\x05\x03%s%s%s',
8+
"ANALOG_WRITE": '\x06\x03%s%s%s',
9+
"ACK": '\xFF\x00',
10+
"ACTUATE": '\xF0',
11+
"PROT_VERSION": '\xF2\x00',
12+
"RESET": '\xFE',
13+
"ACTUATE_REPORT": '\xF1'}
14+
15+
16+
PIN_MODES=collections.namedtuple('PIN', ['AVERAGE', 'BULK', 'RT'], verbose=False)(AVERAGE=0, BULK=1, RT=2)
17+
REPORT_MODES=collections.namedtuple('REPORT', ['INPUT', 'OUTPUT'], verbose=False)(INPUT=0, OUTPUT=1)
1318

1419
class ArduinoInterface:
15-
PIN_MOD = {"INPUT":0, "OUTPUT":1} # 0=input 1=output -- wiring_constants.h
16-
REPORT_MOD = {"AVERAGE":0, "BULK":1, "RT":2}
20+
# 0=input 1=output -- wiring_constants.h
1721

1822
def __init__(self, connection, board):
1923
self._connection = connection
2024
self._anlg_inputs = []
2125
self._digital_inputs = []
2226
self._anlg_outputs = []
2327
self._digital_outputs = []
24-
self._anlg_precition = 10 #Default Arduino analog precision
25-
self._report_mode = "AVERAGE"
26-
self._read_count = 0 #Default number of inputs read
28+
self._anlg_precition = 10 # Default Arduino analog precision
29+
self._report_mode = PIN_MODES.AVERAGE
30+
self._read_count = 0 # Default number of inputs read
2731
self._read_delay = 0
2832
self._board = board
2933

3034
def get_analog_inputs(self):
3135
return self._anlg_inputs()
32-
36+
3337
def get_digital_inputs(self):
3438
return self._digital_inputs
3539

@@ -55,7 +59,8 @@ def set_pwm(self, pin, duty_cicle):
5559
if port in self._anlg_inputs or port in self._digital_inputs:
5660
raise Exception("Port %s is configured as input!" % port)
5761

58-
self._connection.send(_PROTOCOL_CMDS["ANALAOG_WRITE"] % (chr(pin), chr((duty_cicle & 0xFF00) >> 8), chr(duty_cicle & 0x00FF)))
62+
self._connection.send(_PROTOCOL_CMDS["ANALAOG_WRITE"] % (
63+
chr(pin), chr((duty_cicle & 0xFF00) >> 8), chr(duty_cicle & 0x00FF)))
5964

6065
def set_precision(self, bits):
6166
if bits > 32 or bits < 1:
@@ -64,13 +69,15 @@ def set_precision(self, bits):
6469
self._anlg_precition = bits
6570

6671
def __set_pin_mode(self, port, mode):
67-
if mode not in self.PIN_MOD.keys():
68-
raise Exception("Pind mode error. Unknown mode: %s. Modes availables: %s " % (mode, str(self.PIN_MOD.keys())))
69-
70-
self._connection.send(_PROTOCOL_CMDS["PIN_MODE"] % (chr(port), chr(self.PIN_MOD[mode])))
72+
if mode not in PIN_MODES._asdict().values():
73+
raise Exception("Pind mode error. Unknown mode: %s. Modes availables: %s " %
74+
(mode, str(PIN_MODES_asdict().keys())))
75+
76+
self._connection.send(
77+
_PROTOCOL_CMDS["PIN_MODE"] % (chr(port), chr(mode)))
7178

7279
def set_report_mode(self, mode, read_count=1, read_delay=0):
73-
if mode not in self.REPORT_MOD.keys():
80+
if mode not in REPORT_MODES._asdict().values():
7481
raise Exception("Report mode error. Unknown value: %s" % mode)
7582

7683
if read_count <= 0:
@@ -79,27 +86,27 @@ def set_report_mode(self, mode, read_count=1, read_delay=0):
7986
self._report_mode = mode
8087
self._read_count = read_count - 1
8188
self._read_delay = read_delay
82-
83-
self._connection.send(_PROTOCOL_CMDS["REPORT_MODE"] % (chr(self.REPORT_MOD[mode]), chr(self._read_count), chr(self._read_delay)))
84-
85-
89+
90+
self._connection.send(_PROTOCOL_CMDS["REPORT_MODE"] % (
91+
chr(self._report_mode), chr(self._read_count), chr(self._read_delay)))
92+
8693
def add_input(self, port):
8794
if port in self._anlg_outputs or port in self._digital_outputs:
8895
raise Exception("Pin %s is configured as output!" % port)
89-
96+
9097
self.__validate_pin(port)
9198

9299
# Determines if we are setting as input an analog port
93100
if port not in self._anlg_inputs and port in self._board["ANALOG_PINS"]:
94101
self._anlg_inputs.append(port)
95102
self._connection.send(_PROTOCOL_CMDS["SET_INPUT"] % chr(port))
96-
self.__set_pin_mode(port, "INPUT")
103+
self.__set_pin_mode(port, REPORT_MODES.INPUT)
97104

98105
# Determines if we are setting as input a Digital port
99106
if port not in self._digital_inputs and port in self._board["DIGITAL_PINS"]:
100107
self._digital_inputs.append(port)
101108
self._connection.send(_PROTOCOL_CMDS["SET_INPUT"] % chr(port))
102-
self.__set_pin_mode(port, "INPUT")
109+
self.__set_pin_mode(port, REPORT_MODES.INPUT)
103110

104111
def add_output(self, port):
105112
if port in self._anlg_inputs or port in self._digital_inputs:
@@ -110,18 +117,19 @@ def add_output(self, port):
110117
if port not in self._anlg_outputs and port in self._board["ANALOG_PINS"]:
111118
self._anlg_outputs.append(port)
112119
self._connection.send(_PROTOCOL_CMDS["SET_OUTPUT"] % chr(port))
113-
self.__set_pin_mode(port, "OUTPUT")
120+
self.__set_pin_mode(port, REPORT_MODES.OUTPUT)
114121

115122
# Determines if we are setting as input a Digital port
116123
if port not in self._digital_outputs and port in self._board["DIGITAL_PINS"]:
117124
self._digital_outputs.append(port)
118125
self._connection.send(_PROTOCOL_CMDS["SET_OUTPUT"] % chr(port))
119-
self.__set_pin_mode(port, "OUTPUT")
126+
self.__set_pin_mode(port, REPORT_MODES.OUTPUT)
120127

121128
def __validate_pin(self, pin):
122129
if pin not in self._board["DIGITAL_PINS"] and pin not in self._board["ANALOG_PINS"]:
123-
raise Exception("Invalid pin %s for board %s" % (pin, self._board["NAME"]))
124-
130+
raise Exception("Invalid pin %s for board %s" %
131+
(pin, self._board["NAME"]))
132+
125133
def reset(self):
126134
self._connection.send(_PROTOCOL_CMDS["RESET"])
127135
self._anlg_outputs = []
@@ -143,49 +151,62 @@ def actuate(self, data):
143151
if i[0] not in self._anlg_outputs and i[0] not in self._digital_outputs:
144152
raise Exception("Port %s not configured as output!" % i[0])
145153
if i[0] in self._anlg_outputs:
146-
payload = "".join([payload, chr(i[0]), chr((i[1] & 0xFF00) >> 8), chr(i[1] & 0x00FF)])
154+
payload = "".join(
155+
[payload, chr(i[0]), chr((i[1] & 0xFF00) >> 8), chr(i[1] & 0x00FF)])
147156
size += 3
148157
if i[0] in self._digital_outputs:
149158
payload = "".join([payload, chr(i[0]), chr(i[1])])
150159
size += 2
151160

152-
self._connection.send("".join([_PROTOCOL_CMDS["ACTUATE"], chr(size), payload]))
161+
self._connection.send(
162+
"".join([_PROTOCOL_CMDS["ACTUATE"], chr(size), payload]))
153163
response = self._connection.recv(1)
154164

155165
if response == _PROTOCOL_CMDS["ACK"]:
156166
response = self._connection.recv(1)
157167
raise Exception("Actuate error. Code: %s" % response)
158168

159-
if response <> _PROTOCOL_CMDS["ACTUATE_REPORT"]:
160-
raise Exception("Actuate error. Unknown response %s after actuate operation" % ord(response))
169+
if response != _PROTOCOL_CMDS["ACTUATE_REPORT"]:
170+
raise Exception(
171+
"Actuate error. Unknown response %s after actuate operation" % ord(response))
161172

162173
length = ord(self._connection.recv(1))
163174
data = self._connection.recv(length)
164175

165176
pos = 0
166-
results = {x: [] for x in self._anlg_inputs + self._digital_inputs} # One dictionary to save all ports results
177+
digital_res = {"D%d" % (x): [] for x in self._digital_inputs}
178+
analog_res = {"A%d" % (x): [] for x in self._anlg_inputs}
179+
# results = {x: []
180+
# for x in self._anlg_inputs + self._digital_inputs} # One dictionary
181+
# to save all ports results
182+
183+
results = dict(digital_res.items() + analog_res.items())
167184

168185
while pos < length:
169186
pin = ord(data[pos])
170187
if pin in self._anlg_inputs:
171188
for i in range(0, self._read_count + 1):
172-
results[pin].append((ord(data[pos+1]) << 8) + ord(data[pos+2]))
189+
results["A%d" % (pin)].append(
190+
(ord(data[pos + 1]) << 8) + ord(data[pos + 2]))
173191
pos = pos + 2
174192
pos = pos + 1
175193

176194
if self._report_mode == "AVERAGE":
177-
results[pin] = [sum(results[pin]) / (self._read_count + 1)]
195+
results["A%d" % (pin)] = [
196+
sum(results["A%d" % (pin)]) / (self._read_count + 1)]
178197
else:
179198
if pin in self._digital_inputs:
180199
for i in range(0, self._read_count + 1):
181-
results[pin].append(bool(ord(data[pos + 1 + i/8]) & (0x01 << (i % 8))))
182-
pos = pos + 1 + self._read_count/8 + 1
200+
results["D%d" % (pin)].append(
201+
bool(ord(data[pos + 1 + i / 8]) & (0x01 << (i % 8))))
202+
pos = pos + 1 + self._read_count / 8 + 1
183203

184204
if self._report_mode == "AVERAGE":
185-
results[pin] = [ (sum(results[pin]) * 2) > (self._read_count + 1) ]
205+
results["D%d" % (pin)] = [
206+
(sum(results["D%d" % (pin)]) * 2) > (self._read_count + 1)]
186207

187208
else:
188-
raise Exception("Unknown port \"%d\" in response. Restart Arduino board, your software and pray" % pin)
209+
raise Exception(
210+
"Unknown port \"%d\" in response. Restart Arduino board, your software and pray" % pin)
189211

190212
return results
191-

tests/pocs/performance_test.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
#from MLC.arduino.connection import MockConnection
22
from MLC.arduino.connection import SerialConnection
3+
import MLC.arduino.protocol as protocol
34
from MLC.arduino.protocol import ArduinoInterface
45
from MLC.arduino import boards
6+
import MLC.arduino
57
import sys
68
import time
79

10+
11+
BREAK_COUNT=20000
12+
813
def actuate(terminal):
14+
global BREAK_COUNT
915
connection = SerialConnection(port=terminal)
1016
arduinoDue = ArduinoInterface(connection, boards.Due)
1117

1218
arduinoDue.reset() #Just in case
13-
arduinoDue.set_report_mode("AVERAGE", read_count=1, read_delay=200)
19+
arduinoDue.set_report_mode(protocol.PIN_MODES.AVERAGE, read_count=5, read_delay=0)
1420

1521
arduinoDue.add_output(40)
1622
arduinoDue.add_output(66)
@@ -26,12 +32,13 @@ def actuate(terminal):
2632
# arduinoDue.add_input(56)
2733
# arduinoDue.add_input(55)
2834
arduinoDue.add_input(54)
35+
arduinoDue.add_input(55)
2936

3037
last_time = time.time()
3138
start_time = last_time
3239
read_c = 0
3340

34-
for i in xrange(0, 2):
41+
for i in xrange(0, BREAK_COUNT):
3542
output = arduinoDue.actuate([(40,1),(66,255)])
3643
#print output
3744
read_c = read_c + 1

tests/pocs/test_connection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def actuate(terminal):
1010
arduinoDue = ArduinoInterface(connection, boards.Due)
1111

1212
arduinoDue.reset()
13-
# arduinoDue.set_report_mode("BULK", read_count=5, read_delay=200)
13+
arduinoDue.set_report_mode("BULK", read_count=5, read_delay=100)
1414
arduinoDue.add_output(40)
1515
arduinoDue.add_input(64)
1616
arduinoDue.add_input(63)

0 commit comments

Comments
 (0)