Skip to content

Commit 01ade53

Browse files
committed
Issue: #22 Fix en firmware y soporte a puertos digitales
Se elimina bug en actuate que no permitia aplicar valores a los puertos de salida. Se agrega soporte a envío de operaciones de escritura a los pines digitales.
1 parent 680ff2b commit 01ade53

File tree

3 files changed

+76
-42
lines changed

3 files changed

+76
-42
lines changed

MLC/arduino/Firmware/Firmware.ino

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
// defines ahorran ROM... aunque nos sobra de eso XD -- Verificar que los const vayan a la rom!
99
const uint8_t ANALOG_PRECISION_CMD = 0x01;
10-
const uint8_t ADD_ANALOG_INPUT_CMD = 0x02;
11-
const uint8_t ADD_ANALOG_OUTPUT_CMD = 0x03;
10+
const uint8_t ADD_INPUT_PORT_CMD = 0x02;
11+
const uint8_t ADD_OUTPUT_PORT_CMD = 0x03;
1212
const uint8_t SET_PIN_MODE_CMD = 0x04;
1313
const uint8_t SET_REPORT_MODE_CMD = 0x05;
1414
const uint8_t ACTUATE_CMD = 0xF0;
@@ -56,8 +56,8 @@ void set_analog_precision(const char* data)
5656
void set_pin_mode(const char* data)
5757
{
5858
pinMode(data[2], data[3]);
59-
LOG("Changed pin mode on pin ", data[2]);
60-
LOG("Mode set to ", data[3]);
59+
LOG("Changed pin mode on pin ", uint8_t(data[2]));
60+
LOG("Mode set to ", uint8_t(data[3]));
6161
}
6262

6363
/**
@@ -98,7 +98,7 @@ void actuate(const char* data)
9898
int byte_count = byte(data[1]); // Un byte puede llegar a limitar la cantidad de salidas... creo
9999

100100
// ACTUATION ZONE
101-
while (offset > byte_count)
101+
while (offset < byte_count)
102102
{
103103
//Se aplica la acción a cada puerto indicado
104104
int port = byte(data[2 + offset]);
@@ -166,23 +166,23 @@ void setup() {
166166

167167
/** Commands Callbacks **/
168168
executor[ANALOG_PRECISION_CMD] = &set_analog_precision;
169-
executor[ADD_ANALOG_INPUT_CMD] = &set_analog_input;
170-
executor[ADD_ANALOG_OUTPUT_CMD] = &set_analog_output;
169+
executor[ADD_INPUT_PORT_CMD] = &set_analog_input;
170+
executor[ADD_OUTPUT_PORT_CMD] = &set_analog_output;
171171
executor[SET_PIN_MODE_CMD] = &set_pin_mode;
172172
executor[SET_REPORT_MODE_CMD] = &set_report_mode;
173173
executor[ACTUATE_CMD] = &actuate;
174174

175175
executor[ANALOG_PRECISION_CMD]("\x01\x01\x12");
176-
executor[ADD_ANALOG_INPUT_CMD]("\x02\x01\x37"); // Configura a A1 como lectura
177-
executor[ADD_ANALOG_INPUT_CMD]("\x02\x01\x38"); // Configura a A2 como lectura
178-
executor[SET_PIN_MODE_CMD]("\x04\x02\x12\x01");
176+
executor[ADD_INPUT_PORT_CMD]("\x02\x01\x37"); // Configura a A1 como lectura
177+
executor[ADD_INPUT_PORT_CMD]("\x02\x01\x38"); // Configura a A2 como lectura
178+
executor[SET_PIN_MODE_CMD]("\x04\x02\x28\x01");
179179
executor[SET_PIN_MODE_CMD]("\x04\x02\x55\x00");
180180

181181
}
182182

