|
| 1 | +/* |
| 2 | +
|
| 3 | + This Sketch demonstrates how to use onReceive(callbackFunc) with HardwareSerial |
| 4 | +
|
| 5 | + void HardwareSerial::onReceive(OnReceiveCb function, bool onlyOnTimeout = false) |
| 6 | +
|
| 7 | + It is possible to register an UART callback function that will be called |
| 8 | + every time that UART receives data and an associated interrupt is generated. |
| 9 | +
|
| 10 | + In summary, HardwareSerial::onReceive() works like an RX Interrupt callback, that can be adjusted |
| 11 | + using HardwareSerial::setRxFIFOFull() and HardwareSerial::setRxTimeout(). |
| 12 | +
|
| 13 | + OnReceive will be called, while receiving a stream of data, when every 120 bytes are received (default FIFO Full), |
| 14 | + which may not help in case that the application needs to get all data at once before processing it. |
| 15 | + Therefore, a way to make it work is by detecting the end of a stream transmission. This can be based on a protocol |
| 16 | + or based on timeout with the UART line in idle (no data received - this is the case of this example). |
| 17 | +
|
| 18 | + In some cases, it is necessary to wait for receiving all the data before processing it and parsing the |
| 19 | + UART input. This example demonstrates a way to create a String with all data received from UART0 and |
| 20 | + signaling it using a Mutex for another task to process it. This example uses a timeout of 500ms as a way to |
| 21 | + know when the reception of data has finished. |
| 22 | +
|
| 23 | + The onReceive() callback is called whenever the RX ISR is triggered. |
| 24 | + It can occur because of two possible events: |
| 25 | +
|
| 26 | + 1- UART FIFO FULL: it happens when internal UART FIFO reaches a certain number of bytes. |
| 27 | + Its full capacity is 127 bytes. The FIFO Full threshold for the interrupt can be changed |
| 28 | + using HardwareSerial::setRxFIFOFull(uint8_t fifoFull). |
| 29 | + Default FIFO Full Threshold is set in the UART initialization using HardwareSerial::begin() |
| 30 | + This will depend on the baud rate used when begin() is executed. |
| 31 | + For a baud rate of 115200 or lower, it it just 1 byte, mimicking original Arduino UART driver. |
| 32 | + For a baud rate over 115200 it will be 120 bytes for higher performance. |
| 33 | + Anyway, it can be changed by the application at any time. |
| 34 | +
|
| 35 | + 2- UART RX Timeout: it happens, based on a timeout equivalent to a number of symbols at |
| 36 | + the current baud rate. If the UART line is idle for this timeout, it will raise an interrupt. |
| 37 | + This time can be changed by HardwareSerial::setRxTimeout(uint8_t rxTimeout) |
| 38 | +
|
| 39 | + When any of those two interrupts occur, IDF UART driver will copy FIFO data to its internal |
| 40 | + RingBuffer and then Arduino can read such data. At the same time, Arduino Layer will execute |
| 41 | + the callback function defined with HardwareSerial::onReceive(). |
| 42 | +
|
| 43 | + <bool onlyOnTimeout> parameter (default false) can be used by the application to tell Arduino to |
| 44 | + only execute the callback when the second event above happens (Rx Timeout). At this time all |
| 45 | + received data will be available to be read by the Arduino application. But if the number of |
| 46 | + received bytes is higher than the FIFO space, it will generate an error of FIFO overflow. |
| 47 | + In order to avoid such problem, the application shall set an appropriate RX buffer size using |
| 48 | + HardwareSerial::setRxBufferSize(size_t new_size) before executing begin() for the Serial port. |
| 49 | +*/ |
| 50 | + |
| 51 | + |
1 | 52 | // this will make UART0 work in any case (using or not USB)
|
2 | 53 | #if ARDUINO_USB_CDC_ON_BOOT
|
3 | 54 | #define UART0 Serial0
|
|
0 commit comments