11
2- #define DEBUG 1
3- #if DEBUG
4- #define LOG (x,y ) Serial.print(x); Serial.println(y);
5- #else
6- #define LOG (x,y )
7- #endif
8-
9- // defines ahorran ROM... aunque nos sobra de eso XD -- Verificar que los const vayan a la rom!
10- const uint8_t ANALOG_PRECISION_CMD = 0x01 ;
11- const uint8_t ADD_INPUT_PIN_CMD = 0x02 ;
12- const uint8_t ADD_OUTPUT_PIN_CMD = 0x03 ;
13- const uint8_t SET_PIN_MODE_CMD = 0x04 ;
14- const uint8_t SET_REPORT_MODE_CMD = 0x05 ;
15- const uint8_t ANALOG_WRITE = 0x06 ;
16- const uint8_t ACTUATE_CMD = 0xF0 ;
17- const uint8_t RESET_PINS = 0xFE ;
18-
19- // Commands executor caller -- one vector position == one command
20- int (*executor[255 ])(const char *);
21-
22- int not_implemented (const char * data)
23- {
24- // nothing to do...
25- return 1 ;
26- }
27-
28- typedef enum ReportModes {average, bulk, rt};
29-
30- /* * ---------------------------------------------------------- **/
31- /* * GLOBAL CONFIG **/
32-
33- uint8_t REPORT_READ_COUNT = 0 ;
34- uint8_t REPORT_READ_DELAY = 0 ;
35- ReportModes REPORT_MODE = average;
36- uint8_t INPUT_PORTS[129 ]; // Port count in first position
37- uint8_t ANALOG_PINS_COUNT = 0 ;
38- uint8_t DIGITAL_PINS_COUNT = 0 ;
39-
40- /* * ---------------------------------------------------------- **/
41-
42- const char * ACK = " \xFF\x00 " ;
43-
44- /* *
45- * ANALOG_WRITE: 0x06 0x03 [PIN] [H_VALUE][L_VALUE]
46- */
47- int analog_write (const char * data)
48- {
49- uint16_t data = (data[3 ] << 8 ) + data[4 ];
50- analogWrite (data[2 ], data[3 ]);
51- return 5 ;
52- }
53-
54- /* *
55- ANALOG_PRECISION: 0x01 0x01 [BITS]
56- */
57- int set_analog_precision (const char * data)
58- {
59- int i = byte (data[2 ]);
60- // Tal vez conviene separar estas funciones ya que hay boards con resoluciones distintas...
61- // Igual, así funciona bien con el due (y con todos, ya que no hay problema en superar el máximo de la resolución)
62- analogWriteResolution (i);
63- analogReadResolution (i);
64-
65- LOG (" Resolution changed to: " , i);
66-
67- return 3 ; // Command of 3 bytes
68- }
69-
70- /* *
71- PIN_MODE: 0x04 0x02 [PIN] [MODE]
72- */
73- int set_pin_mode (const char * data)
74- {
75- pinMode (data[2 ], data[3 ]);
76- LOG (" Changed pin mode on pin " , uint8_t (data[2 ]));
77- LOG (" Mode set to " , uint8_t (data[3 ]));
78-
79- return 4 ; // Command of 4 bytes
80- }
81-
82- /* *
83- REPORT_MODE: 0x05 0x03 [MODE] [READ_COUNT] [READ_DELAY]
84- */
85- int set_report_mode (const char * data)
86- {
87- REPORT_MODE = (ReportModes)(data[2 ]);
88- REPORT_READ_COUNT = byte (data[3 ]);
89- REPORT_READ_DELAY = byte (data[4 ]);
90- LOG (" Report mode changed on port " , byte (data[3 ]));
91-
92- return 5 ; // Command of 5 bytes
93- }
94-
95- /* *
96- ANALOG_INPUT: 0x02 0x01 [PORT]
97- */
98- int set_analog_input (const char * data)
99- {
100- INPUT_PORTS[0 ] += 1 ;
101- INPUT_PORTS[INPUT_PORTS[0 ]] = byte (data[2 ]);
102-
103- if ( INPUT_PORTS[INPUT_PORTS[0 ]] >= A0 )
104- {
105- ANALOG_PINS_COUNT++;
106- LOG (" New analog input: " , byte (data[2 ]));
107- } else
108- {
109- DIGITAL_PINS_COUNT++;
110- LOG (" New digital input: " , byte (data[2 ]));
111- }
112-
113- return 3 ; // Command of 3 bytes
114- }
115- /* *
116- RESET: 0xFF
117- */
118- int reset (const char * data)
119- {
120- for ( int i = 1 ; i <= byte (INPUT_PORTS[0 ]); i++)
121- {
122- pinMode (INPUT_PORTS[i], OUTPUT);
123- }
124-
125- INPUT_PORTS[0 ] = 0 ;
126- ANALOG_PINS_COUNT = 0 ;
127- DIGITAL_PINS_COUNT = 0 ;
128-
129- LOG (" System reset executed" , " " );
2+ #include " GenericArduinoController.h"
1303
131- return 1 ;
132- }
133-
134- /* *
135- ANALOG_OUTPUT: 0x03 0x01 [PORT]
136- */
137- int set_analog_output (const char * data)
138- {
139- // No se si vale la pena guardar registro de pines de salida...
140-
141- return 3 ; // Command of 3 bytes
142- }
143-
144- /* *
145- ACTUATE: 0xF0 [DATA_LEN] [PIN_A] [VALUE_PIN_A] ... [PIN_N] [VALUE_PIN_N]
146- */
147- int actuate (const char * data)
148- {
149- int offset = 0 ;
150- int byte_count = byte (data[1 ]); // Un byte puede llegar a limitar la cantidad de salidas... creo
151-
152- uint8_t digital_input_buffer[DIGITAL_PINS_COUNT][REPORT_READ_COUNT / 8 + 2 ]; // 255 lectures of 1 bit for every digital pin -- 1 extra byte for the port address
153- uint8_t analog_input_buffer[ANALOG_PINS_COUNT][(2 * REPORT_READ_COUNT) + 3 ]; // 255 lectures of 2 bytes for every analog pin -- 1 extra byte for the port address
154-
155- LOG (" Actutating over payload of size: " , byte_count);
156-
157- // ACTUATION ZONE
158- while (offset < byte_count)
159- {
160- // Se aplica la acción a cada puerto indicado
161- int port = byte (data[2 + offset]);
162-
163- // Detects an analog port
164- if ( port >= A0 )
165- {
166- int value = (data[3 + offset] << 8 ) + data[4 + offset];
167- analogWrite (port, value);
168- offset += 3 ;
169-
170- LOG (" Analog pin written" , port);
171- } else
172- {
173- int value = data[3 + offset] > 0 ? HIGH : LOW; // Creo que da igual si pongo el entero directamente
174- digitalWrite (port, value);
175- offset += 2 ;
176-
177- LOG (" Digital pin written " , port);
178- }
179- }
180-
181- delayMicroseconds (REPORT_READ_DELAY); // FIXME: Usamos variable de 8 bits cuando la precisión de esta función llega a 16 bits.
182-
183- char response[130 ];
184- response[0 ] = ' \xF1 ' ;
185- uint16_t len = 0 ; // Inicia en 1 para evitar pisar el id de comando
186-
187- // Resets of digital buffers (required due the buffering strategy for digital pins)
188- memset (digital_input_buffer, 0 , DIGITAL_PINS_COUNT * (REPORT_READ_COUNT / 8 + 2 ));
189-
190- for (int i = 0 ; i < DIGITAL_PINS_COUNT; i++)
191- {
192- for (int j = 0 ; j < REPORT_READ_COUNT / 8 + 1 ; j++)
193- {
194- Serial.print (digital_input_buffer[i][j], HEX);
195- }
196- Serial.println (" " );
197- }
198-
199- // Tracks count of digital and analog ports
200- LOG (" Number of lectures to report: " , REPORT_READ_COUNT);
201- for (int lecture = 0 ; lecture <= REPORT_READ_COUNT; lecture++)
202- {
203- uint8_t current_digital = 0 ;
204- uint8_t current_analog = 0 ;
205- for (int i = 1 ; i <= byte (INPUT_PORTS[0 ]); i++)
206- {
207- // response[len + 1] = INPUT_PORTS[i];
208- if ( INPUT_PORTS[i] >= A0 )
209- {
210- LOG (" Reading analog port A" , INPUT_PORTS[i] - A0);
211- int data = analogRead (INPUT_PORTS[i] - A0);
212- // response[len + 2] = byte((data & 0xFF00) >> 8); // Se guarda el msb en el buffer
213- // response[len + 3] = byte(data & 0xFF); // Se guarda el lsb en el buffer
214- analog_input_buffer[current_analog][0 ] = INPUT_PORTS[i];
215- analog_input_buffer[current_analog][(lecture * 2 ) + 1 ] = byte ((data & 0xFF00 ) >> 8 );
216- analog_input_buffer[current_analog][(lecture * 2 ) + 2 ] = byte (data & 0xFF );
217-
218- // len += 3; // Cada lectura de un recurso analógico ocupa dos bytes. FIXME: se puede optimizar con bajas resoluciones
219- LOG (" =====================================" , " " );
220- LOG (" Analog pin read: " , INPUT_PORTS[i]);
221- LOG (" Analog read value: " , data);
222-
223- current_analog++;
224- } else
225- {
226- int data = digitalRead (INPUT_PORTS[i]);
227- // response[len + 2] = byte(data);
228- digital_input_buffer[current_digital][0 ] = INPUT_PORTS[i];
229- digital_input_buffer[current_digital][(lecture / 8 ) + 1 ] += (byte (data) & 0x01 ) << (lecture % 8 ); // Just keep first bit
230- current_digital++;
231- // len += 2;
232- LOG (" =====================================" , " " );
233- LOG (" Digital pin read: " , INPUT_PORTS[i]);
234- LOG (" Raw read: " , data);
235- LOG (" Lecture: " , lecture);
236- LOG (" Filtered read: " , (byte (data) & 0x01 ));
237- LOG (" Left padding: " , (lecture % 8 ));
238- LOG (" Added: " , (byte (data) & 0x01 ) << (lecture % 8 ));
239- LOG (" Digital read value: " , digital_input_buffer[current_digital - 1 ][(lecture / 8 ) + 1 ]);
240- }
241- };
242- }
243-
244- // Every analog output will be in the buffer as
245- if (ANALOG_PINS_COUNT > 0 )
246- {
247- len += ANALOG_PINS_COUNT + ((REPORT_READ_COUNT + 1 ) * 2 * ANALOG_PINS_COUNT);
248- }
249-
250- if (DIGITAL_PINS_COUNT > 0 )
251- {
252- len += DIGITAL_PINS_COUNT + (((REPORT_READ_COUNT + 1 ) / 8 ) + 1 ) * DIGITAL_PINS_COUNT;
253- }
254-
255- LOG (" Reporting actuate results " , len - 1 );
256- response[1 ] = len;
257- SerialUSB.write (response, 2 ); // 2 bytes extras por el id de comando y la longitud y -1 por el padding
258-
259- // response[len + 1] = INPUT_PORTS[i];
260- if ( ANALOG_PINS_COUNT > 0 )
261- {
262- SerialUSB.write (analog_input_buffer[0 ], ANALOG_PINS_COUNT + ((REPORT_READ_COUNT + 1 ) * 2 * ANALOG_PINS_COUNT));
263- // SerialUSB.write(INPUT_PORTS[i]);
264- // SerialUSB.write(analog_input_buffer[INPUT_PORTS[i] - A0], (REPORT_READ_COUNT + 1) * 2);
265- LOG (" Reported an analog port with a read count len of: " , ANALOG_PINS_COUNT + (REPORT_READ_COUNT + 1 ) * 2 * ANALOG_PINS_COUNT);
266- }
267-
268- if ( DIGITAL_PINS_COUNT > 0 ) {
269- SerialUSB.write (digital_input_buffer[0 ], DIGITAL_PINS_COUNT + (((REPORT_READ_COUNT + 1 ) / 8 ) + 1 ) * DIGITAL_PINS_COUNT );
270- LOG (" Reported an digital port with a read count len of: " , DIGITAL_PINS_COUNT + (((REPORT_READ_COUNT + 1 ) / 8 ) + 1 ) * DIGITAL_PINS_COUNT );
271- }
272-
273- return len + 2 ;
274- }
4+ GenericArduinoController controller (SerialUSB);
2755
2766void setup () {
2777 SerialUSB.begin (115200 );
@@ -280,44 +10,12 @@ void setup() {
28010 Serial.begin (115200 );
28111#endif
28212
283- for (int i = 0 ; i < 255 ; i++)
284- {
285- executor[i] = ¬_implemented;
286- }
287-
288- INPUT_PORTS[0 ] = 0 ;
289-
290- /* * Commands Callbacks **/
291- executor[ANALOG_PRECISION_CMD] = &set_analog_precision;
292- executor[ADD_INPUT_PIN_CMD] = &set_analog_input;
293- executor[ADD_OUTPUT_PIN_CMD] = &set_analog_output;
294- executor[SET_PIN_MODE_CMD] = &set_pin_mode;
295- executor[SET_REPORT_MODE_CMD] = &set_report_mode;
296- executor[ACTUATE_CMD] = &actuate;
297- executor[RESET_PINS] = &reset;
29813}
29914
30015void loop () {
16+ controller.handle_commands ();
30117
302- if (SerialUSB.available () > 0 )
303- {
304- LOG (" USB serial data available " , SerialUSB.available ());
305- char input[64 ]; // Esto se reserva en el stack, tal vez hacerlo global consume menos recursos...
306-
307- byte b_read = 0 ;
308- byte b_pos = 0 ;
309-
310- while (SerialUSB.available () > 0 )
311- {
312- b_read += SerialUSB.readBytes (input, SerialUSB.available ());
313- }
314-
315- // Loop to process all commands received in the buffer
316- while (b_pos < b_read)
317- {
318- LOG (" Executing command: " , int (input[b_pos]));
319- b_pos += executor[input[b_pos]](&input[b_pos]); // Does the callback for the command
320- LOG (" b_pos " , b_pos);
321- }
322- }
18+ /* *
19+ * HERE the user can insert any command
20+ */
32321}
0 commit comments