183183
void loop() {
184184
LOG("Escribiendo...", " ");
185-
executor[ACTUATE_CMD]("\xF0\x01\x12\x01");
185+
executor[ACTUATE_CMD]("\xF0\x01\x28\x01");
186186

187187
if (SerialUSB.available() > 0)
188188
{

MLC/arduino/protocol.py

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
_PROTOCOL_CMDS = { "ANALOG_PRECISION": '\x01\x01%s',
3-
"ANALOG_INPUT" : '\x02\x01%s',
4-
"ANALOG_OUTPUT" : '\x03\x01%s',
3+
"SET_INPUT" : '\x02\x01%s',
4+
"PIN_OUTPUT" : '\x03\x01%s',
55
"PIN_MODE" : '\x04\x02%s%s',
66
"REPORT_MODE" : '\x05\x03%s%s%s',
77
"ACK" : '\xFF\x00',
@@ -12,11 +12,14 @@ class ArduinoInterface:
1212
PIN_MOD = {"INPUT":0, "OUTPUT":1} # 0=input 1=output -- wiring_constants.h
1313
REPORT_MOD = {"AVERAGE":0, "BULK":1, "RT":2}
1414

15-
def __init__(self, connection):
15+
def __init__(self, connection, board):
1616
self._connection = connection
1717
self._anlg_inputs = []
18+
self._digital_inputs = []
1819
self._anlg_outputs = []
19-
self._anlg_precition = 10 #Default Arduino analog precition
20+
self._digital_outputs = []
21+
self._anlg_precition = 10 #Default Arduino analog precision
22+
self._board = board
2023

2124
def set_precition(self, bits):
2225
if bits > 32 or bits < 1:
@@ -35,27 +38,49 @@ def set_report_mode(self, mode, read_count=1, read_delay=0):
3538
raise Exception("Report mode error. Unknown value: %s" % mode)
3639

3740
self._connection.send(_PROTOCOL_CMDS["REPORT_MODE"] % (chr(self.REPORT_MOD[mode]), chr(read_count), chr(read_delay)))
38-
41+
3942

40-
def add_analog_input(self, port):
41-
if port in self._anlg_outputs:
42-
raise Exception("Port %s is configured as output!" % port)
43-
44-
if port not in self._anlg_inputs:
45-
self._connection.send(_PROTOCOL_CMDS["ANALOG_INPUT"] % chr(port))
43+
def add_input(self, port):
44+
if port in self._anlg_outputs or port in self._digital_outputs:
45+
raise Exception("Pin %s is configured as output!" % port)
46+
47+
self._validate_pin(port)
48+
49+
# Determines if we are setting as input an analog port
50+
if port not in self._anlg_inputs and port in self._board["ANALOG_PINS"]:
51+
# The "analogRead" arduino function maps the ADC pins not by their base pin number but from their relative ADC pin number
52+
self._connection.send(_PROTOCOL_CMDS["SET_INPUT"] % chr(port - min(self._board["ANALOG_PINS"])))
4653
self._anlg_inputs.append(port)
4754

48-
def add_analog_output(self, port):
49-
if port in self._anlg_inputs:
55+
# Determines if we are setting as input a Digital port
56+
if port not in self._digital_inputs and port in self._board["DIGITAL_PINS"]:
57+
self._connection.send(_PROTOCOL_CMDS["SET_INPUT"] % chr(port))
58+
self._digital_inputs.append(port)
59+
60+
61+
def add_output(self, port):
62+
if port in self._anlg_inputs or port in self._digital_inputs:
5063
raise Exception("Port %s is configured as input!" % port)
5164

65+
self._validate_pin(port)
66+
5267
if port not in self._anlg_outputs:
53-
self._connection.send(_PROTOCOL_CMDS["ANALOG_OUTPUT"] % chr(port))
68+
self._connection.send(_PROTOCOL_CMDS["PIN_OUTPUT"] % chr(port))
5469
self._anlg_outputs.append(port)
5570

71+
# Determines if we are setting as input a Digital port
72+
if port not in self._digital_outputs and port in self._board["DIGITAL_PINS"]:
73+
self._connection.send(_PROTOCOL_CMDS["PIN_OUTPUT"] % chr(port))
74+
self._digital_outputs.append(port)
75+
76+
def _validate_pin(self, pin):
77+
if pin not in self._board["DIGITAL_PINS"] and pin not in self._board["ANALOG_PINS"]:
78+
raise Exception("Invalid pin %s for board %s" % (pin, self._board["NAME"]))
79+
return
80+
5681
def actuate(self, data):
5782
"""
58-
Actuate over the input port sent as parameters
83+
Actuate over the parametrized output pins
5984
All the ports must has been configured as output!
6085
6186
arguments:
@@ -65,10 +90,14 @@ def actuate(self, data):
6590
size = 0
6691
#TODO: Ver como validar puertos digitales
6792
for i in data:
68-
if i[0] not in self._anlg_outputs:
93+
if i[0] not in self._anlg_outputs and i[0] not in self._digital_outputs:
6994
raise Exception("Port %s not configured as output!" % i[0])
70-
payload = "".join([payload, chr(i[0]), chr((i[1] & 0xFF00) >> 8), chr(i[1] & 0x00FF)])
71-
size += 3
95+
if i[0] in self._anlg_outputs:
96+
payload = "".join([payload, chr(i[0]), chr((i[1] & 0xFF00) >> 8), chr(i[1] & 0x00FF)])
97+
size += 3
98+
if i[0] in self._digital_outputs:
99+
payload = "".join([payload, chr(i[0]), chr(i[1])])
100+
size += 2
72101

73102
self._connection.send("".join([_PROTOCOL_CMDS["ACTUATE"], chr(size), payload]))
74103
response = self._connection.recv(1)

tests/mlc/arduino_protocol/test_protocol.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import unittest
22
from MLC.arduino.connection import MockConnection
33
from MLC.arduino.protocol import ArduinoInterface
4+
from MLC.arduino import boards
45

56
ACK = "\xFF\x00"
67
NACK = "\xFF\x01"
@@ -11,7 +12,7 @@ class TestArduinoInterface(unittest.TestCase):
1112

1213
def setUp(self):
1314
self._connection = MockConnection(ACK)
14-
self._interface = ArduinoInterface(self._connection)
15+
self._interface = ArduinoInterface(self._connection, boards.Due)
1516

1617
def test_set_precition(self):
1718
self._interface.set_precition(12)
@@ -37,38 +38,42 @@ def test_report_mode(self):
3738
with self.assertRaises(Exception):
3839
self._interface.set_report_mode("SOMETHING")
3940

40-
def test_add_analog_input(self):
41-
self._interface.add_analog_input(60)
41+
def test_add_input(self):
42+
self._interface.add_input(60)
4243
data = self._connection.pop_data()
43-
self.assertEqual("\x02\x01\x3C", data)
44-
self._interface.add_analog_input(60)
44+
self.assertEqual("\x02\x01\x06", data) # 6 = 60 - min(boards.Due["ANALOG_PINS"])
45+
self._interface.add_input(60)
4546
with self.assertRaises(Exception): # Checks that no data has been sent
4647
data = self._connection.pop_data()
48+
with self.assertRaises(Exception): # Checks that no data has been sent
49+
self._interface.add_output(128)
4750

48-
def test_add_analog_output(self):
49-
self._interface.add_analog_output(60)
51+
def test_add_output(self):
52+
self._interface.add_output(60)
5053
data = self._connection.pop_data()
5154
self.assertEqual("\x03\x01\x3C", data)
52-
self._interface.add_analog_output(60)
55+
self._interface.add_output(60)
5356
with self.assertRaises(Exception): # Checks that no data has been sent
5457
data = self._connection.pop_data()
58+
with self.assertRaises(Exception): # Checks that no data has been sent
59+
self._interface.add_output(128)
5560

5661
def test_error_adding_output_that_is_input(self):
57-
self._interface.add_analog_input(60)
62+
self._interface.add_input(60)
5863
with self.assertRaises(Exception):
5964
self._interface.add_analog_output(60)
6065

6166
def test_actuate_error_response(self):
62-
self._interface.add_analog_output(60)
67+
self._interface.add_output(60)
6368
self._connection.pop_data()
6469
with self.assertRaises(Exception):
6570
self._interface.actuate([(60, 128)])
6671

6772
def test_actuate(self):
6873
self._connection = MockConnection(REPORT)
69-
self._interface = ArduinoInterface(self._connection)
70-
self._interface.add_analog_output(60)
71-
self._interface.add_analog_input(61)
74+
self._interface = ArduinoInterface(self._connection, boards.Due)
75+
self._interface.add_output(60)
76+
self._interface.add_input(61)
7277
response = self._interface.actuate([(60, 128)])
7378
self.assertEqual(2, len(response))
7479
self.assertEqual("\x10",response[0][0])

0 commit comments

Comments
 (0)