14
14
15
15
- handlePinMode calls Firmata::setPinMode
16
16
17
- Last updated October 16th, 2016
17
+ Last updated March 16th, 2020
18
18
*/
19
19
20
20
#include " SerialFirmata.h"
21
21
22
+ // The RX and TX hardware FIFOs of the ESP8266 hold 128 bytes that can be
23
+ // extended using interrupt handlers. The Arduino constants are not available
24
+ // for the ESP8266 platform.
25
+ #if !defined(SERIAL_RX_BUFFER_SIZE) && defined(UART_TX_FIFO_SIZE)
26
+ #define SERIAL_RX_BUFFER_SIZE UART_TX_FIFO_SIZE
27
+ #endif
28
+
29
+
22
30
SerialFirmata::SerialFirmata ()
23
31
{
24
32
#if defined(SoftwareSerial_h)
@@ -29,6 +37,12 @@ SerialFirmata::SerialFirmata()
29
37
#endif
30
38
31
39
serialIndex = -1 ;
40
+
41
+ #if defined(FIRMATA_SERIAL_RX_DELAY)
42
+ for (byte i = 0 ; i < SERIAL_READ_ARR_LEN; i++) {
43
+ maxRxDelay[i] = FIRMATA_SERIAL_RX_DELAY; // @todo provide setter
44
+ }
45
+ #endif
32
46
}
33
47
34
48
boolean SerialFirmata::handlePinMode (byte pin, int mode)
@@ -56,13 +70,17 @@ boolean SerialFirmata::handleSysex(byte command, byte argc, byte *argv)
56
70
Stream *serialPort;
57
71
byte mode = argv[0 ] & SERIAL_MODE_MASK;
58
72
byte portId = argv[0 ] & SERIAL_PORT_ID_MASK;
73
+ if (portId >= SERIAL_READ_ARR_LEN) return false ;
59
74
60
75
switch (mode) {
61
76
case SERIAL_CONFIG:
62
77
{
63
78
long baud = (long )argv[1 ] | ((long )argv[2 ] << 7 ) | ((long )argv[3 ] << 14 );
64
79
serial_pins pins;
65
-
80
+ #if defined(FIRMATA_SERIAL_RX_DELAY)
81
+ lastBytesAvailable[portId] = 0 ;
82
+ lastBytesReceived[portId] = 0 ;
83
+ #endif
66
84
if (portId < 8 ) {
67
85
serialPort = getPortFromId (portId);
68
86
if (serialPort != NULL ) {
@@ -229,6 +247,10 @@ void SerialFirmata::reset()
229
247
serialIndex = -1 ;
230
248
for (byte i = 0 ; i < SERIAL_READ_ARR_LEN; i++) {
231
249
serialBytesToRead[i] = 0 ;
250
+ #if defined(FIRMATA_SERIAL_RX_DELAY)
251
+ lastBytesAvailable[i] = 0 ;
252
+ lastBytesReceived[i] = 0 ;
253
+ #endif
232
254
}
233
255
}
234
256
@@ -302,6 +324,10 @@ void SerialFirmata::checkSerial()
302
324
303
325
if (serialIndex > -1 ) {
304
326
327
+ #if defined(FIRMATA_SERIAL_RX_DELAY)
328
+ unsigned long currentMillis = millis ();
329
+ #endif
330
+
305
331
// loop through all reporting (READ_CONTINUOUS) serial ports
306
332
for (byte i = 0 ; i < serialIndex + 1 ; i++) {
307
333
portId = reportSerial[i];
@@ -316,27 +342,53 @@ void SerialFirmata::checkSerial()
316
342
continue ;
317
343
}
318
344
#endif
319
- if (serialPort->available () > 0 ) {
320
- Firmata.write (START_SYSEX);
321
- Firmata.write (SERIAL_MESSAGE);
322
- Firmata.write (SERIAL_REPLY | portId);
323
-
324
- if (bytesToRead == 0 || (serialPort->available () <= bytesToRead)) {
325
- numBytesToRead = serialPort->available ();
345
+ int bytesAvailable = serialPort->available ();
346
+ if (bytesAvailable > 0 ) {
347
+ #if defined(FIRMATA_SERIAL_RX_DELAY)
348
+ if (bytesAvailable > lastBytesAvailable[portId]) {
349
+ lastBytesReceived[portId] = currentMillis;
350
+ }
351
+ lastBytesAvailable[portId] = bytesAvailable;
352
+ #endif
353
+ if (bytesToRead <= 0 || (bytesAvailable <= bytesToRead)) {
354
+ numBytesToRead = bytesAvailable;
326
355
} else {
327
356
numBytesToRead = bytesToRead;
328
357
}
329
-
358
+ #if defined(FIRMATA_SERIAL_RX_DELAY)
359
+ if (maxRxDelay[portId] >= 0 && numBytesToRead > 0 ) {
360
+ // read and send immediately only if
361
+ // - expected bytes are unknown and the receive buffer has reached 50 %
362
+ // - expected bytes are available
363
+ // - maxRxDelay has expired since last receive (or time counter wrap)
364
+ if (!((bytesToRead <= 0 && bytesAvailable >= SERIAL_RX_BUFFER_SIZE/2 )
365
+ || (bytesToRead > 0 && bytesAvailable >= bytesToRead)
366
+ || (maxRxDelay[portId] > 0 && (currentMillis < lastBytesReceived[portId] || (currentMillis - lastBytesReceived[portId]) >= maxRxDelay[portId])))) {
367
+ // delay
368
+ numBytesToRead = 0 ;
369
+ }
370
+ }
371
+ #endif
330
372
// relay serial data to the serial device
331
- while (numBytesToRead > 0 ) {
332
- serialData = serialPort->read ();
333
- Firmata.write (serialData & 0x7F );
334
- Firmata.write ((serialData >> 7 ) & 0x7F );
335
- numBytesToRead--;
373
+ if (numBytesToRead > 0 ) {
374
+ #if defined(FIRMATA_SERIAL_RX_DELAY)
375
+ lastBytesAvailable[portId] -= numBytesToRead;
376
+ #endif
377
+ Firmata.write (START_SYSEX);
378
+ Firmata.write (SERIAL_MESSAGE);
379
+ Firmata.write (SERIAL_REPLY | portId);
380
+
381
+ // relay serial data to the serial device
382
+ while (numBytesToRead > 0 ) {
383
+ serialData = serialPort->read ();
384
+ Firmata.write (serialData & 0x7F );
385
+ Firmata.write ((serialData >> 7 ) & 0x7F );
386
+ numBytesToRead--;
387
+ }
388
+
389
+ Firmata.write (END_SYSEX);
336
390
}
337
- Firmata.write (END_SYSEX);
338
391
}
339
-
340
392
}
341
393
}
342
394
}
0 commit comments