EDIT: I thought I had to parse the things coming into the program but the speed it is running at makes it indistinguishable to the eye that the word is being printed piecewise.
I am trying to create a serial monitor in rust using the serialport crate. I am using the following modification of blink code on the uno to test it:
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
Serial.print("HIGH");
delay(700);
digitalWrite(LED_BUILTIN, LOW);
Serial.print("LOW");
delay(700);
}
with println, I am thinking of just concatenating the received buffers and printing on receiving nl or cr. The serial monitor is doing a pretty good job with how it is able to discern a string if a has ended without NL or CR on running the code. How is it doing that? Here is my code right now:
use std::time::Duration;
use serialport;
fn main() {
let open_port_config = serialport::new("/dev/cu.usbmodem1201", 9600).timeout(Duration::from_secs(10));
let open_port_result = open_port_config.open();
let mut port = match open_port_result {
Ok(res) => res,
Err(_) => panic!("Couldn't open the port")
};
println!("Data bits: {}", port.data_bits().unwrap());
println!("Flow control: {}", port.flow_control().unwrap());
println!("Parity: {}", port.parity().unwrap());
println!("Stop bits: {}", port.stop_bits().unwrap());
loop {
let mut serial_buf: [u8; 8] = [0; 8];
port.read(&mut serial_buf[..]).expect("Found No data");
let output = String::from_utf8(serial_buf.to_vec()).unwrap();
println!("{:?},{:?}: {}", serial_buf, output.trim_matches('0円'), output);
}
}
1 Answer 1
The answer is: It does not know. Or, if you want to look at it in a different way: Timing and chance.
You simply never stumbled upon the case that you read the serial buffer on the PC side in the exact moment when the Arduino is in the middle of writing to it. That special case would be where you read and empty the buffer and output "HI" (followed by newline, because you add it in your code) on your serial monitor; then, during the next loop in your rust code, the remaining characters would be read, outputting "GH".
I'd say that you've been lucky that it always worked so far.
The better way would be to always use println
on the Arduinos side; and on the PCs side: the rust function to "read until newline" from a serial connection (I'm guessing it exists because it does exist in other standard libraries; I never worked with rust before). This way, you'll have in-band signalling for "the next data block begins HERE".
-
1If you are building a serial monitor, you are not in control of how it will be used. Some users will fail to systematically add line terminators.Edgar Bonet– Edgar Bonet2024年01月08日 19:17:12 +00:00Commented Jan 8, 2024 at 19:17
it does not know