### Run List Ports Example Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/README.md Execute the 'list_ports' example to see available serial ports and their type information. ```bash cargo run --example list_ports ``` -------------------------------- ### Run heartbeat and receive_data examples Source: https://github.com/serialport/serialport-rs/blob/main/TESTING.md Simultaneously run the heartbeat example on one device and the receive_data example on another. This is useful for testing two-way communication. ```bash cargo run --example heartbeat ``` ```bash cargo run --example receive_data ``` -------------------------------- ### Run Receive Data Example Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/README.md Execute the 'receive_data' example, specifying a serial port device path to read data from. ```bash cargo run --example receive_data -- /dev/ttyUSB0 ``` -------------------------------- ### Run hardware_check example with loopback mode Source: https://github.com/serialport/serialport-rs/blob/main/TESTING.md Run the hardware_check example in loopback mode with a single device. This simulates a connection by looping the transmit pin back to the receive pin. ```bash cargo run --example hardware_check --loopback ``` -------------------------------- ### Configuration Guide Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/INDEX.md Guide to configuring serial port settings and options. ```APIDOC ## Builder Configuration Options ### Description Details all available configuration options for the `SerialPortBuilder`. ### Options - Baud Rate - Data Bits - Parity - Stop Bits - Flow Control (Software/Hardware) - Timeout settings (read/write) - RTS/DTR control - Exclusive access ### Defaults Provides default values for each configuration option when not explicitly set. ``` ```APIDOC ## Port Path Formats ### Description Specifies the correct format for serial port paths on different platforms. ### Examples - Linux: `/dev/ttyUSB0`, `/dev/ttyACM0` - macOS: `/dev/cu.usbmodem1411` - Windows: `COM1`, `COM3` ``` -------------------------------- ### Full COM Port Example Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-comport.md A complete example of opening a COM port with custom settings, writing data, and reading responses. Includes error handling for read operations and demonstrates cloning the port for concurrent use. Ensure the port name and baud rate are correct for your device. ```rust use serialport::{new, SerialPort, DataBits, Parity, StopBits}; use std::time::Duration; use std::io::{Read, Write}; fn main() -> Result<(), Box> { // Open COM1 with custom settings let mut port = new("COM1", 9600) .data_bits(DataBits::Eight) .parity(Parity::None) .stop_bits(StopBits::One) .timeout(Duration::from_millis(100)) .open()?; // Write data port.write_all(b"Hello")?; port.flush()?; // Read response let mut buffer = [0u8; 64]; match port.read(&mut buffer) { Ok(0) => println!("Timeout: no data received"), Ok(n) => println!("Received {} bytes", n), Err(e) => println!("Error: {}", e), } // Clone port for concurrent operations let _cloned = port.try_clone_native()?; Ok(()) } ``` -------------------------------- ### Run hardware_check example with a single device Source: https://github.com/serialport/serialport-rs/blob/main/TESTING.md Execute the hardware_check example with a single unconnected device. Replace `` with the actual serial port identifier. ```bash cargo run --example hardware_check ``` -------------------------------- ### Windows COMPort Example Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-root.md Demonstrates opening a native COM port on Windows systems. Requires the `COMPort` type. ```rust #[cfg(windows)] { use serialport::COMPort; let port: COMPort = serialport::new("COM1", 9600) .open_native()?; } ``` -------------------------------- ### Install Linux Development Dependencies Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/README.md On Linux systems, ensure necessary development packages like pkg-config and libudev-dev are installed. ```bash # Ubuntu/Debian sudo apt install pkg-config libudev-dev # Fedora sudo dnf install pkgconf-pkg-config systemd-devel ``` -------------------------------- ### TTYPort Pseudo-Terminal Example Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-ttyport.md Demonstrates creating and using a pseudo-terminal (PTY) pair with TTYPort for bidirectional communication. ```APIDOC ## Pseudo-Terminal Example ### Description This example shows how to create a pseudo-terminal (PTY) pair using `TTYPort::pair()`, allowing communication between two ends (master and slave). ### Usage ```rust use serialport::{TTYPort, SerialPort}; use std::io::{Read, Write}; // Create a PTY pair let (mut master, mut slave) = TTYPort::pair()?; println!("Master: {:?}", master.name()); println!("Slave: {:?}", slave.name()); // Write from master side master.write_all(b"test data")?; master.flush()?; // Read from slave side let mut buf = [0u8; 64]; let n = slave.read(&mut buf)?; println!("Slave received: {}", String::from_utf8_lossy(&buf[..n])); // Write from slave side slave.write_all(b"response")?; slave.flush()?; // Read from master side let n = master.read(&mut buf)?; println!("Master received: {}", String::from_utf8_lossy(&buf[..n])); ``` ``` -------------------------------- ### Pseudo-Terminal (PTY) Example Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-ttyport.md Demonstrates creating a PTY pair and performing bidirectional communication between the master and slave ends. ```rust use serialport::{TTYPort, SerialPort}; use std::io::{Read, Write}; // Create a PTY pair let (mut master, mut slave) = TTYPort::pair()?; println!("Master: {:?}", master.name()); println!("Slave: {:?}", slave.name()); // Write from master side master.write_all(b"test data")?; master.flush()?; // Read from slave side let mut buf = [0u8; 64]; let n = slave.read(&mut buf)?; println!("Slave received: {}", String::from_utf8_lossy(&buf[..n])); // Write from slave side slave.write_all(b"response")?; slave.flush()?; // Read from master side let n = master.read(&mut buf)?; println!("Master received: {}", String::from_utf8_lossy(&buf[..n])); ``` -------------------------------- ### Unix TTYPort Example Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-root.md Shows how to open a native TTY port on Unix-like systems and send a break signal. Requires the `TTYPort` and `BreakDuration` types. ```rust #[cfg(unix)] { use serialport::{TTYPort, BreakDuration}; let port: TTYPort = serialport::new("/dev/ttyUSB0", 9600) .open_native()?; port.send_break(BreakDuration::Short)?; } ``` -------------------------------- ### Run hardware_check example with two devices in loopback Source: https://github.com/serialport/serialport-rs/blob/main/TESTING.md Test communication between two devices connected to each other. Specify the first device and the second device to be used as the loopback port. ```bash cargo run --example hardware_check --loopback-port ``` -------------------------------- ### Async Serial Port Read/Write with Tokio Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/README.md Example demonstrating asynchronous reading and writing to a serial port using `tokio-serial`. Ensure you have `tokio-serial` and `tokio` dependencies. ```rust use tokio_serial::{new, SerialPortBuilder}; use tokio::io::{AsyncReadExt, AsyncWriteExt}; let mut port = SerialPortBuilder::new("/dev/ttyUSB0", 9600) .open_native_async()?; // Async read/write port.write_all(b"Hello").await?; ``` -------------------------------- ### Simple Serial Port Read/Write Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-root.md A basic example of opening a serial port, writing data, and then reading the response. Configures a timeout for the port operations. ```rust use serialport::new; use std::time::Duration; use std::io::{Read, Write}; fn main() -> Result<(), Box> { let mut port = new("/dev/ttyUSB0", 115_200) .timeout(Duration::from_millis(100)) .open()?; // Write port.write_all(b"Hello")?; port.flush()?; // Read let mut buf = [0u8; 64]; match port.read(&mut buf) { Ok(n) => println!("Received: {}", String::from_utf8_lossy(&buf[..n])), Err(e) => eprintln!("Error: {}", e), } Ok(()) } ``` -------------------------------- ### SerialPort Timeout Configuration Examples Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/configuration.md Demonstrates setting different timeout values for serial port operations. Includes non-blocking reads, short timeouts for interactive devices, and long timeouts for slow devices. ```rust use serialport::new; use std::time::Duration; // Non-blocking read (immediate timeout) let port = new("/dev/ttyUSB0", 9600) .timeout(Duration::ZERO) .open()?; let mut buf = [0u8; 64]; match port.read(&mut buf) { Ok(0) => println!("No data available"), Ok(n) => println!("Read {} bytes", n), Err(e) => eprintln!("Error: {}", e), } // Short timeout (100ms) — good for interactive devices let port = new("/dev/ttyUSB0", 9600) .timeout(Duration::from_millis(100)) .open()?; // Long timeout (1 second) — good for slow devices let port = new("/dev/ttyUSB0", 9600) .timeout(Duration::from_secs(1)) .open()?; // Very long timeout (use with care) let port = new("/dev/ttyUSB0", 9600) .timeout(Duration::from_secs(60)) .open()?; ``` -------------------------------- ### Handle Device Not Found Error Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/errors.md Check for `ErrorKind::NoDevice` when opening a serial port. Verify the device is connected, the path is correct, and drivers are installed. ```rust use serialport::{new, ErrorKind}; match new("/dev/ttyUSB0", 9600).open() { Err(e) if e.kind() == ErrorKind::NoDevice => { // Solutions: // - Check device is connected // - Verify device path (use available_ports() to find correct path) // - Check USB cable // - Verify driver is installed } _ => {} } ``` -------------------------------- ### SerialPortBuilder::new Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-builder.md Constructs a new SerialPortBuilder with the essential path and baud rate for opening a serial port. This is the starting point for configuring a serial port. ```APIDOC ## SerialPortBuilder::new ### Description Creates a new `SerialPortBuilder` with the specified path and baud rate. ### Method `new(path: impl Into>, baud_rate: u32) -> SerialPortBuilder` ### Parameters #### Path Parameters - **path** (impl Into>) - Required - Serial port path (e.g., `/dev/ttyUSB0` on Unix, `COM1` on Windows) - **baud_rate** (u32) - Required - Baud rate in symbols per second ### Request Example ```rust use serialport::new; let builder = new("/dev/ttyUSB0", 115_200); let port = builder.open()?; ``` ``` -------------------------------- ### Location Parsing and Usage Example Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/types.md Demonstrates how to parse a location string into a `Location` object and use its methods to access bus ID, port chain, and hierarchy information. Requires the `usbportinfo-location` feature. ```rust #[cfg(feature = "usbportinfo-location")] { use std::str::FromStr; use serialport::Location; let loc = Location::from_str("001-1.2.3")?; println!("Bus: {}", loc.bus_id()); println!("Port chain: {:?}", loc.port_chain()); // Check hierarchy let parent_loc = Location::from_str("001-1.2")?; assert!(loc.is_descendant_of(&parent_loc)); // Get parent if let Some(parent) = loc.parent() { println!("Parent: {}", parent); } } ``` -------------------------------- ### Create Serial Port Builder Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-root.md Constructs a builder for opening a serial port with a specified path and baud rate. Use this as a starting point for configuring and opening a serial port. ```rust use serialport::new; let builder = new("/dev/ttyUSB0", 115_200); let port = builder.open()?; ``` -------------------------------- ### Iterate and Match Serial Port Types Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/types.md Example of how to iterate through available serial ports and match their types, specifically identifying USB ports by their Vendor ID (VID) and Product ID (PID). ```rust use serialport::{SerialPortType, available_ports}; let ports = available_ports()?; for port_info in ports { match port_info.port_type { SerialPortType::UsbPort(usb) => { println!("USB: VID=0x{:04x}, PID=0x{:04x}", usb.vid, usb.pid); } SerialPortType::PciPort => println!("PCI port"), SerialPortType::BluetoothPort => println!("Bluetooth"), SerialPortType::Unknown => println!("Unknown type"), } } ``` -------------------------------- ### DTR Control Configuration Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/configuration.md Examples for configuring the Data Terminal Ready (DTR) line on open. Some devices require DTR to be high, while others expect it to be low or preserved from the OS default. ```rust use serialport::new; // Some devices wait for DTR before sending data let port = new("/dev/ttyUSB0", 9600) .dtr_on_open(true) .open()?; // Other devices expect DTR to be low let port = new("/dev/ttyUSB0", 9600) .dtr_on_open(false) .open()?; // Preserve whatever the OS sets by default let port = new("/dev/ttyUSB0", 9600) .preserve_dtr_on_open() .open()?; ``` -------------------------------- ### Discover Available Serial Ports Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/MANIFEST.txt Use `available_ports()` to get a list of serial ports available on the system. This is useful for device discovery. ```rust use serialport::available_ports; fn main() { match available_ports() { Ok(ports) => { if ports.is_empty() { println!("No serial ports found."); } else { println!("Available ports:"); for p in ports { println!(" - {}", p.port_name); } } } Err(e) => { eprintln!("Error listing ports: {}", e); } } } ``` -------------------------------- ### Interactive Serial Port Monitor Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-root.md An example program that creates a serial port connection and then spawns two threads: one for reading data from the port and printing it, and another for reading user input from stdin and writing it to the port. ```rust use serialport::new; use std::io::{self, Read, Write, BufRead}; use std::time::Duration; fn main() -> Result<(), Box> { let port = new("/dev/ttyUSB0", 9600) .timeout(Duration::from_millis(100)) .open()?; let mut cloned = port.try_clone()?; // Read thread let read_handle = std::thread::spawn(move || { let mut buf = [0u8; 64]; loop { match port.read(&mut buf) { Ok(n) => { print!("RX: {}", String::from_utf8_lossy(&buf[..n])); } Err(_) => {} // Timeout } } }); // Write thread let stdin = io::stdin(); for line in stdin.lock().lines() { if let Ok(line) = line { cloned.write_all(line.as_bytes())?; cloned.write_all(b"\r\n")?; } } Ok(()) } ``` -------------------------------- ### Handling Unknown Error in Rust Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/errors.md Provides an example of how to catch the 'Unknown' error kind, which represents unexpected issues. This is useful as a fallback and for debugging platform-specific problems. ```rust use serialport::ErrorKind; match operation() { Ok(result) => println!("Success"), Err(e) if e.kind() == ErrorKind::Unknown => { eprintln!("Unexpected error: {}", e.description); // May warrant reporting as a bug } Err(e) => eprintln!("Known error: {}", e), } ``` -------------------------------- ### macOS/iOS: iossiospeed ioctl usage example Source: https://github.com/serialport/serialport-rs/blob/main/NOTES.md This code demonstrates a scenario where calling `iossiospeed` after `tcsetattr` can lead to issues. Specifically, attempting to get the termios attributes after setting them with `tcsetattr` will fail because `iossiospeed` modifies the kernel's termios struct in a way that prevents a clean round-trip. ```C struct termios t; tcgetattr(fd, &t); tcsetattr(fd, TCSANOW, &t) ``` -------------------------------- ### Get Raw Handle from COMPort Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-comport.md Gets a raw Windows handle for the COM port without taking ownership. This handle can be used with Windows APIs, but requires `unsafe` blocks. ```rust use std::os::windows::io::AsRawHandle; let handle = port.as_raw_handle(); // Use handle with Windows APIs (unsafe) ``` -------------------------------- ### Get Bytes Pending Transmission (Rust) Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-serialport.md Gets the number of bytes that have been written to the output buffer but not yet transmitted by the driver. This is useful for monitoring write operations. Errors can occur if the device disconnects or an I/O error happens. ```rust let pending = port.bytes_to_write()?; println!("Bytes pending transmission: {}", pending); ``` -------------------------------- ### Open Standard and Full Path COM Ports Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-comport.md Demonstrates opening a standard COM port and a port using its full path syntax. Also shows how to list available serial ports on the system. ```rust use serialport::new; // Standard COM port let port = new("COM1", 9600).open()?; // Using full path syntax let port = new(r"\\.\\COM1", 9600).open()?; // Accessing USB-serial adapters by enumeration let ports = serialport::available_ports()?; for p in ports { println!("{}", p.port_name); } ``` -------------------------------- ### serialport::new() Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/_COMPLETION_REPORT.md Creates a new serial port instance. This function is fully documented with examples. ```APIDOC ## serialport::new() ### Description Creates a new serial port instance. This function is fully documented with examples. ### Method (Not specified, likely a constructor or factory function) ### Endpoint (Not applicable for Rust functions) ### Parameters (Not specified in the source text) ### Request Example (Not applicable for Rust functions) ### Response (Not specified in the source text) ``` -------------------------------- ### Enable and run hardware tests with environment variables Source: https://github.com/serialport/serialport-rs/blob/main/TESTING.md Set environment variables for two serial ports and run the hardware tests using cargo. Ensure the paths are absolute using `realpath`. ```bash $ export SERIALPORT_TEST_PORT_1=$(realpath /dev/ttyX) $ export SERIALPORT_TEST_PORT_2=$(realpath /dev/ttyY) $ cargo test --features hardware-tests ``` -------------------------------- ### set_break Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-serialport.md Starts transmitting a break signal, which is a continuous stream of 0-valued bits on the serial line. ```APIDOC ## set_break ### Description Starts transmitting a break signal (continuous stream of 0-valued bits). ### Method `&self` (Rust method) ### Returns - `Result<()>` ### Errors - `NoDevice`: device disconnected - `Io`: platform I/O error ### Example ```rust port.set_break()?; // ... hold break for some duration port.clear_break()?; ``` ``` -------------------------------- ### stop_bits() Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-serialport.md Gets the number of stop bits configured per character for the serial port, which can be One or Two. ```APIDOC ## stop_bits() ### Description Returns the number of stop bits per character. ### Method `stop_bits(&self) -> Result` ### Returns - `Result`: A `StopBits` enum value: `One` or `Two`. ``` -------------------------------- ### Accessing COM Ports with UNC Paths Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-comport.md Demonstrates how to open serial ports using UNC naming conventions, including local and remote access. Ensure the port is available and accessible. ```rust let port = new(r"\\.\\COM1", 9600).open()?; let port = new(r"\\COMPUTER\COM1", 9600).open()?; ``` -------------------------------- ### bytes_to_write Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-serialport.md Gets the number of bytes pending in the output buffer. This shows how many bytes have been written but not yet transmitted by the driver. ```APIDOC ## bytes_to_write ### Description Gets the number of bytes pending in the output buffer. ### Method `&self` (Rust method) ### Returns - `Result`: The number of bytes written but not yet transmitted by the driver. ### Errors - `NoDevice`: device disconnected - `Io`: platform I/O error ### Example ```rust let pending = port.bytes_to_write()?; println!("Bytes pending transmission: {}", pending); ``` ``` -------------------------------- ### Opening Serial Ports Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/README.md Demonstrates how to open a serial port using the `new` function and the `SerialPortBuilder`. ```APIDOC ## Opening Ports ### `serialport::new(path, baud_rate)` Creates a new `SerialPortBuilder` to configure and open a serial port. - **path** (String): The path to the serial port (e.g., `"/dev/ttyUSB0"` or `"COM1"`). - **baud_rate** (u32): The desired baud rate for the serial communication. Returns: - `SerialPortBuilder`: An object for further configuration. ### `SerialPortBuilder::open()` Opens the configured serial port. Returns: - `Result>`: A boxed trait object representing the opened serial port, or an error. ### `SerialPortBuilder::open_native()` Opens the configured serial port, returning the platform-specific implementation. Returns: - `Result`: On Unix-like systems. - `Result`: On Windows systems. - An error if opening fails. ``` -------------------------------- ### flow_control() Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-serialport.md Gets the current flow control mode configured for the serial port, which can be None, Software (XON/XOFF), or Hardware (RTS/CTS). ```APIDOC ## flow_control() ### Description Returns the current flow control mode. ### Method `flow_control(&self) -> Result` ### Returns - `Result`: A `FlowControl` enum value: `None`, `Software` (XON/XOFF), or `Hardware` (RTS/CTS). ### Errors - Returns error if the flow control mode cannot be determined. ``` -------------------------------- ### Configure Serial Port with Detailed Options Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-builder.md Demonstrates a typical pattern for configuring a serial port with detailed options like data bits, parity, stop bits, flow control, timeout, and DTR state. This is a cross-platform method. ```rust use serialport::{new, DataBits, Parity, StopBits, FlowControl}; use std::time::Duration; let port = new("/dev/ttyUSB0", 115_200) .data_bits(DataBits::Eight) .parity(Parity::None) .stop_bits(StopBits::One) .flow_control(FlowControl::None) .timeout(Duration::from_millis(100)) .dtr_on_open(true) .open()?; ``` -------------------------------- ### Get Parity Checking Mode Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-serialport.md Retrieves the current parity checking mode for the serial port. Supported modes are None, Odd, and Even. ```rust let parity = port.parity()?; println!("Parity: {:?}", parity); ``` -------------------------------- ### Troubleshooting: List Ports (Windows) Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/README.md Use `Get-PnPDevice` in PowerShell to list serial port devices on Windows. ```powershell # Device Manager or PowerShell Get-PnPDevice -Class Ports ``` -------------------------------- ### Port Creation and Opening Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-root.md Constructs a builder for opening a serial port with specified path and baud rate. This function initializes a `SerialPortBuilder` with default settings for data bits, flow control, parity, stop bits, timeout, DTR on open, and exclusivity. ```APIDOC ## new(path, baud_rate) -> SerialPortBuilder ### Description Constructs a builder for opening a serial port with specified path and baud rate. This function initializes a `SerialPortBuilder` with default settings for data bits, flow control, parity, stop bits, timeout, DTR on open, and exclusivity. ### Method ```rust pub fn new<'a>( path: impl Into>, baud_rate: u32 ) -> SerialPortBuilder ``` ### Parameters #### Path Parameters - **path** (impl Into>) - Required - Device path: `/dev/ttyUSB0` (Unix), `COM1` (Windows) - **baud_rate** (u32) - Required - Baud rate in symbols per second ### Returns A `SerialPortBuilder` configured with default settings for all other parameters. ### Default Settings Applied - Data bits: `DataBits::Eight` - Flow control: `FlowControl::None` - Parity: `Parity::None` - Stop bits: `StopBits::One` - Timeout: 0ms (blocking indefinitely) - DTR on open: `None` (preserve current state) - Exclusive (Unix): `true` ### Example ```rust use serialport::new; let builder = new("/dev/ttyUSB0", 115_200); let port = builder.open()?; ``` ### String Type Flexibility The `path` parameter accepts any type convertible to `Cow`: ```rust use serialport::new; // String let port = new(String::from("/dev/ttyUSB0"), 9600).open()?; // &str let port = new("/dev/ttyUSB0", 9600).open()?; // String literal const PORT: &str = "/dev/ttyUSB0"; let port = new(PORT, 9600).open()?; // Owned string with modifications let path = format!("/dev/tty ਹੀ{}", "USB0"); let port = new(path, 9600).open()?; ``` ### Common Usage Patterns: Single-line opening with defaults: ```rust let port = serialport::new("/dev/ttyUSB0", 9600).open()?; ``` Configured opening: ```rust use serialport::{new, DataBits, Parity, StopBits, FlowControl}; use std::time::Duration; let port = new("/dev/ttyUSB0", 115_200) .data_bits(DataBits::Eight) .parity(Parity::None) .stop_bits(StopBits::One) .flow_control(FlowControl::Hardware) .timeout(Duration::from_millis(100)) .open()?; ``` ``` -------------------------------- ### Open Serial Port with Error Handling (Rust) Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/README.md Demonstrates how to open a serial port with basic error handling, specifically checking for the 'NoDevice' error kind. ```rust use serialport::{new, ErrorKind}; match new("/dev/ttyUSB0", 9600).open() { Ok(port) => println!("Port opened"), Err(e) if e.kind() == ErrorKind::NoDevice => { eprintln!("Device not found"); } Err(e) => eprintln!("Error: {}", e), } ``` -------------------------------- ### Troubleshooting: List Ports (macOS) Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/README.md Use `ls` commands to list available serial ports on macOS. ```bash # List ports ls /dev/cu.* ls /dev/tty.* ``` -------------------------------- ### bytes_to_read Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-serialport.md Gets the number of bytes available in the input buffer. This indicates how many unread bytes are currently stored in the driver's input buffer. ```APIDOC ## bytes_to_read ### Description Gets the number of bytes available in the input buffer. ### Method `&self` (Rust method) ### Returns - `Result`: The number of unread bytes in the driver's input buffer. ### Errors - `NoDevice`: device disconnected - `Io`: platform I/O error ### Example ```rust let bytes_available = port.bytes_to_read()?; if bytes_available > 0 { println!("Bytes available: {}", bytes_available); } ``` ``` -------------------------------- ### Troubleshooting: Granting Permissions (Linux/macOS) Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/README.md Add your user to the `dialout` group on Linux or change permissions directly on macOS/Linux to resolve 'Permission Denied' errors. Remember to log out and back in after group changes. ```bash # Add user to dialout group (Linux) sudo usermod -a -G dialout $USER # Then log out and log back in # Change permissions (macOS/Linux) sudo chmod 666 /dev/ttyUSB0 ``` -------------------------------- ### Get Stop Bits Setting Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-serialport.md Retrieves the current stop bits setting for the serial port. This can be One or Two stop bits per character. ```rust let stop_bits = port.stop_bits()?; println!("Stop bits: {:?}", stop_bits); ``` -------------------------------- ### Get Flow Control Mode Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-serialport.md Retrieves the current flow control mode configured for the serial port. This can be None, Software (XON/XOFF), or Hardware (RTS/CTS). ```rust let flow_control = port.flow_control()?; println!("Flow control: {:?}", flow_control); ``` -------------------------------- ### Handle Exclusive Port Access on Windows Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-comport.md Demonstrates how attempting to open an already-open COM port on Windows will result in an error due to the OS enforcing exclusive access. No explicit configuration is needed as this is the default behavior. ```rust use serialport::new; let port1 = new("COM1", 9600).open()?; // This will fail: let port2 = new("COM1", 9600).open()?; ``` -------------------------------- ### Get Serial Port Name Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-serialport.md Retrieves the name of the serial port. This might be a shorthand and not the canonical device path. Returns None for virtual ports. ```rust use serialport::SerialPort; let port = serialport::new("/dev/ttyUSB0", 115_200).open()?; if let Some(name) = port.name() { println!("Port name: {}", name); } ``` -------------------------------- ### Open Serial Port with Configuration Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/00-START-HERE.txt Opens a serial port with custom timeout and hardware flow control. Ensure the port path and baud rate are correct. ```rust let port = serialport::new("/dev/ttyUSB0", 9600) .timeout(Duration::from_millis(100)) .flow_control(FlowControl::Hardware) .open()?; ``` -------------------------------- ### `from_raw_fd` Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-ttyport.md Creates a `TTYPort` from a raw file descriptor. This method requires `unsafe` as it takes ownership of a file descriptor and assumes it's a valid TTY device. ```APIDOC ## `from_raw_fd` ### Description Creates a `TTYPort` from a raw file descriptor. ### Method `from_raw_fd(fd: RawFd) -> TTYPort` (unsafe) ### Parameters #### Path Parameters - **fd** (RawFd) - Required - Raw file descriptor from an open TTY device ### Safety - The file descriptor must be a valid, open TTY device - The descriptor must not be shared with other code - The caller must ensure the descriptor is properly closed via `Drop` ### Behavior - Attempts to set exclusive access via `TIOCEXCL` and `flock()` - If either fails, the port will be created in non-exclusive mode (logged but not fatal) - Port name is set to `None` (cannot trivially determine path from FD) - Timeout is set to 100ms ### Example ```rust use std::os::unix::io::FromRawFd; use nix::fcntl::open; use nix::fcntl::OFlag; use std::path::Path; unsafe { let fd = open(Path::new("/dev/ttyS0"), OFlag::O_RDWR, Default::default()).unwrap(); let port = serialport::TTYPort::from_raw_fd(fd); } ``` ``` -------------------------------- ### `as_raw_fd` Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-ttyport.md Gets a raw file descriptor for the underlying TTY device without taking ownership. This allows for low-level Unix API usage with the file descriptor. ```APIDOC ## `as_raw_fd` ### Description Gets a raw file descriptor for the underlying TTY device (does not take ownership). ### Method `as_raw_fd(&self) -> RawFd` ### Example ```rust use std::os::unix::io::AsRawFd; let fd = port.as_raw_fd(); // Use fd with raw Unix APIs (unsafe) ``` ``` -------------------------------- ### Get Read Timeout Duration Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-serialport.md Retrieves the current read timeout setting. A zero duration indicates non-blocking behavior. Note that timeout accuracy is platform-dependent. ```rust let timeout = port.timeout(); println!("Read timeout: {:?}", timeout); ``` -------------------------------- ### Create COMPort from Raw Handle Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-comport.md Creates a `COMPort` instance from a raw Windows handle. The handle must be valid and open, and not shared. The caller must ensure the handle is properly closed via `Drop`. The port name is set to `None` and timeout to 100ms. ```rust use std::os::windows::io::FromRawHandle; use windows_sys::Win32::Storage::FileSystem::*; use windows_sys::Win32::Foundation::*; unsafe { let handle = CreateFileW( "COM1\0".encode_utf16().chain(Some(0)).collect::>().as_ptr(), GENERIC_READ | GENERIC_WRITE, 0, std::ptr::null_mut(), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 as *mut _, ); if handle != INVALID_HANDLE_VALUE { let port = serialport::COMPort::from_raw_handle(handle as RawHandle); } } ``` -------------------------------- ### Open Serial Port (Minimal) Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/00-START-HERE.txt Opens a serial port with minimal configuration. Requires the port path and baud rate. ```rust let port = serialport::new("/dev/ttyUSB0", 115_200).open()?; ``` -------------------------------- ### Get Raw File Descriptor (AsRawFd) Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-ttyport.md Obtain a raw file descriptor for the TTY device without taking ownership. This is useful for interacting with raw Unix APIs. ```rust use std::os::unix::io::AsRawFd; let fd = port.as_raw_fd(); // Use fd with raw Unix APIs (unsafe) ``` -------------------------------- ### Get Data Bits Setting Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-serialport.md Retrieves the current data bits setting for the serial port. This indicates the number of bits per character (5, 6, 7, or 8). ```rust let bits = port.data_bits()?; println!("Data bits: {:?}", bits); ``` -------------------------------- ### Dynamically Reconfigure Serial Port Settings Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/configuration.md Demonstrates how to change serial port settings (baud rate and data bits) after the port has been opened. It includes assertions to verify that the changes have been applied successfully. This allows for runtime adjustments to communication parameters. ```rust use serialport::{ SerialPort, DataBits }; // Change settings after opening port.set_baud_rate(19_200)?; port.set_data_bits(DataBits::Seven)?; // Verify changes assert_eq!(port.baud_rate()?, 19_200); assert_eq!(port.data_bits()?, DataBits::Seven); ``` -------------------------------- ### COMPort::open Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-comport.md Opens a COM port with the specified settings. This function is the primary way to establish a connection to a serial device on Windows. ```APIDOC ## COMPort::open ### Description Opens a COM port with the settings specified in the builder. This is the main entry point for using a serial port on Windows. ### Method Rust function call ### Parameters #### Path Parameters - **builder** (SerialPortBuilder) - Required - Configuration including path, baud rate, and other settings ### Returns - **COMPort** - A Result containing the opened port or an error. ### Errors - **NoDevice**: Device could not be opened (in use, not found, or disconnected). - **InvalidInput**: Invalid device name. - **Io**: I/O error during initialization. ### Port Name Format - Input format: `COM1`, `COM2`, etc. (converted to `\\.\COM1`, etc.) - Alternatively: Full path `\\.\COM1` or raw path beginning with `\\` - Local ports: Paths not starting with `\\` are automatically prefixed with `\\.\` ### Request Example ```rust use serialport::new; use std::time::Duration; let port = new("COM1", 115_200) .timeout(Duration::from_millis(100)) .open()?; ``` ### Response Example (Success returns a `COMPort` object, errors are detailed above) ### Notes - The port is opened in synchronous (blocking) mode. - COM port access is exclusive; attempting to open a port already in use will fail. - Initial timeout is set to platform defaults; configure with `timeout()` builder method. ``` -------------------------------- ### baud_rate() Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-serialport.md Gets the current baud rate of the serial port in symbols per second. Note that the returned rate might differ from the configured rate due to platform specific behavior. ```APIDOC ## baud_rate() ### Description Returns the current baud rate in symbols per second. This may differ from the last specified rate depending on the platform, as some platforms return the actual device baud rate rather than the configured rate. ### Method `baud_rate(&self) -> Result` ### Returns - `Result`: The baud rate as a `u32`. ### Errors - `NoDevice`: Device was disconnected. - `Io`: Platform I/O error. ### Example ```rust let rate = port.baud_rate()?; println!("Current baud rate: {}", rate); ``` ``` -------------------------------- ### Get Current Baud Rate Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-serialport.md Retrieves the current baud rate of the serial port. Note that the returned value might reflect the actual device rate, not necessarily the configured rate. ```rust let rate = port.baud_rate()?; println!("Current baud rate: {}", rate); ``` -------------------------------- ### Enumerating Available Ports Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/README.md Shows how to find all available serial ports on the system. ```APIDOC ## Enumeration ### `serialport::available_ports()` Retrieves a list of all available serial ports on the system. Returns: - `Result>`: A vector of `SerialPortInfo` structs, each containing details about an available port, or an error. ``` -------------------------------- ### Single-line Port Opening with Defaults Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-root.md A concise way to open a serial port using default settings in a single line of code. ```rust let port = serialport::new("/dev/ttyUSB0", 9600).open()?; ``` -------------------------------- ### Platform-Specific COMPort (Windows) Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/MANIFEST.txt This snippet refers to the Windows-specific `COMPort` implementation. It may involve details about Windows handles, COM port naming conventions (e.g., \\.\COMx), and specific Windows API interactions. ```rust // This is a conceptual example. The serialport crate abstracts Windows specifics. // When opening a port on Windows, you'd typically use the COM port name. // Example: // use serialport::new; // // fn main() { // let port_name = "\\\\.\\COM3"; // Windows COM port name // match new(port_name).open() { // Ok(mut port) => { // println!("Successfully opened Windows COM port: {}", port_name); // // Configure and use the port... // } // Err(e) => { // eprintln!("Failed to open Windows COM port {}: {}", port_name, e); // } // } // } ``` -------------------------------- ### Configure Serial Port for Modems Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/configuration.md Sets up a serial port for modems with hardware flow control and a 2-second timeout. ```rust use serialport::{new, FlowControl}; let port = new("/dev/ttyUSB0", 115_200) .flow_control(FlowControl::Hardware) .timeout(Duration::from_secs(2)) .open()?; ``` -------------------------------- ### Validate Serial Port Configuration on Open Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/configuration.md Configuration validation occurs when the port is opened, not when the builder is configured. Invalid settings return errors at `open()` time. This example demonstrates how to handle potential `InvalidInput` errors. ```rust use serialport::{new, DataBits, ErrorKind}; // Builder succeeds (no validation yet) let builder = new("/dev/ttyUSB0", 921_600) .data_bits(DataBits::Five); // Validation happens on open() match builder.open() { Ok(port) => println!("Port opened with requested settings"), Err(e) if e.kind() == ErrorKind::InvalidInput => { println!("Device doesn't support 921600 baud or 5-bit mode"); } Err(e) => println!("Error: {}", e), } ``` -------------------------------- ### Constructing and Displaying a SerialPort Error Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/errors.md Demonstrates how to create a new serialport error with a specific kind and description, and how to print it. ```rust use serialport::{Error, ErrorKind}; let error = Error::new(ErrorKind::NoDevice, "Port /dev/ttyUSB0 not found"); println!("Error: {}", error); // "Error: Port /dev/ttyUSB0 not found" println!("Kind: {:?}", error.kind()); // Kind: NoDevice ``` -------------------------------- ### Get Bytes Available in Input Buffer (Rust) Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-serialport.md Retrieves the number of unread bytes in the input buffer. Use this to check if data is available for reading. Errors can occur if the device disconnects or an I/O error happens. ```rust let bytes_available = port.bytes_to_read()?; if bytes_available > 0 { println!("Bytes available: {}", bytes_available); } ``` -------------------------------- ### Open Serial Port with Basic Configuration Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-builder.md Opens a serial port with a specified path and baud rate, setting a timeout. This is a cross-platform method returning a boxed trait object. ```rust use serialport::new; use std::time::Duration; let mut port = new("/dev/ttyUSB0", 9600) .timeout(Duration::from_secs(1)) .open()?; // Use port via SerialPort trait methods port.write_all(b"Hello")?; ``` -------------------------------- ### Platform-Specific TTYPort (Unix/POSIX) Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/MANIFEST.txt This snippet highlights platform-specific aspects of `TTYPort` on Unix-like systems, such as accessing the raw file descriptor. Exclusive access control is also a key feature. ```rust // This is a conceptual example, actual TTYPort usage might involve // more direct interaction with the underlying file descriptor or specific ioctls. // The serialport crate abstracts much of this. // Example of opening a pseudo-terminal pair (often used for testing): // use serialport::{new, TTYPort}; // use std::os::unix::io::AsRawFd; // // fn main() { // // Creating a pseudo-terminal pair (master and slave) // match TTYPort::open_pair() { // Ok((mut master, slave_name)) => { // println!("Pseudo-terminal pair created. Slave name: {}", slave_name); // // The 'master' can be used like any other serial port // // You can access its raw file descriptor: // let fd = master.as_raw_fd(); // println!("Master file descriptor: {}", fd); // // Use master for communication... // } // Err(e) => { // eprintln!("Failed to create pseudo-terminal pair: {}", e); // } // } // } ``` -------------------------------- ### Create a Pseudo-Terminal (PTY) Pair Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-ttyport.md Creates a pair of connected pseudo-terminal ports for testing or IPC. Both ports start with a 100ms timeout and exclusive access enabled. I/O on the slave port may fail after the master is closed. ```rust use serialport::TTYPort; let (mut master, mut slave) = TTYPort::pair()?; // Write from master, read from slave master.write_all(b"Hello")?; let mut buf = [0u8; 5]; slave.read_exact(&mut buf)?; assert_eq!(&buf, b"Hello"); ``` ```rust use serialport::{new, SerialPort}; let (master, slave) = TTYPort::pair()?; let slave_name = slave.name().unwrap(); // Open slave side through standard serial port API with baud_rate=0 let slave_port = new(&slave_name, 0).open()?; ``` -------------------------------- ### String Type Flexibility for Path Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-root.md Demonstrates the flexibility of the `path` parameter in the `new` function, which accepts various string types convertible to `Cow`. ```rust use serialport::new; // String let port = new(String::from("/dev/ttyUSB0"), 9600).open()?; // &str let port = new("/dev/ttyUSB0", 9600).open()?; // String literal const PORT: &str = "/dev/ttyUSB0"; let port = new(PORT, 9600).open()?; // Owned string with modifications let path = format!("/dev/tty{}", "USB0"); let port = new(path, 9600).open()?; ``` -------------------------------- ### Set and Clear Break Signal (Rust) Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/api-reference-serialport.md Starts transmitting a break signal (continuous stream of 0-valued bits) using `set_break()` and stops it using `clear_break()`. Errors can occur if the device disconnects or an I/O error happens. ```rust port.set_break()?; // ... hold break for some duration port.clear_break()?; ``` -------------------------------- ### Configure Serial Port for Arduino Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/configuration.md Sets up a serial port for an Arduino, specifying the COM port, baud rate, a timeout of 100 milliseconds, and enabling DTR on open. ```rust use serialport::new; use std::time::Duration; let port = new("COM3", 9_600) // or /dev/ttyUSB0 on Linux .timeout(Duration::from_millis(100)) .dtr_on_open(true) .open()?; ``` -------------------------------- ### Handling Io(io::ErrorKind) in Rust Source: https://github.com/serialport/serialport-rs/blob/main/_autodocs/errors.md Illustrates how to catch and inspect platform-specific I/O errors wrapped within the 'Io' error kind. This allows for specific handling of common issues like timeouts or permission denials. ```rust use serialport::ErrorKind; use std::io; match port.read(&mut buffer) { Ok(n) => println!("Read {} bytes", n), Err(e) => { if let ErrorKind::Io(io_kind) = e.kind() { match io_kind { io::ErrorKind::TimedOut => println!("No data within timeout"), io::ErrorKind::Interrupted => println!("Read was interrupted"), io::ErrorKind::PermissionDenied => println!("Access denied"), _ => println!("I/O error: {:?}", io_kind), } } } } ```