我一直在开发一个 Rust 项目,通过串口与 Arduino 进行通信。 我发现了一些可以解决问题的货物依赖项。 但我测试过的少数几个,他们也有同样的问题:
我想要生成一个线程,以便可以阻止 Arduino 在任何给定时刻发送的任何传入数据。使用另一个线程从用户获取输入(例如从控制台输入)并将其发送到 Arduino,从而有 2 个线程同时运行。 但是随着该线程的运行,当线程等待来自 Arduino 的数据时,一旦我给出输入,应该写入 Arduino 的线程就会冻结在该方法上。
这里是使用 serialport 板条箱的示例代码:
use std::{
io::{stdin, stdout, Read, Write},
thread,
};
fn main() {
let mut port = serialport::new("COM5", 9600).open().unwrap();
let r_port = port.try_clone().unwrap();
thread::spawn(move || {
for rb in r_port.bytes() {
// I've used all the read methods in their respective matter, but the write method still gets stuck no matter what.
match rb {
Ok(byte) => {
print!("{}", byte as char);
stdout().flush().unwrap();
}
Err(e) => {
eprintln!("{e}");
}
}
}
});
loop {
let mut input = String::new();
stdin().read_line(&mut input).unwrap();
port.write(input.as_bytes()).unwrap(); // thread gets stuck here
}
}
是的,我确保通讯号正确且波特率一致。 非常感谢任何帮助!
我会使用
Arc<Mutex>
来共享对 serialport
的访问。这可能不是最高效的方法,也不是最好的方法,但我想这是最省力的方法 - 只是开始。
(最好的方法可能是使用一个通道进行读取,一个通道进行写入,并且可能使用 Tokio 的异步方法)。
use std::{
io::{stdin, stdout, Read, Write},
thread,
};
use std::sync::{Arc, Mutex};
fn main() {
let mut port = Arc::new(Mutex::new(serialport::new("COM5", 9600).open().unwrap()));
let mut r_port = port.clone(); // create a new atomic ref-counted pointer to port
thread::spawn(move || {
loop {
let p = r_port.bytes().lock(); // get access to the Mutexed port
let num_bytes_to_read = r_port.bytes_to_read();
if num_bytes_to_read > 0 {
for rb in r_port.bytes() {
match rb {
Ok(byte) => {
print!("{}", byte as char);
stdout().flush().unwrap();
}
Err(e) => {
eprintln!("{e}");
}
}
}
} else {
drop(p); // release lock
time.sleep(Duration::from_msecs(100)); // make port available for writing for 100ms
}
}
});
loop {
let mut input = String::new();
stdin().read_line(&mut input).unwrap();
let mut p = port.lock();
p.write(input.as_bytes()).unwrap(); // thread gets stuck here
}
}