Skip to content

Serial port operation has different performance in (windows10 \ MacOS) #196

Closed
@3Q-

Description

@3Q-

The purpose of setting a timeout when using serialport scratch for serial communication is to prevent read operations from waiting indefinitely when no data arrives. If there is data, respond immediately and reset the timeout time. It is normal for me in MAC OS, but in Windows 10 system, even if there is data, I still need to wait until the timeout is reached before obtaining the data for the second read

use serialport;
use std::io::{self, Read, Write};
use std::thread;
use std::time::Duration;

use std::{
    // collections::HashMap,
    sync::{
        // mpsc::{Receiver, Sender, TryRecvError},
        Arc,
        Mutex,
    },
};

macro_rules! log {
    ($($arg:tt)*) => {
        println!(
            "{} ==> {}",
            chrono::Local::now().format("%Y-%m-%d %H:%M:%S%.3f"),
            format_args!($($arg)*)
        )
    };
}

fn main() {
    println!("Please press enter key:");

    let port_path = "COM1";
    let port = serialport::new(port_path, 115_200)
        .parity(serialport::Parity::None)
        .data_bits(serialport::DataBits::Eight)
        .stop_bits(serialport::StopBits::One)
        .flow_control(serialport::FlowControl::None)
        .timeout(Duration::from_millis(3000))
        .open()
        .unwrap();

    let shared_port = Arc::new(Mutex::new(port));

    let read_port = Arc::clone(&shared_port);

    let read_thread = thread::spawn(move || {
        let mut serial = read_port.lock().unwrap().try_clone().unwrap();
        loop {
            let mut buffer = [0u8; 2048];
            match serial.read(&mut buffer) {
                Ok(size) => {
                    log!("Read {} bytes: {:?}", size, &buffer[..size]);
                }

                Err(_err) => {
                    // log!("Error ! {:?}", &err);
                }
            };
            thread::sleep(Duration::from_millis(200));
        }
    });

    let write_port = Arc::clone(&shared_port);

    let write_thread = thread::spawn(move || {
        let value = [0x1b, 0x03, 0x00, 0x00, 0x1e];
        let mut serial = write_port.lock().unwrap().try_clone().unwrap();
        loop {
            let mut input = String::new();
            io::stdin().read_line(&mut input).unwrap();
            log!("<=== your press time {}", input);

            match serial.write(&value) {
                Ok(size) => {
                    log!("write success  size {}", size);
                }
                Err(error) => {
                    log!("write err  {:?}", &error);
                }
            };
            thread::sleep(Duration::from_millis(100));
        }
    });

    if let Err(e) = read_thread.join() {
        eprintln!("Read thread panicked: {:?}", e);
    }

    if let Err(e) = write_thread.join() {
        eprintln!("Write thread panicked: {:?}", e);
    }
}

windows
image
Mac
image

The same operation is very fast in Mac, and in Windows, it is necessary to reread and call the read method after timeout to obtain data, and the write operation is also very time-consuming.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions