Skip to content

Commit ccfd670

Browse files
committed
Merge branch 'arduino_data_overflow'
2 parents cb51071 + becebcb commit ccfd670

File tree

6 files changed

+165
-144
lines changed

6 files changed

+165
-144
lines changed

MLC/arduino/Firmware/Firmware.ino

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
#include "GenericArduinoController.h"
2-
31
#define DEBUG 0
2+
#include "GenericArduinoController.h"
43

54
GenericArduinoController controller(SerialUSB);
65

@@ -18,6 +17,8 @@ void loop() {
1817
controller.handle_commands();
1918

2019
/**
20+
*
21+
*
2122
* HERE the user can insert any command
2223
*/
2324

MLC/arduino/Firmware/GenericArduinoController.cpp

Lines changed: 102 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
#include "Arduino.h"
22
#include "GenericArduinoController.h"
33

4-
#ifndef DEBUG
4+
#ifndef DEBUG
55
#define DEBUG 0
66
#endif
77

88
#if DEBUG
99
#include <string.h>
1010
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
1111
#define LOG(x,y) Serial.print(__FILENAME__); Serial.print(":"); Serial.print(__LINE__);\
12-
Serial.print(" -- [DEBUG] -- ");Serial.print(x); Serial.println(y);
12+
Serial.print(" -- [DEBUG] -- ");Serial.print(x); Serial.println(y);
1313
#else
1414
#define LOG(x,y)
1515

1616
void inline dump_digital_buffer(const int &digital_pins_count, const int &report_read_count, const uint8_t** digital_input_buffer)
1717
{
18-
for (int i = 0; i < digital_pins_count; i++)
18+
for (int i = 0; i < digital_pins_count; i++)
1919
{
2020
for (int j = 0; j < report_read_count / 8 + 1; j++)
2121
{
@@ -26,10 +26,10 @@ void inline dump_digital_buffer(const int &digital_pins_count, const int &report
2626
}
2727

2828
#endif
29-
29+
3030
#define VERSION "0.1"
3131

32-
const char* ACK = "\xFF\x00";
32+
const char* ACK = "\xFF\x00\x00\x00\x00";
3333

3434
GenericArduinoController::GenericArduinoController(Stream &stream): stream_(stream)
3535
{
@@ -38,7 +38,7 @@ GenericArduinoController::GenericArduinoController(Stream &stream): stream_(stre
3838
{
3939
executor[i] = &GenericArduinoController::not_implemented;
4040
}
41-
41+
4242
REPORT_READ_COUNT = 0;
4343
REPORT_READ_DELAY = 0;
4444
REPORT_MODE = average;
@@ -61,131 +61,138 @@ void GenericArduinoController::handle_commands()
6161
if (stream_.available() > 0)
6262
{
6363
LOG("Data available ", stream_.available());
64-
char input[64]; // Esto se reserva en el stack, tal vez hacerlo global consume menos recursos...
64+
char input[128]; // Esto se reserva en el stack, tal vez hacerlo global consume menos recursos...
6565

6666
byte b_read = 0;
67-
byte b_pos = 0;
6867

69-
while (stream_.available() > 0)
68+
if (stream_.available() >= 5)
7069
{
71-
b_read += stream_.readBytes(input, stream_.available());
72-
}
70+
while (b_read < 5)
71+
{
72+
b_read += stream_.readBytes(&input[b_read], 5 - b_read);
73+
}
74+
75+
uint32_t data_len = (uint32_t(input[1]) << 24) + (uint32_t(input[2]) << 16) + (uint32_t(input[3]) << 8) + uint32_t(input[4]);
76+
77+
LOG("Command: ", int(input[0]));
78+
LOG("Command of length: ", data_len);
79+
80+
while (b_read - 5 < data_len)
81+
{
82+
b_read += stream_.readBytes(&input[b_read], data_len + 5 - b_read);
83+
84+
LOG("Received command part: ", data_len + 5 - b_read);
85+
}
86+
87+
executor[input[0]](this, data_len, &input[0]); // Does the callback for the command
7388

74-
LOG("Bytes obtained: ", b_read);
75-
// Loop to process all commands received in the buffer
76-
while (b_pos < b_read)
77-
{
78-
LOG("command: ", int(input[b_pos]));
79-
b_pos += executor[input[b_pos]](this, &input[b_pos]); // Does the callback for the command
80-
LOG("b_pos ", b_pos);
8189
}
8290
}
83-
84-
LOG("No data", "");
91+
8592
}
8693

87-
void GenericArduinoController::add_handler(uint8_t handler_id, int (*handler)(GenericArduinoController* this_, const char*))
94+
void GenericArduinoController::add_handler(uint8_t handler_id, int (*handler)(GenericArduinoController* this_, uint32_t &buff_len, const char*))
8895
{
89-
executor[handler_id] = handler;
96+
executor[handler_id] = handler;
9097
}
9198

9299
// NULL operation
93-
int GenericArduinoController::not_implemented(GenericArduinoController* this_, const char* data)
100+
int GenericArduinoController::not_implemented(GenericArduinoController* this_, uint32_t &buff_len, const char* data)
94101
{
95-
return 1; //Breaks the loop
102+
LOG("Unknown command received!! Operation: ", data[0]);
103+
return 1 + buff_len; //Breaks the loop
96104
}
97105

98106
/**
99-
* PROTOCOL_VERSION 0x07 0x03 X . Y
100-
*/
101-
int GenericArduinoController::protocol_version(GenericArduinoController* this_, const char* data)
107+
PROTOCOL_VERSION 0x07 0x00 0x00 0x00 0x03 X . Y
108+
*/
109+
int GenericArduinoController::protocol_version(GenericArduinoController* this_, uint32_t &buff_len, const char* data)
102110
{
103-
char response[] = { char(VERSION_RESPONSE), char(0x03)};
104-
this_->stream_.write(response, 2);
111+
char response[] = { char(VERSION_RESPONSE), char(0), char(0), char(0), char(0x03)};
112+
this_->stream_.write(response, 5);
105113
this_->stream_.write(VERSION, 3);
106-
return 2;
114+
return 8;
107115
}
108116

109117
/**
110-
* ANALOG_WRITE: 0x06 0x03 [PIN] [H_VALUE][L_VALUE]
111-
*/
112-
int GenericArduinoController::analog_write(GenericArduinoController* this_, const char* data)
118+
ANALOG_WRITE: 0x06 0x00 0x00 0x00 0x03 [PIN] [H_VALUE][L_VALUE]
119+
*/
120+
int GenericArduinoController::analog_write(GenericArduinoController* this_, uint32_t &buff_len, const char* data)
113121
{
114-
uint16_t value = (data[3] << 8) + data[4];
115-
analogWrite(data[2], value);
116-
return 5;
122+
uint16_t value = (data[7] << 8) + data[8];
123+
analogWrite(data[6], value);
124+
return 8;
117125
}
118126

119127
/**
120-
* ANALOG_PRECISION: 0x01 0x01 [BITS]
121-
*/
122-
int GenericArduinoController::set_analog_precision(GenericArduinoController* this_, const char* data)
128+
ANALOG_PRECISION: 0x01 0x00 0x00 0x00 0x01 [BITS]
129+
*/
130+
int GenericArduinoController::set_analog_precision(GenericArduinoController* this_, uint32_t &buff_len, const char* data)
123131
{
124-
int i = byte(data[2]);
132+
int i = byte(data[6]);
125133
// Tal vez conviene separar estas funciones ya que hay boards con resoluciones distintas...
126134
// Igual, así funciona bien con el due (y con todos, ya que no hay problema en superar el máximo de la resolución)
127135
analogWriteResolution(i);
128136
analogReadResolution(i);
129137

130138
LOG("Resolution changed to: ", i);
131139

132-
return 3; // Command of 3 bytes
140+
return 6; // Command of 6 bytes
133141
}
134142

135-
136143
/**
137-
* PIN_MODE: 0x04 0x02 [PIN] [MODE]
144+
PIN_MODE: 0x04 0x00 0x00 0x00 0x02 [PIN] [MODE]
138145
*/
139-
int GenericArduinoController::set_pin_mode(GenericArduinoController* this_, const char* data)
146+
int GenericArduinoController::set_pin_mode(GenericArduinoController* this_, uint32_t &buff_len, const char* data)
140147
{
141-
pinMode(data[2], data[3]);
142-
LOG("Changed pin mode on pin ", uint8_t(data[2]));
143-
LOG("Mode set to ", uint8_t(data[3]));
148+
pinMode(data[5], data[6]);
149+
LOG("Changed pin mode on pin ", uint8_t(data[5]));
150+
LOG("Mode set to ", uint8_t(data[6]));
144151

145-
return 4; // Command of 4 bytes
152+
return 7; // Command of 7 bytes
146153
}
147154

148155
/**
149-
* REPORT_MODE: 0x05 0x03 [MODE] [READ_COUNT] [READ_DELAY]
156+
REPORT_MODE: 0x05 0x00 0x00 0x00 0x03 [MODE] [READ_COUNT] [READ_DELAY]
150157
*/
151-
int GenericArduinoController::set_report_mode(GenericArduinoController* this_, const char* data)
158+
int GenericArduinoController::set_report_mode(GenericArduinoController* this_, uint32_t &buff_len, const char* data)
152159
{
153-
this_->REPORT_MODE = (ReportModes)(data[2]);
154-
this_->REPORT_READ_COUNT = byte(data[3]);
155-
this_->REPORT_READ_DELAY = byte(data[4]);
160+
this_->REPORT_MODE = (ReportModes)(data[5]);
161+
this_->REPORT_READ_COUNT = byte(data[6]);
162+
this_->REPORT_READ_DELAY = byte(data[7]);
156163
LOG("Report mode changed", "")
157164
LOG("Report mode: ", this_->REPORT_MODE);
158-
LOG("New Read count: ", byte(data[3]));
159-
LOG("New Read delay: ", byte(data[4]));
165+
LOG("New Read count: ", this_->REPORT_READ_COUNT);
166+
LOG("New Read delay: ", this_->REPORT_READ_DELAY);
160167

161-
return 5; // Command of 5 bytes
168+
return 8; // Command of 8 bytes
162169
}
163170

164171
/**
165-
* ANALOG_INPUT: 0x02 0x01 [PORT]
172+
ANALOG_INPUT: 0x02 0x00 0x00 0x00 0x01 [PORT]
166173
*/
167-
int GenericArduinoController::set_analog_input(GenericArduinoController* this_, const char* data)
174+
int GenericArduinoController::set_analog_input(GenericArduinoController* this_, uint32_t &buff_len, const char* data)
168175
{
169176
this_->INPUT_PORTS[0] += 1;
170-
this_->INPUT_PORTS[this_->INPUT_PORTS[0]] = byte(data[2]);
177+
this_->INPUT_PORTS[this_->INPUT_PORTS[0]] = byte(data[5]);
171178

172179
if ( this_->INPUT_PORTS[this_->INPUT_PORTS[0]] >= A0 )
173180
{
174181
this_->ANALOG_PINS_COUNT++;
175-
LOG("New analog input: ", byte(data[2]));
182+
LOG("New analog input: ", byte(data[5]));
176183
} else
177184
{
178185
this_->DIGITAL_PINS_COUNT++;
179-
LOG("New digital input: ", byte(data[2]));
186+
LOG("New digital input: ", byte(data[5]));
180187
}
181188

182-
return 3; // Command of 3 bytes
189+
return 6; // Command of 6 bytes
183190
}
184191

185192
/**
186-
* RESET: 0xFF
193+
RESET: 0xFF 0x00 0x00 0x00 0x00
187194
*/
188-
int GenericArduinoController::reset(GenericArduinoController* this_, const char* data)
195+
int GenericArduinoController::reset(GenericArduinoController* this_, uint32_t &buff_len, const char* data)
189196
{
190197
for ( int i = 1; i <= byte(this_->INPUT_PORTS[0]); i++)
191198
{
@@ -199,34 +206,33 @@ int GenericArduinoController::reset(GenericArduinoController* this_, const char*
199206

200207
LOG("System reset executed", "");
201208

202-
return 1;
209+
return 5;
203210
}
204211

205212
/**
206-
* ANALOG_OUTPUT: 0x03 0x01 [PORT]
213+
ANALOG_OUTPUT: 0x03 0x00 0x00 0x00 0x01 [PORT]
207214
*/
208-
int GenericArduinoController::set_analog_output(GenericArduinoController* this_, const char* data)
215+
int GenericArduinoController::set_analog_output(GenericArduinoController* this_, uint32_t &buff_len, const char* data)
209216
{
210217
// No se si vale la pena guardar registro de pines de salida...
211218

212-
return 3; // Command of 3 bytes
219+
return 6; // Command of 3 bytes
213220
}
214221

215222
/**
216-
* ACTUATE: 0xF0 [DATA_LEN] [PIN_A] [VALUE_PIN_A] ... [PIN_N] [VALUE_PIN_N]
223+
ACTUATE: 0xF0 [DATA_LEN] [PIN_A] [VALUE_PIN_A] ... [PIN_N] [VALUE_PIN_N]
217224
*/
218-
int GenericArduinoController::actuate(GenericArduinoController* this_, const char* data)
225+
int GenericArduinoController::actuate(GenericArduinoController* this_, uint32_t &buff_len, const char* data)
219226
{
220-
int offset = 0;
221-
int byte_count = byte(data[1]); // Un byte puede llegar a limitar la cantidad de salidas... creo
227+
uint32_t offset = 0;
222228

223229
uint8_t digital_input_buffer[this_->DIGITAL_PINS_COUNT][this_->REPORT_READ_COUNT / 8 + 2]; // 255 lectures of 1 bit for every digital pin -- 1 extra byte for the port address
224230
uint8_t analog_input_buffer[this_->ANALOG_PINS_COUNT][(2 * this_->REPORT_READ_COUNT) + 3]; // 255 lectures of 2 bytes for every analog pin -- 1 extra byte for the port address
225231

226-
LOG("Actutating over payload of size: ", byte_count);
232+
LOG("Actutating over payload of size: ", buff_len);
227233

228234
// ACTUATION ZONE
229-
while (offset < byte_count)
235+
while (offset < buff_len)
230236
{
231237
//Se aplica la acción a cada puerto indicado
232238
int port = byte(data[2 + offset]);
@@ -253,7 +259,7 @@ int GenericArduinoController::actuate(GenericArduinoController* this_, const cha
253259

254260
char response[130];
255261
response[0] = '\xF1';
256-
uint16_t len = 0; // Inicia en 1 para evitar pisar el id de comando
262+
uint32_t len = 0; // Inicia en 1 para evitar pisar el id de comando
257263

258264
// Resets of digital buffers (required due the buffering strategy for digital pins)
259265
memset(digital_input_buffer, 0, this_->DIGITAL_PINS_COUNT * (this_->REPORT_READ_COUNT / 8 + 2));
@@ -306,37 +312,45 @@ int GenericArduinoController::actuate(GenericArduinoController* this_, const cha
306312

307313
LOG("Finish", "");
308314

315+
// Stores digital & analog used bytes
316+
uint32_t analog_len = 0;
317+
uint32_t digital_len = 0;
318+
309319
// Every analog output will be in the buffer as
310320
if (this_->ANALOG_PINS_COUNT > 0)
311321
{
312-
len += this_->ANALOG_PINS_COUNT + ((this_->REPORT_READ_COUNT + 1) * 2 * this_->ANALOG_PINS_COUNT);
322+
analog_len = this_->ANALOG_PINS_COUNT + ((this_->REPORT_READ_COUNT + 1) * 2 * this_->ANALOG_PINS_COUNT);
323+
len += analog_len;
313324
}
314325

315326
if (this_->DIGITAL_PINS_COUNT > 0)
316327
{
317-
len += this_->DIGITAL_PINS_COUNT + (((this_->REPORT_READ_COUNT + 1) / 8 ) + 1) * this_->DIGITAL_PINS_COUNT;
328+
digital_len = this_->DIGITAL_PINS_COUNT + (((this_->REPORT_READ_COUNT + 1) / 8 ) + (1 ? (this_->REPORT_READ_COUNT + 1) % 8 != 0 : 0)) * this_->DIGITAL_PINS_COUNT;
329+
len += digital_len;
318330
}
319331

320332
LOG("Reporting actuate results ", len - 1);
321-
LOG("No idea...", "");
322-
response[1] = len;
323-
this_->stream_.write(response, 2); // 2 bytes extras por el id de comando y la longitud y -1 por el padding
333+
334+
response[1] = len >> 24;
335+
response[2] = (len & 0x00FF0000) >> 16;
336+
response[3] = (len & 0x0000FF00) >> 8;
337+
response[4] = len & 0x000000FF;
338+
339+
this_->stream_.write(response, 5); // 5 bytes extras por el id de comando y la longitud y -1 por el padding
324340

325341
//response[len + 1] = INPUT_PORTS[i];
326342
if ( this_->ANALOG_PINS_COUNT > 0)
327343
{
328-
this_->stream_.write(analog_input_buffer[0], this_->ANALOG_PINS_COUNT + ((this_->REPORT_READ_COUNT + 1) * 2 * this_->ANALOG_PINS_COUNT));
329-
//SerialUSB.write(INPUT_PORTS[i]);
330-
//SerialUSB.write(analog_input_buffer[INPUT_PORTS[i] - A0], (REPORT_READ_COUNT + 1) * 2);
331-
LOG("Reported an analog port with a read count len of: ", this_->ANALOG_PINS_COUNT + (this_->REPORT_READ_COUNT + 1) * 2 * this_->ANALOG_PINS_COUNT);
344+
this_->stream_.write(analog_input_buffer[0], analog_len);
345+
LOG("Reported an analog port with a read count len of: ", analog_len);
332346
}
333-
347+
334348
if ( this_->DIGITAL_PINS_COUNT > 0) {
335-
this_->stream_.write(digital_input_buffer[0], this_->DIGITAL_PINS_COUNT + (((this_->REPORT_READ_COUNT + 1) / 8 ) + 1) * this_->DIGITAL_PINS_COUNT );
336-
LOG("Reported an digital port with a read count len of: ", this_->DIGITAL_PINS_COUNT + (((this_->REPORT_READ_COUNT + 1) / 8 ) + 1) * this_->DIGITAL_PINS_COUNT );
349+
this_->stream_.write(digital_input_buffer[0], digital_len );
350+
LOG("Reported a digital port with a read count len of: ", digital_len );
337351
}
338352

339-
return len + 2;
353+
return len + 5;
340354
}
341355

342356

0 commit comments

Comments
 (0)