11
2- #define DEBUG 0
2+ #define DEBUG 1
33#if DEBUG
44#define LOG (x,y ) Serial.print(x); Serial.println(y);
55#else
88
99// defines ahorran ROM... aunque nos sobra de eso XD -- Verificar que los const vayan a la rom!
1010const uint8_t ANALOG_PRECISION_CMD = 0x01 ;
11- const uint8_t ADD_INPUT_PORT_CMD = 0x02 ;
12- const uint8_t ADD_OUTPUT_PORT_CMD = 0x03 ;
11+ const uint8_t ADD_INPUT_PIN_CMD = 0x02 ;
12+ const uint8_t ADD_OUTPUT_PIN_CMD = 0x03 ;
1313const uint8_t SET_PIN_MODE_CMD = 0x04 ;
1414const uint8_t SET_REPORT_MODE_CMD = 0x05 ;
1515const uint8_t ACTUATE_CMD = 0xF0 ;
16+ const uint8_t RESET_PINS = 0xFE ;
1617
1718// Commands executor caller -- one vector position == one command
1819int (*executor[255 ])(const char *);
1920
2021int not_implemented (const char * data)
2122{
2223 // nothing to do...
23- return 0 ;
24+ return 1 ;
2425}
2526
2627typedef enum ReportModes {average, bulk, rt};
@@ -32,6 +33,8 @@ uint8_t REPORT_READ_COUNT = 0;
3233uint8_t REPORT_READ_DELAY = 0 ;
3334ReportModes REPORT_MODE = average;
3435uint8_t INPUT_PORTS[129 ]; // Port count in first position
36+ uint8_t ANALOG_PINS_COUNT = 0 ;
37+ uint8_t DIGITAL_PINS_COUNT = 0 ;
3538
3639/* * ---------------------------------------------------------- **/
3740
@@ -85,14 +88,41 @@ int set_analog_input(const char* data)
8588{
8689 INPUT_PORTS[0 ] += 1 ;
8790 INPUT_PORTS[INPUT_PORTS[0 ]] = byte (data[2 ]);
88- LOG (" New analog input: " , byte (data[2 ]));
91+
92+ if ( INPUT_PORTS[INPUT_PORTS[0 ]] >= A0 )
93+ {
94+ ANALOG_PINS_COUNT++;
95+ LOG (" New analog input: " , byte (data[2 ]));
96+ } else
97+ {
98+ DIGITAL_PINS_COUNT++;
99+ LOG (" New digital input: " , byte (data[2 ]));
100+ }
89101
90102 return 3 ; // Command of 3 bytes
91103}
104+ /* *
105+ RESET: 0xFF
106+ */
107+ int reset (const char * data)
108+ {
109+ for ( int i = 1 ; i <= byte (INPUT_PORTS[0 ]); i++)
110+ {
111+ pinMode (INPUT_PORTS[i], OUTPUT);
112+ }
113+
114+ INPUT_PORTS[0 ] = 0 ;
115+ ANALOG_PINS_COUNT = 0 ;
116+ DIGITAL_PINS_COUNT = 0 ;
117+
118+ LOG (" System reset executed" , " " );
119+
120+ return 1 ;
121+ }
92122
93123/* *
94- * ANALOG_OUTPUT: 0x03 0x01 [PORT]
95- */
124+ ANALOG_OUTPUT: 0x03 0x01 [PORT]
125+ */
96126int set_analog_output (const char * data)
97127{
98128 // No se si vale la pena guardar registro de pines de salida...
@@ -101,13 +131,16 @@ int set_analog_output(const char* data)
101131}
102132
103133/* *
104- * ACTUATE: 0xF0 [DATA_LEN] [PIN_A] [VALUE_PIN_A] ... [PIN_N] [VALUE_PIN_N]
105- */
134+ ACTUATE: 0xF0 [DATA_LEN] [PIN_A] [VALUE_PIN_A] ... [PIN_N] [VALUE_PIN_N]
135+ */
106136int actuate (const char * data)
107137{
108138 int offset = 0 ;
109139 int byte_count = byte (data[1 ]); // Un byte puede llegar a limitar la cantidad de salidas... creo
110140
141+ 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
142+ uint8_t analog_input_buffer[ANALOG_PINS_COUNT][(2 * REPORT_READ_COUNT) + 2 ]; // 255 lectures of 2 bytes for every analog pin -- 1 extra byte for the port address
143+
111144 LOG (" Actutating over payload of size: " , byte_count);
112145
113146 // ACTUATION ZONE
@@ -138,42 +171,104 @@ int actuate(const char* data)
138171
139172 char response[130 ];
140173 response[0 ] = ' \xF1 ' ;
141- byte len = 1 ; // Inicia en 1 para evitar pisar el id de comando
142- for (int i = 1 ; i <= byte (INPUT_PORTS[0 ]); i++)
174+ uint16_t len = 0 ; // Inicia en 1 para evitar pisar el id de comando
175+
176+ // Resets of digital buffers (required due the buffering strategy for digital pins)
177+ memset (digital_input_buffer, 0 , DIGITAL_PINS_COUNT * (REPORT_READ_COUNT / 8 + 2 ));
178+
179+ for (int i = 0 ; i < DIGITAL_PINS_COUNT; i++)
143180 {
144- response[len + 1 ] = INPUT_PORTS[i];
145- if ( INPUT_PORTS[i] >= A0 )
181+ for (int j = 0 ; j < REPORT_READ_COUNT / 8 + 1 ; j++)
146182 {
147- int data = analogRead (INPUT_PORTS[i]-A0);
148- response[len + 2 ] = byte ((data & 0xFF00 ) >> 8 ); // Se guarda el msb en el buffer
149- response[len + 3 ] = byte (data & 0xFF ); // Se guarda el lsb en el buffer
183+ Serial.print (digital_input_buffer[i][j], HEX);
184+ }
185+ Serial.println (" " );
186+ }
150187
151- len += 3 ; // Cada lectura de un recurso analógico ocupa dos bytes. FIXME: se puede optimizar con bajas resoluciones
152- LOG (" Analog pin read: " , INPUT_PORTS[i]);
153- } else
188+ // Tracks count of digital and analog ports
189+ LOG (" Number of lectures to report: " , REPORT_READ_COUNT);
190+ for (int lecture = 0 ; lecture <= REPORT_READ_COUNT; lecture++)
191+ {
192+ uint8_t current_digital = 0 ;
193+ uint8_t current_analog = 0 ;
194+ for (int i = 1 ; i <= byte (INPUT_PORTS[0 ]); i++)
154195 {
155- int data = digitalRead (INPUT_PORTS[i]);
156- response[len + 2 ] = byte (data);
157- len += 2 ;
158- LOG (" Digital pin read: " , INPUT_PORTS[i]);
159- }
160- };
196+ // response[len + 1] = INPUT_PORTS[i];
197+ if ( INPUT_PORTS[i] >= A0 )
198+ {
199+ LOG (" Reading analog port A" , INPUT_PORTS[i] - A0);
200+ int data = analogRead (INPUT_PORTS[i] - A0);
201+ // response[len + 2] = byte((data & 0xFF00) >> 8); // Se guarda el msb en el buffer
202+ // response[len + 3] = byte(data & 0xFF); // Se guarda el lsb en el buffer
203+ analog_input_buffer[current_analog][0 ] = INPUT_PORTS[i];
204+ analog_input_buffer[current_analog][lecture + 1 ] = byte ((data & 0xFF00 ) >> 8 );
205+ analog_input_buffer[current_analog][lecture + 2 ] = byte (data & 0xFF );
206+
207+ current_analog++;
208+
209+ // len += 3; // Cada lectura de un recurso analógico ocupa dos bytes. FIXME: se puede optimizar con bajas resoluciones
210+ LOG (" =====================================" , " " );
211+ LOG (" Analog pin read: " , INPUT_PORTS[i]);
212+ LOG (" Analog read value: " , data);
213+ } else
214+ {
215+ int data = digitalRead (INPUT_PORTS[i]);
216+ // response[len + 2] = byte(data);
217+ digital_input_buffer[current_digital][0 ] = INPUT_PORTS[i];
218+ digital_input_buffer[current_digital][(lecture / 8 ) + 1 ] += (byte (data) & 0x01 ) << (lecture % 8 ); // Just keep first bit
219+ current_digital++;
220+ // len += 2;
221+ LOG (" =====================================" , " " );
222+ LOG (" Digital pin read: " , INPUT_PORTS[i]);
223+ LOG (" Raw read: " , data);
224+ LOG (" Lecture: " , lecture);
225+ LOG (" Filtered read: " , (byte (data) & 0x01 ));
226+ LOG (" Left padding: " , (lecture % 8 ));
227+ LOG (" Added: " , (byte (data) & 0x01 ) << (lecture % 8 ));
228+ LOG (" Digital read value: " , digital_input_buffer[current_digital - 1 ][(lecture / 8 ) + 1 ]);
229+ }
230+ };
231+ }
161232
233+ // Every analog output will be in the buffer as
234+ if (ANALOG_PINS_COUNT > 0 )
235+ {
236+ len += ANALOG_PINS_COUNT + ( (REPORT_READ_COUNT + 1 ) * 2 );
237+ }
238+
239+ if (DIGITAL_PINS_COUNT > 0 )
240+ {
241+ len += DIGITAL_PINS_COUNT + (((REPORT_READ_COUNT + 1 ) / 8 ) + 1 );
242+ }
162243
163244 LOG (" Reporting actuate results " , len - 1 );
164- response[1 ] = len - 1 ;
165- SerialUSB.write (response, len + 1 ); // 2 bytes extras por el id de comando y la longitud y -1 por el padding
245+ response[1 ] = len;
246+ SerialUSB.write (response, 2 ); // 2 bytes extras por el id de comando y la longitud y -1 por el padding
247+
248+ // response[len + 1] = INPUT_PORTS[i];
249+ if ( ANALOG_PINS_COUNT > 0 )
250+ {
251+ SerialUSB.write (analog_input_buffer[0 ], ANALOG_PINS_COUNT + ((REPORT_READ_COUNT + 1 ) * 2 * ANALOG_PINS_COUNT));
252+ // SerialUSB.write(INPUT_PORTS[i]);
253+ // SerialUSB.write(analog_input_buffer[INPUT_PORTS[i] - A0], (REPORT_READ_COUNT + 1) * 2);
254+ LOG (" Reported an analog port with a read count len of: " , (REPORT_READ_COUNT + 1 ) * 2 + 1 );
255+ }
256+
257+ if ( DIGITAL_PINS_COUNT > 0 ) {
258+ SerialUSB.write (digital_input_buffer[0 ], DIGITAL_PINS_COUNT + (((REPORT_READ_COUNT + 1 ) / 8 ) + 1 ) * DIGITAL_PINS_COUNT );
259+ LOG (" Reported an digital port with a read count len of: " , DIGITAL_PINS_COUNT + (((REPORT_READ_COUNT + 1 ) / 8 ) + 1 ) * DIGITAL_PINS_COUNT );
260+ }
166261
167- return offset + 2 ;
262+ return len + 2 ;
168263}
169264
170265void setup () {
171266 SerialUSB.begin (115200 );
172-
173- #if DEBUG
267+
268+ #if DEBUG
174269 Serial.begin (115200 );
175- #endif
176-
270+ #endif
271+
177272 for (int i = 0 ; i < 255 ; i++)
178273 {
179274 executor[i] = ¬_implemented;
@@ -183,36 +278,53 @@ void setup() {
183278
184279 /* * Commands Callbacks **/
185280 executor[ANALOG_PRECISION_CMD] = &set_analog_precision;
186- executor[ADD_INPUT_PORT_CMD] = &set_analog_input;
187- executor[ADD_OUTPUT_PORT_CMD] = &set_analog_output;
281+ executor[ADD_INPUT_PIN_CMD] = &set_analog_input;
282+ executor[ADD_OUTPUT_PIN_CMD] = &set_analog_output;
188283 executor[SET_PIN_MODE_CMD] = &set_pin_mode;
189284 executor[SET_REPORT_MODE_CMD] = &set_report_mode;
190285 executor[ACTUATE_CMD] = &actuate;
286+ executor[RESET_PINS] = &reset;
287+
288+ // executor[SET_PIN_MODE_CMD]("\x04\x02\x3E\x00");
289+ // executor[ANALOG_PRECISION_CMD]("\x01\x01\x0C");
290+ // executor[SET_REPORT_MODE_CMD]("\x05\x03\x00\x09\x00");
291+ // executor[ADD_INPUT_PIN_CMD]("\x02\x01\x3E");
292+ // executor[SET_PIN_MODE_CMD]("\x04\x02\x3E\x00");
293+ // // executor[ADD_INPUT_PIN_CMD]("\x02\x01\x3F");
294+ // // executor[SET_PIN_MODE_CMD]("\x04\x02\x3F\x00");
295+ // executor[ADD_INPUT_PIN_CMD]("\x02\x01\x28");
296+ // executor[SET_PIN_MODE_CMD]("\x04\x02\x28\x00");
297+ // executor[ADD_INPUT_PIN_CMD]("\x02\x01\x29");
298+ // executor[SET_PIN_MODE_CMD]("\x04\x02\x29\x00");
299+ // executor[ADD_INPUT_PIN_CMD]("\x02\x01\x2A");
300+ // executor[SET_PIN_MODE_CMD]("\x04\x02\x2A\x00");
191301
192302}
193303
194304void loop () {
195- // executor[ACTUATE_CMD]("\xF0\x01\x28 \x01");
305+ // executor[ACTUATE_CMD]("\xF0\x01\x2B \x01");
196306
197307 if (SerialUSB.available () > 0 )
198308 {
199309 LOG (" USB serial data available " , SerialUSB.available ());
200310 char input[64 ]; // Esto se reserva en el stack, tal vez hacerlo global consume menos recursos...
201-
311+
202312 byte b_read = 0 ;
203313 byte b_pos = 0 ;
204-
314+
205315 while (SerialUSB.available () > 0 )
206316 {
207317 b_read += SerialUSB.readBytes (input, SerialUSB.available ());
208318 }
209-
319+
210320 // Loop to process all commands received in the buffer
211- while (b_pos < b_read)
321+ while (b_pos < b_read)
212322 {
213323 LOG (" Executing command: " , int (input[b_pos]));
214324 b_pos += executor[input[b_pos]](&input[b_pos]); // Does the callback for the command
215325 LOG (" b_pos " , b_pos);
216326 }
217327 }
328+
329+ delay (4000 );
218330}
0 commit comments