Overview -------- ``HardwareSerial`` provides access to hardware UART serial ports on ESP32 and related chips. It allows configuration, reading, writing, and event handling for serial communication. Constructor & Destructor ------------------------ **HardwareSerial(uint8_t uart_nr)** Creates a serial port object for the specified UART number (e.g., 0, 1, 2). *Precedence:* Must be called before using any other methods. **~HardwareSerial()** Cleans up resources when the object is destroyed. Initialization & Configuration ------------------------------ ``void begin(unsigned long baud, uint32_t config = SERIAL_8N1, int8_t rxPin = -1, int8_t txPin = -1, bool invert = false, unsigned long timeout_ms = 20000UL, uint8_t rxfifo_full_thrhd = 120)`` Initializes the UART port with baud rate, data format, pin assignment, polarity, timeout, and FIFO threshold. **Comments:** - When pins are changed, it will detach the previous ones. - If pin is negative, it won't be set/changed and will be kept as is. - ``timeout_ms`` is used in baudrate detection (ESP32, ESP32S2 only). - ``invert`` will invert RX/TX polarity. - ``rxfifo_full_thrhd`` is the UART Flow Control Threshold in the UART FIFO (max 127). *Precedence:* Must be called before using read/write functions. If you need to set clock source or pins, call those methods *before* ``begin()``. **void end(void)** Deinitializes the UART port, freeing resources. **void updateBaudRate(unsigned long baud)** Changes the baud rate after initialization. **bool setClockSource(SerialClkSrc clkSrc)** Sets the UART clock source. **Comments:** - Must be set before calling ``begin()``, otherwise it won't have any effect. - Not all clock sources are available to every SoC. See comments for compatible options. **bool setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin = -1, int8_t rtsPin = -1)** Assigns RX, TX, CTS, RTS pins. **Comments:** - Negative Pin Number will keep it unmodified, thus this function can set individual pins. - Can be called after or before ``begin()``. - When pins are changed, it will detach the previous ones. **bool setHwFlowCtrlMode(SerialHwFlowCtrl mode = UART_HW_FLOWCTRL_CTS_RTS, uint8_t threshold = 64)** Enables/disables hardware flow control (RTS/CTS). **Comments:** - Must use ``setPins()`` before enabling flow control. - ``UART_HW_FLOWCTRL_DISABLE = 0x0`` disables hardware flow control. - ``UART_HW_FLOWCTRL_RTS = 0x1`` enables RX hardware flow control (RTS). - ``UART_HW_FLOWCTRL_CTS = 0x2`` enables TX hardware flow control (CTS). - ``UART_HW_FLOWCTRL_CTS_RTS = 0x3`` enables both. **bool setMode(SerialMode mode)** Sets UART mode (e.g., RS485, IRDA). **Comments:** - Used to set RS485 modes such as ``UART_MODE_RS485_HALF_DUPLEX`` for Auto RTS function on ESP32. - Should be set before ``begin()``. **void setRxInvert(bool)** Inverts RX/TX polarity. **void setDebugOutput(bool)** Enables debug output for troubleshooting. **size_t setRxBufferSize(size_t new_size)** Sets the size of the RX buffer. **size_t setTxBufferSize(size_t new_size)** Sets the size of the TX buffer. Data Transmission ----------------- **size_t write(uint8_t)** **size_t write(const uint8_t *buffer, size_t size)** **size_t write(const char *buffer, size_t size)** **size_t write(const char *s)** **size_t write(unsigned long n)** **size_t write(long n)** **size_t write(unsigned int n)** **size_t write(int n)** Sends data over the serial port. **Comments:** - Overloads allow writing single bytes, buffers, strings, and numbers. Data Reception -------------- **int available(void)** Returns the number of bytes available to read. **Comments:** - Affected by ``setRxFIFOFull()``, as the internal RxRingBuffer is filled only after the specified number of bytes arrive or a RX Timeout happens. **int availableForWrite(void)** Returns the number of bytes available for writing (free space in TX buffer). **int peek(void)** Returns the next byte in the RX buffer without removing it. **int read(void)** Reads a single byte from the RX buffer. **size_t read(uint8_t *buffer, size_t size)** **size_t read(char *buffer, size_t size)** Reads multiple bytes into a buffer. **size_t readBytes(uint8_t *buffer, size_t length)** **size_t readBytes(char *buffer, size_t length)** Reads a specified number of bytes into a buffer, optimized for speed. **Comments:** - Overrides ``Stream::readBytes()`` to be faster using IDF. **void flush(void)** Waits for transmission of outgoing serial data to complete. **void flush(bool txOnly)** If ``txOnly`` is true, only flushes TX buffer. Event Handling -------------- **bool setRxTimeout(uint8_t symbols_timeout)** Sets the RX inactivity timeout for triggering the ``onReceive`` callback. **Comments:** - ``symbols_timeout`` defines a timeout threshold in UART symbol periods. - Setting 0 disables the callback call by timeout. - Maximum timeout is calculated automatically by IDF; if set above the maximum, it is ignored and an error is printed on Serial0. - Example: For a baudrate of 9600, ``SERIAL_8N1`` (10 bit symbol) and ``symbols_timeout = 3``, the timeout would be 3 / (9600 / 10) = 3.125 ms. **bool setRxFIFOFull(uint8_t fifoBytes)** Sets the RX FIFO threshold for triggering interrupts and filling the RX buffer. **Comments:** - This affects functions such as ``available()`` and ``read()``. - Setting to 1 allows receiving byte by byte, but increases CPU usage. **void onReceive(OnReceiveCb function, bool onlyOnTimeout = false)** Registers a callback for RX events (FIFO full or timeout). **Comments:** - Called whenever a UART interruption occurs (``UART_INTR_RXFIFO_FULL`` or ``UART_INTR_RXFIFO_TOUT``). - ``onlyOnTimeout = true``: Callback only called when RX Timeout happens; whole stream of bytes will be ready at once. - ``onlyOnTimeout = false``: Callback called when FIFO reaches 120 bytes and also on RX Timeout; stream is split into blocks of 120 bytes. - This option avoids Rx Overflow but leaves packet reassembling to the application. **void onReceiveError(OnReceiveErrorCb function)** Registers a callback for UART error events. **Comments:** - Called on error events (see ``hardwareSerial_error_t``). **void eventQueueReset()** Clears all pending RX and error events. **Comments:** - Useful in some use cases. Miscellaneous ------------- **uint32_t baudRate()** Returns the current baud rate (may be rounded). **Comments:** - Baudrate detection is supported; see example in file header. **operator bool() const** Returns true if the serial port is initialized. Usage Order/Precedence ---------------------- 1. **Create** a ``HardwareSerial`` object. 2. *(Optional)* Set clock source, pins, mode, flow control, buffer sizes, RX invert, debug output. 3. **Call ``begin()``** to initialize the port. 4. **Register event callbacks** if needed. 5. **Use read/write methods** for data transfer. 6. **Call ``end()``** to deinitialize when done. Enums & Typedefs ---------------- - ``SerialConfig``: Data format (bits, parity, stop bits). - ``SerialMode``: UART mode (RS485, IRDA, etc.). - ``SerialHwFlowCtrl``: Hardware flow control options. - ``hardwareSerial_error_t``: UART error types. - ``SerialClkSrc``: UART clock source options. - ``OnReceiveCb``: RX event callback type. - ``OnReceiveErrorCb``: Error event callback type. Global Instances ---------------- - ``Serial0``, ``Serial1``, ...: Predefined global objects for each UART port (if available). **Comments:** - If not using CDC on Boot, Arduino Serial is the UART0 device. - There is always Serial0 for UART0. Example: Baudrate Detection --------------------------- .. code-block:: cpp void setup() { Serial.begin(115200); delay(100); Serial.println(); Serial1.begin(0, SERIAL_8N1, -1, -1, true, 11000UL); // Passing 0 for baudrate to detect it, the last parameter is a timeout in ms unsigned long detectedBaudRate = Serial1.baudRate(); if(detectedBaudRate) { Serial.printf("Detected baudrate is %lu\n", detectedBaudRate); } else { Serial.println("No baudrate detected, Serial1 will not work!"); } } # Note: The baudrate returned by ``baudRate()`` may be rounded, e.g., 115200 returns 115201. For further details, see the comments in the source code file.